dw_html.pp 94 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338
  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 AppendDescr(AContext: TPasElement; Parent: TDOMNode;
  170. DescrNode: TDOMElement; AutoInsertBlock: Boolean);
  171. procedure AppendDescrSection(AContext: TPasElement; Parent: TDOMNode;
  172. DescrNode: TDOMElement; const ATitle: DOMString);
  173. procedure AppendShortDescrCell(Parent: TDOMNode; Element: TPasElement);
  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. begin
  1196. if Assigned(DocNode) and Assigned(DocNode.ShortDescr) then
  1197. begin
  1198. PushOutputNode(Parent);
  1199. try
  1200. if not ConvertShort(AContext,TDomElement(DocNode.ShortDescr)) then
  1201. Warning(AContext, SErrInvalidShortDescr)
  1202. finally
  1203. PopOutputNode;
  1204. end;
  1205. end;
  1206. end;
  1207. procedure THTMLWriter.AppendShortDescr(Parent: TDOMNode; Element: TPasElement);
  1208. begin
  1209. AppendShortDescr(Element,Parent,Engine.FindDocNode(Element));
  1210. end;
  1211. procedure THTMLWriter.AppendDescr(AContext: TPasElement; Parent: TDOMNode;
  1212. DescrNode: TDOMElement; AutoInsertBlock: Boolean);
  1213. begin
  1214. if Assigned(DescrNode) then
  1215. begin
  1216. PushOutputNode(Parent);
  1217. try
  1218. ConvertDescr(AContext, DescrNode, AutoInsertBlock);
  1219. finally
  1220. PopOutputNode;
  1221. end;
  1222. end;
  1223. end;
  1224. procedure THTMLWriter.AppendDescrSection(AContext: TPasElement;
  1225. Parent: TDOMNode; DescrNode: TDOMElement; const ATitle: DOMString);
  1226. begin
  1227. if not IsDescrNodeEmpty(DescrNode) then
  1228. begin
  1229. If (ATitle<>'') then // Can be empty for topic.
  1230. AppendText(CreateH2(Parent), ATitle);
  1231. AppendDescr(AContext, Parent, DescrNode, True);
  1232. end;
  1233. end;
  1234. procedure THTMLWriter.AppendShortDescrCell(Parent: TDOMNode;
  1235. Element: TPasElement);
  1236. var
  1237. ParaEl: TDOMElement;
  1238. begin
  1239. if Assigned(Engine.FindShortDescr(Element)) then
  1240. begin
  1241. AppendNbSp(CreatePara(CreateTD(Parent)), 2);
  1242. ParaEl := CreatePara(CreateTD(Parent));
  1243. ParaEl['class'] := 'cmt';
  1244. AppendShortDescr(ParaEl, Element);
  1245. end;
  1246. end;
  1247. function THTMLWriter.AppendHyperlink(Parent: TDOMNode;
  1248. Element: TPasElement): TDOMElement;
  1249. var
  1250. s: String;
  1251. UnitList: TList;
  1252. i: Integer;
  1253. ThisPackage: TLinkNode;
  1254. begin
  1255. if Assigned(Element) then
  1256. begin
  1257. if Element.InheritsFrom(TPasUnresolvedTypeRef) then
  1258. begin
  1259. s := ResolveLinkID(Element.Name);
  1260. if Length(s) = 0 then
  1261. begin
  1262. { Try all packages }
  1263. ThisPackage := Engine.RootLinkNode.FirstChild;
  1264. while Assigned(ThisPackage) do
  1265. begin
  1266. s := ResolveLinkID(ThisPackage.Name + '.' + Element.Name);
  1267. if Length(s) > 0 then
  1268. break;
  1269. ThisPackage := ThisPackage.NextSibling;
  1270. end;
  1271. if Length(s) = 0 then
  1272. begin
  1273. { Okay, then we have to try all imported units of the current module }
  1274. UnitList := Module.InterfaceSection.UsesList;
  1275. for i := UnitList.Count - 1 downto 0 do
  1276. begin
  1277. { Try all packages }
  1278. ThisPackage := Engine.RootLinkNode.FirstChild;
  1279. while Assigned(ThisPackage) do
  1280. begin
  1281. s := ResolveLinkID(ThisPackage.Name + '.' +
  1282. TPasType(UnitList[i]).Name + '.' + Element.Name);
  1283. if Length(s) > 0 then
  1284. break;
  1285. ThisPackage := ThisPackage.NextSibling;
  1286. end;
  1287. if Length(s) > 0 then
  1288. break;
  1289. end;
  1290. end;
  1291. end;
  1292. end else if Element is TPasEnumValue then
  1293. s := ResolveLinkID(Element.Parent.PathName)
  1294. else
  1295. s := ResolveLinkID(Element.PathName);
  1296. if Length(s) > 0 then
  1297. begin
  1298. Result := CreateLink(Parent, s);
  1299. AppendText(Result, Element.Name);
  1300. end else
  1301. begin
  1302. Result := nil;
  1303. AppendText(Parent, Element.Name);
  1304. end;
  1305. end else
  1306. begin
  1307. Result := nil;
  1308. AppendText(CreateWarning(Parent), '<NIL>');
  1309. end;
  1310. end;
  1311. { Returns the new CodeEl, which will be the old CodeEl in most cases }
  1312. function THTMLWriter.AppendType(CodeEl, TableEl: TDOMElement;
  1313. Element: TPasType; Expanded: Boolean; NestingLevel: Integer): TDOMElement;
  1314. Var
  1315. S : String;
  1316. begin
  1317. Result := CodeEl;
  1318. if not Assigned(Element) then
  1319. AppendText(CreateWarning(CodeEl), '<NIL>')
  1320. else if (not Expanded) and (Length(Element.Name) > 0) then
  1321. AppendHyperlink(CodeEl, Element)
  1322. else
  1323. // Array
  1324. if Element.ClassType = TPasArrayType then
  1325. begin
  1326. S:='array ';
  1327. If (TPasArrayType(Element).IndexRange<>'') then
  1328. S:=S+'[' + TPasArrayType(Element).IndexRange + '] ';
  1329. S:=S+'of ';
  1330. If (TPasArrayType(Element).ElType=Nil) then
  1331. S:=S+'Const';
  1332. AppendPasSHFragment(CodeEl,S,0);
  1333. If (TPasArrayType(Element).ElType<>Nil) then
  1334. Result := AppendType(CodeEl, TableEl, TPasArrayType(Element).ElType, False);
  1335. end else
  1336. // Procedure or funtion type
  1337. if Element.InheritsFrom(TPasProcedureType) then
  1338. begin
  1339. AppendKw(CodeEl, TPasProcedureType(Element).TypeName);
  1340. Result := AppendProcType(CodeEl, TableEl, TPasProcedureType(Element), 0)
  1341. end else
  1342. // Range type
  1343. if Element.InheritsFrom(TPasRangeType) then
  1344. AppendPasSHFragment(CodeEl, TPasRangeType(Element).RangeStart + '..' +
  1345. TPasRangeType(Element).RangeEnd, 0)
  1346. // Record type
  1347. else if Element.ClassType = TPasRecordType then
  1348. Result := AppendRecordType(CodeEl, TableEl, TPasRecordType(Element), NestingLevel)
  1349. else if (Element.ClassType = TPasFileType) and (TPasFileType(Element).elType=Nil) then
  1350. AppendPasSHFragment(CodeEl,'file',0)
  1351. else
  1352. // Other types
  1353. AppendHyperlink(CodeEl, Element);
  1354. end;
  1355. function THTMLWriter.AppendProcType(CodeEl, TableEl: TDOMElement;
  1356. Element: TPasProcedureType; Indent: Integer): TDOMElement;
  1357. function CreateIndentedCodeEl(Indent: Integer): TDOMElement;
  1358. begin
  1359. Result := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1360. AppendNbSp(Result, Indent);
  1361. end;
  1362. var
  1363. i: Integer;
  1364. Arg: TPasArgument;
  1365. begin
  1366. if Element.Args.Count > 0 then
  1367. begin
  1368. AppendSym(CodeEl, '(');
  1369. for i := 0 to Element.Args.Count - 1 do
  1370. begin
  1371. Arg := TPasArgument(Element.Args[i]);
  1372. CodeEl := CreateIndentedCodeEl(Indent + 2);
  1373. case Arg.Access of
  1374. argConst: AppendKw(CodeEl, 'const ');
  1375. argVar: AppendKw(CodeEl, 'var ');
  1376. argOut: AppendKw(CodeEl, 'out ');
  1377. end;
  1378. AppendText(CodeEl, Arg.Name);
  1379. if Assigned(Arg.ArgType) then
  1380. begin
  1381. AppendSym(CodeEl, ': ');
  1382. CodeEl := AppendType(CodeEl, TableEl, Arg.ArgType, False);
  1383. end;
  1384. if Length(Arg.Value) > 0 then
  1385. AppendPasSHFragment(CodeEl, ' = ' + Arg.Value, 0);
  1386. if i < Element.Args.Count - 1 then
  1387. AppendSym(CodeEl, ';');
  1388. end;
  1389. if Element.InheritsFrom(TPasFunctionType) or Element.IsOfObject then
  1390. begin
  1391. CodeEl := CreateIndentedCodeEl(Indent);
  1392. if Element.InheritsFrom(TPasFunctionType) then
  1393. begin
  1394. AppendSym(CodeEl, '):');
  1395. AppendHyperlink(CodeEl, TPasFunctionType(Element).ResultEl.ResultType);
  1396. end else
  1397. AppendSym(CodeEl, ')');
  1398. if Element.IsOfObject then
  1399. begin
  1400. AppendText(CodeEl, ' '); // Don't remove
  1401. AppendKw(CodeEl, 'of object');
  1402. end;
  1403. end else
  1404. if Indent > 0 then
  1405. AppendSym(CodeEl, ')')
  1406. else
  1407. begin
  1408. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1409. AppendSym(CodeEl, ')');
  1410. end;
  1411. end else
  1412. begin
  1413. { Procedure or function without arguments }
  1414. if Element.InheritsFrom(TPasFunctionType) then
  1415. begin
  1416. AppendSym(CodeEl, ': ');
  1417. AppendHyperlink(CodeEl, TPasFunctionType(Element).ResultEl.ResultType);
  1418. end;
  1419. if Element.IsOfObject then
  1420. AppendKw(CodeEl, ' of object');
  1421. end;
  1422. Result := CodeEl;
  1423. end;
  1424. procedure THTMLWriter.AppendProcExt(CodeEl: TDOMElement;
  1425. Element: TPasProcedure);
  1426. procedure AppendExt(const Ext: String);
  1427. begin
  1428. AppendKw(CodeEl, ' ' + Ext);
  1429. AppendSym(CodeEl, ';');
  1430. end;
  1431. begin
  1432. if Element.IsVirtual then
  1433. AppendExt('virtual');
  1434. if Element.IsDynamic then
  1435. AppendExt('dynamic');
  1436. if Element.IsAbstract then
  1437. AppendExt('abstract');
  1438. if Element.IsOverride then
  1439. AppendExt('override');
  1440. if Element.IsOverload then
  1441. AppendExt('overload');
  1442. if Element.IsMessage then
  1443. AppendExt('message');
  1444. end;
  1445. { Used in two places:
  1446. - Page for the method of a class
  1447. - Page for a tandalone procedure or function. }
  1448. procedure THTMLWriter.AppendProcDecl(CodeEl, TableEl: TDOMElement;
  1449. Element: TPasProcedureBase);
  1450. procedure WriteVariant(AProc: TPasProcedure);
  1451. begin
  1452. AppendProcArgsSection(TableEl.ParentNode, AProc.ProcType);
  1453. AppendKw(CodeEl, AProc.TypeName);
  1454. if Element.Parent.ClassType = TPasClassType then
  1455. begin
  1456. AppendText(CodeEl, ' ');
  1457. AppendHyperlink(CodeEl, Element.Parent);
  1458. AppendSym(CodeEl, '.');
  1459. AppendText(CodeEl, AProc.Name);
  1460. end else
  1461. AppendText(CodeEl, ' ' + AProc.FullName);
  1462. CodeEl := AppendProcType(CodeEl, TableEl, AProc.ProcType, 0);
  1463. AppendSym(CodeEl, ';');
  1464. AppendProcExt(CodeEl, AProc);
  1465. end;
  1466. var
  1467. i: Integer;
  1468. begin
  1469. if Element.ClassType = TPasOverloadedProc then
  1470. for i := 0 to TPasOverloadedProc(Element).Overloads.Count - 1 do
  1471. begin
  1472. if i > 0 then
  1473. begin
  1474. CreateEl(CodeEl, 'br');
  1475. CreateEl(CodeEl, 'br');
  1476. end;
  1477. WriteVariant(TPasProcedure(TPasOverloadedProc(Element).Overloads[i]));
  1478. end
  1479. else
  1480. WriteVariant(TPasProcedure(Element));
  1481. end;
  1482. procedure THTMLWriter.AppendProcArgsSection(Parent: TDOMNode;
  1483. Element: TPasProcedureType);
  1484. var
  1485. HasFullDescr, IsFirst: Boolean;
  1486. ResultEl: TPasResultElement;
  1487. ArgTableEl, TREl: TDOMElement;
  1488. DocNode: TDocNode;
  1489. i: Integer;
  1490. Arg: TPasArgument;
  1491. begin
  1492. IsFirst := True;
  1493. for i := 0 to Element.Args.Count - 1 do
  1494. begin
  1495. Arg := TPasArgument(Element.Args[i]);
  1496. if IsDescrNodeEmpty(Engine.FindShortDescr(Arg)) then
  1497. continue;
  1498. if IsFirst then
  1499. begin
  1500. IsFirst := False;
  1501. AppendText(CreateH2(Parent), SDocArguments);
  1502. ArgTableEl := CreateTable(Parent);
  1503. end;
  1504. TREl := CreateTR(ArgTableEl);
  1505. AppendText(CreateCode(CreatePara(CreateTD_vtop(TREl))), Arg.Name);
  1506. AppendShortDescrCell(TREl, Arg);
  1507. end;
  1508. if Element.ClassType = TPasFunctionType then
  1509. begin
  1510. ResultEl := TPasFunctionType(Element).ResultEl;
  1511. DocNode := Engine.FindDocNode(ResultEl);
  1512. HasFullDescr := Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr);
  1513. if HasFullDescr or
  1514. (Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.ShortDescr)) then
  1515. begin
  1516. AppendText(CreateH2(Parent), SDocFunctionResult);
  1517. if HasFullDescr then
  1518. AppendDescr(ResultEl, Parent, DocNode.Descr, True)
  1519. else
  1520. AppendDescr(ResultEl, CreatePara(Parent), DocNode.ShortDescr, False);
  1521. end;
  1522. end;
  1523. end;
  1524. function THTMLWriter.AppendRecordType(CodeEl, TableEl: TDOMElement;
  1525. Element: TPasRecordType; NestingLevel: Integer): TDOMElement;
  1526. var
  1527. i, j: Integer;
  1528. Variable: TPasVariable;
  1529. TREl, TDEl: TDOMElement;
  1530. CurVariant: TPasVariant;
  1531. begin
  1532. if not (Element.Parent is TPasVariant) then
  1533. if Element.IsPacked then
  1534. If Element.IsBitPacked then
  1535. AppendKw(CodeEl, 'bitpacked record')
  1536. else
  1537. AppendKW(CodeEl, 'packed record')
  1538. else
  1539. AppendKw(CodeEl, 'record');
  1540. for i := 0 to Element.Members.Count - 1 do
  1541. begin
  1542. Variable := TPasVariable(Element.Members[i]);
  1543. TREl := CreateTR(TableEl);
  1544. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1545. AppendShortDescrCell(TREl, Variable);
  1546. AppendNbSp(CodeEl, NestingLevel * 2 + 2);
  1547. AppendText(CodeEl, Variable.Name);
  1548. AppendSym(CodeEl, ': ');
  1549. CodeEl := AppendType(CodeEl, TableEl, Variable.VarType, False, NestingLevel + 1);
  1550. AppendSym(CodeEl, ';');
  1551. end;
  1552. if Assigned(Element.VariantType) then
  1553. begin
  1554. TREl := CreateTR(TableEl);
  1555. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1556. AppendNbSp(CodeEl, NestingLevel * 2 + 2);
  1557. AppendKw(CodeEl, 'case ');
  1558. if TPasRecordType(Element).VariantName <> '' then
  1559. begin
  1560. AppendText(CodeEl, TPasRecordType(Element).VariantName);
  1561. AppendSym(CodeEl, ': ');
  1562. end;
  1563. CodeEl := AppendType(CodeEl, TableEl, TPasRecordType(Element).VariantType, True);
  1564. AppendKw(CodeEl, ' of');
  1565. for i := 0 to TPasRecordType(Element).Variants.Count - 1 do
  1566. begin
  1567. CurVariant := TPasVariant(Element.Variants[i]);
  1568. TREl := CreateTR(TableEl);
  1569. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1570. AppendNbSp(CodeEl, NestingLevel * 2 + 4);
  1571. for j := 0 to CurVariant.Values.Count - 1 do
  1572. begin
  1573. if j > 0 then
  1574. AppendSym(CodeEl, ', ');
  1575. AppendPasSHFragment(CodeEl, CurVariant.Values[j], 0);
  1576. end;
  1577. AppendSym(CodeEl, ': (');
  1578. AppendType(CodeEl, TableEl, CurVariant.Members, True, NestingLevel + 3);
  1579. CodeEl := CreateCode(CreatePara(CreateTD_vtop(CreateTR(TableEl))));
  1580. AppendNbSp(CodeEl, NestingLevel * 2 + 6);
  1581. AppendSym(CodeEl, ');');
  1582. end;
  1583. end;
  1584. if not (Element.Parent is TPasVariant) then
  1585. begin
  1586. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1587. AppendText(CodeEl, ' '); // !!!: Dirty trick, necessary for current XML writer
  1588. AppendNbSp(CodeEl, NestingLevel * 2);
  1589. AppendKw(CodeEl, 'end');
  1590. end;
  1591. Result := CodeEl;
  1592. end;
  1593. procedure THTMLWriter.AppendTitle(const AText: DOMString);
  1594. begin
  1595. AppendText(TitleElement, AText);
  1596. AppendText(CreateH1(BodyElement), AText);
  1597. end;
  1598. procedure THTMLWriter.AppendTopicMenuBar(Topic : TTopicElement);
  1599. var
  1600. TableEl, TREl, ParaEl, TitleEl: TDOMElement;
  1601. procedure AddLink(El : TPasElement; const AName: String);
  1602. begin
  1603. AppendText(ParaEl, '[');
  1604. AppendText(CreateLink(ParaEl, ResolveLinkWithinPackage(El,0)),AName);
  1605. AppendText(ParaEl, ']');
  1606. end;
  1607. begin
  1608. TableEl := CreateEl(BodyElement, 'table');
  1609. TableEl['cellpadding'] := '4';
  1610. TableEl['cellspacing'] := '0';
  1611. TableEl['border'] := '0';
  1612. TableEl['width'] := '100%';
  1613. TableEl['class'] := 'bar';
  1614. TREl := CreateTR(TableEl);
  1615. ParaEl := CreateEl(CreateTD(TREl), 'b');
  1616. If Assigned(Topic.Previous) then
  1617. AddLink(Topic.Previous,SDocPrevious);
  1618. If Assigned(Topic.Parent) then
  1619. AddLink(Topic.Parent,SDocUp);
  1620. if Assigned(Topic.Next) then
  1621. AddLink(Topic.Next,SDocNext);
  1622. if Length(SearchPage) > 0 then
  1623. begin
  1624. AppendText(ParaEl, '[');
  1625. AppendText(CreateLink(ParaEl, SearchPage), SDocSearch);
  1626. AppendText(ParaEl, ']');
  1627. end;
  1628. ParaEl := CreateTD(TREl);
  1629. ParaEl['align'] := 'right';
  1630. TitleEl := CreateEl(ParaEl, 'span');
  1631. TitleEl['class'] := 'bartitle';
  1632. if Assigned(Module) then
  1633. AppendText(TitleEl, Format(SDocUnitTitle, [Module.Name]));
  1634. if Assigned(Package) then
  1635. begin
  1636. AppendText(TitleEl, ' (');
  1637. AppendHyperlink(TitleEl, Package);
  1638. AppendText(TitleEl, ')');
  1639. end;
  1640. end;
  1641. procedure THTMLWriter.AppendMenuBar(ASubpageIndex: Integer);
  1642. var
  1643. TableEl, TREl, ParaEl, TitleEl: TDOMElement;
  1644. procedure AddLink(ALinkSubpageIndex: Integer; const AName: String);
  1645. begin
  1646. AppendText(ParaEl, '[');
  1647. if ALinkSubpageIndex = ASubpageIndex then
  1648. AppendText(ParaEl, AName)
  1649. else
  1650. AppendText(
  1651. CreateLink(ParaEl, ResolveLinkWithinPackage(Module, ALinkSubpageIndex)),
  1652. AName);
  1653. AppendText(ParaEl, ']');
  1654. end;
  1655. begin
  1656. TableEl := CreateEl(BodyElement, 'table');
  1657. TableEl['cellpadding'] := '4';
  1658. TableEl['cellspacing'] := '0';
  1659. TableEl['border'] := '0';
  1660. TableEl['width'] := '100%';
  1661. TableEl['class'] := 'bar';
  1662. TREl := CreateTR(TableEl);
  1663. ParaEl := CreateEl(CreateTD(TREl), 'b');
  1664. if Assigned(Module) then
  1665. begin
  1666. AddLink(0, SDocOverview);
  1667. if Module.InterfaceSection.ResStrings.Count > 0 then
  1668. AddLink(ResstrSubindex, SDocResStrings);
  1669. if Module.InterfaceSection.Consts.Count > 0 then
  1670. AddLink(ConstsSubindex, SDocConstants);
  1671. if Module.InterfaceSection.Types.Count > 0 then
  1672. AddLink(TypesSubindex, SDocTypes);
  1673. if Module.InterfaceSection.Classes.Count > 0 then
  1674. AddLink(ClassesSubindex, SDocClasses);
  1675. if Module.InterfaceSection.Functions.Count > 0 then
  1676. AddLink(ProcsSubindex, SDocProceduresAndFunctions);
  1677. if Module.InterfaceSection.Variables.Count > 0 then
  1678. AddLink(VarsSubindex, SDocVariables);
  1679. AddLink(IndexSubIndex,SDocIdentifierIndex);
  1680. end
  1681. else
  1682. begin
  1683. // Manually add link for package page
  1684. AppendText(ParaEl, '[');
  1685. if (IndexSubIndex = ASubpageIndex) then
  1686. AppendText(ParaEl, SDocIdentifierIndex)
  1687. else
  1688. AppendText(
  1689. CreateLink(ParaEl, ResolveLinkWithinPackage(Package, IndexSubIndex)),
  1690. SDocIdentifierIndex);
  1691. AppendText(ParaEl, ']');
  1692. end;
  1693. if Length(SearchPage) > 0 then
  1694. begin
  1695. AppendText(ParaEl, '[');
  1696. AppendText(CreateLink(ParaEl, SearchPage), SDocSearch);
  1697. AppendText(ParaEl, ']');
  1698. end;
  1699. ParaEl := CreateTD(TREl);
  1700. ParaEl['align'] := 'right';
  1701. TitleEl := CreateEl(ParaEl, 'span');
  1702. TitleEl['class'] := 'bartitle';
  1703. if Assigned(Module) then
  1704. AppendText(TitleEl, Format(SDocUnitTitle, [Module.Name]));
  1705. if Assigned(Package) then
  1706. begin
  1707. AppendText(TitleEl, ' (');
  1708. AppendHyperlink(TitleEl, Package);
  1709. AppendText(TitleEl, ')');
  1710. end;
  1711. end;
  1712. procedure THTMLWriter.AppendSourceRef(AElement: TPasElement);
  1713. begin
  1714. AppendText(CreatePara(BodyElement), Format(SDocSourcePosition,
  1715. [ExtractFileName(AElement.SourceFilename), AElement.SourceLinenumber]));
  1716. end;
  1717. Procedure THTMLWriter.AppendSeeAlsoSection(AElement : TPasElement;DocNode : TDocNode);
  1718. var
  1719. Node: TDOMNode;
  1720. TableEl, El, TREl, TDEl, ParaEl, NewEl, DescrEl: TDOMElement;
  1721. l,s: String;
  1722. f: Text;
  1723. IsFirstSeeAlso : Boolean;
  1724. begin
  1725. if Not (Assigned(DocNode) and Assigned(DocNode.SeeAlso)) then
  1726. Exit;
  1727. IsFirstSeeAlso := True;
  1728. Node:=DocNode.SeeAlso.FirstChild;
  1729. While Assigned(Node) do
  1730. begin
  1731. if (Node.NodeType=ELEMENT_NODE) and (Node.NodeName='link') then
  1732. begin
  1733. if IsFirstSeeAlso then
  1734. begin
  1735. IsFirstSeeAlso := False;
  1736. AppendText(CreateH2(BodyElement), SDocSeeAlso);
  1737. TableEl := CreateTable(BodyElement);
  1738. end;
  1739. El:=TDOMElement(Node);
  1740. TREl:=CreateTR(TableEl);
  1741. ParaEl:=CreatePara(CreateTD_vtop(TREl));
  1742. l:=El['id'];
  1743. s:= ResolveLinkID(l);
  1744. if Length(s)=0 then
  1745. begin
  1746. WriteLn(Format(SErrUnknownLinkID, [l]));
  1747. NewEl := CreateEl(ParaEl,'b')
  1748. end
  1749. else
  1750. NewEl := CreateLink(ParaEl,s);
  1751. if Not IsDescrNodeEmpty(El) then
  1752. begin
  1753. PushOutputNode(NewEl);
  1754. Try
  1755. ConvertBaseShortList(AElement, El, True)
  1756. Finally
  1757. PopOutputNode;
  1758. end;
  1759. end
  1760. else
  1761. AppendText(NewEl,El['id']);
  1762. l:=El['id'];
  1763. DescrEl := Engine.FindShortDescr(AElement.GetModule,L);
  1764. if Assigned(DescrEl) then
  1765. begin
  1766. AppendNbSp(CreatePara(CreateTD(TREl)), 2);
  1767. ParaEl := CreatePara(CreateTD(TREl));
  1768. ParaEl['class'] := 'cmt';
  1769. PushOutputNode(ParaEl);
  1770. try
  1771. ConvertShort(AElement, DescrEl);
  1772. finally
  1773. PopOutputNode;
  1774. end;
  1775. end;
  1776. end; // Link node
  1777. Node := Node.NextSibling;
  1778. end; // While
  1779. end;
  1780. Procedure THTMLWriter.AppendExampleSection(AElement : TPasElement;DocNode : TDocNode);
  1781. var
  1782. Node: TDOMNode;
  1783. // TableEl, El, TREl, TDEl, ParaEl, NewEl, DescrEl: TDOMElement;
  1784. fn,s: String;
  1785. f: Text;
  1786. begin
  1787. if not (Assigned(DocNode) and Assigned(DocNode.FirstExample)) then
  1788. Exit;
  1789. Node := DocNode.FirstExample;
  1790. while Assigned(Node) do
  1791. begin
  1792. if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'example') then
  1793. begin
  1794. fn:=Engine.GetExampleFilename(TDOMElement(Node));
  1795. If (fn<>'') then
  1796. begin
  1797. AppendText(CreateH2(BodyElement), SDocExample);
  1798. try
  1799. Assign(f, FN);
  1800. Reset(f);
  1801. try
  1802. PushOutputNode(BodyElement);
  1803. DescrBeginCode(False, TDOMElement(Node)['highlighter']);
  1804. while not EOF(f) do
  1805. begin
  1806. ReadLn(f, s);
  1807. DescrWriteCodeLine(s);
  1808. end;
  1809. DescrEndCode;
  1810. PopOutputNode;
  1811. finally
  1812. Close(f);
  1813. end;
  1814. except
  1815. on e: Exception do
  1816. begin
  1817. e.Message := '[example] ' + e.Message;
  1818. raise;
  1819. end;
  1820. end;
  1821. end;
  1822. end;
  1823. Node := Node.NextSibling;
  1824. end;
  1825. end;
  1826. procedure THTMLWriter.AppendFooter;
  1827. Var
  1828. S : String;
  1829. F : TDomElement;
  1830. begin
  1831. if FooterFile<>'' then
  1832. ReadXMLFragment(BodyElement, FooterFile)
  1833. else if IncludeDateInFooter then
  1834. begin
  1835. CreateEl(BodyElement, 'hr');
  1836. F:=CreateEl(BodyElement,'span');
  1837. F['class']:='footer';
  1838. If (FDateFormat='') then
  1839. S:=DateToStr(Date)
  1840. else
  1841. S:=FormatDateTime(FDateFormat,Date);
  1842. AppendText(F,Format(SDocDateGenerated,[S]));
  1843. end;
  1844. end;
  1845. procedure THTMLWriter.FinishElementPage(AElement: TPasElement);
  1846. var
  1847. DocNode: TDocNode;
  1848. begin
  1849. DocNode := Engine.FindDocNode(AElement);
  1850. If Assigned(DocNode) then
  1851. begin
  1852. // Description
  1853. if Assigned(DocNode.Descr) then
  1854. AppendDescrSection(AElement, BodyElement, DocNode.Descr, SDocDescription);
  1855. // Append "Errors" section
  1856. if Assigned(DocNode.ErrorsDoc) then
  1857. AppendDescrSection(AElement, BodyElement, DocNode.ErrorsDoc, SDocErrors);
  1858. // Append "See also" section
  1859. AppendSeeAlsoSection(AElement,DocNode);
  1860. // Append examples, if present
  1861. AppendExampleSection(AElement,DocNode);
  1862. end;
  1863. end;
  1864. Procedure THTMLWriter.CreateTopicPageBody(AElement : TTopicElement);
  1865. var
  1866. DocNode: TDocNode;
  1867. TableEl, TREl: TDOMElement;
  1868. I : Integer;
  1869. S : String;
  1870. begin
  1871. AppendTopicMenuBar(AElement);
  1872. DocNode:=AElement.TopicNode;
  1873. if Assigned(DocNode) then // should always be true, but we're being careful.
  1874. begin
  1875. AppendShortDescr(AElement,TitleElement, DocNode);
  1876. AppendShortDescr(AElement,CreateH2(BodyElement), DocNode);
  1877. if Assigned(DocNode.Descr) then
  1878. AppendDescrSection(AElement, BodyElement, DocNode.Descr, '');
  1879. AppendSeeAlsoSection(AElement,DocNode);
  1880. CreateTopicLinks(DocNode,AElement);
  1881. AppendExampleSection(AElement,DocNode);
  1882. end;
  1883. end;
  1884. procedure THTMLWriter.CreatePageBody(AElement: TPasElement;
  1885. ASubpageIndex: Integer);
  1886. var
  1887. i: Integer;
  1888. Element: TPasElement;
  1889. begin
  1890. CurDirectory := Allocator.GetFilename(AElement, ASubpageIndex);
  1891. i := Length(CurDirectory);
  1892. while (i > 0) and not (CurDirectory[i] in AllowDirectorySeparators) do
  1893. Dec(i);
  1894. CurDirectory := Copy(CurDirectory, 1, i);
  1895. BaseDirectory := Allocator.GetRelativePathToTop(AElement);
  1896. if AElement.ClassType = TPasPackage then
  1897. begin
  1898. Module:=Nil;
  1899. If (ASubPageIndex=0) then
  1900. CreatePackagePageBody
  1901. else if ASubPageIndex=IndexSubIndex then
  1902. CreatePackageIndex
  1903. end
  1904. else
  1905. begin
  1906. Element := AElement;
  1907. while (Element<>Nil) and (Element.ClassType<>TPasModule) do
  1908. Element := Element.Parent;
  1909. Module := TPasModule(Element);
  1910. if AElement.ClassType = TPasModule then
  1911. CreateModulePageBody(TPasModule(AElement), ASubpageIndex)
  1912. else if AElement.Parent.InheritsFrom(TPasClassType) then
  1913. CreateClassMemberPageBody(AElement)
  1914. else if AElement.ClassType = TPasConst then
  1915. CreateConstPageBody(TPasConst(AElement))
  1916. else if AElement.InheritsFrom(TPasClassType) then
  1917. CreateClassPageBody(TPasClassType(AElement), ASubpageIndex)
  1918. else if AElement.InheritsFrom(TPasType) then
  1919. CreateTypePageBody(TPasType(AElement))
  1920. else if AElement.ClassType = TPasVariable then
  1921. CreateVarPageBody(TPasVariable(AElement))
  1922. else if AElement.InheritsFrom(TPasProcedureBase) then
  1923. CreateProcPageBody(TPasProcedure(AElement))
  1924. else if AElement.ClassType = TTopicELement then
  1925. CreateTopicPageBody(TTopicElement(AElement))
  1926. end;
  1927. end;
  1928. procedure THTMLWriter.CreateIndexPage(L : TStringList);
  1929. Var
  1930. Lists : Array['A'..'Z'] of TStringList;
  1931. LOther : TStringList;
  1932. CL : TStringList;
  1933. TableEl, TREl, EL: TDOMElement;
  1934. E : TPasElement;
  1935. I,Rows,J,Index : Integer;
  1936. S : String;
  1937. C : Char;
  1938. begin
  1939. For C:='A' to 'Z' do
  1940. Lists[C]:=Nil;
  1941. L.Sort;
  1942. Cl:=Nil;
  1943. // Divide over alphabet
  1944. For I:=0 to L.Count-1 do
  1945. begin
  1946. S:=L[i];
  1947. E:=TPasElement(L.Objects[i]);
  1948. If not (E is TPasUnresolvedTypeRef) then
  1949. begin
  1950. If (S<>'') then
  1951. begin
  1952. C:=Upcase(S[1]);
  1953. If C='_' then
  1954. C:='A';
  1955. If (C in ['A'..'Z']) and (Lists[C]=Nil) then
  1956. begin
  1957. CL:=TStringList.Create;
  1958. Lists[C]:=CL;
  1959. end;
  1960. end;
  1961. if assigned(cl) then
  1962. CL.AddObject(S,E);
  1963. end;
  1964. end;
  1965. Try
  1966. // Create a quick jump table to all available letters.
  1967. TableEl := CreateTable(BodyElement);
  1968. TableEl['border']:='1';
  1969. TableEl['width']:='50%';
  1970. TREl := CreateTR(TableEl);
  1971. for C:='A' to 'Z' do
  1972. If (Lists[C]<>Nil) then
  1973. begin
  1974. El:=CreateTD_vtop(TREl);
  1975. AppendText(CreateLink(El,'#SECTION'+C),C);
  1976. If C<>'Z' then
  1977. AppendNBsp(El,1);
  1978. end;
  1979. // Now emit all identifiers.
  1980. TableEl:=Nil;
  1981. For C:='A' to 'Z' do
  1982. begin
  1983. CL:=Lists[C];
  1984. If CL<>Nil then
  1985. begin
  1986. El:=CreateH2(BodyElement);
  1987. AppendText(El,C);
  1988. CreateAnchor(El,'SECTION'+C);
  1989. TableEl := CreateTable(BodyElement);
  1990. TableEl['Width']:='80%';
  1991. // Determine number of rows needed
  1992. Rows:=(CL.Count div IndexColCount);
  1993. If ((CL.Count Mod IndexColCount)<>0) then
  1994. Inc(Rows);
  1995. // Fill rows
  1996. For I:=0 to Rows-1 do
  1997. begin
  1998. TREl := CreateTR(TableEl);
  1999. For J:=0 to IndexColCount-1 do
  2000. begin
  2001. El:=CreateTD_vtop(TREl);
  2002. Index:=(J*Rows)+I;
  2003. If (Index<CL.Count) then
  2004. begin
  2005. S:=CL[Index];
  2006. E:=TPasElement(CL.Objects[Index]);
  2007. AppendHyperlink(El,E);
  2008. end;
  2009. end;
  2010. end;
  2011. end; // have List
  2012. end; // For C:=
  2013. Finally
  2014. for C:='A' to 'Z' do
  2015. FreeAndNil(Lists[C]);
  2016. end;
  2017. end;
  2018. procedure THTMLWriter.AddModuleIdentifiers(AModule : TPasModule; L : TStrings);
  2019. Procedure AddElementsFromList(L : TStrings; List : TList);
  2020. Var
  2021. I : Integer;
  2022. El : TPasElement;
  2023. begin
  2024. For I:=0 to List.Count-1 do
  2025. begin
  2026. El:=TPasElement(List[I]);
  2027. L.AddObject(El.Name,El);
  2028. If el is TPasEnumType then
  2029. AddElementsFromList(L,TPasEnumType(el).Values);
  2030. end;
  2031. end;
  2032. begin
  2033. AddElementsFromList(L,AModule.InterfaceSection.Consts);
  2034. AddElementsFromList(L,AModule.InterfaceSection.Types);
  2035. AddElementsFromList(L,AModule.InterfaceSection.Functions);
  2036. AddElementsFromList(L,AModule.InterfaceSection.Classes);
  2037. AddElementsFromList(L,AModule.InterfaceSection.Variables);
  2038. AddElementsFromList(L,AModule.InterfaceSection.ResStrings);
  2039. end;
  2040. procedure THTMLWriter.CreatePackageIndex;
  2041. Var
  2042. L : TStringList;
  2043. I : Integer;
  2044. M : TPasModule;
  2045. E : TPasElement;
  2046. S : String;
  2047. begin
  2048. L:=TStringList.Create;
  2049. try
  2050. L.Capacity:=PageInfos.Count; // Too much, but that doesn't hurt.
  2051. For I:=0 to Package.Modules.Count-1 do
  2052. begin
  2053. M:=TPasModule(Package.Modules[i]);
  2054. L.AddObject(M.Name,M);
  2055. AddModuleIdentifiers(M,L);
  2056. end;
  2057. AppendMenuBar(IndexSubIndex);
  2058. S:=Package.Name;
  2059. If Length(S)>0 then
  2060. Delete(S,1,1);
  2061. AppendTitle(Format(SDocPackageIndex, [S]));
  2062. CreateIndexPage(L);
  2063. Finally
  2064. L.Free;
  2065. end;
  2066. end;
  2067. procedure THTMLWriter.CreatePackagePageBody;
  2068. var
  2069. DocNode: TDocNode;
  2070. TableEl, TREl: TDOMElement;
  2071. i: Integer;
  2072. ThisModule: TPasModule;
  2073. L : TStringList;
  2074. begin
  2075. AppendMenuBar(0);
  2076. AppendTitle(Format(SDocPackageTitle, [Copy(Package.Name, 2, 256)]));
  2077. AppendShortDescr(CreatePara(BodyElement), Package);
  2078. AppendText(CreateH2(BodyElement), SDocUnits);
  2079. TableEl := CreateTable(BodyElement);
  2080. L:=TStringList.Create;
  2081. Try
  2082. L.Sorted:=True;
  2083. // Sort modules.
  2084. For I:=0 to Package.Modules.Count-1 do
  2085. L.AddObject(TPasModule(Package.Modules[i]).Name,TPasModule(Package.Modules[i]));
  2086. // Now create table.
  2087. for i:=0 to L.Count - 1 do
  2088. begin
  2089. ThisModule := TPasModule(L.Objects[i]);
  2090. TREl := CreateTR(TableEl);
  2091. AppendHyperlink(CreateCode(CreatePara(CreateTD_vtop(TREl))), ThisModule);
  2092. AppendShortDescrCell(TREl, ThisModule);
  2093. end;
  2094. Finally
  2095. L.Free;
  2096. end;
  2097. DocNode := Engine.FindDocNode(Package);
  2098. if Assigned(DocNode) then
  2099. begin
  2100. if Assigned(DocNode.Descr) then
  2101. AppendDescrSection(nil, BodyElement, DocNode.Descr, SDocDescription);
  2102. CreateTopicLinks(DocNode,Package);
  2103. end;
  2104. end;
  2105. Procedure THTMLWriter.CreateTopicLinks(Node : TDocNode; PasElement : TPasElement);
  2106. var
  2107. DocNode: TDocNode;
  2108. TableEl, TREl: TDOMElement;
  2109. First : Boolean;
  2110. ThisTopic: TPasElement;
  2111. begin
  2112. DocNode:=Node.FirstChild;
  2113. First:=True;
  2114. While Assigned(DocNode) do
  2115. begin
  2116. If DocNode.TopicNode then
  2117. begin
  2118. if first then
  2119. begin
  2120. First:=False;
  2121. AppendText(CreateH2(BodyElement), SDocRelatedTopics);
  2122. TableEl := CreateTable(BodyElement);
  2123. end;
  2124. TREl := CreateTR(TableEl);
  2125. ThisTopic:=FindTopicElement(DocNode);
  2126. if Assigned(ThisTopic) then
  2127. AppendHyperlink(CreateCode(CreatePara(CreateTD_vtop(TREl))), ThisTopic);
  2128. AppendShortDescrCell(TREl, ThisTopic);
  2129. end;
  2130. DocNode:=DocNode.NextSibling;
  2131. end;
  2132. end;
  2133. procedure THTMLWriter.CreateModuleIndexPage(AModule: TPasModule);
  2134. Var
  2135. L : TStringList;
  2136. begin
  2137. L:=TStringList.Create;
  2138. try
  2139. AddModuleIdentifiers(AModule,L);
  2140. AppendMenuBar(IndexSubIndex);
  2141. AppendTitle(Format(SDocModuleIndex, [AModule.Name]));
  2142. CreateIndexPage(L);
  2143. Finally
  2144. L.Free;
  2145. end;
  2146. end;
  2147. procedure THTMLWriter.CreateModulePageBody(AModule: TPasModule;
  2148. ASubpageIndex: Integer);
  2149. procedure CreateMainPage;
  2150. var
  2151. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  2152. i: Integer;
  2153. UnitRef: TPasType;
  2154. DocNode: TDocNode;
  2155. begin
  2156. AppendMenuBar(0);
  2157. AppendTitle(Format(SDocUnitTitle, [AModule.Name]));
  2158. AppendShortDescr(CreatePara(BodyElement), AModule);
  2159. if AModule.InterfaceSection.UsesList.Count > 0 then
  2160. begin
  2161. TableEl := CreateTable(BodyElement);
  2162. AppendKw(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), 'uses');
  2163. for i := 0 to AModule.InterfaceSection.UsesList.Count - 1 do
  2164. begin
  2165. UnitRef := TPasType(AModule.InterfaceSection.UsesList[i]);
  2166. DocNode := Engine.FindDocNode(UnitRef);
  2167. if Assigned(DocNode) and DocNode.IsSkipped then
  2168. continue;
  2169. TREl := CreateTR(TableEl);
  2170. TDEl := CreateTD_vtop(TREl);
  2171. CodeEl := CreateCode(CreatePara(TDEl));
  2172. AppendNbSp(CodeEl, 2);
  2173. AppendHyperlink(CodeEl, UnitRef);
  2174. if i < AModule.InterfaceSection.UsesList.Count - 1 then
  2175. AppendSym(CodeEl, ',')
  2176. else
  2177. AppendSym(CodeEl, ';');
  2178. AppendText(CodeEl, ' '); // Space for descriptions
  2179. AppendShortDescrCell(TREl, UnitRef);
  2180. end;
  2181. end;
  2182. DocNode := Engine.FindDocNode(AModule);
  2183. if Assigned(DocNode) then
  2184. begin
  2185. if Assigned(DocNode.Descr) then
  2186. AppendDescrSection(AModule, BodyElement, DocNode.Descr, SDocOverview);
  2187. CreateTopicLinks(DocNode,AModule);
  2188. end;
  2189. end;
  2190. procedure CreateSimpleSubpage(const ATitle: DOMString; AList: TList);
  2191. var
  2192. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  2193. i, j: Integer;
  2194. Decl: TPasElement;
  2195. SortedList: TList;
  2196. DocNode: TDocNode;
  2197. S : String;
  2198. begin
  2199. AppendMenuBar(ASubpageIndex);
  2200. S:=ATitle;
  2201. AppendTitle(Format(SDocUnitTitle + ': %s', [AModule.Name, S]));
  2202. SortedList := TList.Create;
  2203. try
  2204. for i := 0 to AList.Count - 1 do
  2205. begin
  2206. Decl := TPasElement(AList[i]);
  2207. DocNode := Engine.FindDocNode(Decl);
  2208. if (not Assigned(DocNode)) or (not DocNode.IsSkipped) then
  2209. begin
  2210. j := 0;
  2211. while (j < SortedList.Count) and (CompareText(
  2212. TPasElement(SortedList[j]).PathName, Decl.PathName) < 0) do
  2213. Inc(j);
  2214. SortedList.Insert(j, Decl);
  2215. end;
  2216. end;
  2217. TableEl := CreateTable(BodyElement);
  2218. for i := 0 to SortedList.Count - 1 do
  2219. begin
  2220. Decl := TPasElement(SortedList[i]);
  2221. TREl := CreateTR(TableEl);
  2222. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  2223. AppendHyperlink(CodeEl, Decl);
  2224. AppendShortDescrCell(TREl, Decl);
  2225. end;
  2226. finally
  2227. SortedList.Free;
  2228. end;
  2229. end;
  2230. procedure CreateResStringsPage;
  2231. var
  2232. ParaEl: TDOMElement;
  2233. i, j: Integer;
  2234. Decl: TPasResString;
  2235. DocNode: TDocNode;
  2236. begin
  2237. AppendMenuBar(ResstrSubindex);
  2238. AppendTitle(Format(SDocUnitTitle + ': %s', [AModule.Name, SDocResStrings]));
  2239. for i := 0 to AModule.InterfaceSection.ResStrings.Count - 1 do
  2240. begin
  2241. Decl := TPasResString(AModule.InterfaceSection.ResStrings[i]);
  2242. CreateEl(BodyElement, 'a')['name'] := LowerCase(Decl.Name);
  2243. ParaEl := CreatePara(BodyElement);
  2244. AppendText(CreateCode(ParaEl), Decl.Name);
  2245. CreateEl(ParaEl, 'br');
  2246. AppendText(ParaEl, Decl.Value);
  2247. end;
  2248. end;
  2249. begin
  2250. case ASubpageIndex of
  2251. 0:
  2252. CreateMainPage;
  2253. ResstrSubindex:
  2254. CreateResStringsPage;
  2255. ConstsSubindex:
  2256. CreateSimpleSubpage(SDocConstants, AModule.InterfaceSection.Consts);
  2257. TypesSubindex:
  2258. CreateSimpleSubpage(SDocTypes, AModule.InterfaceSection.Types);
  2259. ClassesSubindex:
  2260. CreateSimpleSubpage(SDocClasses, AModule.InterfaceSection.Classes);
  2261. ProcsSubindex:
  2262. CreateSimpleSubpage(SDocProceduresAndFunctions, AModule.InterfaceSection.Functions);
  2263. VarsSubindex:
  2264. CreateSimpleSubpage(SDocVariables, AModule.InterfaceSection.Variables);
  2265. IndexSubIndex:
  2266. CreateModuleIndexPage(AModule);
  2267. end;
  2268. end;
  2269. procedure THTMLWriter.CreateConstPageBody(AConst: TPasConst);
  2270. var
  2271. TableEl, CodeEl: TDOMElement;
  2272. begin
  2273. AppendMenuBar(-1);
  2274. AppendTitle(AConst.Name);
  2275. AppendShortDescr(CreatePara(BodyElement), AConst);
  2276. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2277. AppendSourceRef(AConst);
  2278. TableEl := CreateTable(BodyElement);
  2279. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  2280. AppendKw(CodeEl, 'const');
  2281. AppendText(CodeEl, ' ' + AConst.Name);
  2282. if Assigned(AConst.VarType) then
  2283. begin
  2284. AppendSym(CodeEl, ': ');
  2285. AppendType(CodeEl, TableEl, AConst.VarType, False);
  2286. end;
  2287. AppendPasSHFragment(CodeEl, ' = ' + AConst.Value + ';', 0);
  2288. FinishElementPage(AConst);
  2289. end;
  2290. procedure THTMLWriter.CreateTypePageBody(AType: TPasType);
  2291. var
  2292. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  2293. DocNode: TDocNode;
  2294. i: Integer;
  2295. s: String;
  2296. EnumType: TPasEnumType;
  2297. EnumValue: TPasEnumValue;
  2298. Variable: TPasVariable;
  2299. begin
  2300. AppendMenuBar(-1);
  2301. AppendTitle(AType.Name);
  2302. AppendShortDescr(CreatePara(BodyElement), AType);
  2303. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2304. AppendSourceRef(AType);
  2305. TableEl := CreateTable(BodyElement);
  2306. TREl := CreateTR(TableEl);
  2307. TDEl := CreateTD(TREl);
  2308. CodeEl := CreateCode(CreatePara(TDEl));
  2309. DocNode := Engine.FindDocNode(AType);
  2310. AppendKw(CodeEl, 'type ');
  2311. AppendText(CodeEl, AType.Name);
  2312. AppendSym(CodeEl, ' = ');
  2313. If Assigned(DocNode) and
  2314. Assigned(DocNode.Node) and
  2315. (Docnode.Node['opaque']='1') then
  2316. AppendText(CodeEl,SDocOpaque)
  2317. else
  2318. begin
  2319. // Alias
  2320. if AType.ClassType = TPasAliasType then
  2321. begin
  2322. if Assigned(TPasAliasType(AType).DestType) then
  2323. AppendHyperlink(CodeEl, TPasAliasType(AType).DestType)
  2324. else
  2325. AppendText(CreateWarning(CodeEl), '<Destination type is NIL>');
  2326. AppendSym(CodeEl, ';');
  2327. end else
  2328. // Class of
  2329. if AType.ClassType = TPasClassOfType then
  2330. begin
  2331. AppendKw(CodeEl, 'class of ');
  2332. AppendHyperlink(CodeEl, TPasClassOfType(AType).DestType);
  2333. AppendSym(CodeEl, ';');
  2334. end else
  2335. // Enumeration
  2336. if AType.ClassType = TPasEnumType then
  2337. begin
  2338. AppendSym(CodeEl, '(');
  2339. for i := 0 to TPasEnumType(AType).Values.Count - 1 do
  2340. begin
  2341. EnumValue := TPasEnumValue(TPasEnumType(AType).Values[i]);
  2342. TREl := CreateTR(TableEl);
  2343. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  2344. AppendShortDescrCell(TREl, EnumValue);
  2345. AppendNbSp(CodeEl, 2);
  2346. s := EnumValue.Name;
  2347. if EnumValue.IsValueUsed then
  2348. s := s + ' = ' + IntToStr(EnumValue.Value);
  2349. if i < TPasEnumType(AType).Values.Count - 1 then
  2350. s := s + ',';
  2351. AppendPasSHFragment(CodeEl, s, 0);
  2352. end;
  2353. AppendSym(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), ');');
  2354. end else
  2355. // Pointer type
  2356. if AType.ClassType = TPasPointerType then
  2357. begin
  2358. AppendSym(CodeEl, '^');
  2359. if Assigned(TPasPointerType(AType).DestType) then
  2360. AppendHyperlink(CodeEl, TPasPointerType(AType).DestType)
  2361. else
  2362. AppendText(CreateWarning(CodeEl), '<Destination type is NIL>');
  2363. AppendSym(CodeEl, ';');
  2364. end else
  2365. if AType.InheritsFrom(TPasProcedureType) then
  2366. begin
  2367. AppendSym(AppendType(CodeEl, TableEl, TPasType(AType), True), ';');
  2368. AppendProcArgsSection(BodyElement, TPasProcedureType(AType));
  2369. end else
  2370. // Record
  2371. if AType.ClassType = TPasRecordType then
  2372. begin
  2373. CodeEl := AppendRecordType(CodeEl, TableEl, TPasRecordType(AType), 0);
  2374. AppendSym(CodeEl, ';');
  2375. end else
  2376. // Set
  2377. if AType.ClassType = TPasSetType then
  2378. begin
  2379. AppendKw(CodeEl, 'set of ');
  2380. if TPasSetType(AType).EnumType.ClassType = TPasEnumType then
  2381. begin
  2382. AppendSym(CodeEl, '(');
  2383. EnumType := TPasEnumType(TPasSetType(AType).EnumType);
  2384. for i := 0 to EnumType.Values.Count - 1 do
  2385. begin
  2386. EnumValue := TPasEnumValue(EnumType.Values[i]);
  2387. TREl := CreateTR(TableEl);
  2388. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  2389. AppendShortDescrCell(TREl, EnumValue);
  2390. AppendNbSp(CodeEl, 2);
  2391. s := EnumValue.Name;
  2392. if EnumValue.IsValueUsed then
  2393. s := s + ' = ' + IntToStr(EnumValue.Value);
  2394. if i < EnumType.Values.Count - 1 then
  2395. s := s + ',';
  2396. AppendPasSHFragment(CodeEl, s, 0);
  2397. end;
  2398. AppendSym(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), ');');
  2399. end else
  2400. begin
  2401. AppendHyperlink(CodeEl, TPasSetType(AType).EnumType);
  2402. AppendSym(CodeEl, ';');
  2403. end;
  2404. end else
  2405. // Type alias
  2406. if AType.ClassType = TPasTypeAliasType then
  2407. begin
  2408. AppendKw(CodeEl, 'type ');
  2409. AppendHyperlink(CodeEl, TPasTypeAliasType(AType).DestType);
  2410. AppendSym(CodeEl, ';');
  2411. end else
  2412. // Probably one of the simple types, which allowed in other places as wel...
  2413. AppendSym(AppendType(CodeEl, TableEl, TPasType(AType), True), ';');
  2414. end;
  2415. FinishElementPage(AType);
  2416. end;
  2417. function PropertyFilter(AMember: TPasElement): Boolean;
  2418. begin
  2419. Result := (AMember.ClassType = TPasProperty) and
  2420. (Copy(AMember.Name, 1, 2) <> 'On');
  2421. end;
  2422. function MethodFilter(AMember: TPasElement): Boolean;
  2423. begin
  2424. Result := AMember.InheritsFrom(TPasProcedureBase);
  2425. end;
  2426. function EventFilter(AMember: TPasElement): Boolean;
  2427. begin
  2428. Result := (AMember.ClassType = TPasProperty) and
  2429. (Copy(AMember.Name, 1, 2) = 'On');
  2430. end;
  2431. procedure THTMLWriter.CreateClassPageBody(AClass: TPasClassType;
  2432. ASubpageIndex: Integer);
  2433. type
  2434. TMemberFilter = function(AMember: TPasElement): Boolean;
  2435. var
  2436. ParaEl: TDOMElement;
  2437. procedure AppendMemberListLink(AListSubpageIndex: Integer;
  2438. const AText: DOMString);
  2439. var
  2440. LinkEl: TDOMElement;
  2441. begin
  2442. AppendText(ParaEl, '[');
  2443. LinkEl := CreateEl(ParaEl, 'a');
  2444. LinkEl['href'] :=
  2445. FixHtmlPath(ResolveLinkWithinPackage(AClass, AListSubpageIndex));
  2446. LinkEl['onClick'] := 'window.open(''' + LinkEl['href'] + ''', ''list'', ' +
  2447. '''dependent=yes,resizable=yes,scrollbars=yes,height=400,width=300''); return false;';
  2448. AppendText(LinkEl, AText);
  2449. AppendText(ParaEl, ' (');
  2450. LinkEl := CreateEl(ParaEl, 'a');
  2451. LinkEl['href'] :=
  2452. FixHtmlPath(ResolveLinkWithinPackage(AClass, AListSubpageIndex + 1));
  2453. LinkEl['onClick'] := 'window.open(''' + LinkEl['href'] + ''', ''list'', ' +
  2454. '''dependent=yes,resizable=yes,scrollbars=yes,height=400,width=300''); return false;';
  2455. AppendText(LinkEl, SDocByName);
  2456. AppendText(ParaEl, ')');
  2457. AppendText(ParaEl, '] ');
  2458. end;
  2459. procedure CreateMainPage;
  2460. var
  2461. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  2462. DocNode: TDocNode;
  2463. Member: TPasElement;
  2464. CurVisibility: TPasMemberVisibility;
  2465. i: Integer;
  2466. s: String;
  2467. ThisClass: TPasClassType;
  2468. HaveSeenTObject: Boolean;
  2469. begin
  2470. AppendMenuBar(-1);
  2471. AppendTitle(AClass.Name);
  2472. ParaEl := CreatePara(BodyElement);
  2473. AppendMemberListLink(PropertiesByInheritanceSubindex, SDocProperties);
  2474. AppendMemberListLink(MethodsByInheritanceSubindex, SDocMethods);
  2475. AppendMemberListLink(EventsByInheritanceSubindex, SDocEvents);
  2476. AppendShortDescr(CreatePara(BodyElement), AClass);
  2477. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2478. AppendSourceRef(AClass);
  2479. TableEl := CreateTable(BodyElement);
  2480. TREl := CreateTR(TableEl);
  2481. TDEl := CreateTD(TREl);
  2482. CodeEl := CreateCode(CreatePara(TDEl));
  2483. AppendKw(CodeEl, 'type');
  2484. AppendText(CodeEl, ' ' + AClass.Name + ' ');
  2485. AppendSym(CodeEl, '=');
  2486. AppendText(CodeEl, ' ');
  2487. AppendKw(CodeEl, ObjKindNames[AClass.ObjKind]);
  2488. if Assigned(AClass.AncestorType) then
  2489. begin
  2490. AppendSym(CodeEl, '(');
  2491. AppendHyperlink(CodeEl, AClass.AncestorType);
  2492. AppendSym(CodeEl, ')');
  2493. end;
  2494. if AClass.Members.Count > 0 then
  2495. begin
  2496. CurVisibility := visDefault;
  2497. for i := 0 to AClass.Members.Count - 1 do
  2498. begin
  2499. Member := TPasElement(AClass.Members[i]);
  2500. if CurVisibility <> Member.Visibility then
  2501. begin
  2502. CurVisibility := Member.Visibility;
  2503. if ((CurVisibility = visPrivate) and Engine.HidePrivate) or
  2504. ((CurVisibility = visProtected) and Engine.HideProtected) then
  2505. continue;
  2506. case CurVisibility of
  2507. visPrivate: s := 'private';
  2508. visProtected: s := 'protected';
  2509. visPublic: s := 'public';
  2510. visPublished: s := 'published';
  2511. visAutomated: s := 'automated';
  2512. end;
  2513. AppendKw(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), s);
  2514. end else
  2515. if ((CurVisibility = visPrivate) and Engine.HidePrivate) or
  2516. ((CurVisibility = visProtected) and Engine.HideProtected) then
  2517. continue;
  2518. TREl := CreateTR(TableEl);
  2519. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  2520. AppendNbSp(CodeEl, 2);
  2521. AppendShortDescrCell(TREl, Member);
  2522. if Member.InheritsFrom(TPasProcedureBase) then
  2523. begin
  2524. AppendKw(CodeEl, TPasProcedureBase(Member).TypeName + ' ');
  2525. AppendHyperlink(CodeEl, Member);
  2526. if (Member.ClassType = TPasOverloadedProc) or
  2527. (TPasProcedure(Member).ProcType.Args.Count > 0) then
  2528. AppendSym(CodeEl, '();')
  2529. else
  2530. AppendSym(CodeEl, ';');
  2531. if Member.ClassType <> TPasOverloadedProc then
  2532. AppendProcExt(CodeEl, TPasProcedure(Member));
  2533. end else
  2534. if Member.ClassType = TPasVariable then
  2535. begin
  2536. AppendHyperlink(CodeEl, Member);
  2537. AppendSym(CodeEl, ': ');
  2538. AppendHyperlink(CodeEl, TPasVariable(Member).VarType);
  2539. AppendSym(CodeEl, ';');
  2540. end else
  2541. if Member.ClassType = TPasProperty then
  2542. begin
  2543. AppendKw(CodeEl, 'property ');
  2544. AppendHyperlink(CodeEl, Member);
  2545. if Assigned(TPasProperty(Member).VarType) then
  2546. begin
  2547. AppendSym(CodeEl, ': ');
  2548. AppendHyperlink(CodeEl, TPasProperty(Member).VarType);
  2549. end;
  2550. AppendSym(CodeEl, ';');
  2551. if TPasProperty(Member).IsDefault then
  2552. begin
  2553. AppendKw(CodeEl, ' default');
  2554. AppendSym(CodeEl, ';');
  2555. end;
  2556. SetLength(s, 0);
  2557. if Length(TPasProperty(Member).ReadAccessorName) > 0 then
  2558. s := s + 'r';
  2559. if Length(TPasProperty(Member).WriteAccessorName) > 0 then
  2560. s := s + 'w';
  2561. if Length(TPasProperty(Member).StoredAccessorName) > 0 then
  2562. s := s + 's';
  2563. if Length(s) > 0 then
  2564. AppendText(CodeEl, ' [' + s + ']');
  2565. end else
  2566. AppendText(CreateWarning(CodeEl), '<' + Member.ClassName + '>');
  2567. end;
  2568. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  2569. end;
  2570. AppendText(CodeEl, ' '); // !!!: Dirty trick, necessary for current XML writer
  2571. AppendKw(CodeEl, 'end');
  2572. AppendSym(CodeEl, ';');
  2573. AppendText(CreateH2(BodyElement), SDocInheritance);
  2574. TableEl := CreateTable(BodyElement);
  2575. HaveSeenTObject := AClass.ObjKind <> okClass;
  2576. ThisClass := AClass;
  2577. while True do
  2578. begin
  2579. TREl := CreateTR(TableEl);
  2580. TDEl := CreateTD_vtop(TREl);
  2581. TDEl['align'] := 'center';
  2582. CodeEl := CreateCode(CreatePara(TDEl));
  2583. AppendHyperlink(CodeEl, ThisClass);
  2584. AppendShortDescrCell(TREl, ThisClass);
  2585. if HaveSeenTObject or (CompareText(ThisClass.Name, 'TObject') = 0) then
  2586. HaveSeenTObject := True
  2587. else
  2588. begin
  2589. TDEl := CreateTD(CreateTR(TableEl));
  2590. TDEl['align'] := 'center';
  2591. AppendText(TDEl, '|');
  2592. end;
  2593. if Assigned(ThisClass.AncestorType) then
  2594. begin
  2595. if ThisClass.AncestorType.InheritsFrom(TPasClassType) then
  2596. ThisClass := TPasClassType(ThisClass.AncestorType)
  2597. else
  2598. begin
  2599. TDEl := CreateTD(CreateTR(TableEl));
  2600. TDEl['align'] := 'center';
  2601. AppendText(CreateCode(CreatePara(TDEl)), ThisClass.AncestorType.Name);
  2602. if CompareText(ThisClass.AncestorType.Name, 'TObject') = 0 then
  2603. HaveSeenTObject := True
  2604. else
  2605. begin
  2606. TDEl := CreateTD(CreateTR(TableEl));
  2607. TDEl['align'] := 'center';
  2608. AppendText(TDEl, '?');
  2609. end;
  2610. break;
  2611. end
  2612. end else
  2613. break;
  2614. end;
  2615. if not HaveSeenTObject then
  2616. begin
  2617. TDEl := CreateTD(CreateTR(TableEl));
  2618. TDEl['align'] := 'center';
  2619. AppendText(CreateCode(CreatePara(TDEl)), 'TObject');
  2620. end;
  2621. FinishElementPage(AClass);
  2622. end;
  2623. procedure CreateInheritanceSubpage(AFilter: TMemberFilter);
  2624. var
  2625. ThisClass: TPasClassType;
  2626. i: Integer;
  2627. Member: TPasElement;
  2628. TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
  2629. begin
  2630. TableEl := CreateTable(BodyElement);
  2631. ThisClass := AClass;
  2632. while True do
  2633. begin
  2634. TREl := CreateTR(TableEl);
  2635. TDEl := CreateTD(TREl);
  2636. TDEl['colspan'] := '3';
  2637. CreateTD(TREl);
  2638. LinkEl := AppendHyperlink(CreateEl(CreateCode(CreatePara(TDEl)), 'b'), ThisClass);
  2639. if Assigned(LinkEl) then
  2640. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2641. '''; return false;';
  2642. for i := 0 to ThisClass.Members.Count - 1 do
  2643. begin
  2644. Member := TPasElement(ThisClass.Members[i]);
  2645. if ((Member.Visibility = visPrivate) and Engine.HidePrivate) or
  2646. ((Member.Visibility = visProtected) and Engine.HideProtected) or
  2647. not AFilter(Member) then
  2648. continue;
  2649. TREl := CreateTR(TableEl);
  2650. ParaEl := CreatePara(CreateTD(TREl));
  2651. case Member.Visibility of
  2652. visPrivate:
  2653. AppendText(ParaEl, 'pv');
  2654. visProtected:
  2655. AppendText(ParaEl, 'pt');
  2656. visPublished:
  2657. AppendText(ParaEl, 'pl');
  2658. end;
  2659. AppendNbSp(ParaEl, 1);
  2660. ParaEl := CreateTD(TREl);
  2661. if (Member.ClassType = TPasProperty) and
  2662. (Length(TPasProperty(Member).WriteAccessorName) = 0) then
  2663. begin
  2664. AppendText(ParaEl, 'ro');
  2665. AppendNbSp(ParaEl, 1);
  2666. end;
  2667. LinkEl := AppendHyperlink(CreatePara(CreateTD(TREl)), Member);
  2668. if Assigned(LinkEl) then
  2669. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2670. '''; return false;';
  2671. end;
  2672. if (not Assigned(ThisClass.AncestorType)) or
  2673. (not (ThisClass.AncestorType.ClassType = TPasClassType)) then
  2674. break;
  2675. ThisClass := TPasClassType(ThisClass.AncestorType);
  2676. AppendNbSp(CreatePara(CreateTD(CreateTR(TableEl))), 1);
  2677. end;
  2678. end;
  2679. procedure CreateSortedSubpage(AFilter: TMemberFilter);
  2680. var
  2681. List: TList;
  2682. ThisClass: TPasClassType;
  2683. i, j: Integer;
  2684. Member: TPasElement;
  2685. TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
  2686. begin
  2687. List := TList.Create;
  2688. try
  2689. ThisClass := AClass;
  2690. while True do
  2691. begin
  2692. for i := 0 to ThisClass.Members.Count - 1 do
  2693. begin
  2694. Member := TPasElement(ThisClass.Members[i]);
  2695. if (not (((Member.Visibility = visPrivate) and Engine.HidePrivate) or
  2696. ((Member.Visibility = visProtected) and Engine.HideProtected))) and
  2697. AFilter(Member) then
  2698. begin
  2699. j := 0;
  2700. while (j < List.Count) and
  2701. (CompareText(TPasElement(List[j]).Name, Member.Name) < 0) do
  2702. Inc(j);
  2703. List.Insert(j, Member);
  2704. end;
  2705. end;
  2706. if (not Assigned(ThisClass.AncestorType)) or
  2707. (not (ThisClass.AncestorType.ClassType = TPasClassType)) then
  2708. break;
  2709. ThisClass := TPasClassType(ThisClass.AncestorType);
  2710. end;
  2711. TableEl := CreateTable(BodyElement);
  2712. for i := 0 to List.Count - 1 do
  2713. begin
  2714. Member := TPasElement(List[i]);
  2715. TREl := CreateTR(TableEl);
  2716. ParaEl := CreatePara(CreateTD(TREl));
  2717. case Member.Visibility of
  2718. visPrivate:
  2719. AppendText(ParaEl, 'pv');
  2720. visProtected:
  2721. AppendText(ParaEl, 'pt');
  2722. visPublished:
  2723. AppendText(ParaEl, 'pl');
  2724. end;
  2725. AppendNbSp(ParaEl, 1);
  2726. ParaEl := CreatePara(CreateTD(TREl));
  2727. if (Member.ClassType = TPasProperty) and
  2728. (Length(TPasProperty(Member).WriteAccessorName) = 0) then
  2729. begin
  2730. AppendText(ParaEl, 'ro');
  2731. AppendNbSp(ParaEl, 1);
  2732. end;
  2733. TDEl := CreateTD(TREl);
  2734. TDEl['nowrap'] := 'nowrap';
  2735. ParaEl := CreatePara(TDEl);
  2736. LinkEl := AppendHyperlink(ParaEl, Member);
  2737. if Assigned(LinkEl) then
  2738. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2739. '''; return false;';
  2740. AppendText(ParaEl, ' (');
  2741. LinkEl := AppendHyperlink(ParaEl, Member.Parent);
  2742. if Assigned(LinkEl) then
  2743. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2744. '''; return false;';
  2745. AppendText(ParaEl, ')');
  2746. end;
  2747. finally
  2748. List.Free;
  2749. end;
  2750. end;
  2751. begin
  2752. case ASubpageIndex of
  2753. 0:
  2754. CreateMainPage;
  2755. PropertiesByInheritanceSubindex:
  2756. CreateInheritanceSubpage(@PropertyFilter);
  2757. PropertiesByNameSubindex:
  2758. CreateSortedSubpage(@PropertyFilter);
  2759. MethodsByInheritanceSubindex:
  2760. CreateInheritanceSubpage(@MethodFilter);
  2761. MethodsByNameSubindex:
  2762. CreateSortedSubpage(@MethodFilter);
  2763. EventsByInheritanceSubindex:
  2764. CreateInheritanceSubpage(@EventFilter);
  2765. EventsByNameSubindex:
  2766. CreateSortedSubpage(@EventFilter);
  2767. end;
  2768. end;
  2769. procedure THTMLWriter.CreateClassMemberPageBody(AElement: TPasElement);
  2770. var
  2771. TableEl, TREl, CodeEl: TDOMElement;
  2772. procedure CreateVarPage(Element: TPasVariable);
  2773. begin
  2774. AppendHyperlink(CodeEl, Element.Parent);
  2775. AppendSym(CodeEl, '.');
  2776. AppendText(CodeEl, Element.Name);
  2777. if Assigned(Element.VarType) then
  2778. begin
  2779. AppendSym(CodeEl, ': ');
  2780. AppendSym(AppendType(CodeEl, TableEl, Element.VarType, False), ';');
  2781. end;
  2782. end;
  2783. procedure CreatePropertyPage(Element: TPasProperty);
  2784. var
  2785. NeedBreak: Boolean;
  2786. begin
  2787. AppendKw(CodeEl, 'property ');
  2788. AppendHyperlink(CodeEl, Element.Parent);
  2789. AppendSym(CodeEl, '.');
  2790. AppendText(CodeEl, Element.Name);
  2791. if Assigned(Element.VarType) then
  2792. begin
  2793. AppendSym(CodeEl, ': ');
  2794. AppendType(CodeEl, TableEl, Element.VarType, False);
  2795. end;
  2796. NeedBreak := False;
  2797. if Length(TPasProperty(Element).IndexValue) <> 0 then
  2798. begin
  2799. CreateEl(CodeEl, 'br');
  2800. AppendNbsp(CodeEl, 2);
  2801. AppendKw(CodeEl, 'index ');
  2802. AppendPasSHFragment(CodeEl, TPasProperty(Element).IndexValue, 0);
  2803. NeedBreak := True;
  2804. end;
  2805. if Length(TPasProperty(Element).ReadAccessorName) <> 0 then
  2806. begin
  2807. CreateEl(CodeEl, 'br');
  2808. AppendNbsp(CodeEl, 2);
  2809. AppendKw(CodeEl, 'read ');
  2810. AppendText(CodeEl, TPasProperty(Element).ReadAccessorName);
  2811. NeedBreak := True;
  2812. end;
  2813. if Length(TPasProperty(Element).WriteAccessorName) <> 0 then
  2814. begin
  2815. CreateEl(CodeEl, 'br');
  2816. AppendNbsp(CodeEl, 2);
  2817. AppendKw(CodeEl, 'write ');
  2818. AppendText(CodeEl, TPasProperty(Element).WriteAccessorName);
  2819. NeedBreak := True;
  2820. end;
  2821. if Length(TPasProperty(Element).StoredAccessorName) <> 0 then
  2822. begin
  2823. CreateEl(CodeEl, 'br');
  2824. AppendNbsp(CodeEl, 2);
  2825. AppendKw(CodeEl, 'stored ');
  2826. AppendText(CodeEl, TPasProperty(Element).StoredAccessorName);
  2827. NeedBreak := True;
  2828. end;
  2829. if Length(TPasProperty(Element).DefaultValue) <> 0 then
  2830. begin
  2831. CreateEl(CodeEl, 'br');
  2832. AppendNbsp(CodeEl, 2);
  2833. AppendKw(CodeEl, 'default ');
  2834. AppendPasSHFragment(CodeEl, TPasProperty(Element).DefaultValue, 0);
  2835. NeedBreak := True;
  2836. end;
  2837. AppendSym(CodeEl, ';');
  2838. if TPasProperty(Element).IsDefault or TPasProperty(Element).IsNodefault then
  2839. begin
  2840. if NeedBreak then
  2841. begin
  2842. CreateEl(CodeEl, 'br');
  2843. AppendNbsp(CodeEl, 2);
  2844. end;
  2845. if TPasProperty(Element).IsDefault then
  2846. AppendKw(CodeEl, 'default')
  2847. else
  2848. AppendKw(CodeEl, 'nodefault');
  2849. AppendSym(CodeEl, ';');
  2850. end;
  2851. end;
  2852. var
  2853. s: String;
  2854. DocNode: TDocNode;
  2855. begin
  2856. AppendMenuBar(-1);
  2857. AppendTitle(AElement.FullName);
  2858. AppendShortDescr(CreatePara(BodyElement), AElement);
  2859. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2860. AppendSourceRef(AElement);
  2861. TableEl := CreateTable(BodyElement);
  2862. TREl := CreateTR(TableEl);
  2863. CodeEl := CreateCode(CreatePara(CreateTD(TREl)));
  2864. AppendText(CodeEl, ' '); // !!!: Workaround for current HTML writer
  2865. case AElement.Visibility of
  2866. visPrivate: s := 'private';
  2867. visProtected: s := 'protected';
  2868. visPublic: s := 'public';
  2869. visPublished: s := 'published';
  2870. visAutomated: s := 'automated';
  2871. else s := '';
  2872. end;
  2873. if Length(s) > 0 then
  2874. AppendKw(CodeEl, s);
  2875. AppendText(CodeEl, ' ');
  2876. if AElement.ClassType = TPasVariable then
  2877. CreateVarPage(TPasVariable(AElement))
  2878. else if AElement.InheritsFrom(TPasProcedureBase) then
  2879. AppendProcDecl(CodeEl, TableEl, TPasProcedureBase(AElement))
  2880. else if AElement.ClassType = TPasProperty then
  2881. CreatePropertyPage(TPasProperty(AElement))
  2882. else
  2883. AppendText(CreateWarning(BodyElement), '<' + AElement.ClassName + '>');
  2884. FinishElementPage(AElement);
  2885. end;
  2886. procedure THTMLWriter.CreateVarPageBody(AVar: TPasVariable);
  2887. var
  2888. TableEl, TREl, TDEl, CodeEl, El: TDOMElement;
  2889. DocNode: TDocNode;
  2890. begin
  2891. AppendMenuBar(-1);
  2892. AppendTitle(AVar.FullName);
  2893. AppendShortDescr(CreatePara(BodyElement), AVar);
  2894. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2895. AppendSourceRef(AVar);
  2896. TableEl := CreateTable(BodyElement);
  2897. TREl := CreateTR(TableEl);
  2898. TDEl := CreateTD(TREl);
  2899. CodeEl := CreateCode(CreatePara(TDEl));
  2900. AppendKw(CodeEl, 'var');
  2901. AppendText(CodeEl, ' ' + AVar.Name);
  2902. if Assigned(AVar.VarType) then
  2903. begin
  2904. AppendSym(CodeEl, ': ');
  2905. El := AppendType(CodeEl, TableEl, AVar.VarType, False);
  2906. end else
  2907. El := CodeEl;
  2908. if Length(AVar.Value) > 0 then
  2909. AppendPasSHFragment(El, ' = ' + AVar.Value + ';', 0)
  2910. else
  2911. AppendSym(El, ';');
  2912. FinishElementPage(AVar);
  2913. end;
  2914. procedure THTMLWriter.CreateProcPageBody(AProc: TPasProcedureBase);
  2915. var
  2916. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  2917. begin
  2918. AppendMenuBar(-1);
  2919. AppendTitle(AProc.Name);
  2920. AppendShortDescr(CreatePara(BodyElement), AProc);
  2921. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2922. AppendSourceRef(AProc);
  2923. TableEl := CreateTable(BodyElement);
  2924. TREl := CreateTR(TableEl);
  2925. TDEl := CreateTD(TREl);
  2926. CodeEl := CreateCode(CreatePara(TDEl));
  2927. AppendProcDecl(CodeEl, TableEl, AProc);
  2928. FinishElementPage(AProc);
  2929. end;
  2930. Function THTMLWriter.InterPretOption(Const Cmd,Arg : String) : boolean;
  2931. begin
  2932. Result:=True;
  2933. if Cmd = '--html-search' then
  2934. SearchPage := Arg
  2935. else if Cmd = '--footer' then
  2936. FooterFile := Arg
  2937. else if Cmd = '--charset' then
  2938. CharSet := Arg
  2939. else if Cmd = '--index-colcount' then
  2940. IndexColCount := StrToIntDef(Arg,IndexColCount)
  2941. else if Cmd = '--image-url' then
  2942. FBaseImageURL := Arg
  2943. else if Cmd = '--footer-date' then
  2944. begin
  2945. FIDF:=True;
  2946. FDateFormat:=Arg;
  2947. end
  2948. else
  2949. Result:=False;
  2950. end;
  2951. procedure THTMLWriter.WriteDoc;
  2952. begin
  2953. WriteLn(Format(SWritingPages, [PageCount]));
  2954. WriteHTMLPages;
  2955. end;
  2956. class procedure THTMLWriter.Usage(List: TStrings);
  2957. begin
  2958. List.add('--footer');
  2959. List.Add(SHTMLUsageFooter);
  2960. List.Add('--footer-date[=Fmt]');
  2961. List.Add(SHTMLUsageFooterDate);
  2962. List.Add('--charset=set');
  2963. List.Add(SHTMLUsageCharset);
  2964. List.Add('--html-search=pagename');
  2965. List.Add(SHTMLHtmlSearch);
  2966. List.Add('--index-colcount=N');
  2967. List.Add(SHTMLIndexColcount);
  2968. List.Add('--image-url=url');
  2969. List.Add(SHTMLImageUrl);
  2970. end;
  2971. // private methods
  2972. function THTMLWriter.GetPageCount: Integer;
  2973. begin
  2974. Result := PageInfos.Count;
  2975. end;
  2976. procedure THTMLWriter.SetOnTest(const AValue: TNotifyEvent);
  2977. begin
  2978. if FOnTest=AValue then exit;
  2979. FOnTest:=AValue;
  2980. end;
  2981. procedure THTMLWriter.CreateAllocator;
  2982. begin
  2983. FAllocator:=TLongNameFileAllocator.Create('.html');
  2984. end;
  2985. procedure THTMWriter.CreateAllocator;
  2986. begin
  2987. FAllocator:=TShortNameFileAllocator.Create('.htm');
  2988. end;
  2989. initialization
  2990. // Do not localize.
  2991. RegisterWriter(THTMLWriter,'html','HTML output using fpdoc.css stylesheet.');
  2992. RegisterWriter(THTMWriter,'htm','HTM (8.3 filenames) output using fpdoc.css stylesheet.');
  2993. RegisterWriter(TCHMHTMLWriter,'chm','Compressed HTML file output using fpdoc.css stylesheet.');
  2994. finalization
  2995. UnRegisterWriter('html');
  2996. UnRegisterWriter('htm');
  2997. UnRegisterWriter('chm');
  2998. end.