dw_html.pp 79 KB

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