dw_html.pp 72 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614
  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('Suche nach ', 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. break;
  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. AppendKw(CodeEl, 'array ');
  1117. AppendText(CreateWarning(CodeEl), '...');
  1118. AppendKw(CodeEl, ' of ');
  1119. Result := AppendType(CodeEl, TableEl, TPasArrayType(Element).ElType, False);
  1120. end else
  1121. // Procedure or funtion type
  1122. if Element.InheritsFrom(TPasProcedureType) then
  1123. begin
  1124. AppendKw(CodeEl, TPasProcedureType(Element).TypeName);
  1125. Result := AppendProcType(CodeEl, TableEl, TPasProcedureType(Element), 0)
  1126. end else
  1127. // Range type
  1128. if Element.InheritsFrom(TPasRangeType) then
  1129. AppendPasSHFragment(CodeEl, TPasRangeType(Element).RangeStart + '..' +
  1130. TPasRangeType(Element).RangeEnd, 0)
  1131. else
  1132. // Other types
  1133. AppendHyperlink(CodeEl, Element);
  1134. end;
  1135. function THTMLWriter.AppendProcType(CodeEl, TableEl: TDOMElement;
  1136. Element: TPasProcedureType; Indent: Integer): TDOMElement;
  1137. function CreateIndentedCodeEl(Indent: Integer): TDOMElement;
  1138. begin
  1139. Result := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1140. AppendNbSp(Result, Indent);
  1141. end;
  1142. var
  1143. i: Integer;
  1144. Arg: TPasArgument;
  1145. begin
  1146. if Element.Args.Count > 0 then
  1147. begin
  1148. AppendSym(CodeEl, '(');
  1149. for i := 0 to Element.Args.Count - 1 do
  1150. begin
  1151. Arg := TPasArgument(Element.Args[i]);
  1152. CodeEl := CreateIndentedCodeEl(Indent + 2);
  1153. case Arg.Access of
  1154. argConst: AppendKw(CodeEl, 'const ');
  1155. argVar: AppendKw(CodeEl, 'var ');
  1156. argOut: AppendKw(CodeEl, 'out ');
  1157. end;
  1158. AppendText(CodeEl, Arg.Name);
  1159. if Assigned(Arg.ArgType) then
  1160. begin
  1161. AppendSym(CodeEl, ': ');
  1162. CodeEl := AppendType(CodeEl, TableEl, Arg.ArgType, False);
  1163. end;
  1164. if Length(Arg.Value) > 0 then
  1165. AppendPasSHFragment(CodeEl, ' = ' + Arg.Value, 0);
  1166. if i < Element.Args.Count - 1 then
  1167. AppendSym(CodeEl, ';');
  1168. end;
  1169. if Element.InheritsFrom(TPasFunctionType) or Element.IsOfObject then
  1170. begin
  1171. CodeEl := CreateIndentedCodeEl(Indent);
  1172. if Element.InheritsFrom(TPasFunctionType) then
  1173. begin
  1174. AppendSym(CodeEl, '):');
  1175. AppendHyperlink(CodeEl, TPasFunctionType(Element).ResultEl.ResultType);
  1176. end else
  1177. AppendSym(CodeEl, ')');
  1178. if Element.IsOfObject then
  1179. begin
  1180. AppendText(CodeEl, ' '); // Don't remove
  1181. AppendKw(CodeEl, 'of object');
  1182. end;
  1183. end else
  1184. if Indent > 0 then
  1185. AppendSym(CodeEl, ')')
  1186. else
  1187. begin
  1188. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1189. AppendSym(CodeEl, ')');
  1190. end;
  1191. end else
  1192. begin
  1193. { Procedure or function without arguments }
  1194. if Element.InheritsFrom(TPasFunctionType) then
  1195. begin
  1196. AppendSym(CodeEl, ': ');
  1197. AppendHyperlink(CodeEl, TPasFunctionType(Element).ResultEl.ResultType);
  1198. end;
  1199. if Element.IsOfObject then
  1200. AppendKw(CodeEl, ' of object');
  1201. end;
  1202. Result := CodeEl;
  1203. end;
  1204. procedure THTMLWriter.AppendProcExt(CodeEl: TDOMElement;
  1205. Element: TPasProcedure);
  1206. procedure AppendExt(const Ext: String);
  1207. begin
  1208. AppendKw(CodeEl, ' ' + Ext);
  1209. AppendSym(CodeEl, ';');
  1210. end;
  1211. begin
  1212. if Element.IsVirtual then
  1213. AppendExt('virtual');
  1214. if Element.IsDynamic then
  1215. AppendExt('dynamic');
  1216. if Element.IsAbstract then
  1217. AppendExt('abstract');
  1218. if Element.IsOverride then
  1219. AppendExt('override');
  1220. if Element.IsOverload then
  1221. AppendExt('overload');
  1222. if Element.IsMessage then
  1223. AppendExt('message');
  1224. end;
  1225. { Used in two places:
  1226. - Page for the method of a class
  1227. - Page for a tandalone procedure or function. }
  1228. procedure THTMLWriter.AppendProcDecl(CodeEl, TableEl: TDOMElement;
  1229. Element: TPasProcedureBase);
  1230. procedure WriteVariant(AProc: TPasProcedure);
  1231. begin
  1232. AppendProcArgsSection(TableEl.ParentNode, AProc.ProcType);
  1233. AppendKw(CodeEl, AProc.TypeName);
  1234. if Element.Parent.ClassType = TPasClassType then
  1235. begin
  1236. AppendText(CodeEl, ' ');
  1237. AppendHyperlink(CodeEl, Element.Parent);
  1238. AppendSym(CodeEl, '.');
  1239. AppendText(CodeEl, AProc.Name);
  1240. end else
  1241. AppendText(CodeEl, ' ' + AProc.FullName);
  1242. CodeEl := AppendProcType(CodeEl, TableEl, AProc.ProcType, 0);
  1243. AppendSym(CodeEl, ';');
  1244. AppendProcExt(CodeEl, AProc);
  1245. end;
  1246. var
  1247. i: Integer;
  1248. begin
  1249. if Element.ClassType = TPasOverloadedProc then
  1250. for i := 0 to TPasOverloadedProc(Element).Overloads.Count - 1 do
  1251. begin
  1252. if i > 0 then
  1253. begin
  1254. CreateEl(CodeEl, 'br');
  1255. CreateEl(CodeEl, 'br');
  1256. end;
  1257. WriteVariant(TPasProcedure(TPasOverloadedProc(Element).Overloads[i]));
  1258. end
  1259. else
  1260. WriteVariant(TPasProcedure(Element));
  1261. end;
  1262. procedure THTMLWriter.AppendProcArgsSection(Parent: TDOMNode;
  1263. Element: TPasProcedureType);
  1264. var
  1265. HasFullDescr, IsFirst: Boolean;
  1266. ResultEl: TPasResultElement;
  1267. ArgTableEl, TREl: TDOMElement;
  1268. DocNode: TDocNode;
  1269. i: Integer;
  1270. Arg: TPasArgument;
  1271. begin
  1272. IsFirst := True;
  1273. for i := 0 to Element.Args.Count - 1 do
  1274. begin
  1275. Arg := TPasArgument(Element.Args[i]);
  1276. if IsDescrNodeEmpty(Engine.FindShortDescr(Arg)) then
  1277. continue;
  1278. if IsFirst then
  1279. begin
  1280. IsFirst := False;
  1281. AppendText(CreateH2(Parent), SDocArguments);
  1282. ArgTableEl := CreateTable(Parent);
  1283. end;
  1284. TREl := CreateTR(ArgTableEl);
  1285. AppendText(CreateCode(CreatePara(CreateTD_vtop(TREl))), Arg.Name);
  1286. AppendShortDescrCell(TREl, Arg);
  1287. end;
  1288. if Element.ClassType = TPasFunctionType then
  1289. begin
  1290. ResultEl := TPasFunctionType(Element).ResultEl;
  1291. DocNode := Engine.FindDocNode(ResultEl);
  1292. HasFullDescr := Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr);
  1293. if HasFullDescr or
  1294. (Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.ShortDescr)) then
  1295. begin
  1296. AppendText(CreateH2(Parent), SDocFunctionResult);
  1297. if HasFullDescr then
  1298. AppendDescr(ResultEl, Parent, DocNode.Descr, True)
  1299. else
  1300. AppendDescr(ResultEl, CreatePara(Parent), DocNode.ShortDescr, False);
  1301. end;
  1302. end;
  1303. end;
  1304. procedure THTMLWriter.AppendTitle(const AText: DOMString);
  1305. begin
  1306. AppendText(TitleElement, AText);
  1307. AppendText(CreateH1(BodyElement), AText);
  1308. end;
  1309. procedure THTMLWriter.AppendMenuBar(ASubpageIndex: Integer);
  1310. var
  1311. TableEl, TREl, ParaEl, TitleEl: TDOMElement;
  1312. procedure AddLink(ALinkSubpageIndex: Integer; const AName: String);
  1313. begin
  1314. AppendText(ParaEl, '[');
  1315. if ALinkSubpageIndex = ASubpageIndex then
  1316. AppendText(ParaEl, AName)
  1317. else
  1318. AppendText(
  1319. CreateLink(ParaEl, ResolveLinkWithinPackage(Module, ALinkSubpageIndex)),
  1320. AName);
  1321. AppendText(ParaEl, ']');
  1322. end;
  1323. begin
  1324. TableEl := CreateEl(BodyElement, 'table');
  1325. TableEl['cellpadding'] := '4';
  1326. TableEl['cellspacing'] := '0';
  1327. TableEl['border'] := '0';
  1328. TableEl['width'] := '100%';
  1329. TableEl['class'] := 'bar';
  1330. TREl := CreateTR(TableEl);
  1331. ParaEl := CreateEl(CreateTD(TREl), 'b');
  1332. if Assigned(Module) then
  1333. begin
  1334. AddLink(0, SDocOverview);
  1335. if Module.InterfaceSection.ResStrings.Count > 0 then
  1336. AddLink(ResstrSubindex, SDocResStrings);
  1337. if Module.InterfaceSection.Consts.Count > 0 then
  1338. AddLink(ConstsSubindex, SDocConstants);
  1339. if Module.InterfaceSection.Types.Count > 0 then
  1340. AddLink(TypesSubindex, SDocTypes);
  1341. if Module.InterfaceSection.Classes.Count > 0 then
  1342. AddLink(ClassesSubindex, SDocClasses);
  1343. if Module.InterfaceSection.Functions.Count > 0 then
  1344. AddLink(ProcsSubindex, SDocProceduresAndFunctions);
  1345. if Module.InterfaceSection.Variables.Count > 0 then
  1346. AddLink(VarsSubindex, SDocVariables);
  1347. end;
  1348. if Length(SearchPage) > 0 then
  1349. begin
  1350. AppendText(ParaEl, '[');
  1351. AppendText(CreateLink(ParaEl, SearchPage), SDocSearch);
  1352. AppendText(ParaEl, ']');
  1353. end;
  1354. ParaEl := CreateTD(TREl);
  1355. ParaEl['align'] := 'right';
  1356. TitleEl := CreateEl(ParaEl, 'span');
  1357. TitleEl['class'] := 'bartitle';
  1358. if Assigned(Module) then
  1359. AppendText(TitleEl, Format(SDocUnitTitle, [Module.Name]));
  1360. if Assigned(Package) then
  1361. begin
  1362. AppendText(TitleEl, ' (');
  1363. AppendHyperlink(TitleEl, Package);
  1364. AppendText(TitleEl, ')');
  1365. end;
  1366. end;
  1367. procedure THTMLWriter.FinishElementPage(AElement: TPasElement);
  1368. var
  1369. DocNode: TDocNode;
  1370. IsFirstSeeAlso: Boolean;
  1371. Node: TDOMNode;
  1372. TableEl, El, TREl, TDEl, ParaEl, NewEl, DescrEl: TDOMElement;
  1373. s: String;
  1374. f: Text;
  1375. begin
  1376. DocNode := Engine.FindDocNode(AElement);
  1377. if Assigned(DocNode) and Assigned(DocNode.Descr) then
  1378. AppendDescrSection(AElement, BodyElement, DocNode.Descr, SDocDescription);
  1379. // ###
  1380. // Append "Errors" section
  1381. if Assigned(DocNode) and Assigned(DocNode.ErrorsDoc) then
  1382. AppendDescrSection(AElement, BodyElement, DocNode.ErrorsDoc, SDocErrors);
  1383. // Append "See also" section
  1384. if Assigned(DocNode) and Assigned(DocNode.SeeAlso) then
  1385. begin
  1386. IsFirstSeeAlso := True;
  1387. Node := DocNode.SeeAlso.FirstChild;
  1388. while Assigned(Node) do
  1389. begin
  1390. if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'link') then
  1391. begin
  1392. if IsFirstSeeAlso then
  1393. begin
  1394. IsFirstSeeAlso := False;
  1395. AppendText(CreateH2(BodyElement), SDocSeeAlso);
  1396. TableEl := CreateTable(BodyElement);
  1397. end;
  1398. El := TDOMElement(Node);
  1399. TREl := CreateTR(TableEl);
  1400. ParaEl := CreatePara(CreateTD_vtop(TREl));
  1401. s := ResolveLinkID(El['id']);
  1402. if Length(s) = 0 then
  1403. begin
  1404. WriteLn(Format(SErrUnknownLinkID, [El['id']]));
  1405. NewEl := CreateEl(ParaEl, 'b')
  1406. end else
  1407. NewEl := CreateLink(ParaEl, s);
  1408. AppendText(NewEl, El['id']);
  1409. DescrEl := Engine.FindShortDescr(AElement.GetModule, El['id']);
  1410. if Assigned(DescrEl) then
  1411. begin
  1412. AppendNbSp(CreatePara(CreateTD(TREl)), 2);
  1413. ParaEl := CreatePara(CreateTD(TREl));
  1414. ParaEl['class'] := 'cmt';
  1415. PushOutputNode(ParaEl);
  1416. try
  1417. ConvertShort(AElement, DescrEl);
  1418. finally
  1419. PopOutputNode;
  1420. end;
  1421. end;
  1422. end;
  1423. Node := Node.NextSibling;
  1424. end;
  1425. end;
  1426. // Append examples, if present
  1427. if Assigned(DocNode) and Assigned(DocNode.FirstExample) then
  1428. begin
  1429. Node := DocNode.FirstExample;
  1430. while Assigned(Node) do
  1431. begin
  1432. if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'example') then
  1433. begin
  1434. AppendText(CreateH2(BodyElement), SDocExample);
  1435. try
  1436. Assign(f, Engine.GetExampleFilename(TDOMElement(Node)));
  1437. Reset(f);
  1438. try
  1439. PushOutputNode(BodyElement);
  1440. DescrBeginCode(False, TDOMElement(Node)['highlighter']);
  1441. while not EOF(f) do
  1442. begin
  1443. ReadLn(f, s);
  1444. DescrWriteCodeLine(s);
  1445. end;
  1446. DescrEndCode;
  1447. PopOutputNode;
  1448. finally
  1449. Close(f);
  1450. end;
  1451. except
  1452. on e: Exception do
  1453. begin
  1454. e.Message := '[example] ' + e.Message;
  1455. raise;
  1456. end;
  1457. end;
  1458. end;
  1459. Node := Node.NextSibling;
  1460. end;
  1461. end;
  1462. end;
  1463. procedure THTMLWriter.CreatePageBody(AElement: TPasElement;
  1464. ASubpageIndex: Integer);
  1465. var
  1466. i: Integer;
  1467. Element: TPasElement;
  1468. begin
  1469. CurDirectory := Allocator.GetFilename(AElement, ASubpageIndex);
  1470. i := Length(CurDirectory);
  1471. while (i > 0) and not (CurDirectory[i] in DirSeparators) do
  1472. Dec(i);
  1473. CurDirectory := Copy(CurDirectory, 1, i);
  1474. BaseDirectory := Allocator.GetRelativePathToTop(AElement);
  1475. if AElement.ClassType = TPasPackage then
  1476. CreatePackagePageBody
  1477. else
  1478. begin
  1479. Element := AElement;
  1480. while Element.ClassType <> TPasModule do
  1481. Element := Element.Parent;
  1482. Module := TPasModule(Element);
  1483. if AElement.ClassType = TPasModule then
  1484. CreateModulePageBody(TPasModule(AElement), ASubpageIndex)
  1485. else if AElement.Parent.InheritsFrom(TPasClassType) then
  1486. CreateClassMemberPageBody(AElement)
  1487. else if AElement.ClassType = TPasConst then
  1488. CreateConstPageBody(TPasConst(AElement))
  1489. else if AElement.InheritsFrom(TPasClassType) then
  1490. CreateClassPageBody(TPasClassType(AElement), ASubpageIndex)
  1491. else if AElement.InheritsFrom(TPasType) then
  1492. CreateTypePageBody(TPasType(AElement))
  1493. else if AElement.ClassType = TPasVariable then
  1494. CreateVarPageBody(TPasVariable(AElement))
  1495. else if AElement.InheritsFrom(TPasProcedureBase) then
  1496. CreateProcPageBody(TPasProcedure(AElement));
  1497. end;
  1498. end;
  1499. procedure THTMLWriter.CreatePackagePageBody;
  1500. var
  1501. DocNode: TDocNode;
  1502. TableEl, TREl: TDOMElement;
  1503. i: Integer;
  1504. ThisModule: TPasModule;
  1505. begin
  1506. AppendMenuBar(0);
  1507. AppendTitle(Format(SDocPackageTitle, [Copy(Package.Name, 2, 256)]));
  1508. AppendShortDescr(CreatePara(BodyElement), Package);
  1509. AppendText(CreateH2(BodyElement), SDocUnits);
  1510. TableEl := CreateTable(BodyElement);
  1511. for i := 0 to Package.Modules.Count - 1 do
  1512. begin
  1513. ThisModule := TPasModule(Package.Modules[i]);
  1514. TREl := CreateTR(TableEl);
  1515. AppendHyperlink(CreateCode(CreatePara(CreateTD_vtop(TREl))), ThisModule);
  1516. AppendShortDescrCell(TREl, ThisModule);
  1517. end;
  1518. DocNode := Engine.FindDocNode(Package);
  1519. if Assigned(DocNode) and Assigned(DocNode.Descr) then
  1520. AppendDescrSection(nil, BodyElement, DocNode.Descr, SDocDescription);
  1521. end;
  1522. procedure THTMLWriter.CreateModulePageBody(AModule: TPasModule;
  1523. ASubpageIndex: Integer);
  1524. procedure CreateMainPage;
  1525. var
  1526. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  1527. i: Integer;
  1528. UnitRef: TPasType;
  1529. DocNode: TDocNode;
  1530. begin
  1531. AppendMenuBar(0);
  1532. AppendTitle(Format(SDocUnitTitle, [AModule.Name]));
  1533. AppendShortDescr(CreatePara(BodyElement), AModule);
  1534. if AModule.InterfaceSection.UsesList.Count > 0 then
  1535. begin
  1536. TableEl := CreateTable(BodyElement);
  1537. AppendKw(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), 'uses');
  1538. for i := 0 to AModule.InterfaceSection.UsesList.Count - 1 do
  1539. begin
  1540. UnitRef := TPasType(AModule.InterfaceSection.UsesList[i]);
  1541. DocNode := Engine.FindDocNode(UnitRef);
  1542. if Assigned(DocNode) and DocNode.IsSkipped then
  1543. continue;
  1544. TREl := CreateTR(TableEl);
  1545. TDEl := CreateTD_vtop(TREl);
  1546. CodeEl := CreateCode(CreatePara(TDEl));
  1547. AppendNbSp(CodeEl, 2);
  1548. AppendHyperlink(CodeEl, UnitRef);
  1549. if i < AModule.InterfaceSection.UsesList.Count - 1 then
  1550. AppendSym(CodeEl, ',')
  1551. else
  1552. AppendSym(CodeEl, ';');
  1553. AppendText(CodeEl, ' '); // Space for descriptions
  1554. AppendShortDescrCell(TREl, UnitRef);
  1555. end;
  1556. end;
  1557. DocNode := Engine.FindDocNode(AModule);
  1558. if Assigned(DocNode) and Assigned(DocNode.Descr) then
  1559. AppendDescrSection(AModule, BodyElement, DocNode.Descr, SDocOverview);
  1560. end;
  1561. procedure CreateSimpleSubpage(const ATitle: DOMString; AList: TList);
  1562. var
  1563. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  1564. i, j: Integer;
  1565. Decl: TPasElement;
  1566. SortedList: TList;
  1567. DocNode: TDocNode;
  1568. begin
  1569. AppendMenuBar(ASubpageIndex);
  1570. AppendTitle(Format(SDocUnitTitle + ': %s', [AModule.Name, ATitle]));
  1571. SortedList := TList.Create;
  1572. try
  1573. for i := 0 to AList.Count - 1 do
  1574. begin
  1575. Decl := TPasElement(AList[i]);
  1576. DocNode := Engine.FindDocNode(Decl);
  1577. if (not Assigned(DocNode)) or (not DocNode.IsSkipped) then
  1578. begin
  1579. j := 0;
  1580. while (j < SortedList.Count) and (CompareText(
  1581. TPasElement(SortedList[j]).PathName, Decl.PathName) < 0) do
  1582. Inc(j);
  1583. SortedList.Insert(j, Decl);
  1584. end;
  1585. end;
  1586. TableEl := CreateTable(BodyElement);
  1587. for i := 0 to SortedList.Count - 1 do
  1588. begin
  1589. Decl := TPasElement(SortedList[i]);
  1590. TREl := CreateTR(TableEl);
  1591. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1592. AppendHyperlink(CodeEl, Decl);
  1593. AppendShortDescrCell(TREl, Decl);
  1594. end;
  1595. finally
  1596. SortedList.Free;
  1597. end;
  1598. end;
  1599. procedure CreateResStringsPage;
  1600. var
  1601. ParaEl: TDOMElement;
  1602. i, j: Integer;
  1603. Decl: TPasResString;
  1604. DocNode: TDocNode;
  1605. begin
  1606. AppendMenuBar(ResstrSubindex);
  1607. AppendTitle(Format(SDocUnitTitle + ': %s', [AModule.Name, SDocResStrings]));
  1608. for i := 0 to AModule.InterfaceSection.ResStrings.Count - 1 do
  1609. begin
  1610. Decl := TPasResString(AModule.InterfaceSection.ResStrings[i]);
  1611. CreateEl(BodyElement, 'a')['name'] := LowerCase(Decl.Name);
  1612. ParaEl := CreatePara(BodyElement);
  1613. AppendText(CreateCode(ParaEl), Decl.Name);
  1614. CreateEl(ParaEl, 'br');
  1615. AppendText(ParaEl, Decl.Value);
  1616. end;
  1617. end;
  1618. begin
  1619. case ASubpageIndex of
  1620. 0:
  1621. CreateMainPage;
  1622. ResstrSubindex:
  1623. CreateResStringsPage;
  1624. ConstsSubindex:
  1625. CreateSimpleSubpage(SDocConstants, AModule.InterfaceSection.Consts);
  1626. TypesSubindex:
  1627. CreateSimpleSubpage(SDocTypes, AModule.InterfaceSection.Types);
  1628. ClassesSubindex:
  1629. CreateSimpleSubpage(SDocClasses, AModule.InterfaceSection.Classes);
  1630. ProcsSubindex:
  1631. CreateSimpleSubpage(SDocProceduresAndFunctions, AModule.InterfaceSection.Functions);
  1632. VarsSubindex:
  1633. CreateSimpleSubpage(SDocVariables, AModule.InterfaceSection.Variables);
  1634. end;
  1635. end;
  1636. procedure THTMLWriter.CreateConstPageBody(AConst: TPasConst);
  1637. var
  1638. TableEl, CodeEl: TDOMElement;
  1639. begin
  1640. AppendMenuBar(-1);
  1641. AppendTitle(AConst.Name);
  1642. AppendShortDescr(CreatePara(BodyElement), AConst);
  1643. AppendText(CreateH2(BodyElement), SDocDeclaration);
  1644. TableEl := CreateTable(BodyElement);
  1645. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1646. AppendKw(CodeEl, 'const');
  1647. AppendText(CodeEl, ' ' + AConst.Name);
  1648. if Assigned(AConst.VarType) then
  1649. begin
  1650. AppendSym(CodeEl, ': ');
  1651. AppendType(CodeEl, TableEl, AConst.VarType, False);
  1652. end;
  1653. AppendPasSHFragment(CodeEl, ' = ' + AConst.Value + ';', 0);
  1654. FinishElementPage(AConst);
  1655. end;
  1656. procedure THTMLWriter.CreateTypePageBody(AType: TPasType);
  1657. var
  1658. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  1659. DocNode: TDocNode;
  1660. i: Integer;
  1661. s: String;
  1662. EnumType: TPasEnumType;
  1663. EnumValue: TPasEnumValue;
  1664. Variable: TPasVariable;
  1665. begin
  1666. AppendMenuBar(-1);
  1667. AppendTitle(AType.Name);
  1668. AppendShortDescr(CreatePara(BodyElement), AType);
  1669. AppendText(CreateH2(BodyElement), SDocDeclaration);
  1670. TableEl := CreateTable(BodyElement);
  1671. TREl := CreateTR(TableEl);
  1672. TDEl := CreateTD(TREl);
  1673. CodeEl := CreateCode(CreatePara(TDEl));
  1674. AppendKw(CodeEl, 'type ');
  1675. AppendText(CodeEl, AType.Name);
  1676. AppendSym(CodeEl, ' = ');
  1677. // Alias
  1678. if AType.ClassType = TPasAliasType then
  1679. begin
  1680. if Assigned(TPasAliasType(AType).DestType) then
  1681. AppendHyperlink(CodeEl, TPasAliasType(AType).DestType)
  1682. else
  1683. AppendText(CreateWarning(CodeEl), '<Destination type is NIL>');
  1684. AppendSym(CodeEl, ';');
  1685. end else
  1686. // Class of
  1687. if AType.ClassType = TPasClassOfType then
  1688. begin
  1689. AppendKw(CodeEl, 'class of ');
  1690. AppendHyperlink(CodeEl, TPasClassOfType(AType).DestType);
  1691. AppendSym(CodeEl, ';');
  1692. end else
  1693. // Enumeration
  1694. if AType.ClassType = TPasEnumType then
  1695. begin
  1696. AppendSym(CodeEl, '(');
  1697. for i := 0 to TPasEnumType(AType).Values.Count - 1 do
  1698. begin
  1699. EnumValue := TPasEnumValue(TPasEnumType(AType).Values[i]);
  1700. TREl := CreateTR(TableEl);
  1701. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1702. AppendShortDescrCell(TREl, EnumValue);
  1703. AppendNbSp(CodeEl, 2);
  1704. s := EnumValue.Name;
  1705. if EnumValue.IsValueUsed then
  1706. s := s + ' = ' + IntToStr(EnumValue.Value);
  1707. if i < TPasEnumType(AType).Values.Count - 1 then
  1708. s := s + ',';
  1709. AppendPasSHFragment(CodeEl, s, 0);
  1710. end;
  1711. AppendSym(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), ');');
  1712. end else
  1713. // Pointer type
  1714. if AType.ClassType = TPasPointerType then
  1715. begin
  1716. AppendSym(CodeEl, '^');
  1717. if Assigned(TPasPointerType(AType).DestType) then
  1718. AppendHyperlink(CodeEl, TPasPointerType(AType).DestType)
  1719. else
  1720. AppendText(CreateWarning(CodeEl), '<Destination type is NIL>');
  1721. AppendSym(CodeEl, ';');
  1722. end else
  1723. if AType.InheritsFrom(TPasProcedureType) then
  1724. begin
  1725. AppendSym(AppendType(CodeEl, TableEl, TPasType(AType), True), ';');
  1726. AppendProcArgsSection(BodyElement, TPasProcedureType(AType));
  1727. end else
  1728. // Record
  1729. if AType.ClassType = TPasRecordType then
  1730. begin
  1731. if TPasRecordType(AType).IsPacked then
  1732. AppendKw(CodeEl, 'packed record')
  1733. else
  1734. AppendKw(CodeEl, 'record');
  1735. for i := 0 to TPasRecordType(AType).Members.Count - 1 do
  1736. begin
  1737. Variable := TPasVariable(TPasRecordType(AType).Members[i]);
  1738. TREl := CreateTR(TableEl);
  1739. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1740. AppendShortDescrCell(TREl, Variable);
  1741. AppendNbSp(CodeEl, 2);
  1742. AppendText(CodeEl, Variable.Name);
  1743. AppendSym(CodeEl, ': ');
  1744. AppendType(CodeEl, TableEl, Variable.VarType, False);
  1745. AppendSym(CodeEl, ';');
  1746. end;
  1747. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1748. AppendText(CodeEl, ' '); // !!!: Dirty trick, necessary for current XML writer
  1749. AppendKw(CodeEl, 'end');
  1750. AppendSym(CodeEl, ';');
  1751. end else
  1752. // Set
  1753. if AType.ClassType = TPasSetType then
  1754. begin
  1755. AppendKw(CodeEl, 'set of ');
  1756. if TPasSetType(AType).EnumType.ClassType = TPasEnumType then
  1757. begin
  1758. AppendSym(CodeEl, '(');
  1759. EnumType := TPasEnumType(TPasSetType(AType).EnumType);
  1760. for i := 0 to EnumType.Values.Count - 1 do
  1761. begin
  1762. EnumValue := TPasEnumValue(EnumType.Values[i]);
  1763. TREl := CreateTR(TableEl);
  1764. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1765. AppendShortDescrCell(TREl, EnumValue);
  1766. AppendNbSp(CodeEl, 2);
  1767. s := EnumValue.Name;
  1768. if EnumValue.IsValueUsed then
  1769. s := s + ' = ' + IntToStr(EnumValue.Value);
  1770. if i < EnumType.Values.Count - 1 then
  1771. s := s + ',';
  1772. AppendPasSHFragment(CodeEl, s, 0);
  1773. end;
  1774. AppendSym(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), ');');
  1775. end else
  1776. begin
  1777. AppendHyperlink(CodeEl, TPasSetType(AType).EnumType);
  1778. AppendSym(CodeEl, ';');
  1779. end;
  1780. end else
  1781. // Type alias
  1782. if AType.ClassType = TPasTypeAliasType then
  1783. begin
  1784. AppendKw(CodeEl, 'type ');
  1785. AppendHyperlink(CodeEl, TPasTypeAliasType(AType).DestType);
  1786. AppendSym(CodeEl, ';');
  1787. end else
  1788. // Probably one of the simple types, which allowed in other places as wel...
  1789. AppendSym(AppendType(CodeEl, TableEl, TPasType(AType), True), ';');
  1790. FinishElementPage(AType);
  1791. end;
  1792. function PropertyFilter(AMember: TPasElement): Boolean;
  1793. begin
  1794. Result := (AMember.ClassType = TPasProperty) and
  1795. (Copy(AMember.Name, 1, 2) <> 'On');
  1796. end;
  1797. function MethodFilter(AMember: TPasElement): Boolean;
  1798. begin
  1799. Result := AMember.InheritsFrom(TPasProcedureBase);
  1800. end;
  1801. function EventFilter(AMember: TPasElement): Boolean;
  1802. begin
  1803. Result := (AMember.ClassType = TPasProperty) and
  1804. (Copy(AMember.Name, 1, 2) = 'On');
  1805. end;
  1806. procedure THTMLWriter.CreateClassPageBody(AClass: TPasClassType;
  1807. ASubpageIndex: Integer);
  1808. type
  1809. TMemberFilter = function(AMember: TPasElement): Boolean;
  1810. var
  1811. ParaEl: TDOMElement;
  1812. procedure AppendMemberListLink(AListSubpageIndex: Integer;
  1813. const AText: DOMString);
  1814. var
  1815. LinkEl: TDOMElement;
  1816. begin
  1817. AppendText(ParaEl, '[');
  1818. LinkEl := CreateEl(ParaEl, 'a');
  1819. LinkEl['href'] :=
  1820. ResolveLinkWithinPackage(AClass, AListSubpageIndex);
  1821. LinkEl['onClick'] := 'window.open(''' + LinkEl['href'] + ''', ''list'', ' +
  1822. '''dependent=yes,resizable=yes,scrollbars=yes,height=400,width=300''); return false;';
  1823. AppendText(LinkEl, AText);
  1824. AppendText(ParaEl, ' (');
  1825. LinkEl := CreateEl(ParaEl, 'a');
  1826. LinkEl['href'] :=
  1827. ResolveLinkWithinPackage(AClass, AListSubpageIndex + 1);
  1828. LinkEl['onClick'] := 'window.open(''' + LinkEl['href'] + ''', ''list'', ' +
  1829. '''dependent=yes,resizable=yes,scrollbars=yes,height=400,width=300''); return false;';
  1830. AppendText(LinkEl, SDocByName);
  1831. AppendText(ParaEl, ')');
  1832. AppendText(ParaEl, '] ');
  1833. end;
  1834. procedure CreateMainPage;
  1835. var
  1836. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  1837. DocNode: TDocNode;
  1838. Member: TPasElement;
  1839. CurVisibility: TPasMemberVisibility;
  1840. i: Integer;
  1841. s: String;
  1842. ThisClass: TPasClassType;
  1843. HaveSeenTObject: Boolean;
  1844. begin
  1845. AppendMenuBar(-1);
  1846. AppendTitle(AClass.Name);
  1847. ParaEl := CreatePara(BodyElement);
  1848. AppendMemberListLink(PropertiesByInheritanceSubindex, SDocProperties);
  1849. AppendMemberListLink(MethodsByInheritanceSubindex, SDocMethods);
  1850. AppendMemberListLink(EventsByInheritanceSubindex, SDocEvents);
  1851. AppendShortDescr(CreatePara(BodyElement), AClass);
  1852. AppendText(CreateH2(BodyElement), SDocDeclaration);
  1853. TableEl := CreateTable(BodyElement);
  1854. TREl := CreateTR(TableEl);
  1855. TDEl := CreateTD(TREl);
  1856. CodeEl := CreateCode(CreatePara(TDEl));
  1857. AppendKw(CodeEl, 'type');
  1858. AppendText(CodeEl, ' ' + AClass.Name + ' ');
  1859. AppendSym(CodeEl, '=');
  1860. AppendText(CodeEl, ' ');
  1861. AppendKw(CodeEl, ObjKindNames[AClass.ObjKind]);
  1862. if Assigned(AClass.AncestorType) then
  1863. begin
  1864. AppendSym(CodeEl, '(');
  1865. AppendHyperlink(CodeEl, AClass.AncestorType);
  1866. AppendSym(CodeEl, ')');
  1867. end;
  1868. if AClass.Members.Count > 0 then
  1869. begin
  1870. CurVisibility := visDefault;
  1871. for i := 0 to AClass.Members.Count - 1 do
  1872. begin
  1873. Member := TPasElement(AClass.Members[i]);
  1874. if CurVisibility <> Member.Visibility then
  1875. begin
  1876. CurVisibility := Member.Visibility;
  1877. if ((CurVisibility = visPrivate) and Engine.HidePrivate) or
  1878. ((CurVisibility = visProtected) and Engine.HideProtected) then
  1879. continue;
  1880. case CurVisibility of
  1881. visPrivate: s := 'private';
  1882. visProtected: s := 'protected';
  1883. visPublic: s := 'public';
  1884. visPublished: s := 'published';
  1885. visAutomated: s := 'automated';
  1886. end;
  1887. AppendKw(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), s);
  1888. end else
  1889. if ((CurVisibility = visPrivate) and Engine.HidePrivate) or
  1890. ((CurVisibility = visProtected) and Engine.HideProtected) then
  1891. continue;
  1892. TREl := CreateTR(TableEl);
  1893. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1894. AppendNbSp(CodeEl, 2);
  1895. AppendShortDescrCell(TREl, Member);
  1896. if Member.InheritsFrom(TPasProcedureBase) then
  1897. begin
  1898. AppendKw(CodeEl, TPasProcedureBase(Member).TypeName + ' ');
  1899. AppendHyperlink(CodeEl, Member);
  1900. if (Member.ClassType = TPasOverloadedProc) or
  1901. (TPasProcedure(Member).ProcType.Args.Count > 0) then
  1902. AppendSym(CodeEl, '();')
  1903. else
  1904. AppendSym(CodeEl, ';');
  1905. if Member.ClassType <> TPasOverloadedProc then
  1906. AppendProcExt(CodeEl, TPasProcedure(Member));
  1907. end else
  1908. if Member.ClassType = TPasVariable then
  1909. begin
  1910. AppendHyperlink(CodeEl, Member);
  1911. AppendSym(CodeEl, ': ');
  1912. AppendHyperlink(CodeEl, TPasVariable(Member).VarType);
  1913. AppendSym(CodeEl, ';');
  1914. end else
  1915. if Member.ClassType = TPasProperty then
  1916. begin
  1917. AppendKw(CodeEl, 'property ');
  1918. AppendHyperlink(CodeEl, Member);
  1919. if Assigned(TPasProperty(Member).VarType) then
  1920. begin
  1921. AppendSym(CodeEl, ': ');
  1922. AppendHyperlink(CodeEl, TPasProperty(Member).VarType);
  1923. end;
  1924. AppendSym(CodeEl, ';');
  1925. if TPasProperty(Member).IsDefault then
  1926. begin
  1927. AppendKw(CodeEl, ' default');
  1928. AppendSym(CodeEl, ';');
  1929. end;
  1930. SetLength(s, 0);
  1931. if Length(TPasProperty(Member).ReadAccessorName) > 0 then
  1932. s := s + 'r';
  1933. if Length(TPasProperty(Member).WriteAccessorName) > 0 then
  1934. s := s + 'w';
  1935. if Length(TPasProperty(Member).StoredAccessorName) > 0 then
  1936. s := s + 's';
  1937. if Length(s) > 0 then
  1938. AppendText(CodeEl, ' [' + s + ']');
  1939. end else
  1940. AppendText(CreateWarning(CodeEl), '<' + Member.ClassName + '>');
  1941. end;
  1942. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1943. end;
  1944. AppendText(CodeEl, ' '); // !!!: Dirty trick, necessary for current XML writer
  1945. AppendKw(CodeEl, 'end');
  1946. AppendSym(CodeEl, ';');
  1947. AppendText(CreateH2(BodyElement), SDocInheritance);
  1948. TableEl := CreateTable(BodyElement);
  1949. HaveSeenTObject := AClass.ObjKind <> okClass;
  1950. ThisClass := AClass;
  1951. while True do
  1952. begin
  1953. TREl := CreateTR(TableEl);
  1954. TDEl := CreateTD_vtop(TREl);
  1955. TDEl['align'] := 'center';
  1956. CodeEl := CreateCode(CreatePara(TDEl));
  1957. AppendHyperlink(CodeEl, ThisClass);
  1958. AppendShortDescrCell(TREl, ThisClass);
  1959. if HaveSeenTObject or (CompareText(ThisClass.Name, 'TObject') = 0) then
  1960. HaveSeenTObject := True
  1961. else
  1962. begin
  1963. TDEl := CreateTD(CreateTR(TableEl));
  1964. TDEl['align'] := 'center';
  1965. AppendText(TDEl, '|');
  1966. end;
  1967. if Assigned(ThisClass.AncestorType) then
  1968. begin
  1969. if ThisClass.AncestorType.InheritsFrom(TPasClassType) then
  1970. ThisClass := TPasClassType(ThisClass.AncestorType)
  1971. else
  1972. begin
  1973. TDEl := CreateTD(CreateTR(TableEl));
  1974. TDEl['align'] := 'center';
  1975. AppendText(CreateCode(CreatePara(TDEl)), ThisClass.AncestorType.Name);
  1976. if CompareText(ThisClass.AncestorType.Name, 'TObject') = 0 then
  1977. HaveSeenTObject := True
  1978. else
  1979. begin
  1980. TDEl := CreateTD(CreateTR(TableEl));
  1981. TDEl['align'] := 'center';
  1982. AppendText(TDEl, '?');
  1983. end;
  1984. break;
  1985. end
  1986. end else
  1987. break;
  1988. end;
  1989. if not HaveSeenTObject then
  1990. begin
  1991. TDEl := CreateTD(CreateTR(TableEl));
  1992. TDEl['align'] := 'center';
  1993. AppendText(CreateCode(CreatePara(TDEl)), 'TObject');
  1994. end;
  1995. FinishElementPage(AClass);
  1996. end;
  1997. procedure CreateInheritanceSubpage(AFilter: TMemberFilter);
  1998. var
  1999. ThisClass: TPasClassType;
  2000. i: Integer;
  2001. Member: TPasElement;
  2002. TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
  2003. begin
  2004. TableEl := CreateTable(BodyElement);
  2005. ThisClass := AClass;
  2006. while True do
  2007. begin
  2008. TREl := CreateTR(TableEl);
  2009. TDEl := CreateTD(TREl);
  2010. TDEl['colspan'] := '3';
  2011. CreateTD(TREl);
  2012. LinkEl := AppendHyperlink(CreateEl(CreateCode(CreatePara(TDEl)), 'b'), ThisClass);
  2013. if Assigned(LinkEl) then
  2014. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2015. '''; return false;';
  2016. for i := 0 to ThisClass.Members.Count - 1 do
  2017. begin
  2018. Member := TPasElement(ThisClass.Members[i]);
  2019. if ((Member.Visibility = visPrivate) and Engine.HidePrivate) or
  2020. ((Member.Visibility = visProtected) and Engine.HideProtected) or
  2021. not AFilter(Member) then
  2022. continue;
  2023. TREl := CreateTR(TableEl);
  2024. ParaEl := CreatePara(CreateTD(TREl));
  2025. case Member.Visibility of
  2026. visPrivate:
  2027. AppendText(ParaEl, 'pv');
  2028. visProtected:
  2029. AppendText(ParaEl, 'pt');
  2030. visPublished:
  2031. AppendText(ParaEl, 'pl');
  2032. end;
  2033. AppendNbSp(ParaEl, 1);
  2034. ParaEl := CreateTD(TREl);
  2035. if (Member.ClassType = TPasProperty) and
  2036. (Length(TPasProperty(Member).WriteAccessorName) = 0) then
  2037. begin
  2038. AppendText(ParaEl, 'ro');
  2039. AppendNbSp(ParaEl, 1);
  2040. end;
  2041. LinkEl := AppendHyperlink(CreatePara(CreateTD(TREl)), Member);
  2042. if Assigned(LinkEl) then
  2043. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2044. '''; return false;';
  2045. end;
  2046. if (not Assigned(ThisClass.AncestorType)) or
  2047. (not (ThisClass.AncestorType.ClassType = TPasClassType)) then
  2048. break;
  2049. ThisClass := TPasClassType(ThisClass.AncestorType);
  2050. AppendNbSp(CreatePara(CreateTD(CreateTR(TableEl))), 1);
  2051. end;
  2052. end;
  2053. procedure CreateSortedSubpage(AFilter: TMemberFilter);
  2054. var
  2055. List: TList;
  2056. ThisClass: TPasClassType;
  2057. i, j: Integer;
  2058. Member: TPasElement;
  2059. TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
  2060. begin
  2061. List := TList.Create;
  2062. try
  2063. ThisClass := AClass;
  2064. while True do
  2065. begin
  2066. for i := 0 to ThisClass.Members.Count - 1 do
  2067. begin
  2068. Member := TPasElement(ThisClass.Members[i]);
  2069. if (not (((Member.Visibility = visPrivate) and Engine.HidePrivate) or
  2070. ((Member.Visibility = visProtected) and Engine.HideProtected))) and
  2071. AFilter(Member) then
  2072. begin
  2073. j := 0;
  2074. while (j < List.Count) and
  2075. (CompareText(TPasElement(List[j]).Name, Member.Name) < 0) do
  2076. Inc(j);
  2077. List.Insert(j, Member);
  2078. end;
  2079. end;
  2080. if (not Assigned(ThisClass.AncestorType)) or
  2081. (not (ThisClass.AncestorType.ClassType = TPasClassType)) then
  2082. break;
  2083. ThisClass := TPasClassType(ThisClass.AncestorType);
  2084. end;
  2085. TableEl := CreateTable(BodyElement);
  2086. for i := 0 to List.Count - 1 do
  2087. begin
  2088. Member := TPasElement(List[i]);
  2089. TREl := CreateTR(TableEl);
  2090. ParaEl := CreatePara(CreateTD(TREl));
  2091. case Member.Visibility of
  2092. visPrivate:
  2093. AppendText(ParaEl, 'pv');
  2094. visProtected:
  2095. AppendText(ParaEl, 'pt');
  2096. visPublished:
  2097. AppendText(ParaEl, 'pl');
  2098. end;
  2099. AppendNbSp(ParaEl, 1);
  2100. ParaEl := CreatePara(CreateTD(TREl));
  2101. if (Member.ClassType = TPasProperty) and
  2102. (Length(TPasProperty(Member).WriteAccessorName) = 0) then
  2103. begin
  2104. AppendText(ParaEl, 'ro');
  2105. AppendNbSp(ParaEl, 1);
  2106. end;
  2107. TDEl := CreateTD(TREl);
  2108. TDEl['nowrap'] := 'nowrap';
  2109. ParaEl := CreatePara(TDEl);
  2110. LinkEl := AppendHyperlink(ParaEl, Member);
  2111. if Assigned(LinkEl) then
  2112. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2113. '''; return false;';
  2114. AppendText(ParaEl, ' (');
  2115. LinkEl := AppendHyperlink(ParaEl, Member.Parent);
  2116. if Assigned(LinkEl) then
  2117. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2118. '''; return false;';
  2119. AppendText(ParaEl, ')');
  2120. end;
  2121. finally
  2122. List.Free;
  2123. end;
  2124. end;
  2125. begin
  2126. case ASubpageIndex of
  2127. 0:
  2128. CreateMainPage;
  2129. PropertiesByInheritanceSubindex:
  2130. CreateInheritanceSubpage(@PropertyFilter);
  2131. PropertiesByNameSubindex:
  2132. CreateSortedSubpage(@PropertyFilter);
  2133. MethodsByInheritanceSubindex:
  2134. CreateInheritanceSubpage(@MethodFilter);
  2135. MethodsByNameSubindex:
  2136. CreateSortedSubpage(@MethodFilter);
  2137. EventsByInheritanceSubindex:
  2138. CreateInheritanceSubpage(@EventFilter);
  2139. EventsByNameSubindex:
  2140. CreateSortedSubpage(@EventFilter);
  2141. end;
  2142. end;
  2143. procedure THTMLWriter.CreateClassMemberPageBody(AElement: TPasElement);
  2144. var
  2145. TableEl, TREl, CodeEl: TDOMElement;
  2146. procedure CreateVarPage(Element: TPasVariable);
  2147. begin
  2148. AppendHyperlink(CodeEl, Element.Parent);
  2149. AppendSym(CodeEl, '.');
  2150. AppendText(CodeEl, Element.Name);
  2151. if Assigned(Element.VarType) then
  2152. begin
  2153. AppendSym(CodeEl, ': ');
  2154. AppendSym(AppendType(CodeEl, TableEl, Element.VarType, False), ';');
  2155. end;
  2156. end;
  2157. procedure CreatePropertyPage(Element: TPasProperty);
  2158. var
  2159. NeedBreak: Boolean;
  2160. begin
  2161. AppendKw(CodeEl, 'property ');
  2162. AppendHyperlink(CodeEl, Element.Parent);
  2163. AppendSym(CodeEl, '.');
  2164. AppendText(CodeEl, Element.Name);
  2165. if Assigned(Element.VarType) then
  2166. begin
  2167. AppendSym(CodeEl, ': ');
  2168. AppendType(CodeEl, TableEl, Element.VarType, False);
  2169. end;
  2170. NeedBreak := False;
  2171. if Length(TPasProperty(Element).IndexValue) <> 0 then
  2172. begin
  2173. CreateEl(CodeEl, 'br');
  2174. AppendNbsp(CodeEl, 2);
  2175. AppendKw(CodeEl, 'index ');
  2176. AppendPasSHFragment(CodeEl, TPasProperty(Element).IndexValue, 0);
  2177. NeedBreak := True;
  2178. end;
  2179. if Length(TPasProperty(Element).ReadAccessorName) <> 0 then
  2180. begin
  2181. CreateEl(CodeEl, 'br');
  2182. AppendNbsp(CodeEl, 2);
  2183. AppendKw(CodeEl, 'read ');
  2184. AppendText(CodeEl, TPasProperty(Element).ReadAccessorName);
  2185. NeedBreak := True;
  2186. end;
  2187. if Length(TPasProperty(Element).WriteAccessorName) <> 0 then
  2188. begin
  2189. CreateEl(CodeEl, 'br');
  2190. AppendNbsp(CodeEl, 2);
  2191. AppendKw(CodeEl, 'write ');
  2192. AppendText(CodeEl, TPasProperty(Element).WriteAccessorName);
  2193. NeedBreak := True;
  2194. end;
  2195. if Length(TPasProperty(Element).StoredAccessorName) <> 0 then
  2196. begin
  2197. CreateEl(CodeEl, 'br');
  2198. AppendNbsp(CodeEl, 2);
  2199. AppendKw(CodeEl, 'stored ');
  2200. AppendText(CodeEl, TPasProperty(Element).StoredAccessorName);
  2201. NeedBreak := True;
  2202. end;
  2203. if Length(TPasProperty(Element).DefaultValue) <> 0 then
  2204. begin
  2205. CreateEl(CodeEl, 'br');
  2206. AppendNbsp(CodeEl, 2);
  2207. AppendKw(CodeEl, 'default ');
  2208. AppendPasSHFragment(CodeEl, TPasProperty(Element).DefaultValue, 0);
  2209. NeedBreak := True;
  2210. end;
  2211. AppendSym(CodeEl, ';');
  2212. if TPasProperty(Element).IsDefault or TPasProperty(Element).IsNodefault then
  2213. begin
  2214. if NeedBreak then
  2215. begin
  2216. CreateEl(CodeEl, 'br');
  2217. AppendNbsp(CodeEl, 2);
  2218. end;
  2219. if TPasProperty(Element).IsDefault then
  2220. AppendKw(CodeEl, 'default')
  2221. else
  2222. AppendKw(CodeEl, 'nodefault');
  2223. AppendSym(CodeEl, ';');
  2224. end;
  2225. end;
  2226. var
  2227. s: String;
  2228. DocNode: TDocNode;
  2229. begin
  2230. AppendMenuBar(-1);
  2231. AppendTitle(AElement.FullName);
  2232. AppendShortDescr(CreatePara(BodyElement), AElement);
  2233. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2234. TableEl := CreateTable(BodyElement);
  2235. TREl := CreateTR(TableEl);
  2236. CodeEl := CreateCode(CreatePara(CreateTD(TREl)));
  2237. AppendText(CodeEl, ' '); // !!!: Workaround for current HTML writer
  2238. case AElement.Visibility of
  2239. visPrivate: s := 'private';
  2240. visProtected: s := 'protected';
  2241. visPublic: s := 'public';
  2242. visPublished: s := 'published';
  2243. visAutomated: s := 'automated';
  2244. else s := '';
  2245. end;
  2246. if Length(s) > 0 then
  2247. AppendKw(CodeEl, s);
  2248. AppendText(CodeEl, ' ');
  2249. if AElement.ClassType = TPasVariable then
  2250. CreateVarPage(TPasVariable(AElement))
  2251. else if AElement.InheritsFrom(TPasProcedureBase) then
  2252. AppendProcDecl(CodeEl, TableEl, TPasProcedureBase(AElement))
  2253. else if AElement.ClassType = TPasProperty then
  2254. CreatePropertyPage(TPasProperty(AElement))
  2255. else
  2256. AppendText(CreateWarning(BodyElement), '<' + AElement.ClassName + '>');
  2257. FinishElementPage(AElement);
  2258. end;
  2259. procedure THTMLWriter.CreateVarPageBody(AVar: TPasVariable);
  2260. var
  2261. TableEl, TREl, TDEl, CodeEl, El: TDOMElement;
  2262. DocNode: TDocNode;
  2263. begin
  2264. AppendMenuBar(-1);
  2265. AppendTitle(AVar.FullName);
  2266. AppendShortDescr(CreatePara(BodyElement), AVar);
  2267. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2268. TableEl := CreateTable(BodyElement);
  2269. TREl := CreateTR(TableEl);
  2270. TDEl := CreateTD(TREl);
  2271. CodeEl := CreateCode(CreatePara(TDEl));
  2272. AppendKw(CodeEl, 'var');
  2273. AppendText(CodeEl, ' ' + AVar.Name);
  2274. if Assigned(AVar.VarType) then
  2275. begin
  2276. AppendSym(CodeEl, ': ');
  2277. El := AppendType(CodeEl, TableEl, AVar.VarType, False);
  2278. end else
  2279. El := CodeEl;
  2280. if Length(AVar.Value) > 0 then
  2281. AppendPasSHFragment(El, ' = ' + AVar.Value + ';', 0)
  2282. else
  2283. AppendSym(El, ';');
  2284. FinishElementPage(AVar);
  2285. end;
  2286. procedure THTMLWriter.CreateProcPageBody(AProc: TPasProcedureBase);
  2287. var
  2288. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  2289. begin
  2290. AppendMenuBar(-1);
  2291. AppendTitle(AProc.Name);
  2292. AppendShortDescr(CreatePara(BodyElement), AProc);
  2293. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2294. TableEl := CreateTable(BodyElement);
  2295. TREl := CreateTR(TableEl);
  2296. TDEl := CreateTD(TREl);
  2297. CodeEl := CreateCode(CreatePara(TDEl));
  2298. AppendProcDecl(CodeEl, TableEl, AProc);
  2299. FinishElementPage(AProc);
  2300. end;
  2301. // private methods
  2302. function THTMLWriter.GetPageCount: Integer;
  2303. begin
  2304. Result := PageInfos.Count;
  2305. end;
  2306. end.
  2307. {
  2308. $Log$
  2309. Revision 1.2 2003-03-18 19:28:44 michael
  2310. + Some changes to output handling, more suitable for tex output
  2311. Revision 1.1 2003/03/17 23:03:20 michael
  2312. + Initial import in CVS
  2313. Revision 1.15 2003/03/13 22:02:13 sg
  2314. * New version with many bugfixes and our own parser (now independent of the
  2315. compiler source)
  2316. Revision 1.14 2002/11/15 19:46:32 sg
  2317. * Added support for classes and objects (formerly all objects have been
  2318. written als classes)
  2319. Revision 1.13 2002/05/24 00:13:22 sg
  2320. * much improved new version, including many linking and output fixes
  2321. Revision 1.12 2002/03/12 10:58:36 sg
  2322. * reworked linking engine and internal structure
  2323. Revision 1.11 2002/01/20 11:19:55 michael
  2324. + Added link attribute and property to TFPElement
  2325. Revision 1.10 2001/12/21 11:25:13 sg
  2326. * The parser can now unget two tokens from the scanner
  2327. * Added parsing and HTML output of range types
  2328. * Procedure/function variable bugfixes
  2329. Revision 1.9 2001/12/17 22:34:04 sg
  2330. * Fixed typo in output for menu bar
  2331. Revision 1.8 2001/12/17 13:41:17 jonas
  2332. * OsPathSeparator -> PathDelim
  2333. }