dw_html.pp 111 KB

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