dw_html.pp 96 KB

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