dw_html.pp 95 KB

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