dw_html.pp 98 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497
  1. {
  2. FPDoc - Free Pascal Documentation Tool
  3. Copyright (C) 2000 - 2005 by
  4. Areca Systems GmbH / Sebastian Guenther, [email protected]
  5. * HTML/XHTML output generator
  6. See the file COPYING, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. }
  12. {$mode objfpc}
  13. {$H+}
  14. unit dw_HTML;
  15. interface
  16. uses Classes, contnrs, DOM, DOM_HTML, dGlobals, PasTree, dWriter, ChmWriter, ChmBase;
  17. const
  18. // Subpage indices for modules
  19. ResstrSubindex = 1;
  20. ConstsSubindex = 2;
  21. TypesSubindex = 3;
  22. ClassesSubindex = 4;
  23. ProcsSubindex = 5;
  24. VarsSubindex = 6;
  25. // Maybe needed later for topic overview ??
  26. TopicsSubIndex = 7;
  27. IndexSubIndex = 8;
  28. // Subpage indices for classes
  29. PropertiesByInheritanceSubindex = 1;
  30. PropertiesByNameSubindex = 2;
  31. MethodsByInheritanceSubindex = 3;
  32. MethodsByNameSubindex = 4;
  33. EventsByInheritanceSubindex = 5;
  34. EventsByNameSubindex = 6;
  35. type
  36. TFileAllocator = class
  37. public
  38. procedure AllocFilename(AElement: TPasElement; ASubindex: Integer); virtual;
  39. function GetFilename(AElement: TPasElement;
  40. ASubindex: Integer): String; virtual; abstract;
  41. function GetRelativePathToTop(AElement: TPasElement): String; virtual;
  42. function GetCSSFilename(ARelativeTo: TPasElement): DOMString; virtual;
  43. end;
  44. TShortNameFileAllocator = class(TFileAllocator)
  45. private
  46. FExtension: String;
  47. public
  48. constructor Create(const AExtension: String);
  49. procedure AllocFilename(AElement: TPasElement; ASubindex: Integer); override;
  50. property Extension: String read FExtension;
  51. end;
  52. TLongNameFileAllocator = class(TFileAllocator)
  53. private
  54. FExtension: String;
  55. public
  56. constructor Create(const AExtension: String);
  57. function GetFilename(AElement: TPasElement;
  58. ASubindex: Integer): String; override;
  59. function GetRelativePathToTop(AElement: TPasElement): String; override;
  60. property Extension: String read FExtension;
  61. end;
  62. TPageInfo = class
  63. Element: TPasElement;
  64. SubpageIndex: Integer;
  65. end;
  66. { THTMLWriter }
  67. THTMLWriter = class(TFPDocWriter)
  68. private
  69. FImageFileList: TStrings;
  70. FOnTest: TNotifyEvent;
  71. FPackage: TPasPackage;
  72. FCharSet : String;
  73. function GetPageCount: Integer;
  74. procedure SetOnTest(const AValue: TNotifyEvent);
  75. protected
  76. FCSSFile: String;
  77. FAllocator: TFileAllocator;
  78. CurDirectory: String; // relative to curdir of process
  79. BaseDirectory: String; // relative path to package base directory
  80. PageInfos: TObjectList; // list of TPageInfo objects
  81. Doc: THTMLDocument;
  82. BodyElement, TitleElement: TDOMElement;
  83. Module: TPasModule;
  84. OutputNodeStack: TList;
  85. CurOutputNode: TDOMNode;
  86. InsideHeadRow, DoPasHighlighting: Boolean;
  87. HighlighterFlags: Byte;
  88. FooterFile: string;
  89. FIDF : Boolean;
  90. FDateFormat: String;
  91. FIndexColCount : Integer;
  92. FSearchPage : String;
  93. FBaseImageURL : String;
  94. Procedure CreateAllocator; virtual;
  95. function ResolveLinkID(const Name: String): DOMString;
  96. function ResolveLinkIDInUnit(const Name,AUnitName: String): DOMString;
  97. function ResolveLinkWithinPackage(AElement: TPasElement;
  98. ASubpageIndex: Integer): String;
  99. // Helper functions for creating DOM elements
  100. function CreateEl(Parent: TDOMNode; const AName: DOMString): THTMLElement;
  101. function CreatePara(Parent: TDOMNode): THTMLElement;
  102. function CreateH1(Parent: TDOMNode): THTMLElement;
  103. function CreateH2(Parent: TDOMNode): THTMLElement;
  104. function CreateH3(Parent: TDOMNode): THTMLElement;
  105. function CreateTable(Parent: TDOMNode; const AClass: DOMString = ''): THTMLElement;
  106. function CreateContentTable(Parent: TDOMNode): THTMLElement;
  107. function CreateTR(Parent: TDOMNode): THTMLElement;
  108. function CreateTD(Parent: TDOMNode): THTMLElement;
  109. function CreateTD_vtop(Parent: TDOMNode): THTMLElement;
  110. function CreateLink(Parent: TDOMNode; const AHRef: DOMString): THTMLElement;
  111. function CreateAnchor(Parent: TDOMNode; const AName: DOMString): THTMLElement;
  112. function CreateCode(Parent: TDOMNode): THTMLElement;
  113. function CreateWarning(Parent: TDOMNode): THTMLElement;
  114. // Description node conversion
  115. procedure PushOutputNode(ANode: TDOMNode);
  116. procedure PopOutputNode;
  117. procedure DescrWriteText(const AText: DOMString); override;
  118. procedure DescrBeginBold; override;
  119. procedure DescrEndBold; override;
  120. procedure DescrBeginItalic; override;
  121. procedure DescrEndItalic; override;
  122. procedure DescrBeginEmph; override;
  123. procedure DescrEndEmph; override;
  124. procedure DescrWriteImageEl(const AFileName, ACaption, ALinkName : DOMString); override;
  125. procedure DescrWriteFileEl(const AText: DOMString); override;
  126. procedure DescrWriteKeywordEl(const AText: DOMString); override;
  127. procedure DescrWriteVarEl(const AText: DOMString); override;
  128. procedure DescrBeginLink(const AId: DOMString); override;
  129. procedure DescrEndLink; override;
  130. procedure DescrBeginURL(const AURL: DOMString); override;
  131. procedure DescrEndURL; override;
  132. procedure DescrWriteLinebreak; override;
  133. procedure DescrBeginParagraph; override;
  134. procedure DescrEndParagraph; override;
  135. procedure DescrBeginCode(HasBorder: Boolean; const AHighlighterName: String); override;
  136. procedure DescrWriteCodeLine(const ALine: String); override;
  137. procedure DescrEndCode; override;
  138. procedure DescrBeginOrderedList; override;
  139. procedure DescrEndOrderedList; override;
  140. procedure DescrBeginUnorderedList; override;
  141. procedure DescrEndUnorderedList; override;
  142. procedure DescrBeginDefinitionList; override;
  143. procedure DescrEndDefinitionList; override;
  144. procedure DescrBeginListItem; override;
  145. procedure DescrEndListItem; override;
  146. procedure DescrBeginDefinitionTerm; override;
  147. procedure DescrEndDefinitionTerm; override;
  148. procedure DescrBeginDefinitionEntry; override;
  149. procedure DescrEndDefinitionEntry; override;
  150. procedure DescrBeginSectionTitle; override;
  151. procedure DescrBeginSectionBody; override;
  152. procedure DescrEndSection; override;
  153. procedure DescrBeginRemark; override;
  154. procedure DescrEndRemark; override;
  155. procedure DescrBeginTable(ColCount: Integer; HasBorder: Boolean); override;
  156. procedure DescrEndTable; override;
  157. procedure DescrBeginTableCaption; override;
  158. procedure DescrEndTableCaption; override;
  159. procedure DescrBeginTableHeadRow; override;
  160. procedure DescrEndTableHeadRow; override;
  161. procedure DescrBeginTableRow; override;
  162. procedure DescrEndTableRow; override;
  163. procedure DescrBeginTableCell; override;
  164. procedure DescrEndTableCell; override;
  165. procedure AppendText(Parent: TDOMNode; const AText: DOMString);
  166. procedure AppendNbSp(Parent: TDOMNode; ACount: Integer);
  167. procedure AppendSym(Parent: TDOMNode; const AText: DOMString);
  168. procedure AppendKw(Parent: TDOMNode; const AText: DOMString);
  169. function AppendPasSHFragment(Parent: TDOMNode; const AText: String;
  170. AShFlags: Byte): Byte;
  171. Procedure AppendShortDescr(AContext : TPasElement;Parent: TDOMNode; DocNode : TDocNode);
  172. procedure AppendShortDescr(Parent: TDOMNode; Element: TPasElement);
  173. procedure AppendShortDescrCell(Parent: TDOMNode; Element: TPasElement);
  174. procedure AppendDescr(AContext: TPasElement; Parent: TDOMNode;
  175. DescrNode: TDOMElement; AutoInsertBlock: Boolean);
  176. procedure AppendDescrSection(AContext: TPasElement; Parent: TDOMNode;
  177. DescrNode: TDOMElement; const ATitle: DOMString);
  178. function AppendHyperlink(Parent: TDOMNode; Element: TPasElement): TDOMElement;
  179. function AppendType(CodeEl, TableEl: TDOMElement;
  180. Element: TPasType; Expanded: Boolean;
  181. NestingLevel: Integer = 0): TDOMElement;
  182. function AppendProcType(CodeEl, TableEl: TDOMElement;
  183. Element: TPasProcedureType; Indent: Integer): TDOMElement;
  184. procedure AppendProcExt(CodeEl: TDOMElement; Element: TPasProcedure);
  185. procedure AppendProcDecl(CodeEl, TableEl: TDOMElement;
  186. Element: TPasProcedureBase);
  187. procedure AppendProcArgsSection(Parent: TDOMNode;
  188. Element: TPasProcedureType);
  189. function AppendRecordType(CodeEl, TableEl: TDOMElement;
  190. Element: TPasRecordType; NestingLevel: Integer): TDOMElement;
  191. procedure AppendTitle(const AText: DOMString);
  192. procedure AppendMenuBar(ASubpageIndex: Integer);
  193. procedure AppendTopicMenuBar(Topic : TTopicElement);
  194. procedure AppendSourceRef(AElement: TPasElement);
  195. procedure FinishElementPage(AElement: TPasElement);
  196. Procedure AppendSeeAlsoSection(AElement : TPasElement;DocNode : TDocNode);
  197. Procedure AppendExampleSection(AElement : TPasElement;DocNode : TDocNode);
  198. procedure AppendFooter;
  199. procedure CreateIndexPage(L : TStringList);
  200. procedure CreateModuleIndexPage(AModule: TPasModule);
  201. procedure CreatePageBody(AElement: TPasElement; ASubpageIndex: Integer); virtual;
  202. procedure CreatePackagePageBody;
  203. procedure CreatePackageIndex;
  204. procedure AddModuleIdentifiers(AModule : TPasModule; L : TStrings);
  205. Procedure CreateTopicPageBody(AElement : TTopicElement);
  206. procedure CreateModulePageBody(AModule: TPasModule; ASubpageIndex: Integer);
  207. procedure CreateConstPageBody(AConst: TPasConst);
  208. procedure CreateTypePageBody(AType: TPasType);
  209. procedure CreateClassPageBody(AClass: TPasClassType; ASubpageIndex: Integer);
  210. procedure CreateClassMemberPageBody(AElement: TPasElement);
  211. procedure CreateVarPageBody(AVar: TPasVariable);
  212. procedure CreateProcPageBody(AProc: TPasProcedureBase);
  213. Procedure CreateTopicLinks(Node : TDocNode; PasElement : TPasElement);
  214. public
  215. constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
  216. destructor Destroy; override;
  217. // Single-page generation
  218. function CreateHTMLPage(AElement: TPasElement;
  219. ASubpageIndex: Integer): TXMLDocument;
  220. function CreateXHTMLPage(AElement: TPasElement;
  221. ASubpageIndex: Integer): TXMLDocument;
  222. // For producing complete package documentation
  223. procedure WriteHTMLPages; virtual;
  224. procedure WriteXHTMLPages;
  225. Function InterPretOption(Const Cmd,Arg : String) : boolean; override;
  226. Procedure WriteDoc; override;
  227. Class Function FileNameExtension : String; override;
  228. class procedure Usage(List: TStrings); override;
  229. Property SearchPage: String Read FSearchPage Write FSearchPage;
  230. property Allocator: TFileAllocator read FAllocator;
  231. property Package: TPasPackage read FPackage;
  232. property PageCount: Integer read GetPageCount;
  233. Property IncludeDateInFooter : Boolean Read FIDF Write FIDF;
  234. Property DateFormat : String Read FDateFormat Write FDateFormat;
  235. property OnTest: TNotifyEvent read FOnTest write SetOnTest;
  236. Property CharSet : String Read FCharSet Write FCharSet;
  237. Property IndexColCount : Integer Read FIndexColCount write FIndexColCount;
  238. Property BaseImageURL : String Read FBaseImageURL Write FBaseImageURL;
  239. end;
  240. THTMWriter = class(THTMLWriter)
  241. Protected
  242. Procedure CreateAllocator; override;
  243. end;
  244. {$DEFINE chmInterface}
  245. {$I dw_htmlchm.inc}
  246. {$UNDEF chmInterface}
  247. implementation
  248. uses SysUtils, XHTML, XMLRead, XMLWrite, HTMWrite, sh_pas,chmsitemap;
  249. Function FixHTMLpath(S : String) : STring;
  250. begin
  251. Result:=StringReplace(S,'\','/',[rfReplaceAll]);
  252. end;
  253. {$I dw_htmlchm.inc}
  254. procedure TFileAllocator.AllocFilename(AElement: TPasElement;
  255. ASubindex: Integer);
  256. begin
  257. end;
  258. function TFileAllocator.GetRelativePathToTop(AElement: TPasElement): String;
  259. begin
  260. SetLength(Result, 0);
  261. end;
  262. function TFileAllocator.GetCSSFilename(ARelativeTo: TPasElement): DOMString;
  263. begin
  264. Result := GetRelativePathToTop(ARelativeTo) + 'fpdoc.css';
  265. end;
  266. constructor TShortNameFileAllocator.Create(const AExtension: String);
  267. begin
  268. inherited Create;
  269. FExtension := AExtension;
  270. end;
  271. procedure TShortNameFileAllocator.AllocFilename(AElement: TPasElement;
  272. ASubindex: Integer);
  273. begin
  274. // !!!: Add element to file list
  275. end;
  276. constructor TLongNameFileAllocator.Create(const AExtension: String);
  277. begin
  278. inherited Create;
  279. FExtension := AExtension;
  280. end;
  281. function TLongNameFileAllocator.GetFilename(AElement: TPasElement;
  282. ASubindex: Integer): String;
  283. var
  284. s: String;
  285. i: Integer;
  286. begin
  287. if AElement.ClassType = TPasPackage then
  288. Result := 'index'
  289. else if AElement.ClassType = TPasModule then
  290. Result := LowerCase(AElement.Name) + PathDelim + 'index'
  291. else
  292. begin
  293. if AElement is TPasOperator then
  294. begin
  295. Result := LowerCase(AElement.Parent.PathName) + '.op-';
  296. s := Copy(AElement.Name, Pos(' ', AElement.Name) + 1, Length(AElement.Name));
  297. s := Copy(s, 1, Pos('(', s) - 1);
  298. if s = ':=' then
  299. s := 'assign'
  300. else if s = '+' then
  301. s := 'add'
  302. else if s = '-' then
  303. s := 'sub'
  304. else if s = '*' then
  305. s := 'mul'
  306. else if s = '/' then
  307. s := 'div'
  308. else if s = '**' then
  309. s := 'power'
  310. else if s = '=' then
  311. s := 'equal'
  312. else if s = '<>' then
  313. s := 'unequal'
  314. else if s = '<' then
  315. s := 'less'
  316. else if s = '<=' then
  317. s := 'lessequal'
  318. else if s = '>' then
  319. s := 'greater'
  320. else if s = '>=' then
  321. s := 'greaterthan'
  322. else if s = '><' then
  323. s := 'symmetricdifference';
  324. Result := Result + s + '-';
  325. s := '';
  326. i := 1;
  327. while AElement.Name[i] <> '(' do
  328. Inc(i);
  329. Inc(i);
  330. while AElement.Name[i] <> ')' do
  331. begin
  332. if AElement.Name[i] = ',' then
  333. begin
  334. s := s + '-';
  335. Inc(i);
  336. end else
  337. s := s + AElement.Name[i];
  338. Inc(i);
  339. end;
  340. Result := Result + LowerCase(s) + '-' + LowerCase(Copy(AElement.Name,
  341. Pos('):', AElement.Name) + 3, Length(AElement.Name)));
  342. end else
  343. Result := LowerCase(AElement.PathName);
  344. i := 1;
  345. if (Length(Result) > 0) and (Result[1] = '#') then
  346. begin
  347. while Result[i] <> '.' do
  348. Inc(i);
  349. Result := Copy(Result, i + 1, Length(Result));
  350. end;
  351. i := 1;
  352. while (i <= Length(Result)) and (Result[i] <> '.') do
  353. Inc(i);
  354. if (i <= Length(Result)) and (i > 0) then
  355. Result[i] := PathDelim;
  356. end;
  357. if ASubindex > 0 then
  358. Result := Result + '-' + IntToStr(ASubindex);
  359. Result := Result + Extension;
  360. end;
  361. function TLongNameFileAllocator.GetRelativePathToTop(AElement: TPasElement): String;
  362. begin
  363. if (AElement.ClassType=TPasPackage) then
  364. Result := ''
  365. else if (AElement.ClassType=TTopicElement) then
  366. begin
  367. If (AElement.Parent.ClassType=TTopicElement) then
  368. Result:='../'+GetRelativePathToTop(AElement.Parent)
  369. else if (AElement.Parent.ClassType=TPasPackage) then
  370. Result:=''
  371. else if (AElement.Parent.ClassType=TPasModule) then
  372. Result:='../';
  373. end
  374. else
  375. Result := '../';
  376. end;
  377. Type
  378. { TLinkData }
  379. TLinkData = Class(TObject)
  380. FPathName,
  381. FLink,
  382. FModuleName : String;
  383. Constructor Create(Const APathName,ALink,AModuleName : string);
  384. end;
  385. { TLinkData }
  386. constructor TLinkData.Create(Const APathName, ALink, AModuleName: string);
  387. begin
  388. FPathName:=APathName;
  389. FLink:=ALink;
  390. FModuleName:=AModuleName;
  391. end;
  392. constructor THTMLWriter.Create(APackage: TPasPackage; AEngine: TFPDocEngine);
  393. procedure AddPage(AElement: TPasElement; ASubpageIndex: Integer);
  394. var
  395. PageInfo: TPageInfo;
  396. begin
  397. PageInfo := TPageInfo.Create;
  398. PageInfo.Element := AElement;
  399. PageInfo.SubpageIndex := ASubpageIndex;
  400. PageInfos.Add(PageInfo);
  401. Allocator.AllocFilename(AElement, ASubpageIndex);
  402. if ASubpageIndex = 0 then
  403. Engine.AddLink(AElement.PathName,
  404. Allocator.GetFilename(AElement, ASubpageIndex));
  405. end;
  406. procedure AddTopicPages(AElement: TPasElement);
  407. var
  408. PreviousTopic,
  409. TopicElement : TTopicElement;
  410. PageInfo : TPageInfo;
  411. DocNode,
  412. TopicNode : TDocNode;
  413. begin
  414. DocNode:=Engine.FindDocNode(AElement);
  415. If not Assigned(DocNode) then
  416. exit;
  417. TopicNode:=DocNode.FirstChild;
  418. PreviousTopic:=Nil;
  419. While Assigned(TopicNode) do
  420. begin
  421. If TopicNode.TopicNode then
  422. begin
  423. TopicElement:=TTopicElement.Create(TopicNode.Name,AElement);
  424. Topics.Add(TopicElement);
  425. TopicElement.TopicNode:=TopicNode;
  426. TopicElement.Previous:=PreviousTopic;
  427. If Assigned(PreviousTopic) then
  428. PreviousTopic.Next:=TopicElement;
  429. PreviousTopic:=TopicElement;
  430. if AElement is TTopicElement then
  431. TTopicElement(AElement).SubTopics.Add(TopicElement);
  432. PageInfo := TPageInfo.Create;
  433. PageInfo.Element := TopicElement;
  434. PageInfo.SubpageIndex := 0;
  435. PageInfos.Add(PageInfo);
  436. Allocator.AllocFilename(TopicElement,0);
  437. Engine.AddLink(TopicElement.PathName, Allocator.GetFilename(TopicElement,0));
  438. if AElement is TTopicElement then
  439. TTopicElement(AElement).SubTopics.Add(TopicElement)
  440. else // Only one level of recursion.
  441. AddTopicPages(TopicElement);
  442. end;
  443. TopicNode:=TopicNode.NextSibling;
  444. end;
  445. end;
  446. procedure AddPages(AElement: TPasElement; ASubpageIndex: Integer;
  447. AList: TFPList);
  448. var
  449. i: Integer;
  450. begin
  451. if AList.Count > 0 then
  452. begin
  453. AddPage(AElement, ASubpageIndex);
  454. for i := 0 to AList.Count - 1 do
  455. AddPage(TPasElement(AList[i]), 0);
  456. end;
  457. end;
  458. procedure ScanModule(AModule: TPasModule; LinkList : TObjectList);
  459. var
  460. i, j, k: Integer;
  461. s: String;
  462. ClassEl: TPasClassType;
  463. FPEl, AncestorMemberEl: TPasElement;
  464. DocNode: TDocNode;
  465. ALink : DOMString;
  466. DidAutolink: Boolean;
  467. begin
  468. AddPage(AModule, 0);
  469. AddPage(AModule,IndexSubIndex);
  470. AddTopicPages(AModule);
  471. with AModule do
  472. begin
  473. if InterfaceSection.ResStrings.Count > 0 then
  474. begin
  475. AddPage(AModule, ResstrSubindex);
  476. s := Allocator.GetFilename(AModule, ResstrSubindex);
  477. for i := 0 to InterfaceSection.ResStrings.Count - 1 do
  478. with TPasResString(InterfaceSection.ResStrings[i]) do
  479. Engine.AddLink(PathName, s + '#' + LowerCase(Name));
  480. end;
  481. AddPages(AModule, ConstsSubindex, InterfaceSection.Consts);
  482. AddPages(AModule, TypesSubindex, InterfaceSection.Types);
  483. if InterfaceSection.Classes.Count > 0 then
  484. begin
  485. AddPage(AModule, ClassesSubindex);
  486. for i := 0 to InterfaceSection.Classes.Count - 1 do
  487. begin
  488. ClassEl := TPasClassType(InterfaceSection.Classes[i]);
  489. AddPage(ClassEl, 0);
  490. // !!!: Only add when there are items
  491. AddPage(ClassEl, PropertiesByInheritanceSubindex);
  492. AddPage(ClassEl, PropertiesByNameSubindex);
  493. AddPage(ClassEl, MethodsByInheritanceSubindex);
  494. AddPage(ClassEl, MethodsByNameSubindex);
  495. AddPage(ClassEl, EventsByInheritanceSubindex);
  496. AddPage(ClassEl, EventsByNameSubindex);
  497. for j := 0 to ClassEl.Members.Count - 1 do
  498. begin
  499. FPEl := TPasElement(ClassEl.Members[j]);
  500. if ((FPEl.Visibility = visPrivate) and Engine.HidePrivate) or
  501. ((FPEl.Visibility = visProtected) and Engine.HideProtected) then
  502. continue;
  503. DocNode := Engine.FindDocNode(FPEl);
  504. if Assigned(DocNode) then
  505. begin
  506. if Assigned(DocNode.Node) then
  507. ALink:=DocNode.Node['link']
  508. else
  509. ALink:='';
  510. If (ALink<>'') then
  511. LinkList.Add(TLinkData.Create(FPEl.PathName,ALink,AModule.name))
  512. else
  513. AddPage(FPEl, 0);
  514. end
  515. else
  516. begin
  517. DidAutolink := False;
  518. if Assigned(ClassEl.AncestorType) and
  519. (ClassEl.AncestorType.ClassType = TPasClassType) then
  520. begin
  521. for k := 0 to TPasClassType(ClassEl.AncestorType).Members.Count - 1 do
  522. begin
  523. AncestorMemberEl :=
  524. TPasElement(TPasClassType(ClassEl.AncestorType).Members[k]);
  525. if AncestorMemberEl.Name = FPEl.Name then
  526. begin
  527. DocNode := Engine.FindDocNode(AncestorMemberEl);
  528. if Assigned(DocNode) then
  529. begin
  530. DidAutolink := True;
  531. Engine.AddLink(FPEl.PathName,
  532. Engine.FindAbsoluteLink(AncestorMemberEl.PathName));
  533. break;
  534. end;
  535. end;
  536. end;
  537. end;
  538. if not DidAutolink then
  539. AddPage(FPEl, 0);
  540. end;
  541. end;
  542. end;
  543. end;
  544. AddPages(AModule, ProcsSubindex, InterfaceSection.Functions);
  545. AddPages(AModule, VarsSubindex, InterfaceSection.Variables);
  546. end;
  547. end;
  548. var
  549. i: Integer;
  550. L : TObjectList;
  551. begin
  552. inherited ;
  553. IndexColCount:=3;
  554. Charset:='iso-8859-1';
  555. CreateAllocator;
  556. FPackage := APackage;
  557. OutputNodeStack := TList.Create;
  558. PageInfos := TObjectList.Create;
  559. FImageFileList := TStringList.Create;
  560. // Allocate page for the package itself, if a name is given (i.e. <> '#')
  561. if Length(Package.Name) > 1 then
  562. begin
  563. AddPage(Package, 0);
  564. AddPage(Package,IndexSubIndex);
  565. AddTopicPages(Package);
  566. end;
  567. L:=TObjectList.Create;
  568. try
  569. for i := 0 to Package.Modules.Count - 1 do
  570. ScanModule(TPasModule(Package.Modules[i]),L);
  571. // Resolve links
  572. For I:=0 to L.Count-1 do
  573. With TLinkData(L[i]) do
  574. Engine.AddLink(FPathName,ResolveLinkIDInUnit(FLink,FModuleName));
  575. finally
  576. L.Free;
  577. end;
  578. end;
  579. destructor THTMLWriter.Destroy;
  580. begin
  581. PageInfos.Free;
  582. OutputNodeStack.Free;
  583. FAllocator.Free;
  584. FImageFileList.Free;
  585. inherited Destroy;
  586. end;
  587. function THTMLWriter.CreateHTMLPage(AElement: TPasElement;
  588. ASubpageIndex: Integer): TXMLDocument;
  589. var
  590. HTMLEl: THTMLHtmlElement;
  591. HeadEl: THTMLHeadElement;
  592. El: TDOMElement;
  593. begin
  594. Doc := THTMLDocument.Create;
  595. Result := Doc;
  596. Doc.AppendChild(Doc.Impl.CreateDocumentType(
  597. 'HTML', '-//W3C//DTD HTML 4.01 Transitional//EN',
  598. 'http://www.w3.org/TR/html4/loose.dtd'));
  599. HTMLEl := Doc.CreateHtmlElement;
  600. Doc.AppendChild(HTMLEl);
  601. HeadEl := Doc.CreateHeadElement;
  602. HTMLEl.AppendChild(HeadEl);
  603. El := Doc.CreateElement('meta');
  604. HeadEl.AppendChild(El);
  605. El['http-equiv'] := 'Content-Type';
  606. El['content'] := 'text/html; charset=utf-8';
  607. TitleElement := Doc.CreateElement('title');
  608. HeadEl.AppendChild(TitleElement);
  609. El := Doc.CreateElement('link');
  610. BodyElement := Doc.CreateElement('body');
  611. HTMLEl.AppendChild(BodyElement);
  612. CreatePageBody(AElement, ASubpageIndex);
  613. AppendFooter;
  614. HeadEl.AppendChild(El);
  615. El['rel'] := 'stylesheet';
  616. El['type'] := 'text/css';
  617. El['href'] := FixHtmlPath(Allocator.GetCSSFilename(AElement));
  618. end;
  619. function THTMLWriter.CreateXHTMLPage(AElement: TPasElement;
  620. ASubpageIndex: Integer): TXMLDocument;
  621. begin
  622. Result := nil;
  623. end;
  624. procedure CreatePath(const AFilename: String);
  625. var
  626. EndIndex: Integer;
  627. Path: String;
  628. begin
  629. EndIndex := Length(AFilename);
  630. if EndIndex = 0 then
  631. exit;
  632. while not (AFilename[EndIndex] in AllowDirectorySeparators) do
  633. begin
  634. Dec(EndIndex);
  635. if EndIndex = 0 then
  636. exit;
  637. end;
  638. Path := Copy(AFilename, 1, EndIndex - 1);
  639. if not DirectoryExists(Path) then
  640. begin
  641. CreatePath(Path);
  642. MkDir(Path);
  643. end;
  644. end;
  645. procedure THTMLWriter.WriteHTMLPages;
  646. var
  647. i: Integer;
  648. PageDoc: TXMLDocument;
  649. Filename: String;
  650. TempStream: TMemoryStream;
  651. begin
  652. if Engine.Output <> '' then
  653. Engine.Output := IncludeTrailingBackSlash(Engine.Output);
  654. for i := 0 to PageInfos.Count - 1 do
  655. with TPageInfo(PageInfos[i]) do
  656. begin
  657. PageDoc := CreateHTMLPage(Element, SubpageIndex);
  658. try
  659. Filename := Engine.Output + Allocator.GetFilename(Element, SubpageIndex);
  660. try
  661. CreatePath(Filename);
  662. WriteHTMLFile(PageDoc, Filename);
  663. except
  664. on E: Exception do
  665. DoLog(SErrCouldNotCreateFile, [FileName, e.Message]);
  666. end;
  667. finally
  668. PageDoc.Free;
  669. end;
  670. end;
  671. if FCSSFile <> '' then
  672. begin
  673. if not FileExists(FCSSFile) Then
  674. begin
  675. DoLog('Can''t find CSS file "%s"',[FCSSFILE]);
  676. halt(1);
  677. end;
  678. TempStream := TMemoryStream.Create;
  679. TempStream.LoadFromFile(FCSSFile);
  680. TempStream.Position := 0;
  681. TempStream.SaveToFile(Engine.output+ExtractFileName(FCSSFile));
  682. TempStream.Free;
  683. end;
  684. end;
  685. procedure THTMLWriter.WriteXHTMLPages;
  686. begin
  687. end;
  688. {procedure THTMLWriter.CreateDoc(const ATitle: DOMString;
  689. AElement: TPasElement; const AFilename: String);
  690. var
  691. El: TDOMElement;
  692. DocInfo: TDocInfo;
  693. CSSName: String;
  694. begin
  695. Doc := TXHTMLDocument.Create;
  696. with TXHTMLDocument(Doc) do
  697. begin
  698. Encoding := 'ISO8859-1';
  699. CSSName := 'fpdoc.css';
  700. if Assigned(Module) then
  701. CSSName := '../' + CSSName;
  702. $IFNDEF ver1_0
  703. StylesheetType := 'text/css';
  704. StylesheetHRef := CSSName;
  705. $ENDIF
  706. CreateRoot(xhtmlStrict);
  707. with RequestHeadElement do
  708. begin
  709. AppendText(RequestTitleElement, ATitle);
  710. El := CreateElement('link');
  711. AppendChild(El);
  712. El['rel'] := 'stylesheet';
  713. El['type'] := 'text/css';
  714. El['href'] := FixHtmlPath(CSSName);
  715. end;
  716. Self.BodyElement := RequestBodyElement('en');
  717. end;
  718. if Length(AFilename) > 0 then
  719. begin
  720. DocInfo := TDocInfo.Create;
  721. DocInfos.Add(DocInfo);
  722. DocInfo.Element := AElement;
  723. DocInfo.Filename := AFilename;
  724. end;
  725. end;
  726. }
  727. { Used for:
  728. - <link> elements in descriptions
  729. - "see also" entries
  730. - AppendHyperlink (for unresolved parse tree element links)
  731. }
  732. function THTMLWriter.ResolveLinkIDInUnit(const Name,AUnitName: String): DOMString;
  733. begin
  734. Result:=ResolveLinkID(Name);
  735. If (Result='') and (AUnitName<>'') then
  736. Result:=ResolveLinkID(AUnitName+'.'+Name);
  737. end;
  738. function THTMLWriter.ResolveLinkID(const Name: String): DOMString;
  739. var
  740. i: Integer;
  741. ThisPackage: TLinkNode;
  742. begin
  743. if Length(Name) = 0 then
  744. begin
  745. SetLength(Result, 0);
  746. exit;
  747. end;
  748. if Name[1] = '#' then
  749. Result := Engine.FindAbsoluteLink(Name)
  750. else
  751. begin
  752. SetLength(Result, 0);
  753. { Try all packages }
  754. ThisPackage := Engine.RootLinkNode.FirstChild;
  755. while Assigned(ThisPackage) do
  756. begin
  757. Result := Engine.FindAbsoluteLink(ThisPackage.Name + '.' + Name);
  758. if Length(Result) = 0 then
  759. begin
  760. if Assigned(Module) then
  761. begin
  762. Result := Engine.FindAbsoluteLink(Module.PathName + '.' + Name);
  763. // WriteLn('Searching for ', Module.PathName + '.' + Name, ' => ', Result);
  764. end;
  765. if Length(Result) = 0 then
  766. for i := Length(Name) downto 1 do
  767. if Name[i] = '.' then
  768. begin
  769. Result := ResolveLinkID(Copy(Name, 1, i - 1));
  770. exit;
  771. end;
  772. end;
  773. ThisPackage := ThisPackage.NextSibling;
  774. end;
  775. end;
  776. if Length(Result) > 0 then
  777. if Copy(Result, 1, Length(CurDirectory) + 1) = CurDirectory + '/' then
  778. Result := Copy(Result, Length(CurDirectory) + 2, Length(Result))
  779. else if not IsLinkAbsolute(Result) then
  780. Result := BaseDirectory + Result;
  781. end;
  782. function THTMLWriter.ResolveLinkWithinPackage(AElement: TPasElement;
  783. ASubpageIndex: Integer): String;
  784. var
  785. ParentEl: TPasElement;
  786. begin
  787. ParentEl := AElement;
  788. while Assigned(ParentEl) and not (ParentEl.ClassType = TPasPackage) do
  789. ParentEl := ParentEl.Parent;
  790. if Assigned(ParentEl) and (TPasPackage(ParentEl) = Engine.Package) then
  791. begin
  792. Result := Allocator.GetFilename(AElement, ASubpageIndex);
  793. if Copy(Result, 1, Length(CurDirectory) + 1) = CurDirectory + '/' then
  794. Result := Copy(Result, Length(CurDirectory) + 2, Length(Result))
  795. else
  796. Result := BaseDirectory + Result;
  797. end else
  798. SetLength(Result, 0);
  799. end;
  800. function THTMLWriter.CreateEl(Parent: TDOMNode;
  801. const AName: DOMString): THTMLElement;
  802. begin
  803. Result := Doc.CreateElement(AName);
  804. Parent.AppendChild(Result);
  805. end;
  806. function THTMLWriter.CreatePara(Parent: TDOMNode): THTMLElement;
  807. begin
  808. Result := CreateEl(Parent, 'p');
  809. end;
  810. function THTMLWriter.CreateH1(Parent: TDOMNode): THTMLElement;
  811. begin
  812. Result := CreateEl(Parent, 'h1');
  813. end;
  814. function THTMLWriter.CreateH2(Parent: TDOMNode): THTMLElement;
  815. begin
  816. Result := CreateEl(Parent, 'h2');
  817. end;
  818. function THTMLWriter.CreateH3(Parent: TDOMNode): THTMLElement;
  819. begin
  820. Result := CreateEl(Parent, 'h3');
  821. end;
  822. function THTMLWriter.CreateTable(Parent: TDOMNode; const AClass: DOMString = ''): THTMLElement;
  823. begin
  824. Result := CreateEl(Parent, 'table');
  825. Result['cellspacing'] := '0';
  826. Result['cellpadding'] := '0';
  827. if AClass <> '' then
  828. Result['class'] := AClass;
  829. end;
  830. function THTMLWriter.CreateContentTable(Parent: TDOMNode): THTMLElement;
  831. begin
  832. Result := CreateEl(Parent, 'table');
  833. end;
  834. function THTMLWriter.CreateTR(Parent: TDOMNode): THTMLElement;
  835. begin
  836. Result := CreateEl(Parent, 'tr');
  837. end;
  838. function THTMLWriter.CreateTD(Parent: TDOMNode): THTMLElement;
  839. begin
  840. Result := CreateEl(Parent, 'td');
  841. end;
  842. function THTMLWriter.CreateTD_vtop(Parent: TDOMNode): THTMLElement;
  843. begin
  844. Result := CreateEl(Parent, 'td');
  845. Result['valign'] := 'top';
  846. end;
  847. function THTMLWriter.CreateLink(Parent: TDOMNode;
  848. const AHRef: DOMString): THTMLElement;
  849. begin
  850. Result := CreateEl(Parent, 'a');
  851. Result['href'] := FixHtmlPath(AHRef);
  852. end;
  853. function THTMLWriter.CreateAnchor(Parent: TDOMNode;
  854. const AName: DOMString): THTMLElement;
  855. begin
  856. Result := CreateEl(Parent, 'a');
  857. Result['name'] := AName;
  858. end;
  859. function THTMLWriter.CreateCode(Parent: TDOMNode): THTMLElement;
  860. begin
  861. Result := CreateEl(CreateEl(Parent, 'tt'), 'span');
  862. Result['class'] := 'code';
  863. end;
  864. function THTMLWriter.CreateWarning(Parent: TDOMNode): THTMLElement;
  865. begin
  866. Result := CreateEl(Parent, 'span');
  867. Result['class'] := 'warning';
  868. end;
  869. procedure THTMLWriter.PushOutputNode(ANode: TDOMNode);
  870. begin
  871. OutputNodeStack.Add(CurOutputNode);
  872. CurOutputNode := ANode;
  873. end;
  874. procedure THTMLWriter.PopOutputNode;
  875. begin
  876. CurOutputNode := TDOMNode(OutputNodeStack[OutputNodeStack.Count - 1]);
  877. OutputNodeStack.Delete(OutputNodeStack.Count - 1);
  878. end;
  879. procedure THTMLWriter.DescrWriteText(const AText: DOMString);
  880. begin
  881. AppendText(CurOutputNode, AText);
  882. end;
  883. procedure THTMLWriter.DescrBeginBold;
  884. begin
  885. PushOutputNode(CreateEl(CurOutputNode, 'b'));
  886. end;
  887. procedure THTMLWriter.DescrEndBold;
  888. begin
  889. PopOutputNode;
  890. end;
  891. procedure THTMLWriter.DescrBeginItalic;
  892. begin
  893. PushOutputNode(CreateEl(CurOutputNode, 'i'));
  894. end;
  895. procedure THTMLWriter.DescrEndItalic;
  896. begin
  897. PopOutputNode;
  898. end;
  899. procedure THTMLWriter.DescrBeginEmph;
  900. begin
  901. PushOutputNode(CreateEl(CurOutputNode, 'em'));
  902. end;
  903. procedure THTMLWriter.DescrEndEmph;
  904. begin
  905. PopOutputNode;
  906. end;
  907. procedure THTMLWriter.DescrWriteImageEl(const AFileName, ACaption, ALinkName : DOMString);
  908. Var
  909. Pel,Cel,Lel : TDOMNode;
  910. El :TDomElement;
  911. D : String;
  912. L : Integer;
  913. begin
  914. // Determine parent node.
  915. If (ACaption='') then
  916. Pel:=CurOutputNode
  917. else
  918. begin
  919. Cel:=CreateTable(CurOutputNode, 'imagetable');
  920. Pel:=CreateTD(CreateTR(Cel));
  921. Cel:=CreateTD(CreateTR(Cel));
  922. El := CreateEl(Cel, 'span');
  923. El['class'] := 'imagecaption';
  924. Cel := El;
  925. If (ALinkName<>'') then
  926. Cel:=CreateAnchor(Cel,ALinkName);
  927. AppendText(Cel,ACaption);
  928. end;
  929. // Determine URL for image.
  930. If (Module=Nil) then
  931. D:=Allocator.GetRelativePathToTop(Package)
  932. else
  933. D:=Allocator.GetRelativePathToTop(Module);
  934. L:=Length(D);
  935. If (L>0) and (D[L]<>'/') then
  936. D:=D+'/';
  937. // Create image node.
  938. El:=CreateEl(Pel,'img');
  939. EL['src']:=D + BaseImageURL + AFileName;
  940. El['alt']:=ACaption;
  941. //cache image filename, so it can be used later (CHM)
  942. FImageFileList.Add(BaseImageURL + AFileName);
  943. end;
  944. procedure THTMLWriter.DescrWriteFileEl(const AText: DOMString);
  945. var
  946. NewEl: TDOMElement;
  947. begin
  948. NewEl := CreateEl(CurOutputNode, 'span');
  949. NewEl['class'] := 'file';
  950. AppendText(NewEl, AText);
  951. end;
  952. procedure THTMLWriter.DescrWriteKeywordEl(const AText: DOMString);
  953. var
  954. NewEl: TDOMElement;
  955. begin
  956. NewEl := CreateEl(CurOutputNode, 'span');
  957. NewEl['class'] := 'kw';
  958. AppendText(NewEl, AText);
  959. end;
  960. procedure THTMLWriter.DescrWriteVarEl(const AText: DOMString);
  961. begin
  962. AppendText(CreateEl(CurOutputNode, 'var'), AText);
  963. end;
  964. procedure THTMLWriter.DescrBeginLink(const AId: DOMString);
  965. var
  966. a,s: String;
  967. begin
  968. a:=AId;
  969. s := ResolveLinkID(a);
  970. if Length(s) = 0 then
  971. begin
  972. if assigned(module) then
  973. s:=module.name
  974. else
  975. s:='?';
  976. if a='' then a:='<empty>';
  977. DoLog(SErrUnknownLinkID, [s,a]);
  978. PushOutputNode(CreateEl(CurOutputNode, 'b'));
  979. end else
  980. PushOutputNode(CreateLink(CurOutputNode, s));
  981. end;
  982. procedure THTMLWriter.DescrEndLink;
  983. begin
  984. PopOutputNode;
  985. end;
  986. procedure THTMLWriter.DescrBeginURL(const AURL: DOMString);
  987. begin
  988. PushOutputNode(CreateLink(CurOutputNode, AURL));
  989. end;
  990. procedure THTMLWriter.DescrEndURL;
  991. begin
  992. PopOutputNode;
  993. end;
  994. procedure THTMLWriter.DescrWriteLinebreak;
  995. begin
  996. CreateEl(CurOutputNode, 'br');
  997. end;
  998. procedure THTMLWriter.DescrBeginParagraph;
  999. begin
  1000. PushOutputNode(CreatePara(CurOutputNode));
  1001. end;
  1002. procedure THTMLWriter.DescrEndParagraph;
  1003. begin
  1004. PopOutputNode;
  1005. end;
  1006. procedure THTMLWriter.DescrBeginCode(HasBorder: Boolean; const AHighlighterName: String);
  1007. begin
  1008. DoPasHighlighting := (AHighlighterName = '') or (AHighlighterName = 'Pascal');
  1009. HighlighterFlags := 0;
  1010. PushOutputNode(CreateEl(CurOutputNode, 'pre'));
  1011. end;
  1012. procedure THTMLWriter.DescrWriteCodeLine(const ALine: String);
  1013. begin
  1014. if DoPasHighlighting then
  1015. begin
  1016. HighlighterFlags := AppendPasSHFragment(CurOutputNode, ALine,
  1017. HighlighterFlags);
  1018. AppendText(CurOutputNode, #10);
  1019. end else
  1020. AppendText(CurOutputNode, ALine + #10);
  1021. end;
  1022. procedure THTMLWriter.DescrEndCode;
  1023. begin
  1024. PopOutputNode;
  1025. end;
  1026. procedure THTMLWriter.DescrBeginOrderedList;
  1027. begin
  1028. PushOutputNode(CreateEl(CurOutputNode, 'ol'));
  1029. end;
  1030. procedure THTMLWriter.DescrEndOrderedList;
  1031. begin
  1032. PopOutputNode;
  1033. end;
  1034. procedure THTMLWriter.DescrBeginUnorderedList;
  1035. begin
  1036. PushOutputNode(CreateEl(CurOutputNode, 'ul'));
  1037. end;
  1038. procedure THTMLWriter.DescrEndUnorderedList;
  1039. begin
  1040. PopOutputNode;
  1041. end;
  1042. procedure THTMLWriter.DescrBeginDefinitionList;
  1043. begin
  1044. PushOutputNode(CreateEl(CurOutputNode, 'dl'));
  1045. end;
  1046. procedure THTMLWriter.DescrEndDefinitionList;
  1047. begin
  1048. PopOutputNode;
  1049. end;
  1050. procedure THTMLWriter.DescrBeginListItem;
  1051. begin
  1052. PushOutputNode(CreateEl(CurOutputNode, 'li'));
  1053. end;
  1054. procedure THTMLWriter.DescrEndListItem;
  1055. begin
  1056. PopOutputNode;
  1057. end;
  1058. procedure THTMLWriter.DescrBeginDefinitionTerm;
  1059. begin
  1060. PushOutputNode(CreateEl(CurOutputNode, 'dt'));
  1061. end;
  1062. procedure THTMLWriter.DescrEndDefinitionTerm;
  1063. begin
  1064. PopOutputNode;
  1065. end;
  1066. procedure THTMLWriter.DescrBeginDefinitionEntry;
  1067. begin
  1068. PushOutputNode(CreateEl(CurOutputNode, 'dd'));
  1069. end;
  1070. procedure THTMLWriter.DescrEndDefinitionEntry;
  1071. begin
  1072. PopOutputNode;
  1073. end;
  1074. procedure THTMLWriter.DescrBeginSectionTitle;
  1075. begin
  1076. PushOutputNode(CreateEl(CurOutputNode, 'h3'));
  1077. end;
  1078. procedure THTMLWriter.DescrBeginSectionBody;
  1079. begin
  1080. PopOutputNode;
  1081. end;
  1082. procedure THTMLWriter.DescrEndSection;
  1083. begin
  1084. end;
  1085. procedure THTMLWriter.DescrBeginRemark;
  1086. var
  1087. NewEl, TDEl: TDOMElement;
  1088. begin
  1089. NewEl := CreateEl(CurOutputNode, 'table');
  1090. NewEl['width'] := '100%';
  1091. NewEl['border'] := '0';
  1092. NewEl['CellSpacing'] := '0';
  1093. NewEl['class'] := 'remark';
  1094. NewEl := CreateTR(NewEl);
  1095. TDEl := CreateTD(NewEl);
  1096. TDEl['valign'] := 'top';
  1097. TDEl['class'] := 'pre';
  1098. AppendText(CreateEl(TDEl, 'b'), SDocRemark);
  1099. PushOutputNode(CreateTD(NewEl));
  1100. end;
  1101. procedure THTMLWriter.DescrEndRemark;
  1102. begin
  1103. PopOutputNode;
  1104. end;
  1105. procedure THTMLWriter.DescrBeginTable(ColCount: Integer; HasBorder: Boolean);
  1106. var
  1107. Table: TDOMElement;
  1108. begin
  1109. Table := CreateEl(CurOutputNode, 'table');
  1110. Table['border'] := IntToStr(Ord(HasBorder));
  1111. PushOutputNode(Table);
  1112. end;
  1113. procedure THTMLWriter.DescrEndTable;
  1114. begin
  1115. PopOutputNode;
  1116. end;
  1117. procedure THTMLWriter.DescrBeginTableCaption;
  1118. begin
  1119. PushOutputNode(CreateEl(CurOutputNode, 'caption'));
  1120. end;
  1121. procedure THTMLWriter.DescrEndTableCaption;
  1122. begin
  1123. PopOutputNode;
  1124. end;
  1125. procedure THTMLWriter.DescrBeginTableHeadRow;
  1126. begin
  1127. PushOutputNode(CreateTr(CurOutputNode));
  1128. InsideHeadRow := True;
  1129. end;
  1130. procedure THTMLWriter.DescrEndTableHeadRow;
  1131. begin
  1132. InsideHeadRow := False;
  1133. PopOutputNode;
  1134. end;
  1135. procedure THTMLWriter.DescrBeginTableRow;
  1136. begin
  1137. PushOutputNode(CreateTR(CurOutputNode));
  1138. end;
  1139. procedure THTMLWriter.DescrEndTableRow;
  1140. begin
  1141. PopOutputNode;
  1142. end;
  1143. procedure THTMLWriter.DescrBeginTableCell;
  1144. begin
  1145. if InsideHeadRow then
  1146. PushOutputNode(CreateEl(CurOutputNode, 'th'))
  1147. else
  1148. PushOutputNode(CreateTD(CurOutputNode));
  1149. end;
  1150. procedure THTMLWriter.DescrEndTableCell;
  1151. begin
  1152. PopOutputNode;
  1153. end;
  1154. procedure THTMLWriter.AppendText(Parent: TDOMNode; const AText: DOMString);
  1155. begin
  1156. Parent.AppendChild(Doc.CreateTextNode(AText));
  1157. end;
  1158. procedure THTMLWriter.AppendNbSp(Parent: TDOMNode; ACount: Integer);
  1159. begin
  1160. while ACount > 0 do
  1161. begin
  1162. Parent.AppendChild(Doc.CreateEntityReference('nbsp'));
  1163. Dec(ACount);
  1164. end;
  1165. end;
  1166. procedure THTMLWriter.AppendSym(Parent: TDOMNode; const AText: DOMString);
  1167. var
  1168. El: TDOMElement;
  1169. begin
  1170. El := CreateEl(Parent, 'span');
  1171. El['class'] := 'sym';
  1172. AppendText(El, AText);
  1173. end;
  1174. procedure THTMLWriter.AppendKw(Parent: TDOMNode; const AText: DOMString);
  1175. var
  1176. El: TDOMElement;
  1177. begin
  1178. El := CreateEl(Parent, 'span');
  1179. El['class'] := 'kw';
  1180. AppendText(El, AText);
  1181. end;
  1182. function THTMLWriter.AppendPasSHFragment(Parent: TDOMNode;
  1183. const AText: String; AShFlags: Byte): Byte;
  1184. var
  1185. Line, Last, p: PChar;
  1186. IsInSpecial: Boolean;
  1187. lastwasasm : boolean;
  1188. El: TDOMElement;
  1189. Procedure MaybeOutput;
  1190. Var
  1191. CurParent: TDomNode;
  1192. begin
  1193. If (Last<>Nil) then
  1194. begin
  1195. If (el<>Nil) then
  1196. CurParent:=El
  1197. else
  1198. CurParent:=Parent;
  1199. AppendText(CurParent,Last);
  1200. El:=Nil;
  1201. Last:=Nil;
  1202. end;
  1203. end;
  1204. Function NewEl(Const ElType,Attr,AttrVal : String) : TDomElement;
  1205. begin
  1206. Result:=CreateEl(Parent,ElType);
  1207. Result[Attr]:=AttrVal;
  1208. end;
  1209. Function NewSpan(Const AttrVal : String) : TDomElement;
  1210. begin
  1211. Result:=CreateEl(Parent,'span');
  1212. Result['class']:=AttrVal;
  1213. end;
  1214. begin
  1215. GetMem(Line, Length(AText) * 3 + 4);
  1216. Try
  1217. DoPascalHighlighting(AShFlags, PChar(AText), Line);
  1218. Result := AShFlags;
  1219. IsInSpecial := False;
  1220. Last := Nil;
  1221. p := Line;
  1222. el:=nil;
  1223. while p[0] <> #0 do
  1224. begin
  1225. if p[0] = LF_ESCAPE then
  1226. begin
  1227. p[0] := #0;
  1228. MaybeOutput;
  1229. case Ord(p[1]) of
  1230. shDefault: El:=Nil;
  1231. shInvalid: El:=newel('font','color','red');
  1232. shSymbol : El:=newspan('sym');
  1233. shKeyword: El:=newspan('kw');
  1234. shComment: El:=newspan('cmt');
  1235. shDirective: El:=newspan('dir');
  1236. shNumbers: El:=newspan('num');
  1237. shCharacters: El:=newspan('chr');
  1238. shStrings: El:=newspan('str');
  1239. shAssembler: El:=newspan('asm');
  1240. end;
  1241. Inc(P);
  1242. end
  1243. else If (Last=Nil) then
  1244. Last:=P;
  1245. Inc(p);
  1246. end;
  1247. MaybeOutput;
  1248. Finally
  1249. FreeMem(Line);
  1250. end;
  1251. end;
  1252. Procedure THTMLWriter.AppendShortDescr(AContext: TPasElement; Parent: TDOMNode; DocNode : TDocNode);
  1253. Var
  1254. N : TDocNode;
  1255. begin
  1256. if Assigned(DocNode) then
  1257. begin
  1258. If (DocNode.Link<>'') then
  1259. begin
  1260. N:=Engine.FindLinkedNode(DocNode);
  1261. If (N<>Nil) then
  1262. DocNode:=N;
  1263. end;
  1264. If Assigned(DocNode.ShortDescr) then
  1265. begin
  1266. PushOutputNode(Parent);
  1267. try
  1268. if not ConvertShort(AContext,TDomElement(DocNode.ShortDescr)) then
  1269. Warning(AContext, SErrInvalidShortDescr)
  1270. finally
  1271. PopOutputNode;
  1272. end;
  1273. end;
  1274. end;
  1275. end;
  1276. procedure THTMLWriter.AppendShortDescr(Parent: TDOMNode; Element: TPasElement);
  1277. begin
  1278. AppendShortDescr(Element,Parent,Engine.FindDocNode(Element));
  1279. end;
  1280. procedure THTMLWriter.AppendShortDescrCell(Parent: TDOMNode;
  1281. Element: TPasElement);
  1282. var
  1283. ParaEl: TDOMElement;
  1284. begin
  1285. if Assigned(Engine.FindShortDescr(Element)) then
  1286. begin
  1287. AppendNbSp(CreatePara(CreateTD(Parent)), 2);
  1288. ParaEl := CreatePara(CreateTD(Parent));
  1289. ParaEl['class'] := 'cmt';
  1290. AppendShortDescr(ParaEl, Element);
  1291. end;
  1292. end;
  1293. procedure THTMLWriter.AppendDescr(AContext: TPasElement; Parent: TDOMNode;
  1294. DescrNode: TDOMElement; AutoInsertBlock: Boolean);
  1295. begin
  1296. if Assigned(DescrNode) then
  1297. begin
  1298. PushOutputNode(Parent);
  1299. try
  1300. ConvertDescr(AContext, DescrNode, AutoInsertBlock);
  1301. finally
  1302. PopOutputNode;
  1303. end;
  1304. end;
  1305. end;
  1306. procedure THTMLWriter.AppendDescrSection(AContext: TPasElement;
  1307. Parent: TDOMNode; DescrNode: TDOMElement; const ATitle: DOMString);
  1308. begin
  1309. if not IsDescrNodeEmpty(DescrNode) then
  1310. begin
  1311. If (ATitle<>'') then // Can be empty for topic.
  1312. AppendText(CreateH2(Parent), ATitle);
  1313. AppendDescr(AContext, Parent, DescrNode, True);
  1314. end;
  1315. end;
  1316. function THTMLWriter.AppendHyperlink(Parent: TDOMNode;
  1317. Element: TPasElement): TDOMElement;
  1318. var
  1319. s: String;
  1320. UnitList: TFPList;
  1321. i: Integer;
  1322. ThisPackage: TLinkNode;
  1323. begin
  1324. if Assigned(Element) then
  1325. begin
  1326. if Element.InheritsFrom(TPasUnresolvedTypeRef) then
  1327. begin
  1328. s := ResolveLinkID(Element.Name);
  1329. if Length(s) = 0 then
  1330. begin
  1331. { Try all packages }
  1332. ThisPackage := Engine.RootLinkNode.FirstChild;
  1333. while Assigned(ThisPackage) do
  1334. begin
  1335. s := ResolveLinkID(ThisPackage.Name + '.' + Element.Name);
  1336. if Length(s) > 0 then
  1337. break;
  1338. ThisPackage := ThisPackage.NextSibling;
  1339. end;
  1340. if Length(s) = 0 then
  1341. begin
  1342. { Okay, then we have to try all imported units of the current module }
  1343. UnitList := Module.InterfaceSection.UsesList;
  1344. for i := UnitList.Count - 1 downto 0 do
  1345. begin
  1346. { Try all packages }
  1347. ThisPackage := Engine.RootLinkNode.FirstChild;
  1348. while Assigned(ThisPackage) do
  1349. begin
  1350. s := ResolveLinkID(ThisPackage.Name + '.' +
  1351. TPasType(UnitList[i]).Name + '.' + Element.Name);
  1352. if Length(s) > 0 then
  1353. break;
  1354. ThisPackage := ThisPackage.NextSibling;
  1355. end;
  1356. if length(s)=0 then
  1357. s := ResolveLinkID('#rtl.System.' + Element.Name);
  1358. if Length(s) > 0 then
  1359. break;
  1360. end;
  1361. end;
  1362. end;
  1363. end else if Element is TPasEnumValue then
  1364. s := ResolveLinkID(Element.Parent.PathName)
  1365. else
  1366. s := ResolveLinkID(Element.PathName);
  1367. if Length(s) > 0 then
  1368. begin
  1369. Result := CreateLink(Parent, s);
  1370. AppendText(Result, Element.Name);
  1371. end else
  1372. begin
  1373. Result := nil;
  1374. AppendText(Parent, Element.Name);
  1375. end;
  1376. end else
  1377. begin
  1378. Result := nil;
  1379. AppendText(CreateWarning(Parent), '<NIL>');
  1380. end;
  1381. end;
  1382. { Returns the new CodeEl, which will be the old CodeEl in most cases }
  1383. function THTMLWriter.AppendType(CodeEl, TableEl: TDOMElement;
  1384. Element: TPasType; Expanded: Boolean; NestingLevel: Integer): TDOMElement;
  1385. Var
  1386. S : String;
  1387. begin
  1388. Result := CodeEl;
  1389. if not Assigned(Element) then
  1390. AppendText(CreateWarning(CodeEl), '<NIL>')
  1391. else if (not Expanded) and (Length(Element.Name) > 0) then
  1392. AppendHyperlink(CodeEl, Element)
  1393. else
  1394. // Array
  1395. if Element.ClassType = TPasArrayType then
  1396. begin
  1397. S:='array ';
  1398. If (TPasArrayType(Element).IndexRange<>'') then
  1399. S:=S+'[' + TPasArrayType(Element).IndexRange + '] ';
  1400. S:=S+'of ';
  1401. If (TPasArrayType(Element).ElType=Nil) then
  1402. S:=S+'Const';
  1403. AppendPasSHFragment(CodeEl,S,0);
  1404. If (TPasArrayType(Element).ElType<>Nil) then
  1405. Result := AppendType(CodeEl, TableEl, TPasArrayType(Element).ElType, False);
  1406. end else
  1407. // Procedure or funtion type
  1408. if Element.InheritsFrom(TPasProcedureType) then
  1409. begin
  1410. AppendKw(CodeEl, TPasProcedureType(Element).TypeName);
  1411. Result := AppendProcType(CodeEl, TableEl, TPasProcedureType(Element), 0)
  1412. end else
  1413. // Range type
  1414. if Element.InheritsFrom(TPasRangeType) then
  1415. AppendPasSHFragment(CodeEl, TPasRangeType(Element).RangeStart + '..' +
  1416. TPasRangeType(Element).RangeEnd, 0)
  1417. // Record type
  1418. else if Element.ClassType = TPasRecordType then
  1419. Result := AppendRecordType(CodeEl, TableEl, TPasRecordType(Element), NestingLevel)
  1420. else if (Element.ClassType = TPasFileType) and (TPasFileType(Element).elType=Nil) then
  1421. AppendPasSHFragment(CodeEl,'file',0)
  1422. else
  1423. // Other types
  1424. AppendHyperlink(CodeEl, Element);
  1425. end;
  1426. function THTMLWriter.AppendProcType(CodeEl, TableEl: TDOMElement;
  1427. Element: TPasProcedureType; Indent: Integer): TDOMElement;
  1428. function CreateIndentedCodeEl(Indent: Integer): TDOMElement;
  1429. begin
  1430. Result := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1431. AppendNbSp(Result, Indent);
  1432. end;
  1433. var
  1434. i: Integer;
  1435. Arg: TPasArgument;
  1436. begin
  1437. if Element.Args.Count > 0 then
  1438. begin
  1439. AppendSym(CodeEl, '(');
  1440. for i := 0 to Element.Args.Count - 1 do
  1441. begin
  1442. Arg := TPasArgument(Element.Args[i]);
  1443. CodeEl := CreateIndentedCodeEl(Indent + 2);
  1444. case Arg.Access of
  1445. argConst: AppendKw(CodeEl, 'const ');
  1446. argVar: AppendKw(CodeEl, 'var ');
  1447. argOut: AppendKw(CodeEl, 'out ');
  1448. end;
  1449. AppendText(CodeEl, Arg.Name);
  1450. if Assigned(Arg.ArgType) then
  1451. begin
  1452. AppendSym(CodeEl, ': ');
  1453. CodeEl := AppendType(CodeEl, TableEl, Arg.ArgType, False);
  1454. end;
  1455. if Length(Arg.Value) > 0 then
  1456. AppendPasSHFragment(CodeEl, ' = ' + Arg.Value, 0);
  1457. if i < Element.Args.Count - 1 then
  1458. AppendSym(CodeEl, ';');
  1459. end;
  1460. if Element.InheritsFrom(TPasFunctionType) or Element.IsOfObject then
  1461. begin
  1462. CodeEl := CreateIndentedCodeEl(Indent);
  1463. if Element.InheritsFrom(TPasFunctionType) then
  1464. begin
  1465. AppendSym(CodeEl, '):');
  1466. AppendHyperlink(CodeEl, TPasFunctionType(Element).ResultEl.ResultType);
  1467. end else
  1468. AppendSym(CodeEl, ')');
  1469. if Element.IsOfObject then
  1470. begin
  1471. AppendText(CodeEl, ' '); // Don't remove
  1472. AppendKw(CodeEl, 'of object');
  1473. end;
  1474. end else
  1475. if Indent > 0 then
  1476. AppendSym(CodeEl, ')')
  1477. else
  1478. begin
  1479. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1480. AppendSym(CodeEl, ')');
  1481. end;
  1482. end else
  1483. begin
  1484. { Procedure or function without arguments }
  1485. if Element.InheritsFrom(TPasFunctionType) then
  1486. begin
  1487. AppendSym(CodeEl, ': ');
  1488. AppendHyperlink(CodeEl, TPasFunctionType(Element).ResultEl.ResultType);
  1489. end;
  1490. if Element.IsOfObject then
  1491. AppendKw(CodeEl, ' of object');
  1492. end;
  1493. Result := CodeEl;
  1494. end;
  1495. procedure THTMLWriter.AppendProcExt(CodeEl: TDOMElement;
  1496. Element: TPasProcedure);
  1497. procedure AppendExt(const Ext: String);
  1498. begin
  1499. AppendKw(CodeEl, ' ' + Ext);
  1500. AppendSym(CodeEl, ';');
  1501. end;
  1502. begin
  1503. if Element.IsVirtual then
  1504. AppendExt('virtual');
  1505. if Element.IsDynamic then
  1506. AppendExt('dynamic');
  1507. if Element.IsAbstract then
  1508. AppendExt('abstract');
  1509. if Element.IsOverride then
  1510. AppendExt('override');
  1511. if Element.IsOverload then
  1512. AppendExt('overload');
  1513. if Element.IsMessage then
  1514. AppendExt('message');
  1515. end;
  1516. { Used in two places:
  1517. - Page for the method of a class
  1518. - Page for a tandalone procedure or function. }
  1519. procedure THTMLWriter.AppendProcDecl(CodeEl, TableEl: TDOMElement;
  1520. Element: TPasProcedureBase);
  1521. procedure WriteVariant(AProc: TPasProcedure);
  1522. begin
  1523. AppendProcArgsSection(TableEl.ParentNode, AProc.ProcType);
  1524. AppendKw(CodeEl, AProc.TypeName);
  1525. if Element.Parent.ClassType = TPasClassType then
  1526. begin
  1527. AppendText(CodeEl, ' ');
  1528. AppendHyperlink(CodeEl, Element.Parent);
  1529. AppendSym(CodeEl, '.');
  1530. AppendText(CodeEl, AProc.Name);
  1531. end else
  1532. AppendText(CodeEl, ' ' + AProc.FullName);
  1533. CodeEl := AppendProcType(CodeEl, TableEl, AProc.ProcType, 0);
  1534. AppendSym(CodeEl, ';');
  1535. AppendProcExt(CodeEl, AProc);
  1536. end;
  1537. var
  1538. i: Integer;
  1539. begin
  1540. if Element.ClassType = TPasOverloadedProc then
  1541. for i := 0 to TPasOverloadedProc(Element).Overloads.Count - 1 do
  1542. begin
  1543. if i > 0 then
  1544. begin
  1545. CreateEl(CodeEl, 'br');
  1546. CreateEl(CodeEl, 'br');
  1547. end;
  1548. WriteVariant(TPasProcedure(TPasOverloadedProc(Element).Overloads[i]));
  1549. end
  1550. else
  1551. WriteVariant(TPasProcedure(Element));
  1552. end;
  1553. procedure THTMLWriter.AppendProcArgsSection(Parent: TDOMNode;
  1554. Element: TPasProcedureType);
  1555. var
  1556. HasFullDescr, IsFirst: Boolean;
  1557. ResultEl: TPasResultElement;
  1558. ArgTableEl, TREl: TDOMElement;
  1559. DocNode: TDocNode;
  1560. i: Integer;
  1561. Arg: TPasArgument;
  1562. begin
  1563. IsFirst := True;
  1564. for i := 0 to Element.Args.Count - 1 do
  1565. begin
  1566. Arg := TPasArgument(Element.Args[i]);
  1567. if IsDescrNodeEmpty(Engine.FindShortDescr(Arg)) then
  1568. continue;
  1569. if IsFirst then
  1570. begin
  1571. IsFirst := False;
  1572. AppendText(CreateH2(Parent), SDocArguments);
  1573. ArgTableEl := CreateTable(Parent);
  1574. end;
  1575. TREl := CreateTR(ArgTableEl);
  1576. AppendText(CreateCode(CreatePara(CreateTD_vtop(TREl))), Arg.Name);
  1577. AppendShortDescrCell(TREl, Arg);
  1578. end;
  1579. if Element.ClassType = TPasFunctionType then
  1580. begin
  1581. ResultEl := TPasFunctionType(Element).ResultEl;
  1582. DocNode := Engine.FindDocNode(ResultEl);
  1583. HasFullDescr := Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr);
  1584. if HasFullDescr or
  1585. (Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.ShortDescr)) then
  1586. begin
  1587. AppendText(CreateH2(Parent), SDocFunctionResult);
  1588. if HasFullDescr then
  1589. AppendDescr(ResultEl, Parent, DocNode.Descr, True)
  1590. else
  1591. AppendDescr(ResultEl, CreatePara(Parent), DocNode.ShortDescr, False);
  1592. end;
  1593. end;
  1594. end;
  1595. function THTMLWriter.AppendRecordType(CodeEl, TableEl: TDOMElement;
  1596. Element: TPasRecordType; NestingLevel: Integer): TDOMElement;
  1597. var
  1598. i, j: Integer;
  1599. Variable: TPasVariable;
  1600. TREl, TDEl: TDOMElement;
  1601. CurVariant: TPasVariant;
  1602. begin
  1603. if not (Element.Parent is TPasVariant) then
  1604. if Element.IsPacked then
  1605. If Element.IsBitPacked then
  1606. AppendKw(CodeEl, 'bitpacked record')
  1607. else
  1608. AppendKW(CodeEl, 'packed record')
  1609. else
  1610. AppendKw(CodeEl, 'record');
  1611. for i := 0 to Element.Members.Count - 1 do
  1612. begin
  1613. Variable := TPasVariable(Element.Members[i]);
  1614. TREl := CreateTR(TableEl);
  1615. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1616. AppendShortDescrCell(TREl, Variable);
  1617. AppendNbSp(CodeEl, NestingLevel * 2 + 2);
  1618. AppendText(CodeEl, Variable.Name);
  1619. AppendSym(CodeEl, ': ');
  1620. CodeEl := AppendType(CodeEl, TableEl, Variable.VarType, False, NestingLevel + 1);
  1621. AppendSym(CodeEl, ';');
  1622. end;
  1623. if Assigned(Element.VariantType) then
  1624. begin
  1625. TREl := CreateTR(TableEl);
  1626. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1627. AppendNbSp(CodeEl, NestingLevel * 2 + 2);
  1628. AppendKw(CodeEl, 'case ');
  1629. if TPasRecordType(Element).VariantName <> '' then
  1630. begin
  1631. AppendText(CodeEl, TPasRecordType(Element).VariantName);
  1632. AppendSym(CodeEl, ': ');
  1633. end;
  1634. CodeEl := AppendType(CodeEl, TableEl, TPasRecordType(Element).VariantType, True);
  1635. AppendKw(CodeEl, ' of');
  1636. for i := 0 to TPasRecordType(Element).Variants.Count - 1 do
  1637. begin
  1638. CurVariant := TPasVariant(Element.Variants[i]);
  1639. TREl := CreateTR(TableEl);
  1640. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1641. AppendNbSp(CodeEl, NestingLevel * 2 + 4);
  1642. for j := 0 to CurVariant.Values.Count - 1 do
  1643. begin
  1644. if j > 0 then
  1645. AppendSym(CodeEl, ', ');
  1646. AppendPasSHFragment(CodeEl, CurVariant.Values[j], 0);
  1647. end;
  1648. AppendSym(CodeEl, ': (');
  1649. AppendType(CodeEl, TableEl, CurVariant.Members, True, NestingLevel + 3);
  1650. CodeEl := CreateCode(CreatePara(CreateTD_vtop(CreateTR(TableEl))));
  1651. AppendNbSp(CodeEl, NestingLevel * 2 + 6);
  1652. AppendSym(CodeEl, ');');
  1653. end;
  1654. end;
  1655. if not (Element.Parent is TPasVariant) then
  1656. begin
  1657. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1658. AppendText(CodeEl, ' '); // !!!: Dirty trick, necessary for current XML writer
  1659. AppendNbSp(CodeEl, NestingLevel * 2);
  1660. AppendKw(CodeEl, 'end');
  1661. end;
  1662. Result := CodeEl;
  1663. end;
  1664. procedure THTMLWriter.AppendTitle(const AText: DOMString);
  1665. begin
  1666. AppendText(TitleElement, AText);
  1667. AppendText(CreateH1(BodyElement), AText);
  1668. end;
  1669. procedure THTMLWriter.AppendTopicMenuBar(Topic : TTopicElement);
  1670. var
  1671. TableEl, TREl, ParaEl, TitleEl: TDOMElement;
  1672. procedure AddLink(El : TPasElement; const AName: String);
  1673. begin
  1674. AppendText(ParaEl, '[');
  1675. AppendText(CreateLink(ParaEl, ResolveLinkWithinPackage(El,0)),AName);
  1676. AppendText(ParaEl, ']');
  1677. end;
  1678. begin
  1679. TableEl := CreateEl(BodyElement, 'table');
  1680. TableEl['cellpadding'] := '4';
  1681. TableEl['cellspacing'] := '0';
  1682. TableEl['border'] := '0';
  1683. TableEl['width'] := '100%';
  1684. TableEl['class'] := 'bar';
  1685. TREl := CreateTR(TableEl);
  1686. ParaEl := CreateEl(CreateTD(TREl), 'b');
  1687. If Assigned(Topic.Previous) then
  1688. AddLink(Topic.Previous,SDocPrevious);
  1689. If Assigned(Topic.Parent) then
  1690. AddLink(Topic.Parent,SDocUp);
  1691. if Assigned(Topic.Next) then
  1692. AddLink(Topic.Next,SDocNext);
  1693. if Length(SearchPage) > 0 then
  1694. begin
  1695. AppendText(ParaEl, '[');
  1696. AppendText(CreateLink(ParaEl, SearchPage), SDocSearch);
  1697. AppendText(ParaEl, ']');
  1698. end;
  1699. ParaEl := CreateTD(TREl);
  1700. ParaEl['align'] := 'right';
  1701. TitleEl := CreateEl(ParaEl, 'span');
  1702. TitleEl['class'] := 'bartitle';
  1703. if Assigned(Module) then
  1704. AppendText(TitleEl, Format(SDocUnitTitle, [Module.Name]));
  1705. if Assigned(Package) then
  1706. begin
  1707. AppendText(TitleEl, ' (');
  1708. AppendHyperlink(TitleEl, Package);
  1709. AppendText(TitleEl, ')');
  1710. end;
  1711. end;
  1712. procedure THTMLWriter.AppendMenuBar(ASubpageIndex: Integer);
  1713. var
  1714. TableEl, TREl, ParaEl, TitleEl: TDOMElement;
  1715. procedure AddLink(ALinkSubpageIndex: Integer; const AName: String);
  1716. begin
  1717. AppendText(ParaEl, '[');
  1718. if ALinkSubpageIndex = ASubpageIndex then
  1719. AppendText(ParaEl, AName)
  1720. else
  1721. AppendText(
  1722. CreateLink(ParaEl, ResolveLinkWithinPackage(Module, ALinkSubpageIndex)),
  1723. AName);
  1724. AppendText(ParaEl, ']');
  1725. end;
  1726. begin
  1727. TableEl := CreateEl(BodyElement, 'table');
  1728. TableEl['cellpadding'] := '4';
  1729. TableEl['cellspacing'] := '0';
  1730. TableEl['border'] := '0';
  1731. TableEl['width'] := '100%';
  1732. TableEl['class'] := 'bar';
  1733. TREl := CreateTR(TableEl);
  1734. ParaEl := CreateEl(CreateTD(TREl), 'b');
  1735. if Assigned(Module) then
  1736. begin
  1737. AddLink(0, SDocOverview);
  1738. if Module.InterfaceSection.ResStrings.Count > 0 then
  1739. AddLink(ResstrSubindex, SDocResStrings);
  1740. if Module.InterfaceSection.Consts.Count > 0 then
  1741. AddLink(ConstsSubindex, SDocConstants);
  1742. if Module.InterfaceSection.Types.Count > 0 then
  1743. AddLink(TypesSubindex, SDocTypes);
  1744. if Module.InterfaceSection.Classes.Count > 0 then
  1745. AddLink(ClassesSubindex, SDocClasses);
  1746. if Module.InterfaceSection.Functions.Count > 0 then
  1747. AddLink(ProcsSubindex, SDocProceduresAndFunctions);
  1748. if Module.InterfaceSection.Variables.Count > 0 then
  1749. AddLink(VarsSubindex, SDocVariables);
  1750. AddLink(IndexSubIndex,SDocIdentifierIndex);
  1751. end
  1752. else
  1753. begin
  1754. // Manually add link for package page
  1755. AppendText(ParaEl, '[');
  1756. if (IndexSubIndex = ASubpageIndex) then
  1757. AppendText(ParaEl, SDocIdentifierIndex)
  1758. else
  1759. AppendText(
  1760. CreateLink(ParaEl, ResolveLinkWithinPackage(Package, IndexSubIndex)),
  1761. SDocIdentifierIndex);
  1762. AppendText(ParaEl, ']');
  1763. end;
  1764. if Length(SearchPage) > 0 then
  1765. begin
  1766. AppendText(ParaEl, '[');
  1767. AppendText(CreateLink(ParaEl, SearchPage), SDocSearch);
  1768. AppendText(ParaEl, ']');
  1769. end;
  1770. ParaEl := CreateTD(TREl);
  1771. ParaEl['align'] := 'right';
  1772. TitleEl := CreateEl(ParaEl, 'span');
  1773. TitleEl['class'] := 'bartitle';
  1774. if Assigned(Module) then
  1775. AppendText(TitleEl, Format(SDocUnitTitle, [Module.Name]));
  1776. if Assigned(Package) then
  1777. begin
  1778. AppendText(TitleEl, ' (');
  1779. AppendHyperlink(TitleEl, Package);
  1780. AppendText(TitleEl, ')');
  1781. end;
  1782. end;
  1783. procedure THTMLWriter.AppendSourceRef(AElement: TPasElement);
  1784. begin
  1785. AppendText(CreatePara(BodyElement), Format(SDocSourcePosition,
  1786. [ExtractFileName(AElement.SourceFilename), AElement.SourceLinenumber]));
  1787. end;
  1788. Procedure THTMLWriter.AppendSeeAlsoSection(AElement : TPasElement;DocNode : TDocNode);
  1789. var
  1790. Node: TDOMNode;
  1791. TableEl, El, TREl, TDEl, ParaEl, NewEl, DescrEl: TDOMElement;
  1792. l,s: String;
  1793. f: Text;
  1794. IsFirstSeeAlso : Boolean;
  1795. begin
  1796. if Not (Assigned(DocNode) and Assigned(DocNode.SeeAlso)) then
  1797. Exit;
  1798. IsFirstSeeAlso := True;
  1799. Node:=DocNode.SeeAlso.FirstChild;
  1800. While Assigned(Node) do
  1801. begin
  1802. if (Node.NodeType=ELEMENT_NODE) and (Node.NodeName='link') then
  1803. begin
  1804. if IsFirstSeeAlso then
  1805. begin
  1806. IsFirstSeeAlso := False;
  1807. AppendText(CreateH2(BodyElement), SDocSeeAlso);
  1808. TableEl := CreateTable(BodyElement);
  1809. end;
  1810. El:=TDOMElement(Node);
  1811. TREl:=CreateTR(TableEl);
  1812. ParaEl:=CreatePara(CreateTD_vtop(TREl));
  1813. l:=El['id'];
  1814. s:= ResolveLinkID(l);
  1815. if Length(s)=0 then
  1816. begin
  1817. if assigned(module) then
  1818. s:=module.name
  1819. else
  1820. s:='?';
  1821. if l='' then l:='<empty>';
  1822. DoLog(SErrUnknownLinkID, [s,l]);
  1823. NewEl := CreateEl(ParaEl,'b')
  1824. end
  1825. else
  1826. NewEl := CreateLink(ParaEl,s);
  1827. if Not IsDescrNodeEmpty(El) then
  1828. begin
  1829. PushOutputNode(NewEl);
  1830. Try
  1831. ConvertBaseShortList(AElement, El, True)
  1832. Finally
  1833. PopOutputNode;
  1834. end;
  1835. end
  1836. else
  1837. AppendText(NewEl,El['id']);
  1838. l:=El['id'];
  1839. DescrEl := Engine.FindShortDescr(AElement.GetModule,L);
  1840. if Assigned(DescrEl) then
  1841. begin
  1842. AppendNbSp(CreatePara(CreateTD(TREl)), 2);
  1843. ParaEl := CreatePara(CreateTD(TREl));
  1844. ParaEl['class'] := 'cmt';
  1845. PushOutputNode(ParaEl);
  1846. try
  1847. ConvertShort(AElement, DescrEl);
  1848. finally
  1849. PopOutputNode;
  1850. end;
  1851. end;
  1852. end; // Link node
  1853. Node := Node.NextSibling;
  1854. end; // While
  1855. end;
  1856. Procedure THTMLWriter.AppendExampleSection(AElement : TPasElement;DocNode : TDocNode);
  1857. var
  1858. Node: TDOMNode;
  1859. // TableEl, El, TREl, TDEl, ParaEl, NewEl, DescrEl: TDOMElement;
  1860. fn,s: String;
  1861. f: Text;
  1862. begin
  1863. if not (Assigned(DocNode) and Assigned(DocNode.FirstExample)) then
  1864. Exit;
  1865. Node := DocNode.FirstExample;
  1866. while Assigned(Node) do
  1867. begin
  1868. if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'example') then
  1869. begin
  1870. fn:=Engine.GetExampleFilename(TDOMElement(Node));
  1871. If (fn<>'') then
  1872. begin
  1873. AppendText(CreateH2(BodyElement), SDocExample);
  1874. try
  1875. Assign(f, FN);
  1876. Reset(f);
  1877. try
  1878. PushOutputNode(BodyElement);
  1879. DescrBeginCode(False, TDOMElement(Node)['highlighter']);
  1880. while not EOF(f) do
  1881. begin
  1882. ReadLn(f, s);
  1883. DescrWriteCodeLine(s);
  1884. end;
  1885. DescrEndCode;
  1886. PopOutputNode;
  1887. finally
  1888. Close(f);
  1889. end;
  1890. except
  1891. on e: Exception do
  1892. begin
  1893. e.Message := '[example] ' + e.Message;
  1894. raise;
  1895. end;
  1896. end;
  1897. end;
  1898. end;
  1899. Node := Node.NextSibling;
  1900. end;
  1901. end;
  1902. procedure THTMLWriter.AppendFooter;
  1903. Var
  1904. S : String;
  1905. F : TDomElement;
  1906. begin
  1907. if FooterFile<>'' then
  1908. ReadXMLFragment(BodyElement, FooterFile)
  1909. else if IncludeDateInFooter then
  1910. begin
  1911. CreateEl(BodyElement, 'hr');
  1912. F:=CreateEl(BodyElement,'span');
  1913. F['class']:='footer';
  1914. If (FDateFormat='') then
  1915. S:=DateToStr(Date)
  1916. else
  1917. S:=FormatDateTime(FDateFormat,Date);
  1918. AppendText(F,Format(SDocDateGenerated,[S]));
  1919. end;
  1920. end;
  1921. procedure THTMLWriter.FinishElementPage(AElement: TPasElement);
  1922. var
  1923. DocNode: TDocNode;
  1924. begin
  1925. DocNode := Engine.FindDocNode(AElement);
  1926. If Assigned(DocNode) then
  1927. begin
  1928. // Description
  1929. if Assigned(DocNode.Descr) then
  1930. AppendDescrSection(AElement, BodyElement, DocNode.Descr, SDocDescription);
  1931. // Append "Errors" section
  1932. if Assigned(DocNode.ErrorsDoc) then
  1933. AppendDescrSection(AElement, BodyElement, DocNode.ErrorsDoc, SDocErrors);
  1934. // Append Version info
  1935. if Assigned(DocNode.Version) then
  1936. AppendDescrSection(AElement, BodyElement, DocNode.Version, SDocVersion);
  1937. // Append "See also" section
  1938. AppendSeeAlsoSection(AElement,DocNode);
  1939. // Append examples, if present
  1940. AppendExampleSection(AElement,DocNode);
  1941. end;
  1942. end;
  1943. Procedure THTMLWriter.CreateTopicPageBody(AElement : TTopicElement);
  1944. var
  1945. DocNode: TDocNode;
  1946. TableEl, TREl: TDOMElement;
  1947. I : Integer;
  1948. S : String;
  1949. begin
  1950. AppendTopicMenuBar(AElement);
  1951. DocNode:=AElement.TopicNode;
  1952. if Assigned(DocNode) then // should always be true, but we're being careful.
  1953. begin
  1954. AppendShortDescr(AElement,TitleElement, DocNode);
  1955. AppendShortDescr(AElement,CreateH2(BodyElement), DocNode);
  1956. if Assigned(DocNode.Descr) then
  1957. AppendDescrSection(AElement, BodyElement, DocNode.Descr, '');
  1958. AppendSeeAlsoSection(AElement,DocNode);
  1959. CreateTopicLinks(DocNode,AElement);
  1960. AppendExampleSection(AElement,DocNode);
  1961. end;
  1962. end;
  1963. procedure THTMLWriter.CreatePageBody(AElement: TPasElement;
  1964. ASubpageIndex: Integer);
  1965. var
  1966. i: Integer;
  1967. Element: TPasElement;
  1968. begin
  1969. CurDirectory := Allocator.GetFilename(AElement, ASubpageIndex);
  1970. i := Length(CurDirectory);
  1971. while (i > 0) and not (CurDirectory[i] in AllowDirectorySeparators) do
  1972. Dec(i);
  1973. CurDirectory := Copy(CurDirectory, 1, i);
  1974. BaseDirectory := Allocator.GetRelativePathToTop(AElement);
  1975. if AElement.ClassType = TPasPackage then
  1976. begin
  1977. Module:=Nil;
  1978. If (ASubPageIndex=0) then
  1979. CreatePackagePageBody
  1980. else if ASubPageIndex=IndexSubIndex then
  1981. CreatePackageIndex
  1982. end
  1983. else
  1984. begin
  1985. Element := AElement;
  1986. while (Element<>Nil) and (Element.ClassType<>TPasModule) do
  1987. Element := Element.Parent;
  1988. Module := TPasModule(Element);
  1989. if AElement.ClassType = TPasModule then
  1990. CreateModulePageBody(TPasModule(AElement), ASubpageIndex)
  1991. else if AElement.Parent.InheritsFrom(TPasClassType) then
  1992. CreateClassMemberPageBody(AElement)
  1993. else if AElement.ClassType = TPasConst then
  1994. CreateConstPageBody(TPasConst(AElement))
  1995. else if AElement.InheritsFrom(TPasClassType) then
  1996. CreateClassPageBody(TPasClassType(AElement), ASubpageIndex)
  1997. else if AElement.InheritsFrom(TPasType) then
  1998. CreateTypePageBody(TPasType(AElement))
  1999. else if AElement.ClassType = TPasVariable then
  2000. CreateVarPageBody(TPasVariable(AElement))
  2001. else if AElement.InheritsFrom(TPasProcedureBase) then
  2002. CreateProcPageBody(TPasProcedure(AElement))
  2003. else if AElement.ClassType = TTopicELement then
  2004. CreateTopicPageBody(TTopicElement(AElement))
  2005. end;
  2006. end;
  2007. procedure THTMLWriter.CreateIndexPage(L : TStringList);
  2008. Var
  2009. Lists : Array['A'..'Z'] of TStringList;
  2010. LOther : TStringList;
  2011. CL : TStringList;
  2012. TableEl, TREl, EL: TDOMElement;
  2013. E : TPasElement;
  2014. I,Rows,J,Index : Integer;
  2015. S : String;
  2016. C : Char;
  2017. begin
  2018. For C:='A' to 'Z' do
  2019. Lists[C]:=Nil;
  2020. L.Sort;
  2021. Cl:=Nil;
  2022. // Divide over alphabet
  2023. For I:=0 to L.Count-1 do
  2024. begin
  2025. S:=L[i];
  2026. E:=TPasElement(L.Objects[i]);
  2027. If not (E is TPasUnresolvedTypeRef) then
  2028. begin
  2029. If (S<>'') then
  2030. begin
  2031. C:=Upcase(S[1]);
  2032. If C='_' then
  2033. C:='A';
  2034. If (C in ['A'..'Z']) and (Lists[C]=Nil) then
  2035. begin
  2036. CL:=TStringList.Create;
  2037. Lists[C]:=CL;
  2038. end;
  2039. end;
  2040. if assigned(cl) then
  2041. CL.AddObject(S,E);
  2042. end;
  2043. end;
  2044. Try
  2045. // Create a quick jump table to all available letters.
  2046. TableEl := CreateTable(BodyElement);
  2047. TableEl['border']:='1';
  2048. TableEl['width']:='50%';
  2049. TREl := CreateTR(TableEl);
  2050. for C:='A' to 'Z' do
  2051. If (Lists[C]<>Nil) then
  2052. begin
  2053. El:=CreateTD_vtop(TREl);
  2054. AppendText(CreateLink(El,'#SECTION'+C),C);
  2055. If C<>'Z' then
  2056. AppendNBsp(El,1);
  2057. end;
  2058. // Now emit all identifiers.
  2059. TableEl:=Nil;
  2060. For C:='A' to 'Z' do
  2061. begin
  2062. CL:=Lists[C];
  2063. If CL<>Nil then
  2064. begin
  2065. El:=CreateH2(BodyElement);
  2066. AppendText(El,C);
  2067. CreateAnchor(El,'SECTION'+C);
  2068. TableEl := CreateTable(BodyElement);
  2069. TableEl['Width']:='80%';
  2070. // Determine number of rows needed
  2071. Rows:=(CL.Count div IndexColCount);
  2072. If ((CL.Count Mod IndexColCount)<>0) then
  2073. Inc(Rows);
  2074. // Fill rows
  2075. For I:=0 to Rows-1 do
  2076. begin
  2077. TREl := CreateTR(TableEl);
  2078. For J:=0 to IndexColCount-1 do
  2079. begin
  2080. El:=CreateTD_vtop(TREl);
  2081. Index:=(J*Rows)+I;
  2082. If (Index<CL.Count) then
  2083. begin
  2084. S:=CL[Index];
  2085. E:=TPasElement(CL.Objects[Index]);
  2086. AppendHyperlink(El,E);
  2087. end;
  2088. end;
  2089. end;
  2090. end; // have List
  2091. end; // For C:=
  2092. Finally
  2093. for C:='A' to 'Z' do
  2094. FreeAndNil(Lists[C]);
  2095. end;
  2096. end;
  2097. procedure THTMLWriter.AddModuleIdentifiers(AModule : TPasModule; L : TStrings);
  2098. Procedure AddElementsFromList(L : TStrings; List : TFPList);
  2099. Var
  2100. I : Integer;
  2101. El : TPasElement;
  2102. begin
  2103. For I:=0 to List.Count-1 do
  2104. begin
  2105. El:=TPasElement(List[I]);
  2106. L.AddObject(El.Name,El);
  2107. If el is TPasEnumType then
  2108. AddElementsFromList(L,TPasEnumType(el).Values);
  2109. end;
  2110. end;
  2111. begin
  2112. AddElementsFromList(L,AModule.InterfaceSection.Consts);
  2113. AddElementsFromList(L,AModule.InterfaceSection.Types);
  2114. AddElementsFromList(L,AModule.InterfaceSection.Functions);
  2115. AddElementsFromList(L,AModule.InterfaceSection.Classes);
  2116. AddElementsFromList(L,AModule.InterfaceSection.Variables);
  2117. AddElementsFromList(L,AModule.InterfaceSection.ResStrings);
  2118. end;
  2119. procedure THTMLWriter.CreatePackageIndex;
  2120. Var
  2121. L : TStringList;
  2122. I : Integer;
  2123. M : TPasModule;
  2124. E : TPasElement;
  2125. S : String;
  2126. begin
  2127. L:=TStringList.Create;
  2128. try
  2129. L.Capacity:=PageInfos.Count; // Too much, but that doesn't hurt.
  2130. For I:=0 to Package.Modules.Count-1 do
  2131. begin
  2132. M:=TPasModule(Package.Modules[i]);
  2133. L.AddObject(M.Name,M);
  2134. AddModuleIdentifiers(M,L);
  2135. end;
  2136. AppendMenuBar(IndexSubIndex);
  2137. S:=Package.Name;
  2138. If Length(S)>0 then
  2139. Delete(S,1,1);
  2140. AppendTitle(Format(SDocPackageIndex, [S]));
  2141. CreateIndexPage(L);
  2142. Finally
  2143. L.Free;
  2144. end;
  2145. end;
  2146. procedure THTMLWriter.CreatePackagePageBody;
  2147. var
  2148. DocNode: TDocNode;
  2149. TableEl, TREl: TDOMElement;
  2150. i: Integer;
  2151. ThisModule: TPasModule;
  2152. L : TStringList;
  2153. begin
  2154. AppendMenuBar(0);
  2155. AppendTitle(Format(SDocPackageTitle, [Copy(Package.Name, 2, 256)]));
  2156. AppendShortDescr(CreatePara(BodyElement), Package);
  2157. AppendText(CreateH2(BodyElement), SDocUnits);
  2158. TableEl := CreateTable(BodyElement);
  2159. L:=TStringList.Create;
  2160. Try
  2161. L.Sorted:=True;
  2162. // Sort modules.
  2163. For I:=0 to Package.Modules.Count-1 do
  2164. L.AddObject(TPasModule(Package.Modules[i]).Name,TPasModule(Package.Modules[i]));
  2165. // Now create table.
  2166. for i:=0 to L.Count - 1 do
  2167. begin
  2168. ThisModule := TPasModule(L.Objects[i]);
  2169. TREl := CreateTR(TableEl);
  2170. AppendHyperlink(CreateCode(CreatePara(CreateTD_vtop(TREl))), ThisModule);
  2171. AppendShortDescrCell(TREl, ThisModule);
  2172. end;
  2173. Finally
  2174. L.Free;
  2175. end;
  2176. DocNode := Engine.FindDocNode(Package);
  2177. if Assigned(DocNode) then
  2178. begin
  2179. if Assigned(DocNode.Descr) then
  2180. AppendDescrSection(nil, BodyElement, DocNode.Descr, SDocDescription);
  2181. CreateTopicLinks(DocNode,Package);
  2182. end;
  2183. end;
  2184. Procedure THTMLWriter.CreateTopicLinks(Node : TDocNode; PasElement : TPasElement);
  2185. var
  2186. DocNode: TDocNode;
  2187. TableEl, TREl: TDOMElement;
  2188. First : Boolean;
  2189. ThisTopic: TPasElement;
  2190. begin
  2191. DocNode:=Node.FirstChild;
  2192. First:=True;
  2193. While Assigned(DocNode) do
  2194. begin
  2195. If DocNode.TopicNode then
  2196. begin
  2197. if first then
  2198. begin
  2199. First:=False;
  2200. AppendText(CreateH2(BodyElement), SDocRelatedTopics);
  2201. TableEl := CreateTable(BodyElement);
  2202. end;
  2203. TREl := CreateTR(TableEl);
  2204. ThisTopic:=FindTopicElement(DocNode);
  2205. if Assigned(ThisTopic) then
  2206. AppendHyperlink(CreateCode(CreatePara(CreateTD_vtop(TREl))), ThisTopic);
  2207. AppendShortDescrCell(TREl, ThisTopic);
  2208. end;
  2209. DocNode:=DocNode.NextSibling;
  2210. end;
  2211. end;
  2212. procedure THTMLWriter.CreateModuleIndexPage(AModule: TPasModule);
  2213. Var
  2214. L : TStringList;
  2215. begin
  2216. L:=TStringList.Create;
  2217. try
  2218. AddModuleIdentifiers(AModule,L);
  2219. AppendMenuBar(IndexSubIndex);
  2220. AppendTitle(Format(SDocModuleIndex, [AModule.Name]));
  2221. CreateIndexPage(L);
  2222. Finally
  2223. L.Free;
  2224. end;
  2225. end;
  2226. procedure THTMLWriter.CreateModulePageBody(AModule: TPasModule;
  2227. ASubpageIndex: Integer);
  2228. procedure CreateMainPage;
  2229. var
  2230. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  2231. i: Integer;
  2232. UnitRef: TPasType;
  2233. DocNode: TDocNode;
  2234. begin
  2235. AppendMenuBar(0);
  2236. AppendTitle(Format(SDocUnitTitle, [AModule.Name]));
  2237. AppendShortDescr(CreatePara(BodyElement), AModule);
  2238. if AModule.InterfaceSection.UsesList.Count > 0 then
  2239. begin
  2240. TableEl := CreateTable(BodyElement);
  2241. AppendKw(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), 'uses');
  2242. for i := 0 to AModule.InterfaceSection.UsesList.Count - 1 do
  2243. begin
  2244. UnitRef := TPasType(AModule.InterfaceSection.UsesList[i]);
  2245. DocNode := Engine.FindDocNode(UnitRef);
  2246. if Assigned(DocNode) and DocNode.IsSkipped then
  2247. continue;
  2248. TREl := CreateTR(TableEl);
  2249. TDEl := CreateTD_vtop(TREl);
  2250. CodeEl := CreateCode(CreatePara(TDEl));
  2251. AppendNbSp(CodeEl, 2);
  2252. AppendHyperlink(CodeEl, UnitRef);
  2253. if i < AModule.InterfaceSection.UsesList.Count - 1 then
  2254. AppendSym(CodeEl, ',')
  2255. else
  2256. AppendSym(CodeEl, ';');
  2257. AppendText(CodeEl, ' '); // Space for descriptions
  2258. AppendShortDescrCell(TREl, UnitRef);
  2259. end;
  2260. end;
  2261. DocNode := Engine.FindDocNode(AModule);
  2262. if Assigned(DocNode) then
  2263. begin
  2264. if Assigned(DocNode.Descr) then
  2265. AppendDescrSection(AModule, BodyElement, DocNode.Descr, SDocOverview);
  2266. CreateTopicLinks(DocNode,AModule);
  2267. end;
  2268. end;
  2269. procedure CreateSimpleSubpage(const ATitle: DOMString; AList: TFPList);
  2270. var
  2271. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  2272. i, j: Integer;
  2273. Decl: TPasElement;
  2274. SortedList: TFPList;
  2275. DocNode: TDocNode;
  2276. S : String;
  2277. begin
  2278. AppendMenuBar(ASubpageIndex);
  2279. S:=ATitle;
  2280. AppendTitle(Format(SDocUnitTitle + ': %s', [AModule.Name, S]));
  2281. SortedList := TFPList.Create;
  2282. try
  2283. for i := 0 to AList.Count - 1 do
  2284. begin
  2285. Decl := TPasElement(AList[i]);
  2286. DocNode := Engine.FindDocNode(Decl);
  2287. if (not Assigned(DocNode)) or (not DocNode.IsSkipped) then
  2288. begin
  2289. j := 0;
  2290. while (j < SortedList.Count) and (CompareText(
  2291. TPasElement(SortedList[j]).PathName, Decl.PathName) < 0) do
  2292. Inc(j);
  2293. SortedList.Insert(j, Decl);
  2294. end;
  2295. end;
  2296. TableEl := CreateTable(BodyElement);
  2297. for i := 0 to SortedList.Count - 1 do
  2298. begin
  2299. Decl := TPasElement(SortedList[i]);
  2300. TREl := CreateTR(TableEl);
  2301. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  2302. AppendHyperlink(CodeEl, Decl);
  2303. AppendShortDescrCell(TREl, Decl);
  2304. end;
  2305. finally
  2306. SortedList.Free;
  2307. end;
  2308. end;
  2309. procedure CreateResStringsPage;
  2310. var
  2311. ParaEl: TDOMElement;
  2312. i, j: Integer;
  2313. Decl: TPasResString;
  2314. DocNode: TDocNode;
  2315. begin
  2316. AppendMenuBar(ResstrSubindex);
  2317. AppendTitle(Format(SDocUnitTitle + ': %s', [AModule.Name, SDocResStrings]));
  2318. for i := 0 to AModule.InterfaceSection.ResStrings.Count - 1 do
  2319. begin
  2320. Decl := TPasResString(AModule.InterfaceSection.ResStrings[i]);
  2321. CreateEl(BodyElement, 'a')['name'] := LowerCase(Decl.Name);
  2322. ParaEl := CreatePara(BodyElement);
  2323. AppendText(CreateCode(ParaEl), Decl.Name);
  2324. CreateEl(ParaEl, 'br');
  2325. AppendText(ParaEl, Decl.Expr.getDeclaration(true));
  2326. end;
  2327. end;
  2328. begin
  2329. case ASubpageIndex of
  2330. 0:
  2331. CreateMainPage;
  2332. ResstrSubindex:
  2333. CreateResStringsPage;
  2334. ConstsSubindex:
  2335. CreateSimpleSubpage(SDocConstants, AModule.InterfaceSection.Consts);
  2336. TypesSubindex:
  2337. CreateSimpleSubpage(SDocTypes, AModule.InterfaceSection.Types);
  2338. ClassesSubindex:
  2339. CreateSimpleSubpage(SDocClasses, AModule.InterfaceSection.Classes);
  2340. ProcsSubindex:
  2341. CreateSimpleSubpage(SDocProceduresAndFunctions, AModule.InterfaceSection.Functions);
  2342. VarsSubindex:
  2343. CreateSimpleSubpage(SDocVariables, AModule.InterfaceSection.Variables);
  2344. IndexSubIndex:
  2345. CreateModuleIndexPage(AModule);
  2346. end;
  2347. end;
  2348. procedure THTMLWriter.CreateConstPageBody(AConst: TPasConst);
  2349. var
  2350. TableEl, CodeEl: TDOMElement;
  2351. begin
  2352. AppendMenuBar(-1);
  2353. AppendTitle(AConst.Name);
  2354. AppendShortDescr(CreatePara(BodyElement), AConst);
  2355. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2356. AppendSourceRef(AConst);
  2357. TableEl := CreateTable(BodyElement);
  2358. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  2359. AppendKw(CodeEl, 'const');
  2360. AppendText(CodeEl, ' ' + AConst.Name);
  2361. if Assigned(AConst.VarType) then
  2362. begin
  2363. AppendSym(CodeEl, ': ');
  2364. AppendType(CodeEl, TableEl, AConst.VarType, False);
  2365. end;
  2366. AppendPasSHFragment(CodeEl, ' = ' + AConst.Expr.GetDeclaration(True) + ';', 0);
  2367. FinishElementPage(AConst);
  2368. end;
  2369. procedure THTMLWriter.CreateTypePageBody(AType: TPasType);
  2370. var
  2371. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  2372. DocNode: TDocNode;
  2373. i: Integer;
  2374. s: String;
  2375. EnumType: TPasEnumType;
  2376. EnumValue: TPasEnumValue;
  2377. Variable: TPasVariable;
  2378. begin
  2379. AppendMenuBar(-1);
  2380. AppendTitle(AType.Name);
  2381. AppendShortDescr(CreatePara(BodyElement), AType);
  2382. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2383. AppendSourceRef(AType);
  2384. TableEl := CreateTable(BodyElement);
  2385. TREl := CreateTR(TableEl);
  2386. TDEl := CreateTD(TREl);
  2387. CodeEl := CreateCode(CreatePara(TDEl));
  2388. DocNode := Engine.FindDocNode(AType);
  2389. AppendKw(CodeEl, 'type ');
  2390. AppendText(CodeEl, AType.Name);
  2391. AppendSym(CodeEl, ' = ');
  2392. If Assigned(DocNode) and
  2393. Assigned(DocNode.Node) and
  2394. (Docnode.Node['opaque']='1') then
  2395. AppendText(CodeEl,SDocOpaque)
  2396. else
  2397. begin
  2398. // Alias
  2399. if AType.ClassType = TPasAliasType then
  2400. begin
  2401. if Assigned(TPasAliasType(AType).DestType) then
  2402. AppendHyperlink(CodeEl, TPasAliasType(AType).DestType)
  2403. else
  2404. AppendText(CreateWarning(CodeEl), '<Destination type is NIL>');
  2405. AppendSym(CodeEl, ';');
  2406. end else
  2407. // Class of
  2408. if AType.ClassType = TPasClassOfType then
  2409. begin
  2410. AppendKw(CodeEl, 'class of ');
  2411. AppendHyperlink(CodeEl, TPasClassOfType(AType).DestType);
  2412. AppendSym(CodeEl, ';');
  2413. end else
  2414. // Enumeration
  2415. if AType.ClassType = TPasEnumType then
  2416. begin
  2417. AppendSym(CodeEl, '(');
  2418. for i := 0 to TPasEnumType(AType).Values.Count - 1 do
  2419. begin
  2420. EnumValue := TPasEnumValue(TPasEnumType(AType).Values[i]);
  2421. TREl := CreateTR(TableEl);
  2422. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  2423. AppendShortDescrCell(TREl, EnumValue);
  2424. AppendNbSp(CodeEl, 2);
  2425. s := EnumValue.Name;
  2426. if EnumValue.AssignedValue<>'' then
  2427. s := s + ' = ' + EnumValue.AssignedValue;
  2428. if i < TPasEnumType(AType).Values.Count - 1 then
  2429. s := s + ',';
  2430. AppendPasSHFragment(CodeEl, s, 0);
  2431. end;
  2432. AppendSym(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), ');');
  2433. end else
  2434. // Pointer type
  2435. if AType.ClassType = TPasPointerType then
  2436. begin
  2437. AppendSym(CodeEl, '^');
  2438. if Assigned(TPasPointerType(AType).DestType) then
  2439. AppendHyperlink(CodeEl, TPasPointerType(AType).DestType)
  2440. else
  2441. AppendText(CreateWarning(CodeEl), '<Destination type is NIL>');
  2442. AppendSym(CodeEl, ';');
  2443. end else
  2444. if AType.InheritsFrom(TPasProcedureType) then
  2445. begin
  2446. AppendSym(AppendType(CodeEl, TableEl, TPasType(AType), True), ';');
  2447. AppendProcArgsSection(BodyElement, TPasProcedureType(AType));
  2448. end else
  2449. // Record
  2450. if AType.ClassType = TPasRecordType then
  2451. begin
  2452. CodeEl := AppendRecordType(CodeEl, TableEl, TPasRecordType(AType), 0);
  2453. AppendSym(CodeEl, ';');
  2454. end else
  2455. // Set
  2456. if AType.ClassType = TPasSetType then
  2457. begin
  2458. AppendKw(CodeEl, 'set of ');
  2459. if TPasSetType(AType).EnumType.ClassType = TPasEnumType then
  2460. begin
  2461. AppendSym(CodeEl, '(');
  2462. EnumType := TPasEnumType(TPasSetType(AType).EnumType);
  2463. for i := 0 to EnumType.Values.Count - 1 do
  2464. begin
  2465. EnumValue := TPasEnumValue(EnumType.Values[i]);
  2466. TREl := CreateTR(TableEl);
  2467. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  2468. AppendShortDescrCell(TREl, EnumValue);
  2469. AppendNbSp(CodeEl, 2);
  2470. s := EnumValue.Name;
  2471. if (EnumValue.AssignedValue<>'') then
  2472. s := s + ' = ' + EnumValue.AssignedValue;
  2473. if i < EnumType.Values.Count - 1 then
  2474. s := s + ',';
  2475. AppendPasSHFragment(CodeEl, s, 0);
  2476. end;
  2477. AppendSym(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), ');');
  2478. end else
  2479. begin
  2480. AppendHyperlink(CodeEl, TPasSetType(AType).EnumType);
  2481. AppendSym(CodeEl, ';');
  2482. end;
  2483. end else
  2484. // Type alias
  2485. if AType.ClassType = TPasTypeAliasType then
  2486. begin
  2487. AppendKw(CodeEl, 'type ');
  2488. AppendHyperlink(CodeEl, TPasTypeAliasType(AType).DestType);
  2489. AppendSym(CodeEl, ';');
  2490. end else
  2491. // Probably one of the simple types, which allowed in other places as wel...
  2492. AppendSym(AppendType(CodeEl, TableEl, TPasType(AType), True), ';');
  2493. end;
  2494. FinishElementPage(AType);
  2495. end;
  2496. function PropertyFilter(AMember: TPasElement): Boolean;
  2497. begin
  2498. Result := (AMember.ClassType = TPasProperty) and
  2499. (Copy(AMember.Name, 1, 2) <> 'On');
  2500. end;
  2501. function MethodFilter(AMember: TPasElement): Boolean;
  2502. begin
  2503. Result := AMember.InheritsFrom(TPasProcedureBase);
  2504. end;
  2505. function EventFilter(AMember: TPasElement): Boolean;
  2506. begin
  2507. Result := (AMember.ClassType = TPasProperty) and
  2508. (Copy(AMember.Name, 1, 2) = 'On');
  2509. end;
  2510. procedure THTMLWriter.CreateClassPageBody(AClass: TPasClassType;
  2511. ASubpageIndex: Integer);
  2512. type
  2513. TMemberFilter = function(AMember: TPasElement): Boolean;
  2514. var
  2515. ParaEl: TDOMElement;
  2516. procedure AppendMemberListLink(AListSubpageIndex: Integer;
  2517. const AText: DOMString);
  2518. var
  2519. LinkEl: TDOMElement;
  2520. begin
  2521. AppendText(ParaEl, '[');
  2522. LinkEl := CreateEl(ParaEl, 'a');
  2523. LinkEl['href'] :=
  2524. FixHtmlPath(ResolveLinkWithinPackage(AClass, AListSubpageIndex));
  2525. LinkEl['onClick'] := 'window.open(''' + LinkEl['href'] + ''', ''list'', ' +
  2526. '''dependent=yes,resizable=yes,scrollbars=yes,height=400,width=300''); return false;';
  2527. AppendText(LinkEl, AText);
  2528. AppendText(ParaEl, ' (');
  2529. LinkEl := CreateEl(ParaEl, 'a');
  2530. LinkEl['href'] :=
  2531. FixHtmlPath(ResolveLinkWithinPackage(AClass, AListSubpageIndex + 1));
  2532. LinkEl['onClick'] := 'window.open(''' + LinkEl['href'] + ''', ''list'', ' +
  2533. '''dependent=yes,resizable=yes,scrollbars=yes,height=400,width=300''); return false;';
  2534. AppendText(LinkEl, SDocByName);
  2535. AppendText(ParaEl, ')');
  2536. AppendText(ParaEl, '] ');
  2537. end;
  2538. procedure AppendGenericTypes(CodeEl : TDomElement; AList : TFPList; isSpecialize : Boolean);
  2539. Var
  2540. I : integer;
  2541. begin
  2542. for I:=0 to AList.Count-1 do
  2543. begin
  2544. if I=0 then
  2545. AppendSym(CodeEl, '<')
  2546. else
  2547. AppendSym(CodeEl, ',');
  2548. AppendText(CodeEl,TPasGenericTemplateType(AList[i]).Name);
  2549. end;
  2550. AppendSym(CodeEl, '>');
  2551. end;
  2552. procedure CreateMainPage;
  2553. var
  2554. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  2555. DocNode: TDocNode;
  2556. Member: TPasElement;
  2557. CurVisibility: TPasMemberVisibility;
  2558. i: Integer;
  2559. s: String;
  2560. ThisInterface,
  2561. ThisClass: TPasClassType;
  2562. HaveSeenTObject: Boolean;
  2563. begin
  2564. AppendMenuBar(-1);
  2565. AppendTitle(AClass.Name);
  2566. ParaEl := CreatePara(BodyElement);
  2567. AppendMemberListLink(PropertiesByInheritanceSubindex, SDocProperties);
  2568. AppendMemberListLink(MethodsByInheritanceSubindex, SDocMethods);
  2569. AppendMemberListLink(EventsByInheritanceSubindex, SDocEvents);
  2570. AppendShortDescr(CreatePara(BodyElement), AClass);
  2571. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2572. AppendSourceRef(AClass);
  2573. TableEl := CreateTable(BodyElement);
  2574. TREl := CreateTR(TableEl);
  2575. TDEl := CreateTD(TREl);
  2576. CodeEl := CreateCode(CreatePara(TDEl));
  2577. AppendKw(CodeEl, 'type');
  2578. if AClass.ObjKind=okGeneric then
  2579. AppendKw(CodeEl, ' generic ');
  2580. AppendText(CodeEl, ' ' + AClass.Name + ' ');
  2581. if AClass.ObjKind=okGeneric then
  2582. AppendGenericTypes(CodeEl,AClass.GenericTemplateTypes,false);
  2583. AppendSym(CodeEl, '=');
  2584. AppendText(CodeEl, ' ');
  2585. if AClass.ObjKind<>okSpecialize then
  2586. AppendKw(CodeEl, ObjKindNames[AClass.ObjKind])
  2587. else
  2588. AppendKw(CodeEl, ' specialize ');
  2589. if Assigned(AClass.AncestorType) then
  2590. begin
  2591. if AClass.ObjKind=okSpecialize then
  2592. begin
  2593. AppendHyperlink(CodeEl, AClass.AncestorType);
  2594. AppendGenericTypes(CodeEl,AClass.GenericTemplateTypes,true)
  2595. end
  2596. else
  2597. begin
  2598. AppendSym(CodeEl, '(');
  2599. AppendHyperlink(CodeEl, AClass.AncestorType);
  2600. if AClass.Interfaces.count>0 Then
  2601. begin
  2602. for i:=0 to AClass.interfaces.count-1 do
  2603. begin
  2604. AppendSym(CodeEl, ', ');
  2605. AppendHyperlink(CodeEl,TPasClassType(AClass.Interfaces[i]));
  2606. end;
  2607. end;
  2608. AppendSym(CodeEl, ')');
  2609. end;
  2610. end;
  2611. if AClass.Members.Count > 0 then
  2612. begin
  2613. CurVisibility := visDefault;
  2614. for i := 0 to AClass.Members.Count - 1 do
  2615. begin
  2616. Member := TPasElement(AClass.Members[i]);
  2617. if CurVisibility <> Member.Visibility then
  2618. begin
  2619. CurVisibility := Member.Visibility;
  2620. if ((CurVisibility = visPrivate) and Engine.HidePrivate) or
  2621. ((CurVisibility = visProtected) and Engine.HideProtected) then
  2622. continue;
  2623. case CurVisibility of
  2624. visPrivate: s := 'private';
  2625. visProtected: s := 'protected';
  2626. visPublic: s := 'public';
  2627. visPublished: s := 'published';
  2628. visAutomated: s := 'automated';
  2629. end;
  2630. AppendKw(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), s);
  2631. end else
  2632. if ((CurVisibility = visPrivate) and Engine.HidePrivate) or
  2633. ((CurVisibility = visProtected) and Engine.HideProtected) then
  2634. continue;
  2635. TREl := CreateTR(TableEl);
  2636. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  2637. AppendNbSp(CodeEl, 2);
  2638. AppendShortDescrCell(TREl, Member);
  2639. if Member.InheritsFrom(TPasProcedureBase) then
  2640. begin
  2641. AppendKw(CodeEl, TPasProcedureBase(Member).TypeName + ' ');
  2642. AppendHyperlink(CodeEl, Member);
  2643. if (Member.ClassType = TPasOverloadedProc) or
  2644. (TPasProcedure(Member).ProcType.Args.Count > 0) then
  2645. AppendSym(CodeEl, '();')
  2646. else
  2647. AppendSym(CodeEl, ';');
  2648. if Member.ClassType <> TPasOverloadedProc then
  2649. AppendProcExt(CodeEl, TPasProcedure(Member));
  2650. end else
  2651. if Member.ClassType = TPasVariable then
  2652. begin
  2653. AppendHyperlink(CodeEl, Member);
  2654. AppendSym(CodeEl, ': ');
  2655. AppendHyperlink(CodeEl, TPasVariable(Member).VarType);
  2656. AppendSym(CodeEl, ';');
  2657. end else
  2658. if Member.ClassType = TPasProperty then
  2659. begin
  2660. AppendKw(CodeEl, 'property ');
  2661. AppendHyperlink(CodeEl, Member);
  2662. if Assigned(TPasProperty(Member).VarType) then
  2663. begin
  2664. AppendSym(CodeEl, ': ');
  2665. AppendHyperlink(CodeEl, TPasProperty(Member).VarType);
  2666. end;
  2667. AppendSym(CodeEl, ';');
  2668. if TPasProperty(Member).IsDefault then
  2669. begin
  2670. AppendKw(CodeEl, ' default');
  2671. AppendSym(CodeEl, ';');
  2672. end;
  2673. if (TPasProperty(Member).ImplementsName<>'') then
  2674. begin
  2675. AppendKw(CodeEl, ' implements');
  2676. AppendText(CodeEl, ' '+TPasProperty(Member).ImplementsName);
  2677. AppendSym(CodeEl, ';');
  2678. end;
  2679. SetLength(s, 0);
  2680. if Length(TPasProperty(Member).ReadAccessorName) > 0 then
  2681. s := s + 'r';
  2682. if Length(TPasProperty(Member).WriteAccessorName) > 0 then
  2683. s := s + 'w';
  2684. if Length(TPasProperty(Member).StoredAccessorName) > 0 then
  2685. s := s + 's';
  2686. if Length(s) > 0 then
  2687. AppendText(CodeEl, ' [' + s + ']');
  2688. end else
  2689. AppendText(CreateWarning(CodeEl), '<' + Member.ClassName + '>');
  2690. end;
  2691. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  2692. end;
  2693. AppendText(CodeEl, ' '); // !!!: Dirty trick, necessary for current XML writer
  2694. if not AClass.IsShortDefinition then
  2695. AppendKw(CodeEl, 'end');
  2696. AppendSym(CodeEl, ';');
  2697. AppendText(CreateH2(BodyElement), SDocInheritance);
  2698. TableEl := CreateTable(BodyElement);
  2699. HaveSeenTObject := AClass.ObjKind <> okClass;
  2700. ThisClass := AClass;
  2701. while True do
  2702. begin
  2703. TREl := CreateTR(TableEl);
  2704. TDEl := CreateTD_vtop(TREl);
  2705. TDEl['align'] := 'center';
  2706. CodeEl := CreateCode(CreatePara(TDEl));
  2707. AppendHyperlink(CodeEl, ThisClass);
  2708. if ThisClass.Interfaces.count>0 then
  2709. begin
  2710. for i:=0 to ThisClass.interfaces.count-1 do
  2711. begin
  2712. ThisInterface:=TPasClassType(ThisClass.Interfaces[i]);
  2713. AppendText(CodeEl,',');
  2714. AppendHyperlink(CodeEl, ThisInterface);
  2715. end;
  2716. end;
  2717. AppendShortDescrCell(TREl, ThisClass);
  2718. if HaveSeenTObject or (CompareText(ThisClass.Name, 'TObject') = 0) then
  2719. HaveSeenTObject := True
  2720. else
  2721. begin
  2722. TDEl := CreateTD(CreateTR(TableEl));
  2723. TDEl['align'] := 'center';
  2724. AppendText(TDEl, '|');
  2725. end;
  2726. if Assigned(ThisClass.AncestorType) then
  2727. begin
  2728. if ThisClass.AncestorType.InheritsFrom(TPasClassType) then
  2729. ThisClass := TPasClassType(ThisClass.AncestorType)
  2730. else
  2731. begin
  2732. TDEl := CreateTD(CreateTR(TableEl));
  2733. TDEl['align'] := 'center';
  2734. AppendText(CreateCode(CreatePara(TDEl)), ThisClass.AncestorType.Name);
  2735. if CompareText(ThisClass.AncestorType.Name, 'TObject') = 0 then
  2736. HaveSeenTObject := True
  2737. else
  2738. begin
  2739. TDEl := CreateTD(CreateTR(TableEl));
  2740. TDEl['align'] := 'center';
  2741. AppendText(TDEl, '?');
  2742. end;
  2743. break;
  2744. end
  2745. end else
  2746. break;
  2747. end;
  2748. if not HaveSeenTObject then
  2749. begin
  2750. TDEl := CreateTD(CreateTR(TableEl));
  2751. TDEl['align'] := 'center';
  2752. AppendText(CreateCode(CreatePara(TDEl)), 'TObject');
  2753. end;
  2754. FinishElementPage(AClass);
  2755. end;
  2756. procedure CreateInheritanceSubpage(AFilter: TMemberFilter);
  2757. var
  2758. ThisClass: TPasClassType;
  2759. i: Integer;
  2760. Member: TPasElement;
  2761. TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
  2762. begin
  2763. TableEl := CreateTable(BodyElement);
  2764. ThisClass := AClass;
  2765. while True do
  2766. begin
  2767. TREl := CreateTR(TableEl);
  2768. TDEl := CreateTD(TREl);
  2769. TDEl['colspan'] := '3';
  2770. CreateTD(TREl);
  2771. LinkEl := AppendHyperlink(CreateEl(CreateCode(CreatePara(TDEl)), 'b'), ThisClass);
  2772. if Assigned(LinkEl) then
  2773. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2774. '''; return false;';
  2775. for i := 0 to ThisClass.Members.Count - 1 do
  2776. begin
  2777. Member := TPasElement(ThisClass.Members[i]);
  2778. if ((Member.Visibility = visPrivate) and Engine.HidePrivate) or
  2779. ((Member.Visibility = visProtected) and Engine.HideProtected) or
  2780. not AFilter(Member) then
  2781. continue;
  2782. TREl := CreateTR(TableEl);
  2783. ParaEl := CreatePara(CreateTD(TREl));
  2784. case Member.Visibility of
  2785. visPrivate:
  2786. AppendText(ParaEl, 'pv');
  2787. visProtected:
  2788. AppendText(ParaEl, 'pt');
  2789. visPublished:
  2790. AppendText(ParaEl, 'pl');
  2791. end;
  2792. AppendNbSp(ParaEl, 1);
  2793. ParaEl := CreateTD(TREl);
  2794. if (Member.ClassType = TPasProperty) and
  2795. (Length(TPasProperty(Member).WriteAccessorName) = 0) then
  2796. begin
  2797. AppendText(ParaEl, 'ro');
  2798. AppendNbSp(ParaEl, 1);
  2799. end;
  2800. LinkEl := AppendHyperlink(CreatePara(CreateTD(TREl)), Member);
  2801. if Assigned(LinkEl) then
  2802. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2803. '''; return false;';
  2804. end;
  2805. if (not Assigned(ThisClass.AncestorType)) or
  2806. (not (ThisClass.AncestorType.ClassType = TPasClassType)) then
  2807. break;
  2808. ThisClass := TPasClassType(ThisClass.AncestorType);
  2809. AppendNbSp(CreatePara(CreateTD(CreateTR(TableEl))), 1);
  2810. end;
  2811. end;
  2812. procedure CreateSortedSubpage(AFilter: TMemberFilter);
  2813. var
  2814. List: TFPList;
  2815. ThisClass: TPasClassType;
  2816. i, j: Integer;
  2817. Member: TPasElement;
  2818. TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
  2819. begin
  2820. List := TFPList.Create;
  2821. try
  2822. ThisClass := AClass;
  2823. while True do
  2824. begin
  2825. for i := 0 to ThisClass.Members.Count - 1 do
  2826. begin
  2827. Member := TPasElement(ThisClass.Members[i]);
  2828. if (not (((Member.Visibility = visPrivate) and Engine.HidePrivate) or
  2829. ((Member.Visibility = visProtected) and Engine.HideProtected))) and
  2830. AFilter(Member) then
  2831. begin
  2832. j := 0;
  2833. while (j < List.Count) and
  2834. (CompareText(TPasElement(List[j]).Name, Member.Name) < 0) do
  2835. Inc(j);
  2836. List.Insert(j, Member);
  2837. end;
  2838. end;
  2839. if (not Assigned(ThisClass.AncestorType)) or
  2840. (not (ThisClass.AncestorType.ClassType = TPasClassType)) then
  2841. break;
  2842. ThisClass := TPasClassType(ThisClass.AncestorType);
  2843. end;
  2844. TableEl := CreateTable(BodyElement);
  2845. for i := 0 to List.Count - 1 do
  2846. begin
  2847. Member := TPasElement(List[i]);
  2848. TREl := CreateTR(TableEl);
  2849. ParaEl := CreatePara(CreateTD(TREl));
  2850. case Member.Visibility of
  2851. visPrivate:
  2852. AppendText(ParaEl, 'pv');
  2853. visProtected:
  2854. AppendText(ParaEl, 'pt');
  2855. visPublished:
  2856. AppendText(ParaEl, 'pl');
  2857. end;
  2858. AppendNbSp(ParaEl, 1);
  2859. ParaEl := CreatePara(CreateTD(TREl));
  2860. if (Member.ClassType = TPasProperty) and
  2861. (Length(TPasProperty(Member).WriteAccessorName) = 0) then
  2862. begin
  2863. AppendText(ParaEl, 'ro');
  2864. AppendNbSp(ParaEl, 1);
  2865. end;
  2866. TDEl := CreateTD(TREl);
  2867. TDEl['nowrap'] := 'nowrap';
  2868. ParaEl := CreatePara(TDEl);
  2869. LinkEl := AppendHyperlink(ParaEl, Member);
  2870. if Assigned(LinkEl) then
  2871. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2872. '''; return false;';
  2873. AppendText(ParaEl, ' (');
  2874. LinkEl := AppendHyperlink(ParaEl, Member.Parent);
  2875. if Assigned(LinkEl) then
  2876. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2877. '''; return false;';
  2878. AppendText(ParaEl, ')');
  2879. end;
  2880. finally
  2881. List.Free;
  2882. end;
  2883. end;
  2884. begin
  2885. case ASubpageIndex of
  2886. 0:
  2887. CreateMainPage;
  2888. PropertiesByInheritanceSubindex:
  2889. CreateInheritanceSubpage(@PropertyFilter);
  2890. PropertiesByNameSubindex:
  2891. CreateSortedSubpage(@PropertyFilter);
  2892. MethodsByInheritanceSubindex:
  2893. CreateInheritanceSubpage(@MethodFilter);
  2894. MethodsByNameSubindex:
  2895. CreateSortedSubpage(@MethodFilter);
  2896. EventsByInheritanceSubindex:
  2897. CreateInheritanceSubpage(@EventFilter);
  2898. EventsByNameSubindex:
  2899. CreateSortedSubpage(@EventFilter);
  2900. end;
  2901. end;
  2902. procedure THTMLWriter.CreateClassMemberPageBody(AElement: TPasElement);
  2903. var
  2904. TableEl, TREl, CodeEl: TDOMElement;
  2905. procedure CreateVarPage(Element: TPasVariable);
  2906. begin
  2907. AppendHyperlink(CodeEl, Element.Parent);
  2908. AppendSym(CodeEl, '.');
  2909. AppendText(CodeEl, Element.Name);
  2910. if Assigned(Element.VarType) then
  2911. begin
  2912. AppendSym(CodeEl, ': ');
  2913. AppendSym(AppendType(CodeEl, TableEl, Element.VarType, False), ';');
  2914. end;
  2915. end;
  2916. procedure CreatePropertyPage(Element: TPasProperty);
  2917. var
  2918. NeedBreak: Boolean;
  2919. begin
  2920. AppendKw(CodeEl, 'property ');
  2921. AppendHyperlink(CodeEl, Element.Parent);
  2922. AppendSym(CodeEl, '.');
  2923. AppendText(CodeEl, Element.Name);
  2924. if Assigned(Element.VarType) then
  2925. begin
  2926. AppendSym(CodeEl, ': ');
  2927. AppendType(CodeEl, TableEl, Element.VarType, False);
  2928. end;
  2929. NeedBreak := False;
  2930. if Length(TPasProperty(Element).IndexValue) <> 0 then
  2931. begin
  2932. CreateEl(CodeEl, 'br');
  2933. AppendNbsp(CodeEl, 2);
  2934. AppendKw(CodeEl, 'index ');
  2935. AppendPasSHFragment(CodeEl, TPasProperty(Element).IndexValue, 0);
  2936. NeedBreak := True;
  2937. end;
  2938. if Length(TPasProperty(Element).ReadAccessorName) <> 0 then
  2939. begin
  2940. CreateEl(CodeEl, 'br');
  2941. AppendNbsp(CodeEl, 2);
  2942. AppendKw(CodeEl, 'read ');
  2943. AppendText(CodeEl, TPasProperty(Element).ReadAccessorName);
  2944. NeedBreak := True;
  2945. end;
  2946. if Length(TPasProperty(Element).WriteAccessorName) <> 0 then
  2947. begin
  2948. CreateEl(CodeEl, 'br');
  2949. AppendNbsp(CodeEl, 2);
  2950. AppendKw(CodeEl, 'write ');
  2951. AppendText(CodeEl, TPasProperty(Element).WriteAccessorName);
  2952. NeedBreak := True;
  2953. end;
  2954. if Length(TPasProperty(Element).StoredAccessorName) <> 0 then
  2955. begin
  2956. CreateEl(CodeEl, 'br');
  2957. AppendNbsp(CodeEl, 2);
  2958. AppendKw(CodeEl, 'stored ');
  2959. AppendText(CodeEl, TPasProperty(Element).StoredAccessorName);
  2960. NeedBreak := True;
  2961. end;
  2962. if Length(TPasProperty(Element).DefaultValue) <> 0 then
  2963. begin
  2964. CreateEl(CodeEl, 'br');
  2965. AppendNbsp(CodeEl, 2);
  2966. AppendKw(CodeEl, 'default ');
  2967. AppendPasSHFragment(CodeEl, TPasProperty(Element).DefaultValue, 0);
  2968. NeedBreak := True;
  2969. end;
  2970. AppendSym(CodeEl, ';');
  2971. if TPasProperty(Element).IsDefault or TPasProperty(Element).IsNodefault then
  2972. begin
  2973. if NeedBreak then
  2974. begin
  2975. CreateEl(CodeEl, 'br');
  2976. AppendNbsp(CodeEl, 2);
  2977. end;
  2978. if TPasProperty(Element).IsDefault then
  2979. AppendKw(CodeEl, 'default')
  2980. else
  2981. AppendKw(CodeEl, 'nodefault');
  2982. AppendSym(CodeEl, ';');
  2983. end;
  2984. end;
  2985. var
  2986. s: String;
  2987. DocNode: TDocNode;
  2988. begin
  2989. AppendMenuBar(-1);
  2990. AppendTitle(AElement.FullName);
  2991. AppendShortDescr(CreatePara(BodyElement), AElement);
  2992. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2993. AppendSourceRef(AElement);
  2994. TableEl := CreateTable(BodyElement);
  2995. TREl := CreateTR(TableEl);
  2996. CodeEl := CreateCode(CreatePara(CreateTD(TREl)));
  2997. AppendText(CodeEl, ' '); // !!!: Workaround for current HTML writer
  2998. case AElement.Visibility of
  2999. visPrivate: s := 'private';
  3000. visProtected: s := 'protected';
  3001. visPublic: s := 'public';
  3002. visPublished: s := 'published';
  3003. visAutomated: s := 'automated';
  3004. else s := '';
  3005. end;
  3006. if Length(s) > 0 then
  3007. AppendKw(CodeEl, s);
  3008. AppendText(CodeEl, ' ');
  3009. if AElement.ClassType = TPasVariable then
  3010. CreateVarPage(TPasVariable(AElement))
  3011. else if AElement.InheritsFrom(TPasProcedureBase) then
  3012. AppendProcDecl(CodeEl, TableEl, TPasProcedureBase(AElement))
  3013. else if AElement.ClassType = TPasProperty then
  3014. CreatePropertyPage(TPasProperty(AElement))
  3015. else
  3016. AppendText(CreateWarning(BodyElement), '<' + AElement.ClassName + '>');
  3017. FinishElementPage(AElement);
  3018. end;
  3019. procedure THTMLWriter.CreateVarPageBody(AVar: TPasVariable);
  3020. var
  3021. TableEl, TREl, TDEl, CodeEl, El: TDOMElement;
  3022. DocNode: TDocNode;
  3023. begin
  3024. AppendMenuBar(-1);
  3025. AppendTitle(AVar.FullName);
  3026. AppendShortDescr(CreatePara(BodyElement), AVar);
  3027. AppendText(CreateH2(BodyElement), SDocDeclaration);
  3028. AppendSourceRef(AVar);
  3029. TableEl := CreateTable(BodyElement);
  3030. TREl := CreateTR(TableEl);
  3031. TDEl := CreateTD(TREl);
  3032. CodeEl := CreateCode(CreatePara(TDEl));
  3033. AppendKw(CodeEl, 'var');
  3034. AppendText(CodeEl, ' ' + AVar.Name);
  3035. if Assigned(AVar.VarType) then
  3036. begin
  3037. AppendSym(CodeEl, ': ');
  3038. El := AppendType(CodeEl, TableEl, AVar.VarType, False);
  3039. end else
  3040. El := CodeEl;
  3041. if Length(AVar.Value) > 0 then
  3042. AppendPasSHFragment(El, ' = ' + AVar.Value + ';', 0)
  3043. else
  3044. AppendSym(El, ';');
  3045. FinishElementPage(AVar);
  3046. end;
  3047. procedure THTMLWriter.CreateProcPageBody(AProc: TPasProcedureBase);
  3048. var
  3049. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  3050. begin
  3051. AppendMenuBar(-1);
  3052. AppendTitle(AProc.Name);
  3053. AppendShortDescr(CreatePara(BodyElement), AProc);
  3054. AppendText(CreateH2(BodyElement), SDocDeclaration);
  3055. AppendSourceRef(AProc);
  3056. TableEl := CreateTable(BodyElement);
  3057. TREl := CreateTR(TableEl);
  3058. TDEl := CreateTD(TREl);
  3059. CodeEl := CreateCode(CreatePara(TDEl));
  3060. AppendProcDecl(CodeEl, TableEl, AProc);
  3061. FinishElementPage(AProc);
  3062. end;
  3063. Function THTMLWriter.InterPretOption(Const Cmd,Arg : String) : boolean;
  3064. begin
  3065. Result:=True;
  3066. if Cmd = '--html-search' then
  3067. SearchPage := Arg
  3068. else if Cmd = '--footer' then
  3069. FooterFile := Arg
  3070. else if Cmd = '--charset' then
  3071. CharSet := Arg
  3072. else if Cmd = '--index-colcount' then
  3073. IndexColCount := StrToIntDef(Arg,IndexColCount)
  3074. else if Cmd = '--image-url' then
  3075. FBaseImageURL := Arg
  3076. else if Cmd = '--css-file' then
  3077. FCSSFile := arg
  3078. else if Cmd = '--footer-date' then
  3079. begin
  3080. FIDF:=True;
  3081. FDateFormat:=Arg;
  3082. end
  3083. else
  3084. Result:=False;
  3085. end;
  3086. procedure THTMLWriter.WriteDoc;
  3087. begin
  3088. DoLog(SWritingPages, [PageCount]);
  3089. WriteHTMLPages;
  3090. end;
  3091. class procedure THTMLWriter.Usage(List: TStrings);
  3092. begin
  3093. List.add('--footer');
  3094. List.Add(SHTMLUsageFooter);
  3095. List.Add('--footer-date[=Fmt]');
  3096. List.Add(SHTMLUsageFooterDate);
  3097. List.Add('--charset=set');
  3098. List.Add(SHTMLUsageCharset);
  3099. List.Add('--html-search=pagename');
  3100. List.Add(SHTMLHtmlSearch);
  3101. List.Add('--index-colcount=N');
  3102. List.Add(SHTMLIndexColcount);
  3103. List.Add('--image-url=url');
  3104. List.Add(SHTMLImageUrl);
  3105. end;
  3106. Class Function THTMLWriter.FileNameExtension : String;
  3107. begin
  3108. result:='';
  3109. end;
  3110. // private methods
  3111. function THTMLWriter.GetPageCount: Integer;
  3112. begin
  3113. Result := PageInfos.Count;
  3114. end;
  3115. procedure THTMLWriter.SetOnTest(const AValue: TNotifyEvent);
  3116. begin
  3117. if FOnTest=AValue then exit;
  3118. FOnTest:=AValue;
  3119. end;
  3120. procedure THTMLWriter.CreateAllocator;
  3121. begin
  3122. FAllocator:=TLongNameFileAllocator.Create('.html');
  3123. end;
  3124. procedure THTMWriter.CreateAllocator;
  3125. begin
  3126. FAllocator:=TShortNameFileAllocator.Create('.htm');
  3127. end;
  3128. initialization
  3129. // Do not localize.
  3130. RegisterWriter(THTMLWriter,'html','HTML output using fpdoc.css stylesheet.');
  3131. RegisterWriter(THTMWriter,'htm','HTM (8.3 filenames) output using fpdoc.css stylesheet.');
  3132. RegisterWriter(TCHMHTMLWriter,'chm','Compressed HTML file output using fpdoc.css stylesheet.');
  3133. finalization
  3134. UnRegisterWriter('html');
  3135. UnRegisterWriter('htm');
  3136. UnRegisterWriter('chm');
  3137. end.