dw_html.pp 80 KB

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