dw_html.pp 72 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617
  1. {
  2. $Id$
  3. FPDoc - Free Pascal Documentation Tool
  4. Copyright (C) 2000 - 2003 by
  5. Areca Systems GmbH / Sebastian Guenther, [email protected]
  6. * HTML/XHTML output generator
  7. See the file COPYING, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. }
  13. unit dw_HTML;
  14. interface
  15. uses Classes, DOM, DOM_HTML, dGlobals, PasTree, dWriter;
  16. const
  17. // Subpage indices for modules
  18. ResstrSubindex = 1;
  19. ConstsSubindex = 2;
  20. TypesSubindex = 3;
  21. ClassesSubindex = 4;
  22. ProcsSubindex = 5;
  23. VarsSubindex = 6;
  24. // Subpage indices for classes
  25. PropertiesByInheritanceSubindex = 1;
  26. PropertiesByNameSubindex = 2;
  27. MethodsByInheritanceSubindex = 3;
  28. MethodsByNameSubindex = 4;
  29. EventsByInheritanceSubindex = 5;
  30. EventsByNameSubindex = 6;
  31. type
  32. TFileAllocator = class
  33. public
  34. procedure AllocFilename(AElement: TPasElement; ASubindex: Integer); virtual;
  35. function GetFilename(AElement: TPasElement;
  36. ASubindex: Integer): String; virtual; abstract;
  37. function GetRelativePathToTop(AElement: TPasElement): String; virtual;
  38. function GetCSSFilename(ARelativeTo: TPasElement): DOMString; virtual;
  39. end;
  40. TShortNameFileAllocator = class(TFileAllocator)
  41. private
  42. FExtension: String;
  43. public
  44. constructor Create(const AExtension: String);
  45. procedure AllocFilename(AElement: TPasElement; ASubindex: Integer); override;
  46. property Extension: String read FExtension;
  47. end;
  48. TLongNameFileAllocator = class(TFileAllocator)
  49. private
  50. FExtension: String;
  51. public
  52. constructor Create(const AExtension: String);
  53. function GetFilename(AElement: TPasElement;
  54. ASubindex: Integer): String; override;
  55. function GetRelativePathToTop(AElement: TPasElement): String; override;
  56. property Extension: String read FExtension;
  57. end;
  58. TPageInfo = class
  59. Element: TPasElement;
  60. SubpageIndex: Integer;
  61. end;
  62. THTMLWriter = class(TFPDocWriter)
  63. private
  64. FAllocator: TFileAllocator;
  65. FPackage: TPasPackage;
  66. function GetPageCount: Integer;
  67. protected
  68. CurDirectory: String; // relative to curdir of process
  69. BaseDirectory: String; // relative path to package base directory
  70. PageInfos: TObjectList; // list of TPageInfo objects
  71. Doc: THTMLDocument;
  72. BodyElement, TitleElement: TDOMElement;
  73. Module: TPasModule;
  74. OutputNodeStack: TList;
  75. CurOutputNode: TDOMNode;
  76. InsideHeadRow, DoPasHighlighting: Boolean;
  77. HighlighterFlags: Byte;
  78. function ResolveLinkID(const Name: String): DOMString;
  79. function ResolveLinkWithinPackage(AElement: TPasElement;
  80. ASubpageIndex: Integer): String;
  81. // Helper functions for creating DOM elements
  82. function CreateEl(Parent: TDOMNode; const AName: DOMString): THTMLElement;
  83. function CreatePara(Parent: TDOMNode): THTMLElement;
  84. function CreateH1(Parent: TDOMNode): THTMLElement;
  85. function CreateH2(Parent: TDOMNode): THTMLElement;
  86. function CreateH3(Parent: TDOMNode): THTMLElement;
  87. function CreateTable(Parent: TDOMNode): THTMLElement;
  88. function CreateContentTable(Parent: TDOMNode): THTMLElement;
  89. function CreateTR(Parent: TDOMNode): THTMLElement;
  90. function CreateTD(Parent: TDOMNode): THTMLElement;
  91. function CreateTD_vtop(Parent: TDOMNode): THTMLElement;
  92. function CreateLink(Parent: TDOMNode; const AHRef: DOMString): THTMLElement;
  93. function CreateAnchor(Parent: TDOMNode; const AName: DOMString): THTMLElement;
  94. function CreateCode(Parent: TDOMNode): THTMLElement;
  95. function CreateWarning(Parent: TDOMNode): THTMLElement;
  96. // Description node conversion
  97. procedure PushOutputNode(ANode: TDOMNode);
  98. procedure PopOutputNode;
  99. procedure DescrWriteText(const AText: DOMString); override;
  100. procedure DescrBeginBold; override;
  101. procedure DescrEndBold; override;
  102. procedure DescrBeginItalic; override;
  103. procedure DescrEndItalic; override;
  104. procedure DescrBeginEmph; override;
  105. procedure DescrEndEmph; override;
  106. procedure DescrWriteFileEl(const AText: DOMString); override;
  107. procedure DescrWriteKeywordEl(const AText: DOMString); override;
  108. procedure DescrWriteVarEl(const AText: DOMString); override;
  109. procedure DescrBeginLink(const AId: DOMString); override;
  110. procedure DescrEndLink; override;
  111. procedure DescrWriteLinebreak; override;
  112. procedure DescrBeginParagraph; override;
  113. procedure DescrEndParagraph; override;
  114. procedure DescrBeginCode(HasBorder: Boolean; const AHighlighterName: String); override;
  115. procedure DescrWriteCodeLine(const ALine: String); override;
  116. procedure DescrEndCode; override;
  117. procedure DescrBeginOrderedList; override;
  118. procedure DescrEndOrderedList; override;
  119. procedure DescrBeginUnorderedList; override;
  120. procedure DescrEndUnorderedList; override;
  121. procedure DescrBeginDefinitionList; override;
  122. procedure DescrEndDefinitionList; override;
  123. procedure DescrBeginListItem; override;
  124. procedure DescrEndListItem; override;
  125. procedure DescrBeginDefinitionTerm; override;
  126. procedure DescrEndDefinitionTerm; override;
  127. procedure DescrBeginDefinitionEntry; override;
  128. procedure DescrEndDefinitionEntry; override;
  129. procedure DescrBeginSectionTitle; override;
  130. procedure DescrBeginSectionBody; override;
  131. procedure DescrEndSection; override;
  132. procedure DescrBeginRemark; override;
  133. procedure DescrEndRemark; override;
  134. procedure DescrBeginTable(ColCount: Integer; HasBorder: Boolean); override;
  135. procedure DescrEndTable; override;
  136. procedure DescrBeginTableCaption; override;
  137. procedure DescrEndTableCaption; override;
  138. procedure DescrBeginTableHeadRow; override;
  139. procedure DescrEndTableHeadRow; override;
  140. procedure DescrBeginTableRow; override;
  141. procedure DescrEndTableRow; override;
  142. procedure DescrBeginTableCell; override;
  143. procedure DescrEndTableCell; override;
  144. procedure AppendText(Parent: TDOMNode; const AText: DOMString);
  145. procedure AppendNbSp(Parent: TDOMNode; ACount: Integer);
  146. procedure AppendSym(Parent: TDOMNode; const AText: DOMString);
  147. procedure AppendKw(Parent: TDOMNode; const AText: DOMString);
  148. function AppendPasSHFragment(Parent: TDOMNode; const AText: String;
  149. AShFlags: Byte): Byte;
  150. procedure AppendShortDescr(Parent: TDOMNode; Element: TPasElement);
  151. procedure AppendDescr(AContext: TPasElement; Parent: TDOMNode;
  152. DescrNode: TDOMElement; AutoInsertBlock: Boolean);
  153. procedure AppendDescrSection(AContext: TPasElement; Parent: TDOMNode;
  154. DescrNode: TDOMElement; const ATitle: DOMString);
  155. procedure AppendShortDescrCell(Parent: TDOMNode; Element: TPasElement);
  156. function AppendHyperlink(Parent: TDOMNode; Element: TPasElement): TDOMElement;
  157. function AppendType(CodeEl, TableEl: TDOMElement;
  158. Element: TPasType; Expanded: Boolean): TDOMElement;
  159. function AppendProcType(CodeEl, TableEl: TDOMElement;
  160. Element: TPasProcedureType; Indent: Integer): TDOMElement;
  161. procedure AppendProcExt(CodeEl: TDOMElement; Element: TPasProcedure);
  162. procedure AppendProcDecl(CodeEl, TableEl: TDOMElement;
  163. Element: TPasProcedureBase);
  164. procedure AppendProcArgsSection(Parent: TDOMNode;
  165. Element: TPasProcedureType);
  166. procedure AppendTitle(const AText: DOMString);
  167. procedure AppendMenuBar(ASubpageIndex: Integer);
  168. procedure FinishElementPage(AElement: TPasElement);
  169. procedure CreatePageBody(AElement: TPasElement; ASubpageIndex: Integer); virtual;
  170. procedure CreatePackagePageBody;
  171. procedure CreateModulePageBody(AModule: TPasModule; ASubpageIndex: Integer);
  172. procedure CreateConstPageBody(AConst: TPasConst);
  173. procedure CreateTypePageBody(AType: TPasType);
  174. procedure CreateClassPageBody(AClass: TPasClassType; ASubpageIndex: Integer);
  175. procedure CreateClassMemberPageBody(AElement: TPasElement);
  176. procedure CreateVarPageBody(AVar: TPasVariable);
  177. procedure CreateProcPageBody(AProc: TPasProcedureBase);
  178. public
  179. constructor Create(AEngine: TFPDocEngine; AAllocator: TFileAllocator;
  180. APackage: TPasPackage);
  181. destructor Destroy; override;
  182. // Single-page generation
  183. function CreateHTMLPage(AElement: TPasElement;
  184. ASubpageIndex: Integer): TXMLDocument;
  185. function CreateXHTMLPage(AElement: TPasElement;
  186. ASubpageIndex: Integer): TXMLDocument;
  187. // For producing complete package documentation
  188. procedure WriteHTMLPages;
  189. procedure WriteXHTMLPages;
  190. SearchPage: String;
  191. property Allocator: TFileAllocator read FAllocator;
  192. property Package: TPasPackage read FPackage;
  193. property PageCount: Integer read GetPageCount;
  194. property OnTest: TNotifyEvent;
  195. end;
  196. implementation
  197. uses SysUtils, XHTML, XMLWrite, HTMWrite, sh_pas;
  198. procedure TFileAllocator.AllocFilename(AElement: TPasElement;
  199. ASubindex: Integer);
  200. begin
  201. end;
  202. function TFileAllocator.GetRelativePathToTop(AElement: TPasElement): String;
  203. begin
  204. SetLength(Result, 0);
  205. end;
  206. function TFileAllocator.GetCSSFilename(ARelativeTo: TPasElement): DOMString;
  207. begin
  208. Result := GetRelativePathToTop(ARelativeTo) + 'fpdoc.css';
  209. end;
  210. constructor TShortNameFileAllocator.Create(const AExtension: String);
  211. begin
  212. inherited Create;
  213. FExtension := AExtension;
  214. end;
  215. procedure TShortNameFileAllocator.AllocFilename(AElement: TPasElement;
  216. ASubindex: Integer);
  217. begin
  218. // !!!: Add element to file list
  219. end;
  220. constructor TLongNameFileAllocator.Create(const AExtension: String);
  221. begin
  222. inherited Create;
  223. FExtension := AExtension;
  224. end;
  225. function TLongNameFileAllocator.GetFilename(AElement: TPasElement;
  226. ASubindex: Integer): String;
  227. var
  228. i: Integer;
  229. begin
  230. if AElement.ClassType = TPasPackage then
  231. Result := 'index'
  232. else if AElement.ClassType = TPasModule then
  233. Result := LowerCase(AElement.Name) + PathDelim + 'index'
  234. else
  235. begin
  236. Result := LowerCase(AElement.PathName);
  237. i := 1;
  238. if Result[1] = '#' then
  239. begin
  240. while Result[i] <> '.' do
  241. Inc(i);
  242. Result := Copy(Result, i + 1, Length(Result));
  243. end;
  244. i := 1;
  245. while Result[i] <> '.' do
  246. Inc(i);
  247. Result[i] := PathDelim;
  248. end;
  249. if ASubindex > 0 then
  250. Result := Result + '-' + IntToStr(ASubindex);
  251. Result := Result + Extension;
  252. end;
  253. function TLongNameFileAllocator.GetRelativePathToTop(AElement: TPasElement): String;
  254. begin
  255. if AElement.ClassType = TPasPackage then
  256. Result := ''
  257. else
  258. Result := '../';
  259. end;
  260. constructor THTMLWriter.Create(AEngine: TFPDocEngine; AAllocator: TFileAllocator;
  261. APackage: TPasPackage);
  262. procedure AddPage(AElement: TPasElement; ASubpageIndex: Integer);
  263. var
  264. PageInfo: TPageInfo;
  265. begin
  266. PageInfo := TPageInfo.Create;
  267. PageInfo.Element := AElement;
  268. PageInfo.SubpageIndex := ASubpageIndex;
  269. PageInfos.Add(PageInfo);
  270. Allocator.AllocFilename(AElement, ASubpageIndex);
  271. if ASubpageIndex = 0 then
  272. Engine.AddLink(AElement.PathName,
  273. Allocator.GetFilename(AElement, ASubpageIndex));
  274. end;
  275. procedure AddPages(AElement: TPasElement; ASubpageIndex: Integer;
  276. AList: TList);
  277. var
  278. i: Integer;
  279. begin
  280. if AList.Count > 0 then
  281. begin
  282. AddPage(AElement, ASubpageIndex);
  283. for i := 0 to AList.Count - 1 do
  284. AddPage(TPasElement(AList[i]), 0);
  285. end;
  286. end;
  287. procedure ScanModule(AModule: TPasModule);
  288. var
  289. i, j, k: Integer;
  290. s: String;
  291. ClassEl: TPasClassType;
  292. FPEl, AncestorMemberEl: TPasElement;
  293. DocNode: TDocNode;
  294. DidAutolink: Boolean;
  295. begin
  296. AddPage(AModule, 0);
  297. with AModule do
  298. begin
  299. if InterfaceSection.ResStrings.Count > 0 then
  300. begin
  301. AddPage(AModule, ResstrSubindex);
  302. s := Allocator.GetFilename(AModule, ResstrSubindex);
  303. for i := 0 to InterfaceSection.ResStrings.Count - 1 do
  304. with TPasResString(InterfaceSection.ResStrings[i]) do
  305. Engine.AddLink(PathName, s + '#' + LowerCase(Name));
  306. end;
  307. AddPages(AModule, ConstsSubindex, InterfaceSection.Consts);
  308. AddPages(AModule, TypesSubindex, InterfaceSection.Types);
  309. if InterfaceSection.Classes.Count > 0 then
  310. begin
  311. AddPage(AModule, ClassesSubindex);
  312. for i := 0 to InterfaceSection.Classes.Count - 1 do
  313. begin
  314. ClassEl := TPasClassType(InterfaceSection.Classes[i]);
  315. AddPage(ClassEl, 0);
  316. // !!!: Only add when there are items
  317. AddPage(ClassEl, PropertiesByInheritanceSubindex);
  318. AddPage(ClassEl, PropertiesByNameSubindex);
  319. AddPage(ClassEl, MethodsByInheritanceSubindex);
  320. AddPage(ClassEl, MethodsByNameSubindex);
  321. AddPage(ClassEl, EventsByInheritanceSubindex);
  322. AddPage(ClassEl, EventsByNameSubindex);
  323. for j := 0 to ClassEl.Members.Count - 1 do
  324. begin
  325. FPEl := TPasElement(ClassEl.Members[j]);
  326. if ((FPEl.Visibility = visPrivate) and Engine.HidePrivate) or
  327. ((FPEl.Visibility = visProtected) and Engine.HideProtected) then
  328. continue;
  329. DocNode := Engine.FindDocNode(FPEl);
  330. if not Assigned(DocNode) then
  331. begin
  332. DidAutolink := False;
  333. if Assigned(ClassEl.AncestorType) and
  334. (ClassEl.AncestorType.ClassType = TPasClassType) then
  335. begin
  336. for k := 0 to TPasClassType(ClassEl.AncestorType).Members.Count - 1 do
  337. begin
  338. AncestorMemberEl :=
  339. TPasElement(TPasClassType(ClassEl.AncestorType).Members[k]);
  340. if AncestorMemberEl.Name = FPEl.Name then
  341. begin
  342. DocNode := Engine.FindDocNode(AncestorMemberEl);
  343. if Assigned(DocNode) then
  344. begin
  345. DidAutolink := True;
  346. Engine.AddLink(FPEl.PathName,
  347. Engine.FindAbsoluteLink(AncestorMemberEl.PathName));
  348. break;
  349. end;
  350. end;
  351. end;
  352. end;
  353. if not DidAutolink then
  354. AddPage(FPEl, 0);
  355. end else
  356. AddPage(FPEl, 0);
  357. end;
  358. end;
  359. end;
  360. AddPages(AModule, ProcsSubindex, InterfaceSection.Functions);
  361. AddPages(AModule, VarsSubindex, InterfaceSection.Variables);
  362. end;
  363. end;
  364. var
  365. i: Integer;
  366. begin
  367. inherited Create(AEngine);
  368. FAllocator := AAllocator;
  369. FPackage := APackage;
  370. OutputNodeStack := TList.Create;
  371. PageInfos := TObjectList.Create;
  372. // Allocate page for the package itself, if a name is given (i.e. <> '#')
  373. if Length(Package.Name) > 1 then
  374. AddPage(Package, 0);
  375. for i := 0 to Package.Modules.Count - 1 do
  376. ScanModule(TPasModule(Package.Modules[i]));
  377. end;
  378. destructor THTMLWriter.Destroy;
  379. begin
  380. PageInfos.Free;
  381. OutputNodeStack.Free;
  382. inherited Destroy;
  383. end;
  384. function THTMLWriter.CreateHTMLPage(AElement: TPasElement;
  385. ASubpageIndex: Integer): TXMLDocument;
  386. var
  387. HTMLEl: THTMLHtmlElement;
  388. HeadEl: THTMLHeadElement;
  389. El: TDOMElement;
  390. begin
  391. Doc := THTMLDocument.Create;
  392. Result := Doc;
  393. Doc.AppendChild(Doc.CreateProcessingInstruction(
  394. 'DOCTYPE', 'HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"'));
  395. HTMLEl := Doc.CreateHtmlElement;
  396. Doc.AppendChild(HTMLEl);
  397. HeadEl := Doc.CreateHeadElement;
  398. HTMLEl.AppendChild(HeadEl);
  399. El := Doc.CreateElement('meta');
  400. HeadEl.AppendChild(El);
  401. El['http-equiv'] := 'Content-Type';
  402. El['content'] := 'text/html; charset=iso8859-1';
  403. TitleElement := Doc.CreateElement('title');
  404. HeadEl.AppendChild(TitleElement);
  405. El := Doc.CreateElement('link');
  406. BodyElement := Doc.CreateElement('body');
  407. HTMLEl.AppendChild(BodyElement);
  408. CreatePageBody(AElement, ASubpageIndex);
  409. HeadEl.AppendChild(El);
  410. El['rel'] := 'stylesheet';
  411. El['type'] := 'text/css';
  412. El['href'] := Allocator.GetCSSFilename(AElement);
  413. end;
  414. function THTMLWriter.CreateXHTMLPage(AElement: TPasElement;
  415. ASubpageIndex: Integer): TXMLDocument;
  416. begin
  417. Result := nil;
  418. end;
  419. procedure CreatePath(const AFilename: String);
  420. var
  421. EndIndex: Integer;
  422. Path: String;
  423. begin
  424. EndIndex := Length(AFilename);
  425. while not (AFilename[EndIndex] in DirSeparators) do
  426. begin
  427. Dec(EndIndex);
  428. if EndIndex = 0 then
  429. exit;
  430. end;
  431. Path := Copy(AFilename, 1, EndIndex - 1);
  432. if not FileExists(Path) then
  433. begin
  434. CreatePath(Path);
  435. MkDir(Path);
  436. end;
  437. end;
  438. procedure THTMLWriter.WriteHTMLPages;
  439. var
  440. i: Integer;
  441. PageDoc: TXMLDocument;
  442. Filename: String;
  443. begin
  444. Engine.Output := IncludeTrailingBackSlash(Engine.Output);
  445. for i := 0 to PageInfos.Count - 1 do
  446. with TPageInfo(PageInfos[i]) do
  447. begin
  448. PageDoc := CreateHTMLPage(Element, SubpageIndex);
  449. try
  450. Filename := Engine.Output + Allocator.GetFilename(Element, SubpageIndex);
  451. CreatePath(Filename);
  452. WriteHTMLFile(PageDoc, Filename);
  453. finally
  454. PageDoc.Free;
  455. end;
  456. end;
  457. end;
  458. procedure THTMLWriter.WriteXHTMLPages;
  459. begin
  460. end;
  461. {procedure THTMLWriter.CreateDoc(const ATitle: DOMString;
  462. AElement: TPasElement; const AFilename: String);
  463. var
  464. El: TDOMElement;
  465. DocInfo: TDocInfo;
  466. CSSName: String;
  467. begin
  468. Doc := TXHTMLDocument.Create;
  469. with TXHTMLDocument(Doc) do
  470. begin
  471. Encoding := 'ISO8859-1';
  472. CSSName := 'fpdoc.css';
  473. if Assigned(Module) then
  474. CSSName := '../' + CSSName;
  475. $IFNDEF ver1_0
  476. StylesheetType := 'text/css';
  477. StylesheetHRef := CSSName;
  478. $ENDIF
  479. CreateRoot(xhtmlStrict);
  480. with RequestHeadElement do
  481. begin
  482. AppendText(RequestTitleElement, ATitle);
  483. El := CreateElement('link');
  484. AppendChild(El);
  485. El['rel'] := 'stylesheet';
  486. El['type'] := 'text/css';
  487. El['href'] := CSSName;
  488. end;
  489. Self.BodyElement := RequestBodyElement('en');
  490. end;
  491. if Length(AFilename) > 0 then
  492. begin
  493. DocInfo := TDocInfo.Create;
  494. DocInfos.Add(DocInfo);
  495. DocInfo.Element := AElement;
  496. DocInfo.Filename := AFilename;
  497. end;
  498. end;
  499. }
  500. { Used for:
  501. - <link> elements in descriptions
  502. - "see also" entries
  503. - AppendHyperlink (for unresolved parse tree element links)
  504. }
  505. function THTMLWriter.ResolveLinkID(const Name: String): DOMString;
  506. var
  507. i: Integer;
  508. ThisPackage: TLinkNode;
  509. begin
  510. if Length(Name) = 0 then
  511. begin
  512. SetLength(Result, 0);
  513. exit;
  514. end;
  515. if Name[1] = '#' then
  516. Result := Engine.FindAbsoluteLink(Name)
  517. else
  518. begin
  519. SetLength(Result, 0);
  520. { Try all packages }
  521. ThisPackage := Engine.RootLinkNode.FirstChild;
  522. while Assigned(ThisPackage) do
  523. begin
  524. Result := Engine.FindAbsoluteLink(ThisPackage.Name + '.' + Name);
  525. if Length(Result) = 0 then
  526. begin
  527. Result := Engine.FindAbsoluteLink(Module.PathName + '.' + Name);
  528. // WriteLn('Suche nach ', Module.PathName + '.' + Name, ' => ', Result);
  529. if Length(Result) = 0 then
  530. for i := Length(Name) downto 1 do
  531. if Name[i] = '.' then
  532. begin
  533. Result := ResolveLinkID(Copy(Name, 1, i - 1));
  534. break;
  535. end;
  536. end;
  537. ThisPackage := ThisPackage.NextSibling;
  538. end;
  539. end;
  540. if Length(Result) > 0 then
  541. if Copy(Result, 1, Length(CurDirectory) + 1) = CurDirectory + '/' then
  542. Result := Copy(Result, Length(CurDirectory) + 2, Length(Result))
  543. else
  544. Result := BaseDirectory + Result;
  545. end;
  546. function THTMLWriter.ResolveLinkWithinPackage(AElement: TPasElement;
  547. ASubpageIndex: Integer): String;
  548. var
  549. ParentEl: TPasElement;
  550. begin
  551. ParentEl := AElement;
  552. while Assigned(ParentEl) and not (ParentEl.ClassType = TPasPackage) do
  553. ParentEl := ParentEl.Parent;
  554. if Assigned(ParentEl) and (TPasPackage(ParentEl) = Engine.Package) then
  555. begin
  556. Result := Allocator.GetFilename(AElement, ASubpageIndex);
  557. if Copy(Result, 1, Length(CurDirectory) + 1) = CurDirectory + '/' then
  558. Result := Copy(Result, Length(CurDirectory) + 2, Length(Result))
  559. else
  560. Result := BaseDirectory + Result;
  561. end else
  562. SetLength(Result, 0);
  563. end;
  564. function THTMLWriter.CreateEl(Parent: TDOMNode;
  565. const AName: DOMString): THTMLElement;
  566. begin
  567. Result := Doc.CreateElement(AName);
  568. Parent.AppendChild(Result);
  569. end;
  570. function THTMLWriter.CreatePara(Parent: TDOMNode): THTMLElement;
  571. begin
  572. Result := CreateEl(Parent, 'p');
  573. end;
  574. function THTMLWriter.CreateH1(Parent: TDOMNode): THTMLElement;
  575. begin
  576. Result := CreateEl(Parent, 'h1');
  577. end;
  578. function THTMLWriter.CreateH2(Parent: TDOMNode): THTMLElement;
  579. begin
  580. Result := CreateEl(Parent, 'h2');
  581. end;
  582. function THTMLWriter.CreateH3(Parent: TDOMNode): THTMLElement;
  583. begin
  584. Result := CreateEl(Parent, 'h3');
  585. end;
  586. function THTMLWriter.CreateTable(Parent: TDOMNode): THTMLElement;
  587. begin
  588. Result := CreateEl(Parent, 'table');
  589. Result['cellspacing'] := '0';
  590. Result['cellpadding'] := '0';
  591. end;
  592. function THTMLWriter.CreateContentTable(Parent: TDOMNode): THTMLElement;
  593. begin
  594. Result := CreateEl(Parent, 'table');
  595. end;
  596. function THTMLWriter.CreateTR(Parent: TDOMNode): THTMLElement;
  597. begin
  598. Result := CreateEl(Parent, 'tr');
  599. end;
  600. function THTMLWriter.CreateTD(Parent: TDOMNode): THTMLElement;
  601. begin
  602. Result := CreateEl(Parent, 'td');
  603. end;
  604. function THTMLWriter.CreateTD_vtop(Parent: TDOMNode): THTMLElement;
  605. begin
  606. Result := CreateEl(Parent, 'td');
  607. Result['valign'] := 'top';
  608. end;
  609. function THTMLWriter.CreateLink(Parent: TDOMNode;
  610. const AHRef: DOMString): THTMLElement;
  611. begin
  612. Result := CreateEl(Parent, 'a');
  613. Result['href'] := AHRef;
  614. end;
  615. function THTMLWriter.CreateAnchor(Parent: TDOMNode;
  616. const AName: DOMString): THTMLElement;
  617. begin
  618. Result := CreateEl(Parent, 'a');
  619. Result['name'] := AName;
  620. end;
  621. function THTMLWriter.CreateCode(Parent: TDOMNode): THTMLElement;
  622. begin
  623. Result := CreateEl(CreateEl(Parent, 'tt'), 'nobr');
  624. end;
  625. function THTMLWriter.CreateWarning(Parent: TDOMNode): THTMLElement;
  626. begin
  627. Result := CreateEl(Parent, 'span');
  628. Result['class'] := 'warning';
  629. end;
  630. procedure THTMLWriter.PushOutputNode(ANode: TDOMNode);
  631. begin
  632. OutputNodeStack.Add(CurOutputNode);
  633. CurOutputNode := ANode;
  634. end;
  635. procedure THTMLWriter.PopOutputNode;
  636. begin
  637. CurOutputNode := TDOMNode(OutputNodeStack[OutputNodeStack.Count - 1]);
  638. OutputNodeStack.Delete(OutputNodeStack.Count - 1);
  639. end;
  640. procedure THTMLWriter.DescrWriteText(const AText: DOMString);
  641. begin
  642. AppendText(CurOutputNode, AText);
  643. end;
  644. procedure THTMLWriter.DescrBeginBold;
  645. begin
  646. PushOutputNode(CreateEl(CurOutputNode, 'b'));
  647. end;
  648. procedure THTMLWriter.DescrEndBold;
  649. begin
  650. PopOutputNode;
  651. end;
  652. procedure THTMLWriter.DescrBeginItalic;
  653. begin
  654. PushOutputNode(CreateEl(CurOutputNode, 'i'));
  655. end;
  656. procedure THTMLWriter.DescrEndItalic;
  657. begin
  658. PopOutputNode;
  659. end;
  660. procedure THTMLWriter.DescrBeginEmph;
  661. begin
  662. PushOutputNode(CreateEl(CurOutputNode, 'em'));
  663. end;
  664. procedure THTMLWriter.DescrEndEmph;
  665. begin
  666. PopOutputNode;
  667. end;
  668. procedure THTMLWriter.DescrWriteFileEl(const AText: DOMString);
  669. var
  670. NewEl: TDOMElement;
  671. begin
  672. NewEl := CreateEl(CurOutputNode, 'span');
  673. NewEl['class'] := 'file';
  674. AppendText(NewEl, AText);
  675. end;
  676. procedure THTMLWriter.DescrWriteKeywordEl(const AText: DOMString);
  677. var
  678. NewEl: TDOMElement;
  679. begin
  680. NewEl := CreateEl(CurOutputNode, 'span');
  681. NewEl['class'] := 'kw';
  682. AppendText(NewEl, AText);
  683. end;
  684. procedure THTMLWriter.DescrWriteVarEl(const AText: DOMString);
  685. begin
  686. AppendText(CreateEl(CurOutputNode, 'var'), AText);
  687. end;
  688. procedure THTMLWriter.DescrBeginLink(const AId: DOMString);
  689. var
  690. s: DOMString;
  691. begin
  692. s := ResolveLinkID(AId);
  693. if Length(s) = 0 then
  694. begin
  695. WriteLn(Format(SErrUnknownLinkID, [AId]));
  696. PushOutputNode(CreateEl(CurOutputNode, 'b'));
  697. end else
  698. PushOutputNode(CreateLink(CurOutputNode, s));
  699. end;
  700. procedure THTMLWriter.DescrEndLink;
  701. begin
  702. PopOutputNode;
  703. end;
  704. procedure THTMLWriter.DescrWriteLinebreak;
  705. begin
  706. CreateEl(CurOutputNode, 'br');
  707. end;
  708. procedure THTMLWriter.DescrBeginParagraph;
  709. begin
  710. PushOutputNode(CreatePara(CurOutputNode));
  711. end;
  712. procedure THTMLWriter.DescrEndParagraph;
  713. begin
  714. PopOutputNode;
  715. end;
  716. procedure THTMLWriter.DescrBeginCode(HasBorder: Boolean; const AHighlighterName: String);
  717. begin
  718. DoPasHighlighting := (AHighlighterName = '') or (AHighlighterName = 'Pascal');
  719. HighlighterFlags := 0;
  720. PushOutputNode(CreateEl(CurOutputNode, 'pre'));
  721. end;
  722. procedure THTMLWriter.DescrWriteCodeLine(const ALine: String);
  723. begin
  724. if DoPasHighlighting then
  725. begin
  726. HighlighterFlags := AppendPasSHFragment(CurOutputNode, ALine,
  727. HighlighterFlags);
  728. AppendText(CurOutputNode, #10);
  729. end else
  730. AppendText(CurOutputNode, ALine + #10);
  731. end;
  732. procedure THTMLWriter.DescrEndCode;
  733. begin
  734. PopOutputNode;
  735. end;
  736. procedure THTMLWriter.DescrBeginOrderedList;
  737. begin
  738. PushOutputNode(CreateEl(CurOutputNode, 'ol'));
  739. end;
  740. procedure THTMLWriter.DescrEndOrderedList;
  741. begin
  742. PopOutputNode;
  743. end;
  744. procedure THTMLWriter.DescrBeginUnorderedList;
  745. begin
  746. PushOutputNode(CreateEl(CurOutputNode, 'ul'));
  747. end;
  748. procedure THTMLWriter.DescrEndUnorderedList;
  749. begin
  750. PopOutputNode;
  751. end;
  752. procedure THTMLWriter.DescrBeginDefinitionList;
  753. begin
  754. PushOutputNode(CreateEl(CurOutputNode, 'dl'));
  755. end;
  756. procedure THTMLWriter.DescrEndDefinitionList;
  757. begin
  758. PopOutputNode;
  759. end;
  760. procedure THTMLWriter.DescrBeginListItem;
  761. begin
  762. PushOutputNode(CreateEl(CurOutputNode, 'li'));
  763. end;
  764. procedure THTMLWriter.DescrEndListItem;
  765. begin
  766. PopOutputNode;
  767. end;
  768. procedure THTMLWriter.DescrBeginDefinitionTerm;
  769. begin
  770. PushOutputNode(CreateEl(CurOutputNode, 'dt'));
  771. end;
  772. procedure THTMLWriter.DescrEndDefinitionTerm;
  773. begin
  774. PopOutputNode;
  775. end;
  776. procedure THTMLWriter.DescrBeginDefinitionEntry;
  777. begin
  778. PushOutputNode(CreateEl(CurOutputNode, 'dd'));
  779. end;
  780. procedure THTMLWriter.DescrEndDefinitionEntry;
  781. begin
  782. PopOutputNode;
  783. end;
  784. procedure THTMLWriter.DescrBeginSectionTitle;
  785. begin
  786. PushOutputNode(CreateEl(CurOutputNode, 'h3'));
  787. end;
  788. procedure THTMLWriter.DescrBeginSectionBody;
  789. begin
  790. PopOutputNode;
  791. end;
  792. procedure THTMLWriter.DescrEndSection;
  793. begin
  794. end;
  795. procedure THTMLWriter.DescrBeginRemark;
  796. var
  797. NewEl, TDEl: TDOMElement;
  798. begin
  799. NewEl := CreateEl(CurOutputNode, 'table');
  800. NewEl['width'] := '100%';
  801. NewEl['border'] := '0';
  802. NewEl['CellSpacing'] := '0';
  803. NewEl['class'] := 'remark';
  804. NewEl := CreateTR(NewEl);
  805. TDEl := CreateTD(NewEl);
  806. TDEl['valign'] := 'top';
  807. TDEl['class'] := 'pre';
  808. AppendText(CreateEl(TDEl, 'b'), SDocRemark);
  809. PushOutputNode(CreateTD(NewEl));
  810. end;
  811. procedure THTMLWriter.DescrEndRemark;
  812. begin
  813. PopOutputNode;
  814. end;
  815. procedure THTMLWriter.DescrBeginTable(ColCount: Integer; HasBorder: Boolean);
  816. var
  817. Table: TDOMElement;
  818. begin
  819. Table := CreateEl(CurOutputNode, 'table');
  820. Table['border'] := IntToStr(Ord(HasBorder));
  821. PushOutputNode(Table);
  822. end;
  823. procedure THTMLWriter.DescrEndTable;
  824. begin
  825. PopOutputNode;
  826. end;
  827. procedure THTMLWriter.DescrBeginTableCaption;
  828. begin
  829. PushOutputNode(CreateEl(CurOutputNode, 'caption'));
  830. end;
  831. procedure THTMLWriter.DescrEndTableCaption;
  832. begin
  833. PopOutputNode;
  834. end;
  835. procedure THTMLWriter.DescrBeginTableHeadRow;
  836. begin
  837. PushOutputNode(CreateTr(CurOutputNode));
  838. InsideHeadRow := True;
  839. end;
  840. procedure THTMLWriter.DescrEndTableHeadRow;
  841. begin
  842. InsideHeadRow := False;
  843. PopOutputNode;
  844. end;
  845. procedure THTMLWriter.DescrBeginTableRow;
  846. begin
  847. PushOutputNode(CreateTR(CurOutputNode));
  848. end;
  849. procedure THTMLWriter.DescrEndTableRow;
  850. begin
  851. PopOutputNode;
  852. end;
  853. procedure THTMLWriter.DescrBeginTableCell;
  854. begin
  855. if InsideHeadRow then
  856. PushOutputNode(CreateEl(CurOutputNode, 'th'))
  857. else
  858. PushOutputNode(CreateTD(CurOutputNode));
  859. end;
  860. procedure THTMLWriter.DescrEndTableCell;
  861. begin
  862. PopOutputNode;
  863. end;
  864. procedure THTMLWriter.AppendText(Parent: TDOMNode; const AText: DOMString);
  865. begin
  866. Parent.AppendChild(Doc.CreateTextNode(AText));
  867. end;
  868. procedure THTMLWriter.AppendNbSp(Parent: TDOMNode; ACount: Integer);
  869. begin
  870. while ACount > 0 do
  871. begin
  872. Parent.AppendChild(Doc.CreateEntityReference('nbsp'));
  873. Dec(ACount);
  874. end;
  875. end;
  876. procedure THTMLWriter.AppendSym(Parent: TDOMNode; const AText: DOMString);
  877. var
  878. El: TDOMElement;
  879. begin
  880. El := CreateEl(Parent, 'span');
  881. El['class'] := 'sym';
  882. AppendText(El, AText);
  883. end;
  884. procedure THTMLWriter.AppendKw(Parent: TDOMNode; const AText: DOMString);
  885. var
  886. El: TDOMElement;
  887. begin
  888. El := CreateEl(Parent, 'span');
  889. El['class'] := 'kw';
  890. AppendText(El, AText);
  891. end;
  892. function THTMLWriter.AppendPasSHFragment(Parent: TDOMNode;
  893. const AText: String; AShFlags: Byte): Byte;
  894. var
  895. CurParent: TDOMNode;
  896. Line, Last, p: PChar;
  897. IsInSpecial: Boolean;
  898. El: TDOMElement;
  899. begin
  900. GetMem(Line, Length(AText) * 3 + 4);
  901. DoPascalHighlighting(AShFlags, PChar(AText), Line);
  902. Result := AShFlags;
  903. CurParent := Parent;
  904. IsInSpecial := False;
  905. Last := Line;
  906. p := Line;
  907. while p[0] <> #0 do
  908. begin
  909. if p[0] = LF_ESCAPE then
  910. begin
  911. p[0] := #0;
  912. AppendText(CurParent, Last);
  913. if IsInSpecial then
  914. CurParent := Parent;
  915. case Ord(p[1]) of
  916. shDefault:
  917. IsInSpecial := False;
  918. shInvalid:
  919. begin
  920. El := CreateEl(CurParent, 'font');
  921. El['color'] := 'red';
  922. CurParent := El;
  923. IsInSpecial := True;
  924. end;
  925. shSymbol:
  926. begin
  927. El := CreateEl(CurParent, 'span');
  928. El['class'] := 'sym';
  929. CurParent := El;
  930. IsInSpecial := True;
  931. end;
  932. shKeyword:
  933. begin
  934. El := CreateEl(CurParent, 'span');
  935. El['class'] := 'kw';
  936. CurParent := El;
  937. IsInSpecial := True;
  938. end;
  939. shComment:
  940. begin
  941. El := CreateEl(CurParent, 'span');
  942. El['class'] := 'cmt';
  943. CurParent := El;
  944. IsInSpecial := True;
  945. end;
  946. shDirective:
  947. begin
  948. El := CreateEl(CurParent, 'span');
  949. El['class'] := 'dir';
  950. CurParent := El;
  951. IsInSpecial := True;
  952. end;
  953. shNumbers:
  954. begin
  955. El := CreateEl(CurParent, 'span');
  956. El['class'] := 'num';
  957. CurParent := El;
  958. IsInSpecial := True;
  959. end;
  960. shCharacters:
  961. begin
  962. El := CreateEl(CurParent, 'span');
  963. El['class'] := 'chr';
  964. CurParent := El;
  965. IsInSpecial := True;
  966. end;
  967. shStrings:
  968. begin
  969. El := CreateEl(CurParent, 'span');
  970. El['class'] := 'str';
  971. CurParent := El;
  972. IsInSpecial := True;
  973. end;
  974. shAssembler:
  975. begin
  976. El := CreateEl(CurParent, 'span');
  977. El['class'] := 'asm';
  978. CurParent := El;
  979. IsInSpecial := True;
  980. end;
  981. end;
  982. Last := p + 2;
  983. end;
  984. Inc(p);
  985. end;
  986. if Last <> p then
  987. AppendText(CurParent, Last);
  988. FreeMem(Line);
  989. end;
  990. procedure THTMLWriter.AppendShortDescr(Parent: TDOMNode; Element: TPasElement);
  991. var
  992. DocNode: TDocNode;
  993. begin
  994. DocNode := Engine.FindDocNode(Element);
  995. if Assigned(DocNode) and Assigned(DocNode.ShortDescr) then
  996. begin
  997. PushOutputNode(Parent);
  998. try
  999. if not ConvertShort(Element, DocNode.ShortDescr) then
  1000. WriteLn(SErrInvalidShortDescr);
  1001. finally
  1002. PopOutputNode;
  1003. end;
  1004. end;
  1005. end;
  1006. procedure THTMLWriter.AppendDescr(AContext: TPasElement; Parent: TDOMNode;
  1007. DescrNode: TDOMElement; AutoInsertBlock: Boolean);
  1008. begin
  1009. if Assigned(DescrNode) then
  1010. begin
  1011. PushOutputNode(Parent);
  1012. try
  1013. ConvertDescr(AContext, DescrNode, AutoInsertBlock);
  1014. finally
  1015. PopOutputNode;
  1016. end;
  1017. end;
  1018. end;
  1019. procedure THTMLWriter.AppendDescrSection(AContext: TPasElement;
  1020. Parent: TDOMNode; DescrNode: TDOMElement; const ATitle: DOMString);
  1021. begin
  1022. if not IsDescrNodeEmpty(DescrNode) then
  1023. begin
  1024. AppendText(CreateH2(Parent), ATitle);
  1025. AppendDescr(AContext, Parent, DescrNode, True);
  1026. end;
  1027. end;
  1028. procedure THTMLWriter.AppendShortDescrCell(Parent: TDOMNode;
  1029. Element: TPasElement);
  1030. var
  1031. ParaEl: TDOMElement;
  1032. begin
  1033. if Assigned(Engine.FindShortDescr(Element)) then
  1034. begin
  1035. AppendNbSp(CreatePara(CreateTD(Parent)), 2);
  1036. ParaEl := CreatePara(CreateTD(Parent));
  1037. ParaEl['class'] := 'cmt';
  1038. AppendShortDescr(ParaEl, Element);
  1039. end;
  1040. end;
  1041. function THTMLWriter.AppendHyperlink(Parent: TDOMNode;
  1042. Element: TPasElement): TDOMElement;
  1043. var
  1044. s: String;
  1045. UnitList: TList;
  1046. i: Integer;
  1047. ThisPackage: TLinkNode;
  1048. begin
  1049. if Assigned(Element) then
  1050. begin
  1051. if Element.InheritsFrom(TPasUnresolvedTypeRef) then
  1052. begin
  1053. s := ResolveLinkID(Element.Name);
  1054. if Length(s) = 0 then
  1055. begin
  1056. { Try all packages }
  1057. ThisPackage := Engine.RootLinkNode.FirstChild;
  1058. while Assigned(ThisPackage) do
  1059. begin
  1060. s := ResolveLinkID(ThisPackage.Name + '.' + Element.Name);
  1061. if Length(s) > 0 then
  1062. break;
  1063. ThisPackage := ThisPackage.NextSibling;
  1064. end;
  1065. if Length(s) = 0 then
  1066. begin
  1067. { Okay, then we have to try all imported units of the current module }
  1068. UnitList := Module.InterfaceSection.UsesList;
  1069. for i := UnitList.Count - 1 downto 0 do
  1070. begin
  1071. { Try all packages }
  1072. ThisPackage := Engine.RootLinkNode.FirstChild;
  1073. while Assigned(ThisPackage) do
  1074. begin
  1075. s := ResolveLinkID(ThisPackage.Name + '.' +
  1076. TPasType(UnitList[i]).Name + '.' + Element.Name);
  1077. if Length(s) > 0 then
  1078. break;
  1079. ThisPackage := ThisPackage.NextSibling;
  1080. end;
  1081. if Length(s) > 0 then
  1082. break;
  1083. end;
  1084. end;
  1085. end;
  1086. end else
  1087. s := ResolveLinkID(Element.PathName);
  1088. if Length(s) > 0 then
  1089. begin
  1090. Result := CreateLink(Parent, s);
  1091. AppendText(Result, Element.Name);
  1092. end else
  1093. begin
  1094. Result := nil;
  1095. AppendText(Parent, Element.Name);
  1096. end;
  1097. end else
  1098. begin
  1099. Result := nil;
  1100. AppendText(CreateWarning(Parent), '<NIL>');
  1101. end;
  1102. end;
  1103. { Returns the new CodeEl, which will be the old CodeEl in most cases }
  1104. function THTMLWriter.AppendType(CodeEl, TableEl: TDOMElement;
  1105. Element: TPasType; Expanded: Boolean): TDOMElement;
  1106. begin
  1107. Result := CodeEl;
  1108. if not Assigned(Element) then
  1109. AppendText(CreateWarning(CodeEl), '<NIL>')
  1110. else if (not Expanded) and (Length(Element.Name) > 0) then
  1111. AppendHyperlink(CodeEl, Element)
  1112. else
  1113. // Array
  1114. if Element.ClassType = TPasArrayType then
  1115. begin
  1116. AppendPasSHFragment(CodeEl,
  1117. 'array [' + TPasArrayType(Element).IndexRange + '] of ', 0);
  1118. Result := AppendType(CodeEl, TableEl, TPasArrayType(Element).ElType, False);
  1119. end else
  1120. // Procedure or funtion type
  1121. if Element.InheritsFrom(TPasProcedureType) then
  1122. begin
  1123. AppendKw(CodeEl, TPasProcedureType(Element).TypeName);
  1124. Result := AppendProcType(CodeEl, TableEl, TPasProcedureType(Element), 0)
  1125. end else
  1126. // Range type
  1127. if Element.InheritsFrom(TPasRangeType) then
  1128. AppendPasSHFragment(CodeEl, TPasRangeType(Element).RangeStart + '..' +
  1129. TPasRangeType(Element).RangeEnd, 0)
  1130. else
  1131. // Other types
  1132. AppendHyperlink(CodeEl, Element);
  1133. end;
  1134. function THTMLWriter.AppendProcType(CodeEl, TableEl: TDOMElement;
  1135. Element: TPasProcedureType; Indent: Integer): TDOMElement;
  1136. function CreateIndentedCodeEl(Indent: Integer): TDOMElement;
  1137. begin
  1138. Result := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1139. AppendNbSp(Result, Indent);
  1140. end;
  1141. var
  1142. i: Integer;
  1143. Arg: TPasArgument;
  1144. begin
  1145. if Element.Args.Count > 0 then
  1146. begin
  1147. AppendSym(CodeEl, '(');
  1148. for i := 0 to Element.Args.Count - 1 do
  1149. begin
  1150. Arg := TPasArgument(Element.Args[i]);
  1151. CodeEl := CreateIndentedCodeEl(Indent + 2);
  1152. case Arg.Access of
  1153. argConst: AppendKw(CodeEl, 'const ');
  1154. argVar: AppendKw(CodeEl, 'var ');
  1155. argOut: AppendKw(CodeEl, 'out ');
  1156. end;
  1157. AppendText(CodeEl, Arg.Name);
  1158. if Assigned(Arg.ArgType) then
  1159. begin
  1160. AppendSym(CodeEl, ': ');
  1161. CodeEl := AppendType(CodeEl, TableEl, Arg.ArgType, False);
  1162. end;
  1163. if Length(Arg.Value) > 0 then
  1164. AppendPasSHFragment(CodeEl, ' = ' + Arg.Value, 0);
  1165. if i < Element.Args.Count - 1 then
  1166. AppendSym(CodeEl, ';');
  1167. end;
  1168. if Element.InheritsFrom(TPasFunctionType) or Element.IsOfObject then
  1169. begin
  1170. CodeEl := CreateIndentedCodeEl(Indent);
  1171. if Element.InheritsFrom(TPasFunctionType) then
  1172. begin
  1173. AppendSym(CodeEl, '):');
  1174. AppendHyperlink(CodeEl, TPasFunctionType(Element).ResultEl.ResultType);
  1175. end else
  1176. AppendSym(CodeEl, ')');
  1177. if Element.IsOfObject then
  1178. begin
  1179. AppendText(CodeEl, ' '); // Don't remove
  1180. AppendKw(CodeEl, 'of object');
  1181. end;
  1182. end else
  1183. if Indent > 0 then
  1184. AppendSym(CodeEl, ')')
  1185. else
  1186. begin
  1187. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1188. AppendSym(CodeEl, ')');
  1189. end;
  1190. end else
  1191. begin
  1192. { Procedure or function without arguments }
  1193. if Element.InheritsFrom(TPasFunctionType) then
  1194. begin
  1195. AppendSym(CodeEl, ': ');
  1196. AppendHyperlink(CodeEl, TPasFunctionType(Element).ResultEl.ResultType);
  1197. end;
  1198. if Element.IsOfObject then
  1199. AppendKw(CodeEl, ' of object');
  1200. end;
  1201. Result := CodeEl;
  1202. end;
  1203. procedure THTMLWriter.AppendProcExt(CodeEl: TDOMElement;
  1204. Element: TPasProcedure);
  1205. procedure AppendExt(const Ext: String);
  1206. begin
  1207. AppendKw(CodeEl, ' ' + Ext);
  1208. AppendSym(CodeEl, ';');
  1209. end;
  1210. begin
  1211. if Element.IsVirtual then
  1212. AppendExt('virtual');
  1213. if Element.IsDynamic then
  1214. AppendExt('dynamic');
  1215. if Element.IsAbstract then
  1216. AppendExt('abstract');
  1217. if Element.IsOverride then
  1218. AppendExt('override');
  1219. if Element.IsOverload then
  1220. AppendExt('overload');
  1221. if Element.IsMessage then
  1222. AppendExt('message');
  1223. end;
  1224. { Used in two places:
  1225. - Page for the method of a class
  1226. - Page for a tandalone procedure or function. }
  1227. procedure THTMLWriter.AppendProcDecl(CodeEl, TableEl: TDOMElement;
  1228. Element: TPasProcedureBase);
  1229. procedure WriteVariant(AProc: TPasProcedure);
  1230. begin
  1231. AppendProcArgsSection(TableEl.ParentNode, AProc.ProcType);
  1232. AppendKw(CodeEl, AProc.TypeName);
  1233. if Element.Parent.ClassType = TPasClassType then
  1234. begin
  1235. AppendText(CodeEl, ' ');
  1236. AppendHyperlink(CodeEl, Element.Parent);
  1237. AppendSym(CodeEl, '.');
  1238. AppendText(CodeEl, AProc.Name);
  1239. end else
  1240. AppendText(CodeEl, ' ' + AProc.FullName);
  1241. CodeEl := AppendProcType(CodeEl, TableEl, AProc.ProcType, 0);
  1242. AppendSym(CodeEl, ';');
  1243. AppendProcExt(CodeEl, AProc);
  1244. end;
  1245. var
  1246. i: Integer;
  1247. begin
  1248. if Element.ClassType = TPasOverloadedProc then
  1249. for i := 0 to TPasOverloadedProc(Element).Overloads.Count - 1 do
  1250. begin
  1251. if i > 0 then
  1252. begin
  1253. CreateEl(CodeEl, 'br');
  1254. CreateEl(CodeEl, 'br');
  1255. end;
  1256. WriteVariant(TPasProcedure(TPasOverloadedProc(Element).Overloads[i]));
  1257. end
  1258. else
  1259. WriteVariant(TPasProcedure(Element));
  1260. end;
  1261. procedure THTMLWriter.AppendProcArgsSection(Parent: TDOMNode;
  1262. Element: TPasProcedureType);
  1263. var
  1264. HasFullDescr, IsFirst: Boolean;
  1265. ResultEl: TPasResultElement;
  1266. ArgTableEl, TREl: TDOMElement;
  1267. DocNode: TDocNode;
  1268. i: Integer;
  1269. Arg: TPasArgument;
  1270. begin
  1271. IsFirst := True;
  1272. for i := 0 to Element.Args.Count - 1 do
  1273. begin
  1274. Arg := TPasArgument(Element.Args[i]);
  1275. if IsDescrNodeEmpty(Engine.FindShortDescr(Arg)) then
  1276. continue;
  1277. if IsFirst then
  1278. begin
  1279. IsFirst := False;
  1280. AppendText(CreateH2(Parent), SDocArguments);
  1281. ArgTableEl := CreateTable(Parent);
  1282. end;
  1283. TREl := CreateTR(ArgTableEl);
  1284. AppendText(CreateCode(CreatePara(CreateTD_vtop(TREl))), Arg.Name);
  1285. AppendShortDescrCell(TREl, Arg);
  1286. end;
  1287. if Element.ClassType = TPasFunctionType then
  1288. begin
  1289. ResultEl := TPasFunctionType(Element).ResultEl;
  1290. DocNode := Engine.FindDocNode(ResultEl);
  1291. HasFullDescr := Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr);
  1292. if HasFullDescr or
  1293. (Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.ShortDescr)) then
  1294. begin
  1295. AppendText(CreateH2(Parent), SDocFunctionResult);
  1296. if HasFullDescr then
  1297. AppendDescr(ResultEl, Parent, DocNode.Descr, True)
  1298. else
  1299. AppendDescr(ResultEl, CreatePara(Parent), DocNode.ShortDescr, False);
  1300. end;
  1301. end;
  1302. end;
  1303. procedure THTMLWriter.AppendTitle(const AText: DOMString);
  1304. begin
  1305. AppendText(TitleElement, AText);
  1306. AppendText(CreateH1(BodyElement), AText);
  1307. end;
  1308. procedure THTMLWriter.AppendMenuBar(ASubpageIndex: Integer);
  1309. var
  1310. TableEl, TREl, ParaEl, TitleEl: TDOMElement;
  1311. procedure AddLink(ALinkSubpageIndex: Integer; const AName: String);
  1312. begin
  1313. AppendText(ParaEl, '[');
  1314. if ALinkSubpageIndex = ASubpageIndex then
  1315. AppendText(ParaEl, AName)
  1316. else
  1317. AppendText(
  1318. CreateLink(ParaEl, ResolveLinkWithinPackage(Module, ALinkSubpageIndex)),
  1319. AName);
  1320. AppendText(ParaEl, ']');
  1321. end;
  1322. begin
  1323. TableEl := CreateEl(BodyElement, 'table');
  1324. TableEl['cellpadding'] := '4';
  1325. TableEl['cellspacing'] := '0';
  1326. TableEl['border'] := '0';
  1327. TableEl['width'] := '100%';
  1328. TableEl['class'] := 'bar';
  1329. TREl := CreateTR(TableEl);
  1330. ParaEl := CreateEl(CreateTD(TREl), 'b');
  1331. if Assigned(Module) then
  1332. begin
  1333. AddLink(0, SDocOverview);
  1334. if Module.InterfaceSection.ResStrings.Count > 0 then
  1335. AddLink(ResstrSubindex, SDocResStrings);
  1336. if Module.InterfaceSection.Consts.Count > 0 then
  1337. AddLink(ConstsSubindex, SDocConstants);
  1338. if Module.InterfaceSection.Types.Count > 0 then
  1339. AddLink(TypesSubindex, SDocTypes);
  1340. if Module.InterfaceSection.Classes.Count > 0 then
  1341. AddLink(ClassesSubindex, SDocClasses);
  1342. if Module.InterfaceSection.Functions.Count > 0 then
  1343. AddLink(ProcsSubindex, SDocProceduresAndFunctions);
  1344. if Module.InterfaceSection.Variables.Count > 0 then
  1345. AddLink(VarsSubindex, SDocVariables);
  1346. end;
  1347. if Length(SearchPage) > 0 then
  1348. begin
  1349. AppendText(ParaEl, '[');
  1350. AppendText(CreateLink(ParaEl, SearchPage), SDocSearch);
  1351. AppendText(ParaEl, ']');
  1352. end;
  1353. ParaEl := CreateTD(TREl);
  1354. ParaEl['align'] := 'right';
  1355. TitleEl := CreateEl(ParaEl, 'span');
  1356. TitleEl['class'] := 'bartitle';
  1357. if Assigned(Module) then
  1358. AppendText(TitleEl, Format(SDocUnitTitle, [Module.Name]));
  1359. if Assigned(Package) then
  1360. begin
  1361. AppendText(TitleEl, ' (');
  1362. AppendHyperlink(TitleEl, Package);
  1363. AppendText(TitleEl, ')');
  1364. end;
  1365. end;
  1366. procedure THTMLWriter.FinishElementPage(AElement: TPasElement);
  1367. var
  1368. DocNode: TDocNode;
  1369. IsFirstSeeAlso: Boolean;
  1370. Node: TDOMNode;
  1371. TableEl, El, TREl, TDEl, ParaEl, NewEl, DescrEl: TDOMElement;
  1372. s: String;
  1373. f: Text;
  1374. begin
  1375. DocNode := Engine.FindDocNode(AElement);
  1376. if Assigned(DocNode) and Assigned(DocNode.Descr) then
  1377. AppendDescrSection(AElement, BodyElement, DocNode.Descr, SDocDescription);
  1378. // ###
  1379. // Append "Errors" section
  1380. if Assigned(DocNode) and Assigned(DocNode.ErrorsDoc) then
  1381. AppendDescrSection(AElement, BodyElement, DocNode.ErrorsDoc, SDocErrors);
  1382. // Append "See also" section
  1383. if Assigned(DocNode) and Assigned(DocNode.SeeAlso) then
  1384. begin
  1385. IsFirstSeeAlso := True;
  1386. Node := DocNode.SeeAlso.FirstChild;
  1387. while Assigned(Node) do
  1388. begin
  1389. if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'link') then
  1390. begin
  1391. if IsFirstSeeAlso then
  1392. begin
  1393. IsFirstSeeAlso := False;
  1394. AppendText(CreateH2(BodyElement), SDocSeeAlso);
  1395. TableEl := CreateTable(BodyElement);
  1396. end;
  1397. El := TDOMElement(Node);
  1398. TREl := CreateTR(TableEl);
  1399. ParaEl := CreatePara(CreateTD_vtop(TREl));
  1400. s := ResolveLinkID(El['id']);
  1401. if Length(s) = 0 then
  1402. begin
  1403. WriteLn(Format(SErrUnknownLinkID, [El['id']]));
  1404. NewEl := CreateEl(ParaEl, 'b')
  1405. end else
  1406. NewEl := CreateLink(ParaEl, s);
  1407. AppendText(NewEl, El['id']);
  1408. DescrEl := Engine.FindShortDescr(AElement.GetModule, El['id']);
  1409. if Assigned(DescrEl) then
  1410. begin
  1411. AppendNbSp(CreatePara(CreateTD(TREl)), 2);
  1412. ParaEl := CreatePara(CreateTD(TREl));
  1413. ParaEl['class'] := 'cmt';
  1414. PushOutputNode(ParaEl);
  1415. try
  1416. ConvertShort(AElement, DescrEl);
  1417. finally
  1418. PopOutputNode;
  1419. end;
  1420. end;
  1421. end;
  1422. Node := Node.NextSibling;
  1423. end;
  1424. end;
  1425. // Append examples, if present
  1426. if Assigned(DocNode) and Assigned(DocNode.FirstExample) then
  1427. begin
  1428. Node := DocNode.FirstExample;
  1429. while Assigned(Node) do
  1430. begin
  1431. if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'example') then
  1432. begin
  1433. AppendText(CreateH2(BodyElement), SDocExample);
  1434. try
  1435. Assign(f, Engine.GetExampleFilename(TDOMElement(Node)));
  1436. Reset(f);
  1437. try
  1438. PushOutputNode(BodyElement);
  1439. DescrBeginCode(False, TDOMElement(Node)['highlighter']);
  1440. while not EOF(f) do
  1441. begin
  1442. ReadLn(f, s);
  1443. DescrWriteCodeLine(s);
  1444. end;
  1445. DescrEndCode;
  1446. PopOutputNode;
  1447. finally
  1448. Close(f);
  1449. end;
  1450. except
  1451. on e: Exception do
  1452. begin
  1453. e.Message := '[example] ' + e.Message;
  1454. raise;
  1455. end;
  1456. end;
  1457. end;
  1458. Node := Node.NextSibling;
  1459. end;
  1460. end;
  1461. end;
  1462. procedure THTMLWriter.CreatePageBody(AElement: TPasElement;
  1463. ASubpageIndex: Integer);
  1464. var
  1465. i: Integer;
  1466. Element: TPasElement;
  1467. begin
  1468. CurDirectory := Allocator.GetFilename(AElement, ASubpageIndex);
  1469. i := Length(CurDirectory);
  1470. while (i > 0) and not (CurDirectory[i] in DirSeparators) do
  1471. Dec(i);
  1472. CurDirectory := Copy(CurDirectory, 1, i);
  1473. BaseDirectory := Allocator.GetRelativePathToTop(AElement);
  1474. if AElement.ClassType = TPasPackage then
  1475. CreatePackagePageBody
  1476. else
  1477. begin
  1478. Element := AElement;
  1479. while Element.ClassType <> TPasModule do
  1480. Element := Element.Parent;
  1481. Module := TPasModule(Element);
  1482. if AElement.ClassType = TPasModule then
  1483. CreateModulePageBody(TPasModule(AElement), ASubpageIndex)
  1484. else if AElement.Parent.InheritsFrom(TPasClassType) then
  1485. CreateClassMemberPageBody(AElement)
  1486. else if AElement.ClassType = TPasConst then
  1487. CreateConstPageBody(TPasConst(AElement))
  1488. else if AElement.InheritsFrom(TPasClassType) then
  1489. CreateClassPageBody(TPasClassType(AElement), ASubpageIndex)
  1490. else if AElement.InheritsFrom(TPasType) then
  1491. CreateTypePageBody(TPasType(AElement))
  1492. else if AElement.ClassType = TPasVariable then
  1493. CreateVarPageBody(TPasVariable(AElement))
  1494. else if AElement.InheritsFrom(TPasProcedureBase) then
  1495. CreateProcPageBody(TPasProcedure(AElement));
  1496. end;
  1497. end;
  1498. procedure THTMLWriter.CreatePackagePageBody;
  1499. var
  1500. DocNode: TDocNode;
  1501. TableEl, TREl: TDOMElement;
  1502. i: Integer;
  1503. ThisModule: TPasModule;
  1504. begin
  1505. AppendMenuBar(0);
  1506. AppendTitle(Format(SDocPackageTitle, [Copy(Package.Name, 2, 256)]));
  1507. WriteLn('Package Pathname: ', Package.PathName); // ###
  1508. AppendShortDescr(CreatePara(BodyElement), Package);
  1509. AppendText(CreateH2(BodyElement), SDocUnits);
  1510. TableEl := CreateTable(BodyElement);
  1511. for i := 0 to Package.Modules.Count - 1 do
  1512. begin
  1513. ThisModule := TPasModule(Package.Modules[i]);
  1514. TREl := CreateTR(TableEl);
  1515. AppendHyperlink(CreateCode(CreatePara(CreateTD_vtop(TREl))), ThisModule);
  1516. AppendShortDescrCell(TREl, ThisModule);
  1517. end;
  1518. DocNode := Engine.FindDocNode(Package);
  1519. if Assigned(DocNode) and Assigned(DocNode.Descr) then
  1520. AppendDescrSection(nil, BodyElement, DocNode.Descr, SDocDescription);
  1521. end;
  1522. procedure THTMLWriter.CreateModulePageBody(AModule: TPasModule;
  1523. ASubpageIndex: Integer);
  1524. procedure CreateMainPage;
  1525. var
  1526. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  1527. i: Integer;
  1528. UnitRef: TPasType;
  1529. DocNode: TDocNode;
  1530. begin
  1531. AppendMenuBar(0);
  1532. AppendTitle(Format(SDocUnitTitle, [AModule.Name]));
  1533. AppendShortDescr(CreatePara(BodyElement), AModule);
  1534. if AModule.InterfaceSection.UsesList.Count > 0 then
  1535. begin
  1536. TableEl := CreateTable(BodyElement);
  1537. AppendKw(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), 'uses');
  1538. for i := 0 to AModule.InterfaceSection.UsesList.Count - 1 do
  1539. begin
  1540. UnitRef := TPasType(AModule.InterfaceSection.UsesList[i]);
  1541. DocNode := Engine.FindDocNode(UnitRef);
  1542. if Assigned(DocNode) and DocNode.IsSkipped then
  1543. continue;
  1544. TREl := CreateTR(TableEl);
  1545. TDEl := CreateTD_vtop(TREl);
  1546. CodeEl := CreateCode(CreatePara(TDEl));
  1547. AppendNbSp(CodeEl, 2);
  1548. AppendHyperlink(CodeEl, UnitRef);
  1549. if i < AModule.InterfaceSection.UsesList.Count - 1 then
  1550. AppendSym(CodeEl, ',')
  1551. else
  1552. AppendSym(CodeEl, ';');
  1553. AppendText(CodeEl, ' '); // Space for descriptions
  1554. AppendShortDescrCell(TREl, UnitRef);
  1555. end;
  1556. end;
  1557. DocNode := Engine.FindDocNode(AModule);
  1558. if Assigned(DocNode) and Assigned(DocNode.Descr) then
  1559. AppendDescrSection(AModule, BodyElement, DocNode.Descr, SDocOverview);
  1560. end;
  1561. procedure CreateSimpleSubpage(const ATitle: DOMString; AList: TList);
  1562. var
  1563. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  1564. i, j: Integer;
  1565. Decl: TPasElement;
  1566. SortedList: TList;
  1567. DocNode: TDocNode;
  1568. begin
  1569. AppendMenuBar(ASubpageIndex);
  1570. AppendTitle(Format(SDocUnitTitle + ': %s', [AModule.Name, ATitle]));
  1571. SortedList := TList.Create;
  1572. try
  1573. for i := 0 to AList.Count - 1 do
  1574. begin
  1575. Decl := TPasElement(AList[i]);
  1576. DocNode := Engine.FindDocNode(Decl);
  1577. if (not Assigned(DocNode)) or (not DocNode.IsSkipped) then
  1578. begin
  1579. j := 0;
  1580. while (j < SortedList.Count) and (CompareText(
  1581. TPasElement(SortedList[j]).PathName, Decl.PathName) < 0) do
  1582. Inc(j);
  1583. SortedList.Insert(j, Decl);
  1584. end;
  1585. end;
  1586. TableEl := CreateTable(BodyElement);
  1587. for i := 0 to SortedList.Count - 1 do
  1588. begin
  1589. Decl := TPasElement(SortedList[i]);
  1590. TREl := CreateTR(TableEl);
  1591. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1592. AppendHyperlink(CodeEl, Decl);
  1593. AppendShortDescrCell(TREl, Decl);
  1594. end;
  1595. finally
  1596. SortedList.Free;
  1597. end;
  1598. end;
  1599. procedure CreateResStringsPage;
  1600. var
  1601. ParaEl: TDOMElement;
  1602. i, j: Integer;
  1603. Decl: TPasResString;
  1604. DocNode: TDocNode;
  1605. begin
  1606. AppendMenuBar(ResstrSubindex);
  1607. AppendTitle(Format(SDocUnitTitle + ': %s', [AModule.Name, SDocResStrings]));
  1608. for i := 0 to AModule.InterfaceSection.ResStrings.Count - 1 do
  1609. begin
  1610. Decl := TPasResString(AModule.InterfaceSection.ResStrings[i]);
  1611. CreateEl(BodyElement, 'a')['name'] := LowerCase(Decl.Name);
  1612. ParaEl := CreatePara(BodyElement);
  1613. AppendText(CreateCode(ParaEl), Decl.Name);
  1614. CreateEl(ParaEl, 'br');
  1615. AppendText(ParaEl, Decl.Value);
  1616. end;
  1617. end;
  1618. begin
  1619. case ASubpageIndex of
  1620. 0:
  1621. CreateMainPage;
  1622. ResstrSubindex:
  1623. CreateResStringsPage;
  1624. ConstsSubindex:
  1625. CreateSimpleSubpage(SDocConstants, AModule.InterfaceSection.Consts);
  1626. TypesSubindex:
  1627. CreateSimpleSubpage(SDocTypes, AModule.InterfaceSection.Types);
  1628. ClassesSubindex:
  1629. CreateSimpleSubpage(SDocClasses, AModule.InterfaceSection.Classes);
  1630. ProcsSubindex:
  1631. CreateSimpleSubpage(SDocProceduresAndFunctions, AModule.InterfaceSection.Functions);
  1632. VarsSubindex:
  1633. CreateSimpleSubpage(SDocVariables, AModule.InterfaceSection.Variables);
  1634. end;
  1635. end;
  1636. procedure THTMLWriter.CreateConstPageBody(AConst: TPasConst);
  1637. var
  1638. TableEl, CodeEl: TDOMElement;
  1639. begin
  1640. AppendMenuBar(-1);
  1641. AppendTitle(AConst.Name);
  1642. AppendShortDescr(CreatePara(BodyElement), AConst);
  1643. AppendText(CreateH2(BodyElement), SDocDeclaration);
  1644. TableEl := CreateTable(BodyElement);
  1645. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1646. AppendKw(CodeEl, 'const');
  1647. AppendText(CodeEl, ' ' + AConst.Name);
  1648. if Assigned(AConst.VarType) then
  1649. begin
  1650. AppendSym(CodeEl, ': ');
  1651. AppendType(CodeEl, TableEl, AConst.VarType, False);
  1652. end;
  1653. AppendPasSHFragment(CodeEl, ' = ' + AConst.Value + ';', 0);
  1654. FinishElementPage(AConst);
  1655. end;
  1656. procedure THTMLWriter.CreateTypePageBody(AType: TPasType);
  1657. var
  1658. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  1659. DocNode: TDocNode;
  1660. i: Integer;
  1661. s: String;
  1662. EnumType: TPasEnumType;
  1663. EnumValue: TPasEnumValue;
  1664. Variable: TPasVariable;
  1665. begin
  1666. AppendMenuBar(-1);
  1667. AppendTitle(AType.Name);
  1668. AppendShortDescr(CreatePara(BodyElement), AType);
  1669. AppendText(CreateH2(BodyElement), SDocDeclaration);
  1670. TableEl := CreateTable(BodyElement);
  1671. TREl := CreateTR(TableEl);
  1672. TDEl := CreateTD(TREl);
  1673. CodeEl := CreateCode(CreatePara(TDEl));
  1674. AppendKw(CodeEl, 'type ');
  1675. AppendText(CodeEl, AType.Name);
  1676. AppendSym(CodeEl, ' = ');
  1677. // Alias
  1678. if AType.ClassType = TPasAliasType then
  1679. begin
  1680. if Assigned(TPasAliasType(AType).DestType) then
  1681. AppendHyperlink(CodeEl, TPasAliasType(AType).DestType)
  1682. else
  1683. AppendText(CreateWarning(CodeEl), '<Destination type is NIL>');
  1684. AppendSym(CodeEl, ';');
  1685. end else
  1686. // Class of
  1687. if AType.ClassType = TPasClassOfType then
  1688. begin
  1689. AppendKw(CodeEl, 'class of ');
  1690. AppendHyperlink(CodeEl, TPasClassOfType(AType).DestType);
  1691. AppendSym(CodeEl, ';');
  1692. end else
  1693. // Enumeration
  1694. if AType.ClassType = TPasEnumType then
  1695. begin
  1696. AppendSym(CodeEl, '(');
  1697. for i := 0 to TPasEnumType(AType).Values.Count - 1 do
  1698. begin
  1699. EnumValue := TPasEnumValue(TPasEnumType(AType).Values[i]);
  1700. TREl := CreateTR(TableEl);
  1701. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1702. AppendShortDescrCell(TREl, EnumValue);
  1703. AppendNbSp(CodeEl, 2);
  1704. s := EnumValue.Name;
  1705. if EnumValue.IsValueUsed then
  1706. s := s + ' = ' + IntToStr(EnumValue.Value);
  1707. if i < TPasEnumType(AType).Values.Count - 1 then
  1708. s := s + ',';
  1709. AppendPasSHFragment(CodeEl, s, 0);
  1710. end;
  1711. AppendSym(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), ');');
  1712. end else
  1713. // Pointer type
  1714. if AType.ClassType = TPasPointerType then
  1715. begin
  1716. AppendSym(CodeEl, '^');
  1717. if Assigned(TPasPointerType(AType).DestType) then
  1718. AppendHyperlink(CodeEl, TPasPointerType(AType).DestType)
  1719. else
  1720. AppendText(CreateWarning(CodeEl), '<Destination type is NIL>');
  1721. AppendSym(CodeEl, ';');
  1722. end else
  1723. if AType.InheritsFrom(TPasProcedureType) then
  1724. begin
  1725. AppendSym(AppendType(CodeEl, TableEl, TPasType(AType), True), ';');
  1726. AppendProcArgsSection(BodyElement, TPasProcedureType(AType));
  1727. end else
  1728. // Record
  1729. if AType.ClassType = TPasRecordType then
  1730. begin
  1731. if TPasRecordType(AType).IsPacked then
  1732. AppendKw(CodeEl, 'packed record')
  1733. else
  1734. AppendKw(CodeEl, 'record');
  1735. for i := 0 to TPasRecordType(AType).Members.Count - 1 do
  1736. begin
  1737. Variable := TPasVariable(TPasRecordType(AType).Members[i]);
  1738. TREl := CreateTR(TableEl);
  1739. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1740. AppendShortDescrCell(TREl, Variable);
  1741. AppendNbSp(CodeEl, 2);
  1742. AppendText(CodeEl, Variable.Name);
  1743. AppendSym(CodeEl, ': ');
  1744. AppendType(CodeEl, TableEl, Variable.VarType, False);
  1745. AppendSym(CodeEl, ';');
  1746. end;
  1747. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1748. AppendText(CodeEl, ' '); // !!!: Dirty trick, necessary for current XML writer
  1749. AppendKw(CodeEl, 'end');
  1750. AppendSym(CodeEl, ';');
  1751. end else
  1752. // Set
  1753. if AType.ClassType = TPasSetType then
  1754. begin
  1755. AppendKw(CodeEl, 'set of ');
  1756. if TPasSetType(AType).EnumType.ClassType = TPasEnumType then
  1757. begin
  1758. AppendSym(CodeEl, '(');
  1759. EnumType := TPasEnumType(TPasSetType(AType).EnumType);
  1760. for i := 0 to EnumType.Values.Count - 1 do
  1761. begin
  1762. EnumValue := TPasEnumValue(EnumType.Values[i]);
  1763. TREl := CreateTR(TableEl);
  1764. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1765. AppendShortDescrCell(TREl, EnumValue);
  1766. AppendNbSp(CodeEl, 2);
  1767. s := EnumValue.Name;
  1768. if EnumValue.IsValueUsed then
  1769. s := s + ' = ' + IntToStr(EnumValue.Value);
  1770. if i < EnumType.Values.Count - 1 then
  1771. s := s + ',';
  1772. AppendPasSHFragment(CodeEl, s, 0);
  1773. end;
  1774. AppendSym(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), ');');
  1775. end else
  1776. begin
  1777. AppendHyperlink(CodeEl, TPasSetType(AType).EnumType);
  1778. AppendSym(CodeEl, ';');
  1779. end;
  1780. end else
  1781. // Type alias
  1782. if AType.ClassType = TPasTypeAliasType then
  1783. begin
  1784. AppendKw(CodeEl, 'type ');
  1785. AppendHyperlink(CodeEl, TPasTypeAliasType(AType).DestType);
  1786. AppendSym(CodeEl, ';');
  1787. end else
  1788. // Probably one of the simple types, which allowed in other places as wel...
  1789. AppendSym(AppendType(CodeEl, TableEl, TPasType(AType), True), ';');
  1790. FinishElementPage(AType);
  1791. end;
  1792. function PropertyFilter(AMember: TPasElement): Boolean;
  1793. begin
  1794. Result := (AMember.ClassType = TPasProperty) and
  1795. (Copy(AMember.Name, 1, 2) <> 'On');
  1796. end;
  1797. function MethodFilter(AMember: TPasElement): Boolean;
  1798. begin
  1799. Result := AMember.InheritsFrom(TPasProcedureBase);
  1800. end;
  1801. function EventFilter(AMember: TPasElement): Boolean;
  1802. begin
  1803. Result := (AMember.ClassType = TPasProperty) and
  1804. (Copy(AMember.Name, 1, 2) = 'On');
  1805. end;
  1806. procedure THTMLWriter.CreateClassPageBody(AClass: TPasClassType;
  1807. ASubpageIndex: Integer);
  1808. type
  1809. TMemberFilter = function(AMember: TPasElement): Boolean;
  1810. var
  1811. ParaEl: TDOMElement;
  1812. procedure AppendMemberListLink(AListSubpageIndex: Integer;
  1813. const AText: DOMString);
  1814. var
  1815. LinkEl: TDOMElement;
  1816. begin
  1817. AppendText(ParaEl, '[');
  1818. LinkEl := CreateEl(ParaEl, 'a');
  1819. LinkEl['href'] :=
  1820. ResolveLinkWithinPackage(AClass, AListSubpageIndex);
  1821. LinkEl['onClick'] := 'window.open(''' + LinkEl['href'] + ''', ''list'', ' +
  1822. '''dependent=yes,resizable=yes,scrollbars=yes,height=400,width=300''); return false;';
  1823. AppendText(LinkEl, AText);
  1824. AppendText(ParaEl, ' (');
  1825. LinkEl := CreateEl(ParaEl, 'a');
  1826. LinkEl['href'] :=
  1827. ResolveLinkWithinPackage(AClass, AListSubpageIndex + 1);
  1828. LinkEl['onClick'] := 'window.open(''' + LinkEl['href'] + ''', ''list'', ' +
  1829. '''dependent=yes,resizable=yes,scrollbars=yes,height=400,width=300''); return false;';
  1830. AppendText(LinkEl, SDocByName);
  1831. AppendText(ParaEl, ')');
  1832. AppendText(ParaEl, '] ');
  1833. end;
  1834. procedure CreateMainPage;
  1835. var
  1836. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  1837. DocNode: TDocNode;
  1838. Member: TPasElement;
  1839. CurVisibility: TPasMemberVisibility;
  1840. i: Integer;
  1841. s: String;
  1842. ThisClass: TPasClassType;
  1843. HaveSeenTObject: Boolean;
  1844. begin
  1845. AppendMenuBar(-1);
  1846. AppendTitle(AClass.Name);
  1847. ParaEl := CreatePara(BodyElement);
  1848. AppendMemberListLink(PropertiesByInheritanceSubindex, SDocProperties);
  1849. AppendMemberListLink(MethodsByInheritanceSubindex, SDocMethods);
  1850. AppendMemberListLink(EventsByInheritanceSubindex, SDocEvents);
  1851. AppendShortDescr(CreatePara(BodyElement), AClass);
  1852. AppendText(CreateH2(BodyElement), SDocDeclaration);
  1853. TableEl := CreateTable(BodyElement);
  1854. TREl := CreateTR(TableEl);
  1855. TDEl := CreateTD(TREl);
  1856. CodeEl := CreateCode(CreatePara(TDEl));
  1857. AppendKw(CodeEl, 'type');
  1858. AppendText(CodeEl, ' ' + AClass.Name + ' ');
  1859. AppendSym(CodeEl, '=');
  1860. AppendText(CodeEl, ' ');
  1861. AppendKw(CodeEl, ObjKindNames[AClass.ObjKind]);
  1862. if Assigned(AClass.AncestorType) then
  1863. begin
  1864. AppendSym(CodeEl, '(');
  1865. AppendHyperlink(CodeEl, AClass.AncestorType);
  1866. AppendSym(CodeEl, ')');
  1867. end;
  1868. if AClass.Members.Count > 0 then
  1869. begin
  1870. CurVisibility := visDefault;
  1871. for i := 0 to AClass.Members.Count - 1 do
  1872. begin
  1873. Member := TPasElement(AClass.Members[i]);
  1874. if CurVisibility <> Member.Visibility then
  1875. begin
  1876. CurVisibility := Member.Visibility;
  1877. if ((CurVisibility = visPrivate) and Engine.HidePrivate) or
  1878. ((CurVisibility = visProtected) and Engine.HideProtected) then
  1879. continue;
  1880. case CurVisibility of
  1881. visPrivate: s := 'private';
  1882. visProtected: s := 'protected';
  1883. visPublic: s := 'public';
  1884. visPublished: s := 'published';
  1885. visAutomated: s := 'automated';
  1886. end;
  1887. AppendKw(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), s);
  1888. end else
  1889. if ((CurVisibility = visPrivate) and Engine.HidePrivate) or
  1890. ((CurVisibility = visProtected) and Engine.HideProtected) then
  1891. continue;
  1892. TREl := CreateTR(TableEl);
  1893. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1894. AppendNbSp(CodeEl, 2);
  1895. AppendShortDescrCell(TREl, Member);
  1896. if Member.InheritsFrom(TPasProcedureBase) then
  1897. begin
  1898. AppendKw(CodeEl, TPasProcedureBase(Member).TypeName + ' ');
  1899. AppendHyperlink(CodeEl, Member);
  1900. if (Member.ClassType = TPasOverloadedProc) or
  1901. (TPasProcedure(Member).ProcType.Args.Count > 0) then
  1902. AppendSym(CodeEl, '();')
  1903. else
  1904. AppendSym(CodeEl, ';');
  1905. if Member.ClassType <> TPasOverloadedProc then
  1906. AppendProcExt(CodeEl, TPasProcedure(Member));
  1907. end else
  1908. if Member.ClassType = TPasVariable then
  1909. begin
  1910. AppendHyperlink(CodeEl, Member);
  1911. AppendSym(CodeEl, ': ');
  1912. AppendHyperlink(CodeEl, TPasVariable(Member).VarType);
  1913. AppendSym(CodeEl, ';');
  1914. end else
  1915. if Member.ClassType = TPasProperty then
  1916. begin
  1917. AppendKw(CodeEl, 'property ');
  1918. AppendHyperlink(CodeEl, Member);
  1919. if Assigned(TPasProperty(Member).VarType) then
  1920. begin
  1921. AppendSym(CodeEl, ': ');
  1922. AppendHyperlink(CodeEl, TPasProperty(Member).VarType);
  1923. end;
  1924. AppendSym(CodeEl, ';');
  1925. if TPasProperty(Member).IsDefault then
  1926. begin
  1927. AppendKw(CodeEl, ' default');
  1928. AppendSym(CodeEl, ';');
  1929. end;
  1930. SetLength(s, 0);
  1931. if Length(TPasProperty(Member).ReadAccessorName) > 0 then
  1932. s := s + 'r';
  1933. if Length(TPasProperty(Member).WriteAccessorName) > 0 then
  1934. s := s + 'w';
  1935. if Length(TPasProperty(Member).StoredAccessorName) > 0 then
  1936. s := s + 's';
  1937. if Length(s) > 0 then
  1938. AppendText(CodeEl, ' [' + s + ']');
  1939. end else
  1940. AppendText(CreateWarning(CodeEl), '<' + Member.ClassName + '>');
  1941. end;
  1942. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1943. end;
  1944. AppendText(CodeEl, ' '); // !!!: Dirty trick, necessary for current XML writer
  1945. AppendKw(CodeEl, 'end');
  1946. AppendSym(CodeEl, ';');
  1947. AppendText(CreateH2(BodyElement), SDocInheritance);
  1948. TableEl := CreateTable(BodyElement);
  1949. HaveSeenTObject := AClass.ObjKind <> okClass;
  1950. ThisClass := AClass;
  1951. while True do
  1952. begin
  1953. TREl := CreateTR(TableEl);
  1954. TDEl := CreateTD_vtop(TREl);
  1955. TDEl['align'] := 'center';
  1956. CodeEl := CreateCode(CreatePara(TDEl));
  1957. AppendHyperlink(CodeEl, ThisClass);
  1958. AppendShortDescrCell(TREl, ThisClass);
  1959. if HaveSeenTObject or (CompareText(ThisClass.Name, 'TObject') = 0) then
  1960. HaveSeenTObject := True
  1961. else
  1962. begin
  1963. TDEl := CreateTD(CreateTR(TableEl));
  1964. TDEl['align'] := 'center';
  1965. AppendText(TDEl, '|');
  1966. end;
  1967. if Assigned(ThisClass.AncestorType) then
  1968. begin
  1969. if ThisClass.AncestorType.InheritsFrom(TPasClassType) then
  1970. ThisClass := TPasClassType(ThisClass.AncestorType)
  1971. else
  1972. begin
  1973. TDEl := CreateTD(CreateTR(TableEl));
  1974. TDEl['align'] := 'center';
  1975. AppendText(CreateCode(CreatePara(TDEl)), ThisClass.AncestorType.Name);
  1976. if CompareText(ThisClass.AncestorType.Name, 'TObject') = 0 then
  1977. HaveSeenTObject := True
  1978. else
  1979. begin
  1980. TDEl := CreateTD(CreateTR(TableEl));
  1981. TDEl['align'] := 'center';
  1982. AppendText(TDEl, '?');
  1983. end;
  1984. break;
  1985. end
  1986. end else
  1987. break;
  1988. end;
  1989. if not HaveSeenTObject then
  1990. begin
  1991. TDEl := CreateTD(CreateTR(TableEl));
  1992. TDEl['align'] := 'center';
  1993. AppendText(CreateCode(CreatePara(TDEl)), 'TObject');
  1994. end;
  1995. FinishElementPage(AClass);
  1996. end;
  1997. procedure CreateInheritanceSubpage(AFilter: TMemberFilter);
  1998. var
  1999. ThisClass: TPasClassType;
  2000. i: Integer;
  2001. Member: TPasElement;
  2002. TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
  2003. begin
  2004. TableEl := CreateTable(BodyElement);
  2005. ThisClass := AClass;
  2006. while True do
  2007. begin
  2008. TREl := CreateTR(TableEl);
  2009. TDEl := CreateTD(TREl);
  2010. TDEl['colspan'] := '3';
  2011. CreateTD(TREl);
  2012. LinkEl := AppendHyperlink(CreateEl(CreateCode(CreatePara(TDEl)), 'b'), ThisClass);
  2013. if Assigned(LinkEl) then
  2014. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2015. '''; return false;';
  2016. for i := 0 to ThisClass.Members.Count - 1 do
  2017. begin
  2018. Member := TPasElement(ThisClass.Members[i]);
  2019. if ((Member.Visibility = visPrivate) and Engine.HidePrivate) or
  2020. ((Member.Visibility = visProtected) and Engine.HideProtected) or
  2021. not AFilter(Member) then
  2022. continue;
  2023. TREl := CreateTR(TableEl);
  2024. ParaEl := CreatePara(CreateTD(TREl));
  2025. case Member.Visibility of
  2026. visPrivate:
  2027. AppendText(ParaEl, 'pv');
  2028. visProtected:
  2029. AppendText(ParaEl, 'pt');
  2030. visPublished:
  2031. AppendText(ParaEl, 'pl');
  2032. end;
  2033. AppendNbSp(ParaEl, 1);
  2034. ParaEl := CreateTD(TREl);
  2035. if (Member.ClassType = TPasProperty) and
  2036. (Length(TPasProperty(Member).WriteAccessorName) = 0) then
  2037. begin
  2038. AppendText(ParaEl, 'ro');
  2039. AppendNbSp(ParaEl, 1);
  2040. end;
  2041. LinkEl := AppendHyperlink(CreatePara(CreateTD(TREl)), Member);
  2042. if Assigned(LinkEl) then
  2043. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2044. '''; return false;';
  2045. end;
  2046. if (not Assigned(ThisClass.AncestorType)) or
  2047. (not (ThisClass.AncestorType.ClassType = TPasClassType)) then
  2048. break;
  2049. ThisClass := TPasClassType(ThisClass.AncestorType);
  2050. AppendNbSp(CreatePara(CreateTD(CreateTR(TableEl))), 1);
  2051. end;
  2052. end;
  2053. procedure CreateSortedSubpage(AFilter: TMemberFilter);
  2054. var
  2055. List: TList;
  2056. ThisClass: TPasClassType;
  2057. i, j: Integer;
  2058. Member: TPasElement;
  2059. TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
  2060. begin
  2061. List := TList.Create;
  2062. try
  2063. ThisClass := AClass;
  2064. while True do
  2065. begin
  2066. for i := 0 to ThisClass.Members.Count - 1 do
  2067. begin
  2068. Member := TPasElement(ThisClass.Members[i]);
  2069. if (not (((Member.Visibility = visPrivate) and Engine.HidePrivate) or
  2070. ((Member.Visibility = visProtected) and Engine.HideProtected))) and
  2071. AFilter(Member) then
  2072. begin
  2073. j := 0;
  2074. while (j < List.Count) and
  2075. (CompareText(TPasElement(List[j]).Name, Member.Name) < 0) do
  2076. Inc(j);
  2077. List.Insert(j, Member);
  2078. end;
  2079. end;
  2080. if (not Assigned(ThisClass.AncestorType)) or
  2081. (not (ThisClass.AncestorType.ClassType = TPasClassType)) then
  2082. break;
  2083. ThisClass := TPasClassType(ThisClass.AncestorType);
  2084. end;
  2085. TableEl := CreateTable(BodyElement);
  2086. for i := 0 to List.Count - 1 do
  2087. begin
  2088. Member := TPasElement(List[i]);
  2089. TREl := CreateTR(TableEl);
  2090. ParaEl := CreatePara(CreateTD(TREl));
  2091. case Member.Visibility of
  2092. visPrivate:
  2093. AppendText(ParaEl, 'pv');
  2094. visProtected:
  2095. AppendText(ParaEl, 'pt');
  2096. visPublished:
  2097. AppendText(ParaEl, 'pl');
  2098. end;
  2099. AppendNbSp(ParaEl, 1);
  2100. ParaEl := CreatePara(CreateTD(TREl));
  2101. if (Member.ClassType = TPasProperty) and
  2102. (Length(TPasProperty(Member).WriteAccessorName) = 0) then
  2103. begin
  2104. AppendText(ParaEl, 'ro');
  2105. AppendNbSp(ParaEl, 1);
  2106. end;
  2107. TDEl := CreateTD(TREl);
  2108. TDEl['nowrap'] := 'nowrap';
  2109. ParaEl := CreatePara(TDEl);
  2110. LinkEl := AppendHyperlink(ParaEl, Member);
  2111. if Assigned(LinkEl) then
  2112. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2113. '''; return false;';
  2114. AppendText(ParaEl, ' (');
  2115. LinkEl := AppendHyperlink(ParaEl, Member.Parent);
  2116. if Assigned(LinkEl) then
  2117. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2118. '''; return false;';
  2119. AppendText(ParaEl, ')');
  2120. end;
  2121. finally
  2122. List.Free;
  2123. end;
  2124. end;
  2125. begin
  2126. case ASubpageIndex of
  2127. 0:
  2128. CreateMainPage;
  2129. PropertiesByInheritanceSubindex:
  2130. CreateInheritanceSubpage(@PropertyFilter);
  2131. PropertiesByNameSubindex:
  2132. CreateSortedSubpage(@PropertyFilter);
  2133. MethodsByInheritanceSubindex:
  2134. CreateInheritanceSubpage(@MethodFilter);
  2135. MethodsByNameSubindex:
  2136. CreateSortedSubpage(@MethodFilter);
  2137. EventsByInheritanceSubindex:
  2138. CreateInheritanceSubpage(@EventFilter);
  2139. EventsByNameSubindex:
  2140. CreateSortedSubpage(@EventFilter);
  2141. end;
  2142. end;
  2143. procedure THTMLWriter.CreateClassMemberPageBody(AElement: TPasElement);
  2144. var
  2145. TableEl, TREl, CodeEl: TDOMElement;
  2146. procedure CreateVarPage(Element: TPasVariable);
  2147. begin
  2148. AppendHyperlink(CodeEl, Element.Parent);
  2149. AppendSym(CodeEl, '.');
  2150. AppendText(CodeEl, Element.Name);
  2151. if Assigned(Element.VarType) then
  2152. begin
  2153. AppendSym(CodeEl, ': ');
  2154. AppendSym(AppendType(CodeEl, TableEl, Element.VarType, False), ';');
  2155. end;
  2156. end;
  2157. procedure CreatePropertyPage(Element: TPasProperty);
  2158. var
  2159. NeedBreak: Boolean;
  2160. begin
  2161. AppendKw(CodeEl, 'property ');
  2162. AppendHyperlink(CodeEl, Element.Parent);
  2163. AppendSym(CodeEl, '.');
  2164. AppendText(CodeEl, Element.Name);
  2165. if Assigned(Element.VarType) then
  2166. begin
  2167. AppendSym(CodeEl, ': ');
  2168. AppendType(CodeEl, TableEl, Element.VarType, False);
  2169. end;
  2170. NeedBreak := False;
  2171. if Length(TPasProperty(Element).IndexValue) <> 0 then
  2172. begin
  2173. CreateEl(CodeEl, 'br');
  2174. AppendNbsp(CodeEl, 2);
  2175. AppendKw(CodeEl, 'index ');
  2176. AppendPasSHFragment(CodeEl, TPasProperty(Element).IndexValue, 0);
  2177. NeedBreak := True;
  2178. end;
  2179. if Length(TPasProperty(Element).ReadAccessorName) <> 0 then
  2180. begin
  2181. CreateEl(CodeEl, 'br');
  2182. AppendNbsp(CodeEl, 2);
  2183. AppendKw(CodeEl, 'read ');
  2184. AppendText(CodeEl, TPasProperty(Element).ReadAccessorName);
  2185. NeedBreak := True;
  2186. end;
  2187. if Length(TPasProperty(Element).WriteAccessorName) <> 0 then
  2188. begin
  2189. CreateEl(CodeEl, 'br');
  2190. AppendNbsp(CodeEl, 2);
  2191. AppendKw(CodeEl, 'write ');
  2192. AppendText(CodeEl, TPasProperty(Element).WriteAccessorName);
  2193. NeedBreak := True;
  2194. end;
  2195. if Length(TPasProperty(Element).StoredAccessorName) <> 0 then
  2196. begin
  2197. CreateEl(CodeEl, 'br');
  2198. AppendNbsp(CodeEl, 2);
  2199. AppendKw(CodeEl, 'stored ');
  2200. AppendText(CodeEl, TPasProperty(Element).StoredAccessorName);
  2201. NeedBreak := True;
  2202. end;
  2203. if Length(TPasProperty(Element).DefaultValue) <> 0 then
  2204. begin
  2205. CreateEl(CodeEl, 'br');
  2206. AppendNbsp(CodeEl, 2);
  2207. AppendKw(CodeEl, 'default ');
  2208. AppendPasSHFragment(CodeEl, TPasProperty(Element).DefaultValue, 0);
  2209. NeedBreak := True;
  2210. end;
  2211. AppendSym(CodeEl, ';');
  2212. if TPasProperty(Element).IsDefault or TPasProperty(Element).IsNodefault then
  2213. begin
  2214. if NeedBreak then
  2215. begin
  2216. CreateEl(CodeEl, 'br');
  2217. AppendNbsp(CodeEl, 2);
  2218. end;
  2219. if TPasProperty(Element).IsDefault then
  2220. AppendKw(CodeEl, 'default')
  2221. else
  2222. AppendKw(CodeEl, 'nodefault');
  2223. AppendSym(CodeEl, ';');
  2224. end;
  2225. end;
  2226. var
  2227. s: String;
  2228. DocNode: TDocNode;
  2229. begin
  2230. AppendMenuBar(-1);
  2231. AppendTitle(AElement.FullName);
  2232. AppendShortDescr(CreatePara(BodyElement), AElement);
  2233. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2234. TableEl := CreateTable(BodyElement);
  2235. TREl := CreateTR(TableEl);
  2236. CodeEl := CreateCode(CreatePara(CreateTD(TREl)));
  2237. AppendText(CodeEl, ' '); // !!!: Workaround for current HTML writer
  2238. case AElement.Visibility of
  2239. visPrivate: s := 'private';
  2240. visProtected: s := 'protected';
  2241. visPublic: s := 'public';
  2242. visPublished: s := 'published';
  2243. visAutomated: s := 'automated';
  2244. else s := '';
  2245. end;
  2246. if Length(s) > 0 then
  2247. AppendKw(CodeEl, s);
  2248. AppendText(CodeEl, ' ');
  2249. if AElement.ClassType = TPasVariable then
  2250. CreateVarPage(TPasVariable(AElement))
  2251. else if AElement.InheritsFrom(TPasProcedureBase) then
  2252. AppendProcDecl(CodeEl, TableEl, TPasProcedureBase(AElement))
  2253. else if AElement.ClassType = TPasProperty then
  2254. CreatePropertyPage(TPasProperty(AElement))
  2255. else
  2256. AppendText(CreateWarning(BodyElement), '<' + AElement.ClassName + '>');
  2257. FinishElementPage(AElement);
  2258. end;
  2259. procedure THTMLWriter.CreateVarPageBody(AVar: TPasVariable);
  2260. var
  2261. TableEl, TREl, TDEl, CodeEl, El: TDOMElement;
  2262. DocNode: TDocNode;
  2263. begin
  2264. AppendMenuBar(-1);
  2265. AppendTitle(AVar.FullName);
  2266. AppendShortDescr(CreatePara(BodyElement), AVar);
  2267. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2268. TableEl := CreateTable(BodyElement);
  2269. TREl := CreateTR(TableEl);
  2270. TDEl := CreateTD(TREl);
  2271. CodeEl := CreateCode(CreatePara(TDEl));
  2272. AppendKw(CodeEl, 'var');
  2273. AppendText(CodeEl, ' ' + AVar.Name);
  2274. if Assigned(AVar.VarType) then
  2275. begin
  2276. AppendSym(CodeEl, ': ');
  2277. El := AppendType(CodeEl, TableEl, AVar.VarType, False);
  2278. end else
  2279. El := CodeEl;
  2280. if Length(AVar.Value) > 0 then
  2281. AppendPasSHFragment(El, ' = ' + AVar.Value + ';', 0)
  2282. else
  2283. AppendSym(El, ';');
  2284. FinishElementPage(AVar);
  2285. end;
  2286. procedure THTMLWriter.CreateProcPageBody(AProc: TPasProcedureBase);
  2287. var
  2288. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  2289. begin
  2290. AppendMenuBar(-1);
  2291. AppendTitle(AProc.Name);
  2292. AppendShortDescr(CreatePara(BodyElement), AProc);
  2293. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2294. TableEl := CreateTable(BodyElement);
  2295. TREl := CreateTR(TableEl);
  2296. TDEl := CreateTD(TREl);
  2297. CodeEl := CreateCode(CreatePara(TDEl));
  2298. AppendProcDecl(CodeEl, TableEl, AProc);
  2299. FinishElementPage(AProc);
  2300. end;
  2301. // private methods
  2302. function THTMLWriter.GetPageCount: Integer;
  2303. begin
  2304. Result := PageInfos.Count;
  2305. end;
  2306. end.
  2307. {
  2308. $Log$
  2309. Revision 1.3 2003-04-17 14:15:24 sg
  2310. * Added writing of array ranges
  2311. Revision 1.2 2003/03/18 19:28:44 michael
  2312. + Some changes to output handling, more suitable for tex output
  2313. Revision 1.1 2003/03/17 23:03:20 michael
  2314. + Initial import in CVS
  2315. Revision 1.15 2003/03/13 22:02:13 sg
  2316. * New version with many bugfixes and our own parser (now independent of the
  2317. compiler source)
  2318. Revision 1.14 2002/11/15 19:46:32 sg
  2319. * Added support for classes and objects (formerly all objects have been
  2320. written als classes)
  2321. Revision 1.13 2002/05/24 00:13:22 sg
  2322. * much improved new version, including many linking and output fixes
  2323. Revision 1.12 2002/03/12 10:58:36 sg
  2324. * reworked linking engine and internal structure
  2325. Revision 1.11 2002/01/20 11:19:55 michael
  2326. + Added link attribute and property to TFPElement
  2327. Revision 1.10 2001/12/21 11:25:13 sg
  2328. * The parser can now unget two tokens from the scanner
  2329. * Added parsing and HTML output of range types
  2330. * Procedure/function variable bugfixes
  2331. Revision 1.9 2001/12/17 22:34:04 sg
  2332. * Fixed typo in output for menu bar
  2333. Revision 1.8 2001/12/17 13:41:17 jonas
  2334. * OsPathSeparator -> PathDelim
  2335. }