dw_html.pp 94 KB

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