dw_html.pp 80 KB

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