dw_html.pp 80 KB

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