dw_html.pp 86 KB

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