dw_html.pp 73 KB

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