dw_html.pp 93 KB

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