dw_html.pp 111 KB

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