dw_html.pp 95 KB

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