dw_html.pp 110 KB

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