dw_html.pp 95 KB

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