dw_html.pp 95 KB

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