dw_html.pp 107 KB

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