dw_html.pp 86 KB

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