dw_html.pp 97 KB

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