dw_html.pp 95 KB

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