dw_html.pp 94 KB

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