dw_html.pp 86 KB

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