dw_html.pp 79 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854
  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. a,s: String;
  757. begin
  758. a:=AId;
  759. s := ResolveLinkID(a);
  760. if Length(s) = 0 then
  761. begin
  762. WriteLn(Format(SErrUnknownLinkID, [a]));
  763. PushOutputNode(CreateEl(CurOutputNode, 'b'));
  764. end else
  765. PushOutputNode(CreateLink(CurOutputNode, s));
  766. end;
  767. procedure THTMLWriter.DescrEndLink;
  768. begin
  769. PopOutputNode;
  770. end;
  771. procedure THTMLWriter.DescrWriteLinebreak;
  772. begin
  773. CreateEl(CurOutputNode, 'br');
  774. end;
  775. procedure THTMLWriter.DescrBeginParagraph;
  776. begin
  777. PushOutputNode(CreatePara(CurOutputNode));
  778. end;
  779. procedure THTMLWriter.DescrEndParagraph;
  780. begin
  781. PopOutputNode;
  782. end;
  783. procedure THTMLWriter.DescrBeginCode(HasBorder: Boolean; const AHighlighterName: String);
  784. begin
  785. DoPasHighlighting := (AHighlighterName = '') or (AHighlighterName = 'Pascal');
  786. HighlighterFlags := 0;
  787. PushOutputNode(CreateEl(CurOutputNode, 'pre'));
  788. end;
  789. procedure THTMLWriter.DescrWriteCodeLine(const ALine: String);
  790. begin
  791. if DoPasHighlighting then
  792. begin
  793. HighlighterFlags := AppendPasSHFragment(CurOutputNode, ALine,
  794. HighlighterFlags);
  795. AppendText(CurOutputNode, #10);
  796. end else
  797. AppendText(CurOutputNode, ALine + #10);
  798. end;
  799. procedure THTMLWriter.DescrEndCode;
  800. begin
  801. PopOutputNode;
  802. end;
  803. procedure THTMLWriter.DescrBeginOrderedList;
  804. begin
  805. PushOutputNode(CreateEl(CurOutputNode, 'ol'));
  806. end;
  807. procedure THTMLWriter.DescrEndOrderedList;
  808. begin
  809. PopOutputNode;
  810. end;
  811. procedure THTMLWriter.DescrBeginUnorderedList;
  812. begin
  813. PushOutputNode(CreateEl(CurOutputNode, 'ul'));
  814. end;
  815. procedure THTMLWriter.DescrEndUnorderedList;
  816. begin
  817. PopOutputNode;
  818. end;
  819. procedure THTMLWriter.DescrBeginDefinitionList;
  820. begin
  821. PushOutputNode(CreateEl(CurOutputNode, 'dl'));
  822. end;
  823. procedure THTMLWriter.DescrEndDefinitionList;
  824. begin
  825. PopOutputNode;
  826. end;
  827. procedure THTMLWriter.DescrBeginListItem;
  828. begin
  829. PushOutputNode(CreateEl(CurOutputNode, 'li'));
  830. end;
  831. procedure THTMLWriter.DescrEndListItem;
  832. begin
  833. PopOutputNode;
  834. end;
  835. procedure THTMLWriter.DescrBeginDefinitionTerm;
  836. begin
  837. PushOutputNode(CreateEl(CurOutputNode, 'dt'));
  838. end;
  839. procedure THTMLWriter.DescrEndDefinitionTerm;
  840. begin
  841. PopOutputNode;
  842. end;
  843. procedure THTMLWriter.DescrBeginDefinitionEntry;
  844. begin
  845. PushOutputNode(CreateEl(CurOutputNode, 'dd'));
  846. end;
  847. procedure THTMLWriter.DescrEndDefinitionEntry;
  848. begin
  849. PopOutputNode;
  850. end;
  851. procedure THTMLWriter.DescrBeginSectionTitle;
  852. begin
  853. PushOutputNode(CreateEl(CurOutputNode, 'h3'));
  854. end;
  855. procedure THTMLWriter.DescrBeginSectionBody;
  856. begin
  857. PopOutputNode;
  858. end;
  859. procedure THTMLWriter.DescrEndSection;
  860. begin
  861. end;
  862. procedure THTMLWriter.DescrBeginRemark;
  863. var
  864. NewEl, TDEl: TDOMElement;
  865. begin
  866. NewEl := CreateEl(CurOutputNode, 'table');
  867. NewEl['width'] := '100%';
  868. NewEl['border'] := '0';
  869. NewEl['CellSpacing'] := '0';
  870. NewEl['class'] := 'remark';
  871. NewEl := CreateTR(NewEl);
  872. TDEl := CreateTD(NewEl);
  873. TDEl['valign'] := 'top';
  874. TDEl['class'] := 'pre';
  875. AppendText(CreateEl(TDEl, 'b'), SDocRemark);
  876. PushOutputNode(CreateTD(NewEl));
  877. end;
  878. procedure THTMLWriter.DescrEndRemark;
  879. begin
  880. PopOutputNode;
  881. end;
  882. procedure THTMLWriter.DescrBeginTable(ColCount: Integer; HasBorder: Boolean);
  883. var
  884. Table: TDOMElement;
  885. begin
  886. Table := CreateEl(CurOutputNode, 'table');
  887. Table['border'] := IntToStr(Ord(HasBorder));
  888. PushOutputNode(Table);
  889. end;
  890. procedure THTMLWriter.DescrEndTable;
  891. begin
  892. PopOutputNode;
  893. end;
  894. procedure THTMLWriter.DescrBeginTableCaption;
  895. begin
  896. PushOutputNode(CreateEl(CurOutputNode, 'caption'));
  897. end;
  898. procedure THTMLWriter.DescrEndTableCaption;
  899. begin
  900. PopOutputNode;
  901. end;
  902. procedure THTMLWriter.DescrBeginTableHeadRow;
  903. begin
  904. PushOutputNode(CreateTr(CurOutputNode));
  905. InsideHeadRow := True;
  906. end;
  907. procedure THTMLWriter.DescrEndTableHeadRow;
  908. begin
  909. InsideHeadRow := False;
  910. PopOutputNode;
  911. end;
  912. procedure THTMLWriter.DescrBeginTableRow;
  913. begin
  914. PushOutputNode(CreateTR(CurOutputNode));
  915. end;
  916. procedure THTMLWriter.DescrEndTableRow;
  917. begin
  918. PopOutputNode;
  919. end;
  920. procedure THTMLWriter.DescrBeginTableCell;
  921. begin
  922. if InsideHeadRow then
  923. PushOutputNode(CreateEl(CurOutputNode, 'th'))
  924. else
  925. PushOutputNode(CreateTD(CurOutputNode));
  926. end;
  927. procedure THTMLWriter.DescrEndTableCell;
  928. begin
  929. PopOutputNode;
  930. end;
  931. procedure THTMLWriter.AppendText(Parent: TDOMNode; const AText: DOMString);
  932. begin
  933. Parent.AppendChild(Doc.CreateTextNode(AText));
  934. end;
  935. procedure THTMLWriter.AppendNbSp(Parent: TDOMNode; ACount: Integer);
  936. begin
  937. while ACount > 0 do
  938. begin
  939. Parent.AppendChild(Doc.CreateEntityReference('nbsp'));
  940. Dec(ACount);
  941. end;
  942. end;
  943. procedure THTMLWriter.AppendSym(Parent: TDOMNode; const AText: DOMString);
  944. var
  945. El: TDOMElement;
  946. begin
  947. El := CreateEl(Parent, 'span');
  948. El['class'] := 'sym';
  949. AppendText(El, AText);
  950. end;
  951. procedure THTMLWriter.AppendKw(Parent: TDOMNode; const AText: DOMString);
  952. var
  953. El: TDOMElement;
  954. begin
  955. El := CreateEl(Parent, 'span');
  956. El['class'] := 'kw';
  957. AppendText(El, AText);
  958. end;
  959. function THTMLWriter.AppendPasSHFragment(Parent: TDOMNode;
  960. const AText: String; AShFlags: Byte): Byte;
  961. var
  962. CurParent: TDOMNode;
  963. Line, Last, p: PChar;
  964. IsInSpecial: Boolean;
  965. El: TDOMElement;
  966. begin
  967. GetMem(Line, Length(AText) * 3 + 4);
  968. DoPascalHighlighting(AShFlags, PChar(AText), Line);
  969. Result := AShFlags;
  970. CurParent := Parent;
  971. IsInSpecial := False;
  972. Last := Line;
  973. p := Line;
  974. while p[0] <> #0 do
  975. begin
  976. if p[0] = LF_ESCAPE then
  977. begin
  978. p[0] := #0;
  979. AppendText(CurParent, Last);
  980. if IsInSpecial then
  981. CurParent := Parent;
  982. case Ord(p[1]) of
  983. shDefault:
  984. IsInSpecial := False;
  985. shInvalid:
  986. begin
  987. El := CreateEl(CurParent, 'font');
  988. El['color'] := 'red';
  989. CurParent := El;
  990. IsInSpecial := True;
  991. end;
  992. shSymbol:
  993. begin
  994. El := CreateEl(CurParent, 'span');
  995. El['class'] := 'sym';
  996. CurParent := El;
  997. IsInSpecial := True;
  998. end;
  999. shKeyword:
  1000. begin
  1001. El := CreateEl(CurParent, 'span');
  1002. El['class'] := 'kw';
  1003. CurParent := El;
  1004. IsInSpecial := True;
  1005. end;
  1006. shComment:
  1007. begin
  1008. El := CreateEl(CurParent, 'span');
  1009. El['class'] := 'cmt';
  1010. CurParent := El;
  1011. IsInSpecial := True;
  1012. end;
  1013. shDirective:
  1014. begin
  1015. El := CreateEl(CurParent, 'span');
  1016. El['class'] := 'dir';
  1017. CurParent := El;
  1018. IsInSpecial := True;
  1019. end;
  1020. shNumbers:
  1021. begin
  1022. El := CreateEl(CurParent, 'span');
  1023. El['class'] := 'num';
  1024. CurParent := El;
  1025. IsInSpecial := True;
  1026. end;
  1027. shCharacters:
  1028. begin
  1029. El := CreateEl(CurParent, 'span');
  1030. El['class'] := 'chr';
  1031. CurParent := El;
  1032. IsInSpecial := True;
  1033. end;
  1034. shStrings:
  1035. begin
  1036. El := CreateEl(CurParent, 'span');
  1037. El['class'] := 'str';
  1038. CurParent := El;
  1039. IsInSpecial := True;
  1040. end;
  1041. shAssembler:
  1042. begin
  1043. El := CreateEl(CurParent, 'span');
  1044. El['class'] := 'asm';
  1045. CurParent := El;
  1046. IsInSpecial := True;
  1047. end;
  1048. end;
  1049. Last := p + 2;
  1050. end;
  1051. Inc(p);
  1052. end;
  1053. if Last <> p then
  1054. AppendText(CurParent, Last);
  1055. FreeMem(Line);
  1056. end;
  1057. Procedure THTMLWriter.AppendShortDescr(AContext: TPasElement; Parent: TDOMNode; DocNode : TDocNode);
  1058. begin
  1059. if Assigned(DocNode) and Assigned(DocNode.ShortDescr) then
  1060. begin
  1061. PushOutputNode(Parent);
  1062. try
  1063. if not ConvertShort(AContext,TDomElement(DocNode.ShortDescr)) then
  1064. WriteLn(SErrInvalidShortDescr);
  1065. finally
  1066. PopOutputNode;
  1067. end;
  1068. end;
  1069. end;
  1070. procedure THTMLWriter.AppendShortDescr(Parent: TDOMNode; Element: TPasElement);
  1071. begin
  1072. AppendShortDescr(Element,Parent,Engine.FindDocNode(Element));
  1073. end;
  1074. procedure THTMLWriter.AppendDescr(AContext: TPasElement; Parent: TDOMNode;
  1075. DescrNode: TDOMElement; AutoInsertBlock: Boolean);
  1076. begin
  1077. if Assigned(DescrNode) then
  1078. begin
  1079. PushOutputNode(Parent);
  1080. try
  1081. ConvertDescr(AContext, DescrNode, AutoInsertBlock);
  1082. finally
  1083. PopOutputNode;
  1084. end;
  1085. end;
  1086. end;
  1087. procedure THTMLWriter.AppendDescrSection(AContext: TPasElement;
  1088. Parent: TDOMNode; DescrNode: TDOMElement; const ATitle: DOMString);
  1089. begin
  1090. if not IsDescrNodeEmpty(DescrNode) then
  1091. begin
  1092. If (ATitle<>'') then // Can be empty for topic.
  1093. AppendText(CreateH2(Parent), ATitle);
  1094. AppendDescr(AContext, Parent, DescrNode, True);
  1095. end;
  1096. end;
  1097. procedure THTMLWriter.AppendShortDescrCell(Parent: TDOMNode;
  1098. Element: TPasElement);
  1099. var
  1100. ParaEl: TDOMElement;
  1101. begin
  1102. if Assigned(Engine.FindShortDescr(Element)) then
  1103. begin
  1104. AppendNbSp(CreatePara(CreateTD(Parent)), 2);
  1105. ParaEl := CreatePara(CreateTD(Parent));
  1106. ParaEl['class'] := 'cmt';
  1107. AppendShortDescr(ParaEl, Element);
  1108. end;
  1109. end;
  1110. function THTMLWriter.AppendHyperlink(Parent: TDOMNode;
  1111. Element: TPasElement): TDOMElement;
  1112. var
  1113. s: String;
  1114. UnitList: TList;
  1115. i: Integer;
  1116. ThisPackage: TLinkNode;
  1117. begin
  1118. if Assigned(Element) then
  1119. begin
  1120. if Element.InheritsFrom(TPasUnresolvedTypeRef) then
  1121. begin
  1122. s := ResolveLinkID(Element.Name);
  1123. if Length(s) = 0 then
  1124. begin
  1125. { Try all packages }
  1126. ThisPackage := Engine.RootLinkNode.FirstChild;
  1127. while Assigned(ThisPackage) do
  1128. begin
  1129. s := ResolveLinkID(ThisPackage.Name + '.' + Element.Name);
  1130. if Length(s) > 0 then
  1131. break;
  1132. ThisPackage := ThisPackage.NextSibling;
  1133. end;
  1134. if Length(s) = 0 then
  1135. begin
  1136. { Okay, then we have to try all imported units of the current module }
  1137. UnitList := Module.InterfaceSection.UsesList;
  1138. for i := UnitList.Count - 1 downto 0 do
  1139. begin
  1140. { Try all packages }
  1141. ThisPackage := Engine.RootLinkNode.FirstChild;
  1142. while Assigned(ThisPackage) do
  1143. begin
  1144. s := ResolveLinkID(ThisPackage.Name + '.' +
  1145. TPasType(UnitList[i]).Name + '.' + Element.Name);
  1146. if Length(s) > 0 then
  1147. break;
  1148. ThisPackage := ThisPackage.NextSibling;
  1149. end;
  1150. if Length(s) > 0 then
  1151. break;
  1152. end;
  1153. end;
  1154. end;
  1155. end else
  1156. s := ResolveLinkID(Element.PathName);
  1157. if Length(s) > 0 then
  1158. begin
  1159. Result := CreateLink(Parent, s);
  1160. AppendText(Result, Element.Name);
  1161. end else
  1162. begin
  1163. Result := nil;
  1164. AppendText(Parent, Element.Name);
  1165. end;
  1166. end else
  1167. begin
  1168. Result := nil;
  1169. AppendText(CreateWarning(Parent), '<NIL>');
  1170. end;
  1171. end;
  1172. { Returns the new CodeEl, which will be the old CodeEl in most cases }
  1173. function THTMLWriter.AppendType(CodeEl, TableEl: TDOMElement;
  1174. Element: TPasType; Expanded: Boolean): TDOMElement;
  1175. begin
  1176. Result := CodeEl;
  1177. if not Assigned(Element) then
  1178. AppendText(CreateWarning(CodeEl), '<NIL>')
  1179. else if (not Expanded) and (Length(Element.Name) > 0) then
  1180. AppendHyperlink(CodeEl, Element)
  1181. else
  1182. // Array
  1183. if Element.ClassType = TPasArrayType then
  1184. begin
  1185. AppendPasSHFragment(CodeEl,
  1186. 'array [' + TPasArrayType(Element).IndexRange + '] of ', 0);
  1187. Result := AppendType(CodeEl, TableEl, TPasArrayType(Element).ElType, False);
  1188. end else
  1189. // Procedure or funtion type
  1190. if Element.InheritsFrom(TPasProcedureType) then
  1191. begin
  1192. AppendKw(CodeEl, TPasProcedureType(Element).TypeName);
  1193. Result := AppendProcType(CodeEl, TableEl, TPasProcedureType(Element), 0)
  1194. end else
  1195. // Range type
  1196. if Element.InheritsFrom(TPasRangeType) then
  1197. AppendPasSHFragment(CodeEl, TPasRangeType(Element).RangeStart + '..' +
  1198. TPasRangeType(Element).RangeEnd, 0)
  1199. else
  1200. // Other types
  1201. AppendHyperlink(CodeEl, Element);
  1202. end;
  1203. function THTMLWriter.AppendProcType(CodeEl, TableEl: TDOMElement;
  1204. Element: TPasProcedureType; Indent: Integer): TDOMElement;
  1205. function CreateIndentedCodeEl(Indent: Integer): TDOMElement;
  1206. begin
  1207. Result := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1208. AppendNbSp(Result, Indent);
  1209. end;
  1210. var
  1211. i: Integer;
  1212. Arg: TPasArgument;
  1213. begin
  1214. if Element.Args.Count > 0 then
  1215. begin
  1216. AppendSym(CodeEl, '(');
  1217. for i := 0 to Element.Args.Count - 1 do
  1218. begin
  1219. Arg := TPasArgument(Element.Args[i]);
  1220. CodeEl := CreateIndentedCodeEl(Indent + 2);
  1221. case Arg.Access of
  1222. argConst: AppendKw(CodeEl, 'const ');
  1223. argVar: AppendKw(CodeEl, 'var ');
  1224. argOut: AppendKw(CodeEl, 'out ');
  1225. end;
  1226. AppendText(CodeEl, Arg.Name);
  1227. if Assigned(Arg.ArgType) then
  1228. begin
  1229. AppendSym(CodeEl, ': ');
  1230. CodeEl := AppendType(CodeEl, TableEl, Arg.ArgType, False);
  1231. end;
  1232. if Length(Arg.Value) > 0 then
  1233. AppendPasSHFragment(CodeEl, ' = ' + Arg.Value, 0);
  1234. if i < Element.Args.Count - 1 then
  1235. AppendSym(CodeEl, ';');
  1236. end;
  1237. if Element.InheritsFrom(TPasFunctionType) or Element.IsOfObject then
  1238. begin
  1239. CodeEl := CreateIndentedCodeEl(Indent);
  1240. if Element.InheritsFrom(TPasFunctionType) then
  1241. begin
  1242. AppendSym(CodeEl, '):');
  1243. AppendHyperlink(CodeEl, TPasFunctionType(Element).ResultEl.ResultType);
  1244. end else
  1245. AppendSym(CodeEl, ')');
  1246. if Element.IsOfObject then
  1247. begin
  1248. AppendText(CodeEl, ' '); // Don't remove
  1249. AppendKw(CodeEl, 'of object');
  1250. end;
  1251. end else
  1252. if Indent > 0 then
  1253. AppendSym(CodeEl, ')')
  1254. else
  1255. begin
  1256. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1257. AppendSym(CodeEl, ')');
  1258. end;
  1259. end else
  1260. begin
  1261. { Procedure or function without arguments }
  1262. if Element.InheritsFrom(TPasFunctionType) then
  1263. begin
  1264. AppendSym(CodeEl, ': ');
  1265. AppendHyperlink(CodeEl, TPasFunctionType(Element).ResultEl.ResultType);
  1266. end;
  1267. if Element.IsOfObject then
  1268. AppendKw(CodeEl, ' of object');
  1269. end;
  1270. Result := CodeEl;
  1271. end;
  1272. procedure THTMLWriter.AppendProcExt(CodeEl: TDOMElement;
  1273. Element: TPasProcedure);
  1274. procedure AppendExt(const Ext: String);
  1275. begin
  1276. AppendKw(CodeEl, ' ' + Ext);
  1277. AppendSym(CodeEl, ';');
  1278. end;
  1279. begin
  1280. if Element.IsVirtual then
  1281. AppendExt('virtual');
  1282. if Element.IsDynamic then
  1283. AppendExt('dynamic');
  1284. if Element.IsAbstract then
  1285. AppendExt('abstract');
  1286. if Element.IsOverride then
  1287. AppendExt('override');
  1288. if Element.IsOverload then
  1289. AppendExt('overload');
  1290. if Element.IsMessage then
  1291. AppendExt('message');
  1292. end;
  1293. { Used in two places:
  1294. - Page for the method of a class
  1295. - Page for a tandalone procedure or function. }
  1296. procedure THTMLWriter.AppendProcDecl(CodeEl, TableEl: TDOMElement;
  1297. Element: TPasProcedureBase);
  1298. procedure WriteVariant(AProc: TPasProcedure);
  1299. begin
  1300. AppendProcArgsSection(TableEl.ParentNode, AProc.ProcType);
  1301. AppendKw(CodeEl, AProc.TypeName);
  1302. if Element.Parent.ClassType = TPasClassType then
  1303. begin
  1304. AppendText(CodeEl, ' ');
  1305. AppendHyperlink(CodeEl, Element.Parent);
  1306. AppendSym(CodeEl, '.');
  1307. AppendText(CodeEl, AProc.Name);
  1308. end else
  1309. AppendText(CodeEl, ' ' + AProc.FullName);
  1310. CodeEl := AppendProcType(CodeEl, TableEl, AProc.ProcType, 0);
  1311. AppendSym(CodeEl, ';');
  1312. AppendProcExt(CodeEl, AProc);
  1313. end;
  1314. var
  1315. i: Integer;
  1316. begin
  1317. if Element.ClassType = TPasOverloadedProc then
  1318. for i := 0 to TPasOverloadedProc(Element).Overloads.Count - 1 do
  1319. begin
  1320. if i > 0 then
  1321. begin
  1322. CreateEl(CodeEl, 'br');
  1323. CreateEl(CodeEl, 'br');
  1324. end;
  1325. WriteVariant(TPasProcedure(TPasOverloadedProc(Element).Overloads[i]));
  1326. end
  1327. else
  1328. WriteVariant(TPasProcedure(Element));
  1329. end;
  1330. procedure THTMLWriter.AppendProcArgsSection(Parent: TDOMNode;
  1331. Element: TPasProcedureType);
  1332. var
  1333. HasFullDescr, IsFirst: Boolean;
  1334. ResultEl: TPasResultElement;
  1335. ArgTableEl, TREl: TDOMElement;
  1336. DocNode: TDocNode;
  1337. i: Integer;
  1338. Arg: TPasArgument;
  1339. begin
  1340. IsFirst := True;
  1341. for i := 0 to Element.Args.Count - 1 do
  1342. begin
  1343. Arg := TPasArgument(Element.Args[i]);
  1344. if IsDescrNodeEmpty(Engine.FindShortDescr(Arg)) then
  1345. continue;
  1346. if IsFirst then
  1347. begin
  1348. IsFirst := False;
  1349. AppendText(CreateH2(Parent), SDocArguments);
  1350. ArgTableEl := CreateTable(Parent);
  1351. end;
  1352. TREl := CreateTR(ArgTableEl);
  1353. AppendText(CreateCode(CreatePara(CreateTD_vtop(TREl))), Arg.Name);
  1354. AppendShortDescrCell(TREl, Arg);
  1355. end;
  1356. if Element.ClassType = TPasFunctionType then
  1357. begin
  1358. ResultEl := TPasFunctionType(Element).ResultEl;
  1359. DocNode := Engine.FindDocNode(ResultEl);
  1360. HasFullDescr := Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr);
  1361. if HasFullDescr or
  1362. (Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.ShortDescr)) then
  1363. begin
  1364. AppendText(CreateH2(Parent), SDocFunctionResult);
  1365. if HasFullDescr then
  1366. AppendDescr(ResultEl, Parent, DocNode.Descr, True)
  1367. else
  1368. AppendDescr(ResultEl, CreatePara(Parent), DocNode.ShortDescr, False);
  1369. end;
  1370. end;
  1371. end;
  1372. procedure THTMLWriter.AppendTitle(const AText: DOMString);
  1373. begin
  1374. AppendText(TitleElement, AText);
  1375. AppendText(CreateH1(BodyElement), AText);
  1376. end;
  1377. procedure THTMLWriter.AppendTopicMenuBar(Topic : TTopicElement);
  1378. var
  1379. TableEl, TREl, ParaEl, TitleEl: TDOMElement;
  1380. procedure AddLink(El : TPasElement; const AName: String);
  1381. begin
  1382. AppendText(ParaEl, '[');
  1383. AppendText(CreateLink(ParaEl, ResolveLinkWithinPackage(El,0)),AName);
  1384. AppendText(ParaEl, ']');
  1385. end;
  1386. begin
  1387. TableEl := CreateEl(BodyElement, 'table');
  1388. TableEl['cellpadding'] := '4';
  1389. TableEl['cellspacing'] := '0';
  1390. TableEl['border'] := '0';
  1391. TableEl['width'] := '100%';
  1392. TableEl['class'] := 'bar';
  1393. TREl := CreateTR(TableEl);
  1394. ParaEl := CreateEl(CreateTD(TREl), 'b');
  1395. If Assigned(Topic.Previous) then
  1396. AddLink(Topic.Previous,SDocPrevious);
  1397. If Assigned(Topic.Parent) then
  1398. AddLink(Topic.Parent,SDocUp);
  1399. if Assigned(Topic.Next) then
  1400. AddLink(Topic.Next,SDocNext);
  1401. if Length(SearchPage) > 0 then
  1402. begin
  1403. AppendText(ParaEl, '[');
  1404. AppendText(CreateLink(ParaEl, SearchPage), SDocSearch);
  1405. AppendText(ParaEl, ']');
  1406. end;
  1407. ParaEl := CreateTD(TREl);
  1408. ParaEl['align'] := 'right';
  1409. TitleEl := CreateEl(ParaEl, 'span');
  1410. TitleEl['class'] := 'bartitle';
  1411. if Assigned(Module) then
  1412. AppendText(TitleEl, Format(SDocUnitTitle, [Module.Name]));
  1413. if Assigned(Package) then
  1414. begin
  1415. AppendText(TitleEl, ' (');
  1416. AppendHyperlink(TitleEl, Package);
  1417. AppendText(TitleEl, ')');
  1418. end;
  1419. end;
  1420. procedure THTMLWriter.AppendMenuBar(ASubpageIndex: Integer);
  1421. var
  1422. TableEl, TREl, ParaEl, TitleEl: TDOMElement;
  1423. procedure AddLink(ALinkSubpageIndex: Integer; const AName: String);
  1424. begin
  1425. AppendText(ParaEl, '[');
  1426. if ALinkSubpageIndex = ASubpageIndex then
  1427. AppendText(ParaEl, AName)
  1428. else
  1429. AppendText(
  1430. CreateLink(ParaEl, ResolveLinkWithinPackage(Module, ALinkSubpageIndex)),
  1431. AName);
  1432. AppendText(ParaEl, ']');
  1433. end;
  1434. begin
  1435. TableEl := CreateEl(BodyElement, 'table');
  1436. TableEl['cellpadding'] := '4';
  1437. TableEl['cellspacing'] := '0';
  1438. TableEl['border'] := '0';
  1439. TableEl['width'] := '100%';
  1440. TableEl['class'] := 'bar';
  1441. TREl := CreateTR(TableEl);
  1442. ParaEl := CreateEl(CreateTD(TREl), 'b');
  1443. if Assigned(Module) then
  1444. begin
  1445. AddLink(0, SDocOverview);
  1446. if Module.InterfaceSection.ResStrings.Count > 0 then
  1447. AddLink(ResstrSubindex, SDocResStrings);
  1448. if Module.InterfaceSection.Consts.Count > 0 then
  1449. AddLink(ConstsSubindex, SDocConstants);
  1450. if Module.InterfaceSection.Types.Count > 0 then
  1451. AddLink(TypesSubindex, SDocTypes);
  1452. if Module.InterfaceSection.Classes.Count > 0 then
  1453. AddLink(ClassesSubindex, SDocClasses);
  1454. if Module.InterfaceSection.Functions.Count > 0 then
  1455. AddLink(ProcsSubindex, SDocProceduresAndFunctions);
  1456. if Module.InterfaceSection.Variables.Count > 0 then
  1457. AddLink(VarsSubindex, SDocVariables);
  1458. end;
  1459. if Length(SearchPage) > 0 then
  1460. begin
  1461. AppendText(ParaEl, '[');
  1462. AppendText(CreateLink(ParaEl, SearchPage), SDocSearch);
  1463. AppendText(ParaEl, ']');
  1464. end;
  1465. ParaEl := CreateTD(TREl);
  1466. ParaEl['align'] := 'right';
  1467. TitleEl := CreateEl(ParaEl, 'span');
  1468. TitleEl['class'] := 'bartitle';
  1469. if Assigned(Module) then
  1470. AppendText(TitleEl, Format(SDocUnitTitle, [Module.Name]));
  1471. if Assigned(Package) then
  1472. begin
  1473. AppendText(TitleEl, ' (');
  1474. AppendHyperlink(TitleEl, Package);
  1475. AppendText(TitleEl, ')');
  1476. end;
  1477. end;
  1478. procedure THTMLWriter.AppendSourceRef(AElement: TPasElement);
  1479. begin
  1480. AppendText(CreatePara(BodyElement), Format(SDocSourcePosition,
  1481. [ExtractFileName(AElement.SourceFilename), AElement.SourceLinenumber]));
  1482. end;
  1483. Procedure THTMLWriter.AppendSeeAlsoSection(AElement : TPasElement;DocNode : TDocNode);
  1484. var
  1485. Node: TDOMNode;
  1486. TableEl, El, TREl, TDEl, ParaEl, NewEl, DescrEl: TDOMElement;
  1487. s: String;
  1488. f: Text;
  1489. IsFirstSeeAlso : Boolean;
  1490. begin
  1491. if Not (Assigned(DocNode) and Assigned(DocNode.SeeAlso)) then
  1492. Exit;
  1493. IsFirstSeeAlso := True;
  1494. Node:=DocNode.SeeAlso.FirstChild;
  1495. While Assigned(Node) do
  1496. begin
  1497. if (Node.NodeType=ELEMENT_NODE) and (Node.NodeName='link') then
  1498. begin
  1499. if IsFirstSeeAlso then
  1500. begin
  1501. IsFirstSeeAlso := False;
  1502. AppendText(CreateH2(BodyElement), SDocSeeAlso);
  1503. TableEl := CreateTable(BodyElement);
  1504. end;
  1505. El:=TDOMElement(Node);
  1506. TREl:=CreateTR(TableEl);
  1507. ParaEl:=CreatePara(CreateTD_vtop(TREl));
  1508. s:= ResolveLinkID(El['id']);
  1509. if Length(s)=0 then
  1510. begin
  1511. WriteLn(Format(SErrUnknownLinkID, [El['id']]));
  1512. NewEl := CreateEl(ParaEl,'b')
  1513. end
  1514. else
  1515. NewEl := CreateLink(ParaEl,s);
  1516. AppendText(NewEl,El['id']);
  1517. DescrEl := Engine.FindShortDescr(AElement.GetModule, El['id']);
  1518. if Assigned(DescrEl) then
  1519. begin
  1520. AppendNbSp(CreatePara(CreateTD(TREl)), 2);
  1521. ParaEl := CreatePara(CreateTD(TREl));
  1522. ParaEl['class'] := 'cmt';
  1523. PushOutputNode(ParaEl);
  1524. try
  1525. ConvertShort(AElement, DescrEl);
  1526. finally
  1527. PopOutputNode;
  1528. end;
  1529. end;
  1530. end; // Link node
  1531. Node := Node.NextSibling;
  1532. end; // While
  1533. end;
  1534. Procedure THTMLWriter.AppendExampleSection(AElement : TPasElement;DocNode : TDocNode);
  1535. var
  1536. Node: TDOMNode;
  1537. // TableEl, El, TREl, TDEl, ParaEl, NewEl, DescrEl: TDOMElement;
  1538. s: String;
  1539. f: Text;
  1540. begin
  1541. if not (Assigned(DocNode) and Assigned(DocNode.FirstExample)) then
  1542. Exit;
  1543. Node := DocNode.FirstExample;
  1544. while Assigned(Node) do
  1545. begin
  1546. if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'example') then
  1547. begin
  1548. AppendText(CreateH2(BodyElement), SDocExample);
  1549. try
  1550. Assign(f, Engine.GetExampleFilename(TDOMElement(Node)));
  1551. Reset(f);
  1552. try
  1553. PushOutputNode(BodyElement);
  1554. DescrBeginCode(False, TDOMElement(Node)['highlighter']);
  1555. while not EOF(f) do
  1556. begin
  1557. ReadLn(f, s);
  1558. DescrWriteCodeLine(s);
  1559. end;
  1560. DescrEndCode;
  1561. PopOutputNode;
  1562. finally
  1563. Close(f);
  1564. end;
  1565. except
  1566. on e: Exception do
  1567. begin
  1568. e.Message := '[example] ' + e.Message;
  1569. raise;
  1570. end;
  1571. end;
  1572. end;
  1573. Node := Node.NextSibling;
  1574. end;
  1575. end;
  1576. procedure THTMLWriter.FinishElementPage(AElement: TPasElement);
  1577. var
  1578. DocNode: TDocNode;
  1579. begin
  1580. DocNode := Engine.FindDocNode(AElement);
  1581. If Assigned(DocNode) then
  1582. begin
  1583. // Description
  1584. if Assigned(DocNode.Descr) then
  1585. AppendDescrSection(AElement, BodyElement, DocNode.Descr, SDocDescription);
  1586. // Append "Errors" section
  1587. if Assigned(DocNode.ErrorsDoc) then
  1588. AppendDescrSection(AElement, BodyElement, DocNode.ErrorsDoc, SDocErrors);
  1589. // Append "See also" section
  1590. AppendSeeAlsoSection(AElement,DocNode);
  1591. // Append examples, if present
  1592. AppendExampleSection(AElement,DocNode);
  1593. end;
  1594. end;
  1595. Procedure THTMLWriter.CreateTopicPageBody(AElement : TTopicElement);
  1596. var
  1597. DocNode: TDocNode;
  1598. TableEl, TREl: TDOMElement;
  1599. I : Integer;
  1600. S : String;
  1601. begin
  1602. AppendTopicMenuBar(AElement);
  1603. DocNode:=AElement.TopicNode;
  1604. if Assigned(DocNode) then // should always be true, but we're being careful.
  1605. begin
  1606. AppendShortDescr(AElement,TitleElement, DocNode);
  1607. AppendShortDescr(AElement,CreateH2(BodyElement), DocNode);
  1608. if Assigned(DocNode.Descr) then
  1609. AppendDescrSection(nil, BodyElement, DocNode.Descr, '');
  1610. AppendSeeAlsoSection(AElement,DocNode);
  1611. CreateTopicLinks(DocNode,AElement);
  1612. AppendExampleSection(AElement,DocNode);
  1613. end;
  1614. end;
  1615. procedure THTMLWriter.CreatePageBody(AElement: TPasElement;
  1616. ASubpageIndex: Integer);
  1617. var
  1618. i: Integer;
  1619. Element: TPasElement;
  1620. begin
  1621. CurDirectory := Allocator.GetFilename(AElement, ASubpageIndex);
  1622. i := Length(CurDirectory);
  1623. while (i > 0) and not (CurDirectory[i] in DirSeparators) do
  1624. Dec(i);
  1625. CurDirectory := Copy(CurDirectory, 1, i);
  1626. BaseDirectory := Allocator.GetRelativePathToTop(AElement);
  1627. if AElement.ClassType = TPasPackage then
  1628. CreatePackagePageBody
  1629. else
  1630. begin
  1631. Element := AElement;
  1632. while (Element<>Nil) and (Element.ClassType<>TPasModule) do
  1633. Element := Element.Parent;
  1634. Module := TPasModule(Element);
  1635. if AElement.ClassType = TPasModule then
  1636. CreateModulePageBody(TPasModule(AElement), ASubpageIndex)
  1637. else if AElement.Parent.InheritsFrom(TPasClassType) then
  1638. CreateClassMemberPageBody(AElement)
  1639. else if AElement.ClassType = TPasConst then
  1640. CreateConstPageBody(TPasConst(AElement))
  1641. else if AElement.InheritsFrom(TPasClassType) then
  1642. CreateClassPageBody(TPasClassType(AElement), ASubpageIndex)
  1643. else if AElement.InheritsFrom(TPasType) then
  1644. CreateTypePageBody(TPasType(AElement))
  1645. else if AElement.ClassType = TPasVariable then
  1646. CreateVarPageBody(TPasVariable(AElement))
  1647. else if AElement.InheritsFrom(TPasProcedureBase) then
  1648. CreateProcPageBody(TPasProcedure(AElement))
  1649. else if AElement.ClassType = TTopicELement then
  1650. CreateTopicPageBody(TTopicElement(AElement))
  1651. end;
  1652. end;
  1653. procedure THTMLWriter.CreatePackagePageBody;
  1654. var
  1655. DocNode: TDocNode;
  1656. TableEl, TREl: TDOMElement;
  1657. i: Integer;
  1658. ThisModule: TPasModule;
  1659. begin
  1660. AppendMenuBar(0);
  1661. AppendTitle(Format(SDocPackageTitle, [Copy(Package.Name, 2, 256)]));
  1662. AppendShortDescr(CreatePara(BodyElement), Package);
  1663. AppendText(CreateH2(BodyElement), SDocUnits);
  1664. TableEl := CreateTable(BodyElement);
  1665. for i := 0 to Package.Modules.Count - 1 do
  1666. begin
  1667. ThisModule := TPasModule(Package.Modules[i]);
  1668. TREl := CreateTR(TableEl);
  1669. AppendHyperlink(CreateCode(CreatePara(CreateTD_vtop(TREl))), ThisModule);
  1670. AppendShortDescrCell(TREl, ThisModule);
  1671. end;
  1672. DocNode := Engine.FindDocNode(Package);
  1673. if Assigned(DocNode) then
  1674. begin
  1675. if Assigned(DocNode.Descr) then
  1676. AppendDescrSection(nil, BodyElement, DocNode.Descr, SDocDescription);
  1677. CreateTopicLinks(DocNode,Package);
  1678. end;
  1679. end;
  1680. Procedure THTMLWriter.CreateTopicLinks(Node : TDocNode; PasElement : TPasElement);
  1681. var
  1682. DocNode: TDocNode;
  1683. TableEl, TREl: TDOMElement;
  1684. First : Boolean;
  1685. ThisTopic: TPasElement;
  1686. begin
  1687. DocNode:=Node.FirstChild;
  1688. First:=True;
  1689. While Assigned(DocNode) do
  1690. begin
  1691. If DocNode.TopicNode then
  1692. begin
  1693. if first then
  1694. begin
  1695. First:=False;
  1696. AppendText(CreateH2(BodyElement), SDocRelatedTopics);
  1697. TableEl := CreateTable(BodyElement);
  1698. end;
  1699. TREl := CreateTR(TableEl);
  1700. ThisTopic:=FindTopicElement(DocNode);
  1701. if Assigned(ThisTopic) then
  1702. AppendHyperlink(CreateCode(CreatePara(CreateTD_vtop(TREl))), ThisTopic);
  1703. AppendShortDescrCell(TREl, ThisTopic);
  1704. end;
  1705. DocNode:=DocNode.NextSibling;
  1706. end;
  1707. end;
  1708. procedure THTMLWriter.CreateModulePageBody(AModule: TPasModule;
  1709. ASubpageIndex: Integer);
  1710. procedure CreateMainPage;
  1711. var
  1712. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  1713. i: Integer;
  1714. UnitRef: TPasType;
  1715. DocNode: TDocNode;
  1716. begin
  1717. AppendMenuBar(0);
  1718. AppendTitle(Format(SDocUnitTitle, [AModule.Name]));
  1719. AppendShortDescr(CreatePara(BodyElement), AModule);
  1720. if AModule.InterfaceSection.UsesList.Count > 0 then
  1721. begin
  1722. TableEl := CreateTable(BodyElement);
  1723. AppendKw(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), 'uses');
  1724. for i := 0 to AModule.InterfaceSection.UsesList.Count - 1 do
  1725. begin
  1726. UnitRef := TPasType(AModule.InterfaceSection.UsesList[i]);
  1727. DocNode := Engine.FindDocNode(UnitRef);
  1728. if Assigned(DocNode) and DocNode.IsSkipped then
  1729. continue;
  1730. TREl := CreateTR(TableEl);
  1731. TDEl := CreateTD_vtop(TREl);
  1732. CodeEl := CreateCode(CreatePara(TDEl));
  1733. AppendNbSp(CodeEl, 2);
  1734. AppendHyperlink(CodeEl, UnitRef);
  1735. if i < AModule.InterfaceSection.UsesList.Count - 1 then
  1736. AppendSym(CodeEl, ',')
  1737. else
  1738. AppendSym(CodeEl, ';');
  1739. AppendText(CodeEl, ' '); // Space for descriptions
  1740. AppendShortDescrCell(TREl, UnitRef);
  1741. end;
  1742. end;
  1743. DocNode := Engine.FindDocNode(AModule);
  1744. if Assigned(DocNode) then
  1745. begin
  1746. if Assigned(DocNode.Descr) then
  1747. AppendDescrSection(AModule, BodyElement, DocNode.Descr, SDocOverview);
  1748. CreateTopicLinks(DocNode,AModule);
  1749. end;
  1750. end;
  1751. procedure CreateSimpleSubpage(const ATitle: DOMString; AList: TList);
  1752. var
  1753. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  1754. i, j: Integer;
  1755. Decl: TPasElement;
  1756. SortedList: TList;
  1757. DocNode: TDocNode;
  1758. S : String;
  1759. begin
  1760. AppendMenuBar(ASubpageIndex);
  1761. S:=ATitle;
  1762. AppendTitle(Format(SDocUnitTitle + ': %s', [AModule.Name, S]));
  1763. SortedList := TList.Create;
  1764. try
  1765. for i := 0 to AList.Count - 1 do
  1766. begin
  1767. Decl := TPasElement(AList[i]);
  1768. DocNode := Engine.FindDocNode(Decl);
  1769. if (not Assigned(DocNode)) or (not DocNode.IsSkipped) then
  1770. begin
  1771. j := 0;
  1772. while (j < SortedList.Count) and (CompareText(
  1773. TPasElement(SortedList[j]).PathName, Decl.PathName) < 0) do
  1774. Inc(j);
  1775. SortedList.Insert(j, Decl);
  1776. end;
  1777. end;
  1778. TableEl := CreateTable(BodyElement);
  1779. for i := 0 to SortedList.Count - 1 do
  1780. begin
  1781. Decl := TPasElement(SortedList[i]);
  1782. TREl := CreateTR(TableEl);
  1783. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1784. AppendHyperlink(CodeEl, Decl);
  1785. AppendShortDescrCell(TREl, Decl);
  1786. end;
  1787. finally
  1788. SortedList.Free;
  1789. end;
  1790. end;
  1791. procedure CreateResStringsPage;
  1792. var
  1793. ParaEl: TDOMElement;
  1794. i, j: Integer;
  1795. Decl: TPasResString;
  1796. DocNode: TDocNode;
  1797. begin
  1798. AppendMenuBar(ResstrSubindex);
  1799. AppendTitle(Format(SDocUnitTitle + ': %s', [AModule.Name, SDocResStrings]));
  1800. for i := 0 to AModule.InterfaceSection.ResStrings.Count - 1 do
  1801. begin
  1802. Decl := TPasResString(AModule.InterfaceSection.ResStrings[i]);
  1803. CreateEl(BodyElement, 'a')['name'] := LowerCase(Decl.Name);
  1804. ParaEl := CreatePara(BodyElement);
  1805. AppendText(CreateCode(ParaEl), Decl.Name);
  1806. CreateEl(ParaEl, 'br');
  1807. AppendText(ParaEl, Decl.Value);
  1808. end;
  1809. end;
  1810. begin
  1811. case ASubpageIndex of
  1812. 0:
  1813. CreateMainPage;
  1814. ResstrSubindex:
  1815. CreateResStringsPage;
  1816. ConstsSubindex:
  1817. CreateSimpleSubpage(SDocConstants, AModule.InterfaceSection.Consts);
  1818. TypesSubindex:
  1819. CreateSimpleSubpage(SDocTypes, AModule.InterfaceSection.Types);
  1820. ClassesSubindex:
  1821. CreateSimpleSubpage(SDocClasses, AModule.InterfaceSection.Classes);
  1822. ProcsSubindex:
  1823. CreateSimpleSubpage(SDocProceduresAndFunctions, AModule.InterfaceSection.Functions);
  1824. VarsSubindex:
  1825. CreateSimpleSubpage(SDocVariables, AModule.InterfaceSection.Variables);
  1826. end;
  1827. end;
  1828. procedure THTMLWriter.CreateConstPageBody(AConst: TPasConst);
  1829. var
  1830. TableEl, CodeEl: TDOMElement;
  1831. begin
  1832. AppendMenuBar(-1);
  1833. AppendTitle(AConst.Name);
  1834. AppendShortDescr(CreatePara(BodyElement), AConst);
  1835. AppendText(CreateH2(BodyElement), SDocDeclaration);
  1836. AppendSourceRef(AConst);
  1837. TableEl := CreateTable(BodyElement);
  1838. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1839. AppendKw(CodeEl, 'const');
  1840. AppendText(CodeEl, ' ' + AConst.Name);
  1841. if Assigned(AConst.VarType) then
  1842. begin
  1843. AppendSym(CodeEl, ': ');
  1844. AppendType(CodeEl, TableEl, AConst.VarType, False);
  1845. end;
  1846. AppendPasSHFragment(CodeEl, ' = ' + AConst.Value + ';', 0);
  1847. FinishElementPage(AConst);
  1848. end;
  1849. procedure THTMLWriter.CreateTypePageBody(AType: TPasType);
  1850. var
  1851. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  1852. DocNode: TDocNode;
  1853. i: Integer;
  1854. s: String;
  1855. EnumType: TPasEnumType;
  1856. EnumValue: TPasEnumValue;
  1857. Variable: TPasVariable;
  1858. begin
  1859. AppendMenuBar(-1);
  1860. AppendTitle(AType.Name);
  1861. AppendShortDescr(CreatePara(BodyElement), AType);
  1862. AppendText(CreateH2(BodyElement), SDocDeclaration);
  1863. AppendSourceRef(AType);
  1864. TableEl := CreateTable(BodyElement);
  1865. TREl := CreateTR(TableEl);
  1866. TDEl := CreateTD(TREl);
  1867. CodeEl := CreateCode(CreatePara(TDEl));
  1868. AppendKw(CodeEl, 'type ');
  1869. AppendText(CodeEl, AType.Name);
  1870. AppendSym(CodeEl, ' = ');
  1871. // Alias
  1872. if AType.ClassType = TPasAliasType then
  1873. begin
  1874. if Assigned(TPasAliasType(AType).DestType) then
  1875. AppendHyperlink(CodeEl, TPasAliasType(AType).DestType)
  1876. else
  1877. AppendText(CreateWarning(CodeEl), '<Destination type is NIL>');
  1878. AppendSym(CodeEl, ';');
  1879. end else
  1880. // Class of
  1881. if AType.ClassType = TPasClassOfType then
  1882. begin
  1883. AppendKw(CodeEl, 'class of ');
  1884. AppendHyperlink(CodeEl, TPasClassOfType(AType).DestType);
  1885. AppendSym(CodeEl, ';');
  1886. end else
  1887. // Enumeration
  1888. if AType.ClassType = TPasEnumType then
  1889. begin
  1890. AppendSym(CodeEl, '(');
  1891. for i := 0 to TPasEnumType(AType).Values.Count - 1 do
  1892. begin
  1893. EnumValue := TPasEnumValue(TPasEnumType(AType).Values[i]);
  1894. TREl := CreateTR(TableEl);
  1895. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1896. AppendShortDescrCell(TREl, EnumValue);
  1897. AppendNbSp(CodeEl, 2);
  1898. s := EnumValue.Name;
  1899. if EnumValue.IsValueUsed then
  1900. s := s + ' = ' + IntToStr(EnumValue.Value);
  1901. if i < TPasEnumType(AType).Values.Count - 1 then
  1902. s := s + ',';
  1903. AppendPasSHFragment(CodeEl, s, 0);
  1904. end;
  1905. AppendSym(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), ');');
  1906. end else
  1907. // Pointer type
  1908. if AType.ClassType = TPasPointerType then
  1909. begin
  1910. AppendSym(CodeEl, '^');
  1911. if Assigned(TPasPointerType(AType).DestType) then
  1912. AppendHyperlink(CodeEl, TPasPointerType(AType).DestType)
  1913. else
  1914. AppendText(CreateWarning(CodeEl), '<Destination type is NIL>');
  1915. AppendSym(CodeEl, ';');
  1916. end else
  1917. if AType.InheritsFrom(TPasProcedureType) then
  1918. begin
  1919. AppendSym(AppendType(CodeEl, TableEl, TPasType(AType), True), ';');
  1920. AppendProcArgsSection(BodyElement, TPasProcedureType(AType));
  1921. end else
  1922. // Record
  1923. if AType.ClassType = TPasRecordType then
  1924. begin
  1925. if TPasRecordType(AType).IsPacked then
  1926. AppendKw(CodeEl, 'packed record')
  1927. else
  1928. AppendKw(CodeEl, 'record');
  1929. for i := 0 to TPasRecordType(AType).Members.Count - 1 do
  1930. begin
  1931. Variable := TPasVariable(TPasRecordType(AType).Members[i]);
  1932. TREl := CreateTR(TableEl);
  1933. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1934. AppendShortDescrCell(TREl, Variable);
  1935. AppendNbSp(CodeEl, 2);
  1936. AppendText(CodeEl, Variable.Name);
  1937. AppendSym(CodeEl, ': ');
  1938. AppendType(CodeEl, TableEl, Variable.VarType, False);
  1939. AppendSym(CodeEl, ';');
  1940. end;
  1941. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  1942. AppendText(CodeEl, ' '); // !!!: Dirty trick, necessary for current XML writer
  1943. AppendKw(CodeEl, 'end');
  1944. AppendSym(CodeEl, ';');
  1945. end else
  1946. // Set
  1947. if AType.ClassType = TPasSetType then
  1948. begin
  1949. AppendKw(CodeEl, 'set of ');
  1950. if TPasSetType(AType).EnumType.ClassType = TPasEnumType then
  1951. begin
  1952. AppendSym(CodeEl, '(');
  1953. EnumType := TPasEnumType(TPasSetType(AType).EnumType);
  1954. for i := 0 to EnumType.Values.Count - 1 do
  1955. begin
  1956. EnumValue := TPasEnumValue(EnumType.Values[i]);
  1957. TREl := CreateTR(TableEl);
  1958. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  1959. AppendShortDescrCell(TREl, EnumValue);
  1960. AppendNbSp(CodeEl, 2);
  1961. s := EnumValue.Name;
  1962. if EnumValue.IsValueUsed then
  1963. s := s + ' = ' + IntToStr(EnumValue.Value);
  1964. if i < EnumType.Values.Count - 1 then
  1965. s := s + ',';
  1966. AppendPasSHFragment(CodeEl, s, 0);
  1967. end;
  1968. AppendSym(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), ');');
  1969. end else
  1970. begin
  1971. AppendHyperlink(CodeEl, TPasSetType(AType).EnumType);
  1972. AppendSym(CodeEl, ';');
  1973. end;
  1974. end else
  1975. // Type alias
  1976. if AType.ClassType = TPasTypeAliasType then
  1977. begin
  1978. AppendKw(CodeEl, 'type ');
  1979. AppendHyperlink(CodeEl, TPasTypeAliasType(AType).DestType);
  1980. AppendSym(CodeEl, ';');
  1981. end else
  1982. // Probably one of the simple types, which allowed in other places as wel...
  1983. AppendSym(AppendType(CodeEl, TableEl, TPasType(AType), True), ';');
  1984. FinishElementPage(AType);
  1985. end;
  1986. function PropertyFilter(AMember: TPasElement): Boolean;
  1987. begin
  1988. Result := (AMember.ClassType = TPasProperty) and
  1989. (Copy(AMember.Name, 1, 2) <> 'On');
  1990. end;
  1991. function MethodFilter(AMember: TPasElement): Boolean;
  1992. begin
  1993. Result := AMember.InheritsFrom(TPasProcedureBase);
  1994. end;
  1995. function EventFilter(AMember: TPasElement): Boolean;
  1996. begin
  1997. Result := (AMember.ClassType = TPasProperty) and
  1998. (Copy(AMember.Name, 1, 2) = 'On');
  1999. end;
  2000. procedure THTMLWriter.CreateClassPageBody(AClass: TPasClassType;
  2001. ASubpageIndex: Integer);
  2002. type
  2003. TMemberFilter = function(AMember: TPasElement): Boolean;
  2004. var
  2005. ParaEl: TDOMElement;
  2006. procedure AppendMemberListLink(AListSubpageIndex: Integer;
  2007. const AText: DOMString);
  2008. var
  2009. LinkEl: TDOMElement;
  2010. begin
  2011. AppendText(ParaEl, '[');
  2012. LinkEl := CreateEl(ParaEl, 'a');
  2013. LinkEl['href'] :=
  2014. ResolveLinkWithinPackage(AClass, AListSubpageIndex);
  2015. LinkEl['onClick'] := 'window.open(''' + LinkEl['href'] + ''', ''list'', ' +
  2016. '''dependent=yes,resizable=yes,scrollbars=yes,height=400,width=300''); return false;';
  2017. AppendText(LinkEl, AText);
  2018. AppendText(ParaEl, ' (');
  2019. LinkEl := CreateEl(ParaEl, 'a');
  2020. LinkEl['href'] :=
  2021. ResolveLinkWithinPackage(AClass, AListSubpageIndex + 1);
  2022. LinkEl['onClick'] := 'window.open(''' + LinkEl['href'] + ''', ''list'', ' +
  2023. '''dependent=yes,resizable=yes,scrollbars=yes,height=400,width=300''); return false;';
  2024. AppendText(LinkEl, SDocByName);
  2025. AppendText(ParaEl, ')');
  2026. AppendText(ParaEl, '] ');
  2027. end;
  2028. procedure CreateMainPage;
  2029. var
  2030. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  2031. DocNode: TDocNode;
  2032. Member: TPasElement;
  2033. CurVisibility: TPasMemberVisibility;
  2034. i: Integer;
  2035. s: String;
  2036. ThisClass: TPasClassType;
  2037. HaveSeenTObject: Boolean;
  2038. begin
  2039. AppendMenuBar(-1);
  2040. AppendTitle(AClass.Name);
  2041. ParaEl := CreatePara(BodyElement);
  2042. AppendMemberListLink(PropertiesByInheritanceSubindex, SDocProperties);
  2043. AppendMemberListLink(MethodsByInheritanceSubindex, SDocMethods);
  2044. AppendMemberListLink(EventsByInheritanceSubindex, SDocEvents);
  2045. AppendShortDescr(CreatePara(BodyElement), AClass);
  2046. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2047. AppendSourceRef(AClass);
  2048. TableEl := CreateTable(BodyElement);
  2049. TREl := CreateTR(TableEl);
  2050. TDEl := CreateTD(TREl);
  2051. CodeEl := CreateCode(CreatePara(TDEl));
  2052. AppendKw(CodeEl, 'type');
  2053. AppendText(CodeEl, ' ' + AClass.Name + ' ');
  2054. AppendSym(CodeEl, '=');
  2055. AppendText(CodeEl, ' ');
  2056. AppendKw(CodeEl, ObjKindNames[AClass.ObjKind]);
  2057. if Assigned(AClass.AncestorType) then
  2058. begin
  2059. AppendSym(CodeEl, '(');
  2060. AppendHyperlink(CodeEl, AClass.AncestorType);
  2061. AppendSym(CodeEl, ')');
  2062. end;
  2063. if AClass.Members.Count > 0 then
  2064. begin
  2065. CurVisibility := visDefault;
  2066. for i := 0 to AClass.Members.Count - 1 do
  2067. begin
  2068. Member := TPasElement(AClass.Members[i]);
  2069. if CurVisibility <> Member.Visibility then
  2070. begin
  2071. CurVisibility := Member.Visibility;
  2072. if ((CurVisibility = visPrivate) and Engine.HidePrivate) or
  2073. ((CurVisibility = visProtected) and Engine.HideProtected) then
  2074. continue;
  2075. case CurVisibility of
  2076. visPrivate: s := 'private';
  2077. visProtected: s := 'protected';
  2078. visPublic: s := 'public';
  2079. visPublished: s := 'published';
  2080. visAutomated: s := 'automated';
  2081. end;
  2082. AppendKw(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), s);
  2083. end else
  2084. if ((CurVisibility = visPrivate) and Engine.HidePrivate) or
  2085. ((CurVisibility = visProtected) and Engine.HideProtected) then
  2086. continue;
  2087. TREl := CreateTR(TableEl);
  2088. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  2089. AppendNbSp(CodeEl, 2);
  2090. AppendShortDescrCell(TREl, Member);
  2091. if Member.InheritsFrom(TPasProcedureBase) then
  2092. begin
  2093. AppendKw(CodeEl, TPasProcedureBase(Member).TypeName + ' ');
  2094. AppendHyperlink(CodeEl, Member);
  2095. if (Member.ClassType = TPasOverloadedProc) or
  2096. (TPasProcedure(Member).ProcType.Args.Count > 0) then
  2097. AppendSym(CodeEl, '();')
  2098. else
  2099. AppendSym(CodeEl, ';');
  2100. if Member.ClassType <> TPasOverloadedProc then
  2101. AppendProcExt(CodeEl, TPasProcedure(Member));
  2102. end else
  2103. if Member.ClassType = TPasVariable then
  2104. begin
  2105. AppendHyperlink(CodeEl, Member);
  2106. AppendSym(CodeEl, ': ');
  2107. AppendHyperlink(CodeEl, TPasVariable(Member).VarType);
  2108. AppendSym(CodeEl, ';');
  2109. end else
  2110. if Member.ClassType = TPasProperty then
  2111. begin
  2112. AppendKw(CodeEl, 'property ');
  2113. AppendHyperlink(CodeEl, Member);
  2114. if Assigned(TPasProperty(Member).VarType) then
  2115. begin
  2116. AppendSym(CodeEl, ': ');
  2117. AppendHyperlink(CodeEl, TPasProperty(Member).VarType);
  2118. end;
  2119. AppendSym(CodeEl, ';');
  2120. if TPasProperty(Member).IsDefault then
  2121. begin
  2122. AppendKw(CodeEl, ' default');
  2123. AppendSym(CodeEl, ';');
  2124. end;
  2125. SetLength(s, 0);
  2126. if Length(TPasProperty(Member).ReadAccessorName) > 0 then
  2127. s := s + 'r';
  2128. if Length(TPasProperty(Member).WriteAccessorName) > 0 then
  2129. s := s + 'w';
  2130. if Length(TPasProperty(Member).StoredAccessorName) > 0 then
  2131. s := s + 's';
  2132. if Length(s) > 0 then
  2133. AppendText(CodeEl, ' [' + s + ']');
  2134. end else
  2135. AppendText(CreateWarning(CodeEl), '<' + Member.ClassName + '>');
  2136. end;
  2137. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  2138. end;
  2139. AppendText(CodeEl, ' '); // !!!: Dirty trick, necessary for current XML writer
  2140. AppendKw(CodeEl, 'end');
  2141. AppendSym(CodeEl, ';');
  2142. AppendText(CreateH2(BodyElement), SDocInheritance);
  2143. TableEl := CreateTable(BodyElement);
  2144. HaveSeenTObject := AClass.ObjKind <> okClass;
  2145. ThisClass := AClass;
  2146. while True do
  2147. begin
  2148. TREl := CreateTR(TableEl);
  2149. TDEl := CreateTD_vtop(TREl);
  2150. TDEl['align'] := 'center';
  2151. CodeEl := CreateCode(CreatePara(TDEl));
  2152. AppendHyperlink(CodeEl, ThisClass);
  2153. AppendShortDescrCell(TREl, ThisClass);
  2154. if HaveSeenTObject or (CompareText(ThisClass.Name, 'TObject') = 0) then
  2155. HaveSeenTObject := True
  2156. else
  2157. begin
  2158. TDEl := CreateTD(CreateTR(TableEl));
  2159. TDEl['align'] := 'center';
  2160. AppendText(TDEl, '|');
  2161. end;
  2162. if Assigned(ThisClass.AncestorType) then
  2163. begin
  2164. if ThisClass.AncestorType.InheritsFrom(TPasClassType) then
  2165. ThisClass := TPasClassType(ThisClass.AncestorType)
  2166. else
  2167. begin
  2168. TDEl := CreateTD(CreateTR(TableEl));
  2169. TDEl['align'] := 'center';
  2170. AppendText(CreateCode(CreatePara(TDEl)), ThisClass.AncestorType.Name);
  2171. if CompareText(ThisClass.AncestorType.Name, 'TObject') = 0 then
  2172. HaveSeenTObject := True
  2173. else
  2174. begin
  2175. TDEl := CreateTD(CreateTR(TableEl));
  2176. TDEl['align'] := 'center';
  2177. AppendText(TDEl, '?');
  2178. end;
  2179. break;
  2180. end
  2181. end else
  2182. break;
  2183. end;
  2184. if not HaveSeenTObject then
  2185. begin
  2186. TDEl := CreateTD(CreateTR(TableEl));
  2187. TDEl['align'] := 'center';
  2188. AppendText(CreateCode(CreatePara(TDEl)), 'TObject');
  2189. end;
  2190. FinishElementPage(AClass);
  2191. end;
  2192. procedure CreateInheritanceSubpage(AFilter: TMemberFilter);
  2193. var
  2194. ThisClass: TPasClassType;
  2195. i: Integer;
  2196. Member: TPasElement;
  2197. TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
  2198. begin
  2199. TableEl := CreateTable(BodyElement);
  2200. ThisClass := AClass;
  2201. while True do
  2202. begin
  2203. TREl := CreateTR(TableEl);
  2204. TDEl := CreateTD(TREl);
  2205. TDEl['colspan'] := '3';
  2206. CreateTD(TREl);
  2207. LinkEl := AppendHyperlink(CreateEl(CreateCode(CreatePara(TDEl)), 'b'), ThisClass);
  2208. if Assigned(LinkEl) then
  2209. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2210. '''; return false;';
  2211. for i := 0 to ThisClass.Members.Count - 1 do
  2212. begin
  2213. Member := TPasElement(ThisClass.Members[i]);
  2214. if ((Member.Visibility = visPrivate) and Engine.HidePrivate) or
  2215. ((Member.Visibility = visProtected) and Engine.HideProtected) or
  2216. not AFilter(Member) then
  2217. continue;
  2218. TREl := CreateTR(TableEl);
  2219. ParaEl := CreatePara(CreateTD(TREl));
  2220. case Member.Visibility of
  2221. visPrivate:
  2222. AppendText(ParaEl, 'pv');
  2223. visProtected:
  2224. AppendText(ParaEl, 'pt');
  2225. visPublished:
  2226. AppendText(ParaEl, 'pl');
  2227. end;
  2228. AppendNbSp(ParaEl, 1);
  2229. ParaEl := CreateTD(TREl);
  2230. if (Member.ClassType = TPasProperty) and
  2231. (Length(TPasProperty(Member).WriteAccessorName) = 0) then
  2232. begin
  2233. AppendText(ParaEl, 'ro');
  2234. AppendNbSp(ParaEl, 1);
  2235. end;
  2236. LinkEl := AppendHyperlink(CreatePara(CreateTD(TREl)), Member);
  2237. if Assigned(LinkEl) then
  2238. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2239. '''; return false;';
  2240. end;
  2241. if (not Assigned(ThisClass.AncestorType)) or
  2242. (not (ThisClass.AncestorType.ClassType = TPasClassType)) then
  2243. break;
  2244. ThisClass := TPasClassType(ThisClass.AncestorType);
  2245. AppendNbSp(CreatePara(CreateTD(CreateTR(TableEl))), 1);
  2246. end;
  2247. end;
  2248. procedure CreateSortedSubpage(AFilter: TMemberFilter);
  2249. var
  2250. List: TList;
  2251. ThisClass: TPasClassType;
  2252. i, j: Integer;
  2253. Member: TPasElement;
  2254. TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
  2255. begin
  2256. List := TList.Create;
  2257. try
  2258. ThisClass := AClass;
  2259. while True do
  2260. begin
  2261. for i := 0 to ThisClass.Members.Count - 1 do
  2262. begin
  2263. Member := TPasElement(ThisClass.Members[i]);
  2264. if (not (((Member.Visibility = visPrivate) and Engine.HidePrivate) or
  2265. ((Member.Visibility = visProtected) and Engine.HideProtected))) and
  2266. AFilter(Member) then
  2267. begin
  2268. j := 0;
  2269. while (j < List.Count) and
  2270. (CompareText(TPasElement(List[j]).Name, Member.Name) < 0) do
  2271. Inc(j);
  2272. List.Insert(j, Member);
  2273. end;
  2274. end;
  2275. if (not Assigned(ThisClass.AncestorType)) or
  2276. (not (ThisClass.AncestorType.ClassType = TPasClassType)) then
  2277. break;
  2278. ThisClass := TPasClassType(ThisClass.AncestorType);
  2279. end;
  2280. TableEl := CreateTable(BodyElement);
  2281. for i := 0 to List.Count - 1 do
  2282. begin
  2283. Member := TPasElement(List[i]);
  2284. TREl := CreateTR(TableEl);
  2285. ParaEl := CreatePara(CreateTD(TREl));
  2286. case Member.Visibility of
  2287. visPrivate:
  2288. AppendText(ParaEl, 'pv');
  2289. visProtected:
  2290. AppendText(ParaEl, 'pt');
  2291. visPublished:
  2292. AppendText(ParaEl, 'pl');
  2293. end;
  2294. AppendNbSp(ParaEl, 1);
  2295. ParaEl := CreatePara(CreateTD(TREl));
  2296. if (Member.ClassType = TPasProperty) and
  2297. (Length(TPasProperty(Member).WriteAccessorName) = 0) then
  2298. begin
  2299. AppendText(ParaEl, 'ro');
  2300. AppendNbSp(ParaEl, 1);
  2301. end;
  2302. TDEl := CreateTD(TREl);
  2303. TDEl['nowrap'] := 'nowrap';
  2304. ParaEl := CreatePara(TDEl);
  2305. LinkEl := AppendHyperlink(ParaEl, Member);
  2306. if Assigned(LinkEl) then
  2307. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2308. '''; return false;';
  2309. AppendText(ParaEl, ' (');
  2310. LinkEl := AppendHyperlink(ParaEl, Member.Parent);
  2311. if Assigned(LinkEl) then
  2312. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  2313. '''; return false;';
  2314. AppendText(ParaEl, ')');
  2315. end;
  2316. finally
  2317. List.Free;
  2318. end;
  2319. end;
  2320. begin
  2321. case ASubpageIndex of
  2322. 0:
  2323. CreateMainPage;
  2324. PropertiesByInheritanceSubindex:
  2325. CreateInheritanceSubpage(@PropertyFilter);
  2326. PropertiesByNameSubindex:
  2327. CreateSortedSubpage(@PropertyFilter);
  2328. MethodsByInheritanceSubindex:
  2329. CreateInheritanceSubpage(@MethodFilter);
  2330. MethodsByNameSubindex:
  2331. CreateSortedSubpage(@MethodFilter);
  2332. EventsByInheritanceSubindex:
  2333. CreateInheritanceSubpage(@EventFilter);
  2334. EventsByNameSubindex:
  2335. CreateSortedSubpage(@EventFilter);
  2336. end;
  2337. end;
  2338. procedure THTMLWriter.CreateClassMemberPageBody(AElement: TPasElement);
  2339. var
  2340. TableEl, TREl, CodeEl: TDOMElement;
  2341. procedure CreateVarPage(Element: TPasVariable);
  2342. begin
  2343. AppendHyperlink(CodeEl, Element.Parent);
  2344. AppendSym(CodeEl, '.');
  2345. AppendText(CodeEl, Element.Name);
  2346. if Assigned(Element.VarType) then
  2347. begin
  2348. AppendSym(CodeEl, ': ');
  2349. AppendSym(AppendType(CodeEl, TableEl, Element.VarType, False), ';');
  2350. end;
  2351. end;
  2352. procedure CreatePropertyPage(Element: TPasProperty);
  2353. var
  2354. NeedBreak: Boolean;
  2355. begin
  2356. AppendKw(CodeEl, 'property ');
  2357. AppendHyperlink(CodeEl, Element.Parent);
  2358. AppendSym(CodeEl, '.');
  2359. AppendText(CodeEl, Element.Name);
  2360. if Assigned(Element.VarType) then
  2361. begin
  2362. AppendSym(CodeEl, ': ');
  2363. AppendType(CodeEl, TableEl, Element.VarType, False);
  2364. end;
  2365. NeedBreak := False;
  2366. if Length(TPasProperty(Element).IndexValue) <> 0 then
  2367. begin
  2368. CreateEl(CodeEl, 'br');
  2369. AppendNbsp(CodeEl, 2);
  2370. AppendKw(CodeEl, 'index ');
  2371. AppendPasSHFragment(CodeEl, TPasProperty(Element).IndexValue, 0);
  2372. NeedBreak := True;
  2373. end;
  2374. if Length(TPasProperty(Element).ReadAccessorName) <> 0 then
  2375. begin
  2376. CreateEl(CodeEl, 'br');
  2377. AppendNbsp(CodeEl, 2);
  2378. AppendKw(CodeEl, 'read ');
  2379. AppendText(CodeEl, TPasProperty(Element).ReadAccessorName);
  2380. NeedBreak := True;
  2381. end;
  2382. if Length(TPasProperty(Element).WriteAccessorName) <> 0 then
  2383. begin
  2384. CreateEl(CodeEl, 'br');
  2385. AppendNbsp(CodeEl, 2);
  2386. AppendKw(CodeEl, 'write ');
  2387. AppendText(CodeEl, TPasProperty(Element).WriteAccessorName);
  2388. NeedBreak := True;
  2389. end;
  2390. if Length(TPasProperty(Element).StoredAccessorName) <> 0 then
  2391. begin
  2392. CreateEl(CodeEl, 'br');
  2393. AppendNbsp(CodeEl, 2);
  2394. AppendKw(CodeEl, 'stored ');
  2395. AppendText(CodeEl, TPasProperty(Element).StoredAccessorName);
  2396. NeedBreak := True;
  2397. end;
  2398. if Length(TPasProperty(Element).DefaultValue) <> 0 then
  2399. begin
  2400. CreateEl(CodeEl, 'br');
  2401. AppendNbsp(CodeEl, 2);
  2402. AppendKw(CodeEl, 'default ');
  2403. AppendPasSHFragment(CodeEl, TPasProperty(Element).DefaultValue, 0);
  2404. NeedBreak := True;
  2405. end;
  2406. AppendSym(CodeEl, ';');
  2407. if TPasProperty(Element).IsDefault or TPasProperty(Element).IsNodefault then
  2408. begin
  2409. if NeedBreak then
  2410. begin
  2411. CreateEl(CodeEl, 'br');
  2412. AppendNbsp(CodeEl, 2);
  2413. end;
  2414. if TPasProperty(Element).IsDefault then
  2415. AppendKw(CodeEl, 'default')
  2416. else
  2417. AppendKw(CodeEl, 'nodefault');
  2418. AppendSym(CodeEl, ';');
  2419. end;
  2420. end;
  2421. var
  2422. s: String;
  2423. DocNode: TDocNode;
  2424. begin
  2425. AppendMenuBar(-1);
  2426. AppendTitle(AElement.FullName);
  2427. AppendShortDescr(CreatePara(BodyElement), AElement);
  2428. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2429. AppendSourceRef(AElement);
  2430. TableEl := CreateTable(BodyElement);
  2431. TREl := CreateTR(TableEl);
  2432. CodeEl := CreateCode(CreatePara(CreateTD(TREl)));
  2433. AppendText(CodeEl, ' '); // !!!: Workaround for current HTML writer
  2434. case AElement.Visibility of
  2435. visPrivate: s := 'private';
  2436. visProtected: s := 'protected';
  2437. visPublic: s := 'public';
  2438. visPublished: s := 'published';
  2439. visAutomated: s := 'automated';
  2440. else s := '';
  2441. end;
  2442. if Length(s) > 0 then
  2443. AppendKw(CodeEl, s);
  2444. AppendText(CodeEl, ' ');
  2445. if AElement.ClassType = TPasVariable then
  2446. CreateVarPage(TPasVariable(AElement))
  2447. else if AElement.InheritsFrom(TPasProcedureBase) then
  2448. AppendProcDecl(CodeEl, TableEl, TPasProcedureBase(AElement))
  2449. else if AElement.ClassType = TPasProperty then
  2450. CreatePropertyPage(TPasProperty(AElement))
  2451. else
  2452. AppendText(CreateWarning(BodyElement), '<' + AElement.ClassName + '>');
  2453. FinishElementPage(AElement);
  2454. end;
  2455. procedure THTMLWriter.CreateVarPageBody(AVar: TPasVariable);
  2456. var
  2457. TableEl, TREl, TDEl, CodeEl, El: TDOMElement;
  2458. DocNode: TDocNode;
  2459. begin
  2460. AppendMenuBar(-1);
  2461. AppendTitle(AVar.FullName);
  2462. AppendShortDescr(CreatePara(BodyElement), AVar);
  2463. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2464. AppendSourceRef(AVar);
  2465. TableEl := CreateTable(BodyElement);
  2466. TREl := CreateTR(TableEl);
  2467. TDEl := CreateTD(TREl);
  2468. CodeEl := CreateCode(CreatePara(TDEl));
  2469. AppendKw(CodeEl, 'var');
  2470. AppendText(CodeEl, ' ' + AVar.Name);
  2471. if Assigned(AVar.VarType) then
  2472. begin
  2473. AppendSym(CodeEl, ': ');
  2474. El := AppendType(CodeEl, TableEl, AVar.VarType, False);
  2475. end else
  2476. El := CodeEl;
  2477. if Length(AVar.Value) > 0 then
  2478. AppendPasSHFragment(El, ' = ' + AVar.Value + ';', 0)
  2479. else
  2480. AppendSym(El, ';');
  2481. FinishElementPage(AVar);
  2482. end;
  2483. procedure THTMLWriter.CreateProcPageBody(AProc: TPasProcedureBase);
  2484. var
  2485. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  2486. begin
  2487. AppendMenuBar(-1);
  2488. AppendTitle(AProc.Name);
  2489. AppendShortDescr(CreatePara(BodyElement), AProc);
  2490. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2491. AppendSourceRef(AProc);
  2492. TableEl := CreateTable(BodyElement);
  2493. TREl := CreateTR(TableEl);
  2494. TDEl := CreateTD(TREl);
  2495. CodeEl := CreateCode(CreatePara(TDEl));
  2496. AppendProcDecl(CodeEl, TableEl, AProc);
  2497. FinishElementPage(AProc);
  2498. end;
  2499. // private methods
  2500. function THTMLWriter.GetPageCount: Integer;
  2501. begin
  2502. Result := PageInfos.Count;
  2503. end;
  2504. end.
  2505. {
  2506. $Log$
  2507. Revision 1.7 2004-07-25 22:40:13 michael
  2508. + Strip path from sourcefilename in generated docs
  2509. Revision 1.6 2004/06/06 10:53:02 michael
  2510. + Added Topic support
  2511. Revision 1.5 2003/11/28 12:51:37 sg
  2512. * Added support for source references
  2513. Revision 1.4 2003/04/22 00:00:05 sg
  2514. * Fixed bug in path building for links to elements which don't have their
  2515. own page, but their parent element has
  2516. Revision 1.3 2003/04/17 14:15:24 sg
  2517. * Added writing of array ranges
  2518. Revision 1.2 2003/03/18 19:28:44 michael
  2519. + Some changes to output handling, more suitable for tex output
  2520. Revision 1.1 2003/03/17 23:03:20 michael
  2521. + Initial import in CVS
  2522. Revision 1.15 2003/03/13 22:02:13 sg
  2523. * New version with many bugfixes and our own parser (now independent of the
  2524. compiler source)
  2525. Revision 1.14 2002/11/15 19:46:32 sg
  2526. * Added support for classes and objects (formerly all objects have been
  2527. written als classes)
  2528. Revision 1.13 2002/05/24 00:13:22 sg
  2529. * much improved new version, including many linking and output fixes
  2530. Revision 1.12 2002/03/12 10:58:36 sg
  2531. * reworked linking engine and internal structure
  2532. Revision 1.11 2002/01/20 11:19:55 michael
  2533. + Added link attribute and property to TFPElement
  2534. Revision 1.10 2001/12/21 11:25:13 sg
  2535. * The parser can now unget two tokens from the scanner
  2536. * Added parsing and HTML output of range types
  2537. * Procedure/function variable bugfixes
  2538. Revision 1.9 2001/12/17 22:34:04 sg
  2539. * Fixed typo in output for menu bar
  2540. Revision 1.8 2001/12/17 13:41:17 jonas
  2541. * OsPathSeparator -> PathDelim
  2542. }