dw_html.pp 72 KB

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