dw_html.pp 93 KB

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