dw_html.pp 95 KB

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