dw_html.pp 108 KB

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