dw_html.pp 111 KB

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