dw_html.pp 82 KB

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