dw_html.pp 82 KB

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