2
0

dw_html.pp 108 KB

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