dw_html.pp 109 KB

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