dw_html.pp 108 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868
  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 = 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 (Element.ClassType<>TPasModule) do
  2222. Element := Element.Parent;
  2223. Module := TPasModule(Element);
  2224. if AElement.ClassType = 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. end;
  2241. end;
  2242. procedure THTMLWriter.CreateIndexPage(L : TStringList);
  2243. Var
  2244. Lists : Array['A'..'Z'] of TStringList;
  2245. LOther : TStringList;
  2246. CL : TStringList;
  2247. TableEl, TREl, EL: TDOMElement;
  2248. E : TPasElement;
  2249. I,Rows,J,Index : Integer;
  2250. S : String;
  2251. C : Char;
  2252. begin
  2253. For C:='A' to 'Z' do
  2254. Lists[C]:=Nil;
  2255. L.Sort;
  2256. Cl:=Nil;
  2257. // Divide over alphabet
  2258. For I:=0 to L.Count-1 do
  2259. begin
  2260. S:=L[i];
  2261. E:=TPasElement(L.Objects[i]);
  2262. If not (E is TPasUnresolvedTypeRef) then
  2263. begin
  2264. If (S<>'') then
  2265. begin
  2266. C:=Upcase(S[1]);
  2267. If C='_' then
  2268. C:='A';
  2269. If (C in ['A'..'Z']) and (Lists[C]=Nil) then
  2270. begin
  2271. CL:=TStringList.Create;
  2272. Lists[C]:=CL;
  2273. end;
  2274. end;
  2275. if assigned(cl) then
  2276. CL.AddObject(S,E);
  2277. end;
  2278. end;
  2279. Try
  2280. // Create a quick jump table to all available letters.
  2281. TableEl := CreateTable(BodyElement);
  2282. TableEl['border']:='1';
  2283. TableEl['width']:='50%';
  2284. TREl := CreateTR(TableEl);
  2285. for C:='A' to 'Z' do
  2286. If (Lists[C]<>Nil) then
  2287. begin
  2288. El:=CreateTD_vtop(TREl);
  2289. AppendText(CreateLink(El,'#SECTION'+C),C);
  2290. If C<>'Z' then
  2291. AppendNBsp(El,1);
  2292. end;
  2293. // Now emit all identifiers.
  2294. TableEl:=Nil;
  2295. For C:='A' to 'Z' do
  2296. begin
  2297. CL:=Lists[C];
  2298. If CL<>Nil then
  2299. begin
  2300. El:=CreateH2(BodyElement);
  2301. AppendText(El,C);
  2302. CreateAnchor(El,'SECTION'+C);
  2303. TableEl := CreateTable(BodyElement);
  2304. TableEl['Width']:='80%';
  2305. // Determine number of rows needed
  2306. Rows:=(CL.Count div IndexColCount);
  2307. If ((CL.Count Mod IndexColCount)<>0) then
  2308. Inc(Rows);
  2309. // Fill rows
  2310. For I:=0 to Rows-1 do
  2311. begin
  2312. TREl := CreateTR(TableEl);
  2313. For J:=0 to IndexColCount-1 do
  2314. begin
  2315. El:=CreateTD_vtop(TREl);
  2316. Index:=(J*Rows)+I;
  2317. If (Index<CL.Count) then
  2318. begin
  2319. S:=CL[Index];
  2320. E:=TPasElement(CL.Objects[Index]);
  2321. AppendHyperlink(El,E);
  2322. end;
  2323. end;
  2324. end;
  2325. end; // have List
  2326. end; // For C:=
  2327. Finally
  2328. for C:='A' to 'Z' do
  2329. FreeAndNil(Lists[C]);
  2330. end;
  2331. end;
  2332. Procedure THTMLWriter.AddElementsFromList(L : TStrings; List : TFPList; UsePathName : Boolean = False);
  2333. Var
  2334. I : Integer;
  2335. El : TPasElement;
  2336. begin
  2337. For I:=0 to List.Count-1 do
  2338. begin
  2339. El:=TPasElement(List[I]);
  2340. if UsePathName then
  2341. L.AddObject(El.PathName,El)
  2342. else
  2343. L.AddObject(El.Name,El);
  2344. If el is TPasEnumType then
  2345. AddElementsFromList(L,TPasEnumType(el).Values);
  2346. end;
  2347. end;
  2348. procedure THTMLWriter.AddModuleIdentifiers(AModule : TPasModule; L : TStrings);
  2349. begin
  2350. if assigned(AModule.InterfaceSection) Then
  2351. begin
  2352. AddElementsFromList(L,AModule.InterfaceSection.Consts);
  2353. AddElementsFromList(L,AModule.InterfaceSection.Types);
  2354. AddElementsFromList(L,AModule.InterfaceSection.Functions);
  2355. AddElementsFromList(L,AModule.InterfaceSection.Classes);
  2356. AddElementsFromList(L,AModule.InterfaceSection.Variables);
  2357. AddElementsFromList(L,AModule.InterfaceSection.ResStrings);
  2358. end;
  2359. end;
  2360. procedure THTMLWriter.CreatePackageIndex;
  2361. Var
  2362. L : TStringList;
  2363. I : Integer;
  2364. M : TPasModule;
  2365. E : TPasElement;
  2366. S : String;
  2367. begin
  2368. L:=TStringList.Create;
  2369. try
  2370. L.Capacity:=PageInfos.Count; // Too much, but that doesn't hurt.
  2371. For I:=0 to Package.Modules.Count-1 do
  2372. begin
  2373. M:=TPasModule(Package.Modules[i]);
  2374. L.AddObject(M.Name,M);
  2375. AddModuleIdentifiers(M,L);
  2376. end;
  2377. AppendMenuBar(IndexSubIndex);
  2378. S:=Package.Name;
  2379. If Length(S)>0 then
  2380. Delete(S,1,1);
  2381. AppendTitle(Format(SDocPackageIndex, [S]));
  2382. CreateIndexPage(L);
  2383. Finally
  2384. L.Free;
  2385. end;
  2386. end;
  2387. procedure THTMLWriter.CreatePackagePageBody;
  2388. var
  2389. DocNode: TDocNode;
  2390. TableEl, TREl: TDOMElement;
  2391. i: Integer;
  2392. ThisModule: TPasModule;
  2393. L : TStringList;
  2394. begin
  2395. AppendMenuBar(0);
  2396. AppendTitle(Format(SDocPackageTitle, [Copy(Package.Name, 2, 256)]));
  2397. AppendShortDescr(CreatePara(BodyElement), Package);
  2398. AppendText(CreateH2(BodyElement), SDocUnits);
  2399. TableEl := CreateTable(BodyElement);
  2400. L:=TStringList.Create;
  2401. Try
  2402. L.Sorted:=True;
  2403. // Sort modules.
  2404. For I:=0 to Package.Modules.Count-1 do
  2405. L.AddObject(TPasModule(Package.Modules[i]).Name,TPasModule(Package.Modules[i]));
  2406. // Now create table.
  2407. for i:=0 to L.Count - 1 do
  2408. begin
  2409. ThisModule := TPasModule(L.Objects[i]);
  2410. TREl := CreateTR(TableEl);
  2411. AppendHyperlink(CreateCode(CreatePara(CreateTD_vtop(TREl))), ThisModule);
  2412. AppendShortDescrCell(TREl, ThisModule);
  2413. end;
  2414. Finally
  2415. L.Free;
  2416. end;
  2417. DocNode := Engine.FindDocNode(Package);
  2418. if Assigned(DocNode) then
  2419. begin
  2420. if Assigned(DocNode.Descr) then
  2421. AppendDescrSection(nil, BodyElement, DocNode.Descr, SDocDescription);
  2422. CreateTopicLinks(DocNode,Package);
  2423. end;
  2424. end;
  2425. Procedure THTMLWriter.CreateTopicLinks(Node : TDocNode; PasElement : TPasElement);
  2426. var
  2427. DocNode: TDocNode;
  2428. TableEl, TREl: TDOMElement;
  2429. First : Boolean;
  2430. ThisTopic: TPasElement;
  2431. begin
  2432. DocNode:=Node.FirstChild;
  2433. First:=True;
  2434. While Assigned(DocNode) do
  2435. begin
  2436. If DocNode.TopicNode then
  2437. begin
  2438. if first then
  2439. begin
  2440. First:=False;
  2441. AppendText(CreateH2(BodyElement), SDocRelatedTopics);
  2442. TableEl := CreateTable(BodyElement);
  2443. end;
  2444. TREl := CreateTR(TableEl);
  2445. ThisTopic:=FindTopicElement(DocNode);
  2446. if Assigned(ThisTopic) then
  2447. AppendHyperlink(CreateCode(CreatePara(CreateTD_vtop(TREl))), ThisTopic);
  2448. AppendShortDescrCell(TREl, ThisTopic);
  2449. end;
  2450. DocNode:=DocNode.NextSibling;
  2451. end;
  2452. end;
  2453. procedure THTMLWriter.CreateModuleIndexPage(AModule: TPasModule);
  2454. Var
  2455. L : TStringList;
  2456. begin
  2457. L:=TStringList.Create;
  2458. try
  2459. AddModuleIdentifiers(AModule,L);
  2460. AppendMenuBar(IndexSubIndex);
  2461. AppendTitle(Format(SDocModuleIndex, [AModule.Name]));
  2462. CreateIndexPage(L);
  2463. Finally
  2464. L.Free;
  2465. end;
  2466. end;
  2467. procedure THTMLWriter.CreateModulePageBody(AModule: TPasModule;
  2468. ASubpageIndex: Integer);
  2469. procedure CreateMainPage;
  2470. var
  2471. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  2472. i: Integer;
  2473. UnitRef: TPasType;
  2474. DocNode: TDocNode;
  2475. begin
  2476. AppendMenuBar(0);
  2477. AppendTitle(Format(SDocUnitTitle, [AModule.Name]));
  2478. AppendShortDescr(CreatePara(BodyElement), AModule);
  2479. if AModule.InterfaceSection.UsesList.Count > 0 then
  2480. begin
  2481. TableEl := CreateTable(BodyElement);
  2482. AppendKw(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), 'uses');
  2483. for i := 0 to AModule.InterfaceSection.UsesList.Count - 1 do
  2484. begin
  2485. UnitRef := TPasType(AModule.InterfaceSection.UsesList[i]);
  2486. DocNode := Engine.FindDocNode(UnitRef);
  2487. if Assigned(DocNode) and DocNode.IsSkipped then
  2488. continue;
  2489. TREl := CreateTR(TableEl);
  2490. TDEl := CreateTD_vtop(TREl);
  2491. CodeEl := CreateCode(CreatePara(TDEl));
  2492. AppendNbSp(CodeEl, 2);
  2493. AppendHyperlink(CodeEl, UnitRef);
  2494. if i < AModule.InterfaceSection.UsesList.Count - 1 then
  2495. AppendSym(CodeEl, ',')
  2496. else
  2497. AppendSym(CodeEl, ';');
  2498. AppendText(CodeEl, ' '); // Space for descriptions
  2499. AppendShortDescrCell(TREl, UnitRef);
  2500. end;
  2501. end;
  2502. DocNode := Engine.FindDocNode(AModule);
  2503. if Assigned(DocNode) then
  2504. begin
  2505. if Assigned(DocNode.Descr) then
  2506. AppendDescrSection(AModule, BodyElement, DocNode.Descr, SDocOverview);
  2507. ConvertNotes(AModule,DocNode.Notes);
  2508. CreateTopicLinks(DocNode,AModule);
  2509. end;
  2510. end;
  2511. procedure CreateSimpleSubpage(const ATitle: DOMString; AList: TFPList);
  2512. var
  2513. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  2514. i, j: Integer;
  2515. Decl: TPasElement;
  2516. SortedList: TFPList;
  2517. DocNode: TDocNode;
  2518. S : String;
  2519. begin
  2520. AppendMenuBar(ASubpageIndex);
  2521. S:=ATitle;
  2522. AppendTitle(Format(SDocUnitTitle + ': %s', [AModule.Name, S]));
  2523. SortedList := TFPList.Create;
  2524. try
  2525. for i := 0 to AList.Count - 1 do
  2526. begin
  2527. Decl := TPasElement(AList[i]);
  2528. DocNode := Engine.FindDocNode(Decl);
  2529. if (not Assigned(DocNode)) or (not DocNode.IsSkipped) then
  2530. begin
  2531. j := 0;
  2532. while (j < SortedList.Count) and (CompareText(
  2533. TPasElement(SortedList[j]).PathName, Decl.PathName) < 0) do
  2534. Inc(j);
  2535. SortedList.Insert(j, Decl);
  2536. end;
  2537. end;
  2538. TableEl := CreateTable(BodyElement);
  2539. for i := 0 to SortedList.Count - 1 do
  2540. begin
  2541. Decl := TPasElement(SortedList[i]);
  2542. TREl := CreateTR(TableEl);
  2543. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  2544. AppendHyperlink(CodeEl, Decl);
  2545. AppendShortDescrCell(TREl, Decl);
  2546. end;
  2547. finally
  2548. SortedList.Free;
  2549. end;
  2550. end;
  2551. procedure CreateResStringsPage;
  2552. var
  2553. ParaEl: TDOMElement;
  2554. i, j: Integer;
  2555. Decl: TPasResString;
  2556. DocNode: TDocNode;
  2557. begin
  2558. AppendMenuBar(ResstrSubindex);
  2559. AppendTitle(Format(SDocUnitTitle + ': %s', [AModule.Name, SDocResStrings]));
  2560. for i := 0 to AModule.InterfaceSection.ResStrings.Count - 1 do
  2561. begin
  2562. Decl := TPasResString(AModule.InterfaceSection.ResStrings[i]);
  2563. CreateEl(BodyElement, 'a')['name'] := LowerCase(Decl.Name);
  2564. ParaEl := CreatePara(BodyElement);
  2565. AppendText(CreateCode(ParaEl), Decl.Name);
  2566. CreateEl(ParaEl, 'br');
  2567. AppendText(ParaEl, Decl.Expr.getDeclaration(true));
  2568. end;
  2569. end;
  2570. begin
  2571. case ASubpageIndex of
  2572. 0:
  2573. CreateMainPage;
  2574. ResstrSubindex:
  2575. CreateResStringsPage;
  2576. ConstsSubindex:
  2577. CreateSimpleSubpage(SDocConstants, AModule.InterfaceSection.Consts);
  2578. TypesSubindex:
  2579. CreateSimpleSubpage(SDocTypes, AModule.InterfaceSection.Types);
  2580. ClassesSubindex:
  2581. CreateSimpleSubpage(SDocClasses, AModule.InterfaceSection.Classes);
  2582. ProcsSubindex:
  2583. CreateSimpleSubpage(SDocProceduresAndFunctions, AModule.InterfaceSection.Functions);
  2584. VarsSubindex:
  2585. CreateSimpleSubpage(SDocVariables, AModule.InterfaceSection.Variables);
  2586. IndexSubIndex:
  2587. CreateModuleIndexPage(AModule);
  2588. end;
  2589. end;
  2590. procedure THTMLWriter.CreateConstPageBody(AConst: TPasConst);
  2591. var
  2592. TableEl, CodeEl: TDOMElement;
  2593. begin
  2594. AppendMenuBar(-1);
  2595. AppendTitle(AConst.Name);
  2596. AppendShortDescr(CreatePara(BodyElement), AConst);
  2597. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2598. AppendSourceRef(AConst);
  2599. TableEl := CreateTable(BodyElement);
  2600. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  2601. AppendKw(CodeEl, 'const');
  2602. AppendText(CodeEl, ' ' + AConst.Name);
  2603. if Assigned(AConst.VarType) then
  2604. begin
  2605. AppendSym(CodeEl, ': ');
  2606. AppendType(CodeEl, TableEl, AConst.VarType, False);
  2607. end;
  2608. AppendPasSHFragment(CodeEl, ' = ' + AConst.Expr.GetDeclaration(True) + ';', 0);
  2609. FinishElementPage(AConst);
  2610. end;
  2611. procedure THTMLWriter.AppendTypeDecl(AType: TPasType; TableEl,CodeEl : TDomElement);
  2612. Var
  2613. TREl : TDomElement;
  2614. i: Integer;
  2615. s: String;
  2616. EnumType: TPasEnumType;
  2617. EnumValue: TPasEnumValue;
  2618. Variable: TPasVariable;
  2619. begin
  2620. // Alias
  2621. if AType.ClassType = TPasAliasType then
  2622. begin
  2623. if Assigned(TPasAliasType(AType).DestType) then
  2624. AppendHyperlink(CodeEl, TPasAliasType(AType).DestType)
  2625. else
  2626. AppendText(CreateWarning(CodeEl), '<Destination type is NIL>');
  2627. AppendSym(CodeEl, ';');
  2628. end else
  2629. // Class of
  2630. if AType.ClassType = TPasClassOfType then
  2631. begin
  2632. AppendKw(CodeEl, 'class of ');
  2633. AppendHyperlink(CodeEl, TPasClassOfType(AType).DestType);
  2634. AppendSym(CodeEl, ';');
  2635. end else
  2636. // Enumeration
  2637. if AType.ClassType = TPasEnumType then
  2638. begin
  2639. AppendSym(CodeEl, '(');
  2640. for i := 0 to TPasEnumType(AType).Values.Count - 1 do
  2641. begin
  2642. EnumValue := TPasEnumValue(TPasEnumType(AType).Values[i]);
  2643. TREl := CreateTR(TableEl);
  2644. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  2645. AppendShortDescrCell(TREl, EnumValue);
  2646. AppendNbSp(CodeEl, 2);
  2647. s := EnumValue.Name;
  2648. if EnumValue.AssignedValue<>'' then
  2649. s := s + ' = ' + EnumValue.AssignedValue;
  2650. if i < TPasEnumType(AType).Values.Count - 1 then
  2651. s := s + ',';
  2652. AppendPasSHFragment(CodeEl, s, 0);
  2653. end;
  2654. AppendSym(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), ');');
  2655. end else
  2656. // Pointer type
  2657. if AType.ClassType = TPasPointerType then
  2658. begin
  2659. AppendSym(CodeEl, '^');
  2660. if Assigned(TPasPointerType(AType).DestType) then
  2661. AppendHyperlink(CodeEl, TPasPointerType(AType).DestType)
  2662. else
  2663. AppendText(CreateWarning(CodeEl), '<Destination type is NIL>');
  2664. AppendSym(CodeEl, ';');
  2665. end else
  2666. if AType.InheritsFrom(TPasProcedureType) then
  2667. begin
  2668. AppendSym(AppendType(CodeEl, TableEl, TPasType(AType), True), ';');
  2669. AppendProcArgsSection(BodyElement, TPasProcedureType(AType));
  2670. end else
  2671. // Record
  2672. if AType.ClassType = TPasRecordType then
  2673. begin
  2674. CodeEl := AppendRecordType(CodeEl, TableEl, TPasRecordType(AType), 0);
  2675. AppendSym(CodeEl, ';');
  2676. end else
  2677. // Set
  2678. if AType.ClassType = TPasSetType then
  2679. begin
  2680. AppendKw(CodeEl, 'set of ');
  2681. if TPasSetType(AType).EnumType.ClassType = TPasEnumType then
  2682. begin
  2683. AppendSym(CodeEl, '(');
  2684. EnumType := TPasEnumType(TPasSetType(AType).EnumType);
  2685. for i := 0 to EnumType.Values.Count - 1 do
  2686. begin
  2687. EnumValue := TPasEnumValue(EnumType.Values[i]);
  2688. TREl := CreateTR(TableEl);
  2689. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  2690. AppendShortDescrCell(TREl, EnumValue);
  2691. AppendNbSp(CodeEl, 2);
  2692. s := EnumValue.Name;
  2693. if (EnumValue.AssignedValue<>'') then
  2694. s := s + ' = ' + EnumValue.AssignedValue;
  2695. if i < EnumType.Values.Count - 1 then
  2696. s := s + ',';
  2697. AppendPasSHFragment(CodeEl, s, 0);
  2698. end;
  2699. AppendSym(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), ');');
  2700. end else
  2701. begin
  2702. AppendHyperlink(CodeEl, TPasSetType(AType).EnumType);
  2703. AppendSym(CodeEl, ';');
  2704. end;
  2705. end else
  2706. // Type alias
  2707. if AType.ClassType = TPasTypeAliasType then
  2708. begin
  2709. AppendKw(CodeEl, 'type ');
  2710. AppendHyperlink(CodeEl, TPasTypeAliasType(AType).DestType);
  2711. AppendSym(CodeEl, ';');
  2712. end else
  2713. // Probably one of the simple types, which allowed in other places as wel...
  2714. AppendSym(AppendType(CodeEl, TableEl, TPasType(AType), True), ';');
  2715. end;
  2716. procedure THTMLWriter.CreateTypePageBody(AType: TPasType);
  2717. var
  2718. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  2719. DocNode: TDocNode;
  2720. i: Integer;
  2721. s: String;
  2722. EnumType: TPasEnumType;
  2723. EnumValue: TPasEnumValue;
  2724. Variable: TPasVariable;
  2725. begin
  2726. AppendMenuBar(-1);
  2727. AppendTitle(AType.Name);
  2728. AppendShortDescr(CreatePara(BodyElement), AType);
  2729. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2730. AppendSourceRef(AType);
  2731. TableEl := CreateTable(BodyElement);
  2732. TREl := CreateTR(TableEl);
  2733. TDEl := CreateTD(TREl);
  2734. CodeEl := CreateCode(CreatePara(TDEl));
  2735. DocNode := Engine.FindDocNode(AType);
  2736. AppendKw(CodeEl, 'type ');
  2737. AppendText(CodeEl, AType.Name);
  2738. AppendSym(CodeEl, ' = ');
  2739. If Assigned(DocNode) and
  2740. Assigned(DocNode.Node) and
  2741. (Docnode.Node['opaque']='1') then
  2742. AppendText(CodeEl,SDocOpaque)
  2743. else
  2744. begin
  2745. AppendTypeDecl(AType,TableEl,CodeEl);
  2746. end;
  2747. FinishElementPage(AType);
  2748. end;
  2749. function PropertyFilter(AMember: TPasElement): Boolean;
  2750. begin
  2751. Result := (AMember.ClassType = TPasProperty) and
  2752. (Copy(AMember.Name, 1, 2) <> 'On');
  2753. end;
  2754. function MethodFilter(AMember: TPasElement): Boolean;
  2755. begin
  2756. Result := AMember.InheritsFrom(TPasProcedureBase);
  2757. end;
  2758. function EventFilter(AMember: TPasElement): Boolean;
  2759. begin
  2760. Result := (AMember.ClassType = TPasProperty) and
  2761. (Copy(AMember.Name, 1, 2) = 'On');
  2762. end;
  2763. procedure THTMLWriter.CreateClassPageBody(AClass: TPasClassType;
  2764. ASubpageIndex: Integer);
  2765. type
  2766. TMemberFilter = function(AMember: TPasElement): Boolean;
  2767. var
  2768. ParaEl: TDOMElement;
  2769. procedure AppendMemberListLink(AListSubpageIndex: Integer;
  2770. const AText: DOMString);
  2771. var
  2772. LinkEl: TDOMElement;
  2773. begin
  2774. if FUseMenuBrackets then
  2775. AppendText(ParaEl, '[');
  2776. LinkEl := CreateEl(ParaEl, 'a');
  2777. LinkEl['href'] :=
  2778. FixHtmlPath(ResolveLinkWithinPackage(AClass, AListSubpageIndex));
  2779. LinkEl['onClick'] := 'window.open(''' + LinkEl['href'] + ''', ''list'', ' +
  2780. '''dependent=yes,resizable=yes,scrollbars=yes,height=400,width=300''); return false;';
  2781. AppendText(LinkEl, AText);
  2782. AppendText(ParaEl, ' (');
  2783. LinkEl := CreateEl(ParaEl, 'a');
  2784. LinkEl['href'] :=
  2785. FixHtmlPath(ResolveLinkWithinPackage(AClass, AListSubpageIndex + 1));
  2786. LinkEl['onClick'] := 'window.open(''' + LinkEl['href'] + ''', ''list'', ' +
  2787. '''dependent=yes,resizable=yes,scrollbars=yes,height=400,width=300''); return false;';
  2788. AppendText(LinkEl, SDocByName);
  2789. AppendText(ParaEl, ')');
  2790. if FUseMenuBrackets then
  2791. AppendText(ParaEl, '] ')
  2792. else
  2793. AppendText(ParaEl, ' ');
  2794. end;
  2795. procedure AppendGenericTypes(CodeEl : TDomElement; AList : TFPList; isSpecialize : Boolean);
  2796. Var
  2797. I : integer;
  2798. begin
  2799. for I:=0 to AList.Count-1 do
  2800. begin
  2801. if I=0 then
  2802. AppendSym(CodeEl, '<')
  2803. else
  2804. AppendSym(CodeEl, ',');
  2805. AppendText(CodeEl,TPasGenericTemplateType(AList[i]).Name);
  2806. end;
  2807. AppendSym(CodeEl, '>');
  2808. end;
  2809. procedure CreateMainPage;
  2810. var
  2811. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  2812. DocNode: TDocNode;
  2813. Member: TPasElement;
  2814. MVisibility,
  2815. CurVisibility: TPasMemberVisibility;
  2816. i: Integer;
  2817. s: String;
  2818. t : TPasType;
  2819. ah,ol,wt,ct,wc,cc : boolean;
  2820. ThisInterface,
  2821. ThisClass: TPasClassType;
  2822. HaveSeenTObject: Boolean;
  2823. LName : String;
  2824. ThisNode : TPasUnresolvedTypeRef;
  2825. begin
  2826. AppendMenuBar(-1);
  2827. AppendTitle(AClass.Name);
  2828. ParaEl := CreatePara(BodyElement);
  2829. AppendMemberListLink(PropertiesByInheritanceSubindex, SDocProperties);
  2830. AppendMemberListLink(MethodsByInheritanceSubindex, SDocMethods);
  2831. AppendMemberListLink(EventsByInheritanceSubindex, SDocEvents);
  2832. AppendShortDescr(CreatePara(BodyElement), AClass);
  2833. AppendText(CreateH2(BodyElement), SDocDeclaration);
  2834. AppendSourceRef(AClass);
  2835. TableEl := CreateTable(BodyElement);
  2836. TREl := CreateTR(TableEl);
  2837. TDEl := CreateTD(TREl);
  2838. CodeEl := CreateCode(CreatePara(TDEl));
  2839. AppendKw(CodeEl, 'type');
  2840. if AClass.ObjKind=okGeneric then
  2841. AppendKw(CodeEl, ' generic ');
  2842. AppendText(CodeEl, ' ' + AClass.Name + ' ');
  2843. if AClass.ObjKind=okGeneric then
  2844. AppendGenericTypes(CodeEl,AClass.GenericTemplateTypes,false);
  2845. AppendSym(CodeEl, '=');
  2846. AppendText(CodeEl, ' ');
  2847. if AClass.ObjKind<>okSpecialize then
  2848. AppendKw(CodeEl, ObjKindNames[AClass.ObjKind])
  2849. else
  2850. AppendKw(CodeEl, ' specialize ');
  2851. if Assigned(AClass.AncestorType) then
  2852. begin
  2853. if AClass.ObjKind=okSpecialize then
  2854. begin
  2855. AppendHyperlink(CodeEl, AClass.AncestorType);
  2856. AppendGenericTypes(CodeEl,AClass.GenericTemplateTypes,true)
  2857. end
  2858. else
  2859. begin
  2860. AppendSym(CodeEl, '(');
  2861. AppendHyperlink(CodeEl, AClass.AncestorType);
  2862. if AClass.Interfaces.count>0 Then
  2863. begin
  2864. for i:=0 to AClass.interfaces.count-1 do
  2865. begin
  2866. AppendSym(CodeEl, ', ');
  2867. AppendHyperlink(CodeEl,TPasClassType(AClass.Interfaces[i]));
  2868. end;
  2869. end;
  2870. AppendSym(CodeEl, ')');
  2871. end;
  2872. end;
  2873. if AClass.Members.Count > 0 then
  2874. begin
  2875. wt:=False;
  2876. wc:=False;
  2877. CurVisibility := visDefault;
  2878. for i := 0 to AClass.Members.Count - 1 do
  2879. begin
  2880. Member := TPasElement(AClass.Members[i]);
  2881. MVisibility:=Member.Visibility;
  2882. ol:=(Member is TPasOverloadedProc);
  2883. ah:=ol or ((Member is TPasProcedure) and (TPasProcedure(Member).ProcType.Args.Count > 0));
  2884. if ol then
  2885. Member:=TPasElement((Member as TPasOverloadedProc).Overloads[0]);
  2886. if ((MVisibility = visPrivate) and Engine.HidePrivate) or
  2887. ( (MVisibility = visProtected) and Engine.HideProtected) then
  2888. continue;
  2889. if (CurVisibility <> MVisibility) then
  2890. begin
  2891. CurVisibility := MVisibility;
  2892. s:=VisibilityNames[MVisibility];
  2893. AppendKw(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), s);
  2894. end;
  2895. ct:=(Member is TPasType);
  2896. if ct and (not wt) then
  2897. begin
  2898. AppendKw(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), 'Type');
  2899. end;
  2900. wt:=ct;
  2901. cc:=(Member is TPasConst);
  2902. if cc and (not wc) then
  2903. begin
  2904. AppendKw(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), 'Const');
  2905. end;
  2906. wc:=cc;
  2907. TREl := CreateTR(TableEl);
  2908. CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
  2909. AppendNbSp(CodeEl, 2);
  2910. AppendShortDescrCell(TREl, Member);
  2911. if (Member is TPasProcedureBase) then
  2912. begin
  2913. AppendKw(CodeEl, TPasProcedureBase(Member).TypeName + ' ');
  2914. AppendHyperlink(CodeEl, Member);
  2915. if ah then
  2916. AppendSym(CodeEl, '();')
  2917. else
  2918. AppendSym(CodeEl, ';');
  2919. if Not OL then
  2920. AppendProcExt(CodeEl, TPasProcedure(Member));
  2921. end
  2922. else if (Member is TPasConst) then
  2923. begin
  2924. AppendHyperlink(CodeEl, Member);
  2925. If Assigned(TPasConst(Member).VarType) then
  2926. begin
  2927. AppendSym(CodeEl, ' = ');
  2928. AppendTypeDecl(TPasType(Member),TableEl,CodeEl);
  2929. end;
  2930. AppendSym(CodeEl, ' = ');
  2931. AppendText(CodeEl,TPasConst(Member).Expr.GetDeclaration(True));
  2932. end
  2933. else if (Member is TPasType) then
  2934. begin
  2935. AppendHyperlink(CodeEl, Member);
  2936. AppendSym(CodeEl, ' = ');
  2937. AppendTypeDecl(TPasType(Member),TableEl,CodeEl);
  2938. end
  2939. else if (Member is TPasProperty) then
  2940. begin
  2941. AppendKw(CodeEl, 'property ');
  2942. AppendHyperlink(CodeEl, Member);
  2943. t:=TPasProperty(Member).ResolvedType;
  2944. if Assigned(T) then
  2945. begin
  2946. AppendSym(CodeEl, ': ');
  2947. AppendHyperlink(CodeEl, T);
  2948. end;
  2949. AppendSym(CodeEl, ';');
  2950. if TPasProperty(Member).IsDefault then
  2951. begin
  2952. AppendKw(CodeEl, ' default');
  2953. AppendSym(CodeEl, ';');
  2954. end;
  2955. if (TPasProperty(Member).ImplementsName<>'') then
  2956. begin
  2957. AppendKw(CodeEl, ' implements');
  2958. AppendText(CodeEl, ' '+TPasProperty(Member).ImplementsName);
  2959. AppendSym(CodeEl, ';');
  2960. end;
  2961. SetLength(s, 0);
  2962. if Length(TPasProperty(Member).ReadAccessorName) > 0 then
  2963. s := s + 'r';
  2964. if Length(TPasProperty(Member).WriteAccessorName) > 0 then
  2965. s := s + 'w';
  2966. if Length(TPasProperty(Member).StoredAccessorName) > 0 then
  2967. s := s + 's';
  2968. if Length(s) > 0 then
  2969. AppendText(CodeEl, ' [' + s + ']');
  2970. end
  2971. else if (Member is TPasVariable) then
  2972. begin
  2973. AppendHyperlink(CodeEl, Member);
  2974. AppendSym(CodeEl, ': ');
  2975. AppendHyperlink(CodeEl, TPasVariable(Member).VarType);
  2976. AppendSym(CodeEl, ';');
  2977. end
  2978. else
  2979. AppendText(CreateWarning(CodeEl), '<' + Member.ClassName + '>');
  2980. end;
  2981. CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
  2982. end;
  2983. AppendText(CodeEl, ' '); // !!!: Dirty trick, necessary for current XML writer
  2984. if not AClass.IsShortDefinition then
  2985. AppendKw(CodeEl, 'end');
  2986. AppendSym(CodeEl, ';');
  2987. AppendText(CreateH2(BodyElement), SDocInheritance);
  2988. TableEl := CreateTable(BodyElement);
  2989. HaveSeenTObject := AClass.ObjKind <> okClass;
  2990. // we try to track classes. But imported classes
  2991. // are TLinkNode's not the TPasClassType generated by the parser.
  2992. ThisClass := AClass; ThisNode := Nil;
  2993. while True do
  2994. begin
  2995. TREl := CreateTR(TableEl);
  2996. TDEl := CreateTD_vtop(TREl);
  2997. TDEl['align'] := 'center';
  2998. CodeEl := CreateCode(CreatePara(TDEl));
  2999. if Assigned(ThisClass) then
  3000. LName:=ThisClass.Name
  3001. Else
  3002. LName:=ThisNode.Name;
  3003. if Assigned(ThisClass) Then
  3004. AppendHyperlink(CodeEl, ThisClass)
  3005. else
  3006. AppendHyperlink(CodeEl, ThisNode);
  3007. if Assigned(ThisClass) and (ThisClass.Interfaces.count>0) then
  3008. begin
  3009. for i:=0 to ThisClass.interfaces.count-1 do
  3010. begin
  3011. ThisInterface:=TPasClassType(ThisClass.Interfaces[i]);
  3012. AppendText(CodeEl,',');
  3013. AppendHyperlink(CodeEl, ThisInterface);
  3014. end;
  3015. end;
  3016. AppendShortDescrCell(TREl, ThisClass);
  3017. if HaveSeenTObject or (CompareText(LName, 'TObject') = 0) then
  3018. HaveSeenTObject := True
  3019. else
  3020. begin
  3021. TDEl := CreateTD(CreateTR(TableEl));
  3022. TDEl['align'] := 'center';
  3023. AppendText(TDEl, '|');
  3024. end;
  3025. if Assigned(ThisClass.AncestorType) then
  3026. begin
  3027. if ThisClass.AncestorType.InheritsFrom(TPasClassType) then
  3028. ThisClass := TPasClassType(ThisClass.AncestorType)
  3029. else
  3030. begin
  3031. TDEl := CreateTD(CreateTR(TableEl));
  3032. TDEl['align'] := 'center';
  3033. AppendText(CreateCode(CreatePara(TDEl)), ThisClass.AncestorType.Name);
  3034. if CompareText(ThisClass.AncestorType.Name, 'TObject') = 0 then
  3035. HaveSeenTObject := True
  3036. else
  3037. begin
  3038. TDEl := CreateTD(CreateTR(TableEl));
  3039. TDEl['align'] := 'center';
  3040. AppendText(TDEl, '?');
  3041. end;
  3042. break;
  3043. end
  3044. end else
  3045. break;
  3046. end;
  3047. if not HaveSeenTObject then
  3048. begin
  3049. TDEl := CreateTD(CreateTR(TableEl));
  3050. TDEl['align'] := 'center';
  3051. AppendText(CreateCode(CreatePara(TDEl)), 'TObject');
  3052. end;
  3053. FinishElementPage(AClass);
  3054. end;
  3055. procedure CreateInheritanceSubpage(AFilter: TMemberFilter);
  3056. var
  3057. ThisClass: TPasClassType;
  3058. i: Integer;
  3059. Member: TPasElement;
  3060. TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
  3061. begin
  3062. TableEl := CreateTable(BodyElement);
  3063. ThisClass := AClass;
  3064. while True do
  3065. begin
  3066. TREl := CreateTR(TableEl);
  3067. TDEl := CreateTD(TREl);
  3068. TDEl['colspan'] := '3';
  3069. CreateTD(TREl);
  3070. LinkEl := AppendHyperlink(CreateEl(CreateCode(CreatePara(TDEl)), 'b'), ThisClass);
  3071. if Assigned(LinkEl) then
  3072. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  3073. '''; return false;';
  3074. for i := 0 to ThisClass.Members.Count - 1 do
  3075. begin
  3076. Member := TPasElement(ThisClass.Members[i]);
  3077. if ((Member.Visibility = visPrivate) and Engine.HidePrivate) or
  3078. ((Member.Visibility = visProtected) and Engine.HideProtected) or
  3079. not AFilter(Member) then
  3080. continue;
  3081. TREl := CreateTR(TableEl);
  3082. ParaEl := CreatePara(CreateTD(TREl));
  3083. case Member.Visibility of
  3084. visPrivate:
  3085. AppendText(ParaEl, 'pv');
  3086. visProtected:
  3087. AppendText(ParaEl, 'pt');
  3088. visPublished:
  3089. AppendText(ParaEl, 'pl');
  3090. end;
  3091. AppendNbSp(ParaEl, 1);
  3092. ParaEl := CreateTD(TREl);
  3093. if (Member.ClassType = TPasProperty) and
  3094. (Length(TPasProperty(Member).WriteAccessorName) = 0) then
  3095. begin
  3096. AppendText(ParaEl, 'ro');
  3097. AppendNbSp(ParaEl, 1);
  3098. end;
  3099. LinkEl := AppendHyperlink(CreatePara(CreateTD(TREl)), Member);
  3100. if Assigned(LinkEl) then
  3101. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  3102. '''; return false;';
  3103. end;
  3104. if (not Assigned(ThisClass.AncestorType)) or
  3105. (not (ThisClass.AncestorType.ClassType = TPasClassType)) then
  3106. break;
  3107. ThisClass := TPasClassType(ThisClass.AncestorType);
  3108. AppendNbSp(CreatePara(CreateTD(CreateTR(TableEl))), 1);
  3109. end;
  3110. end;
  3111. procedure CreateSortedSubpage(AFilter: TMemberFilter);
  3112. var
  3113. List: TFPList;
  3114. ThisClass: TPasClassType;
  3115. i, j: Integer;
  3116. Member: TPasElement;
  3117. TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
  3118. begin
  3119. List := TFPList.Create;
  3120. try
  3121. ThisClass := AClass;
  3122. while True do
  3123. begin
  3124. for i := 0 to ThisClass.Members.Count - 1 do
  3125. begin
  3126. Member := TPasElement(ThisClass.Members[i]);
  3127. if (not (((Member.Visibility = visPrivate) and Engine.HidePrivate) or
  3128. ((Member.Visibility = visProtected) and Engine.HideProtected))) and
  3129. AFilter(Member) then
  3130. begin
  3131. j := 0;
  3132. while (j < List.Count) and
  3133. (CompareText(TPasElement(List[j]).Name, Member.Name) < 0) do
  3134. Inc(j);
  3135. List.Insert(j, Member);
  3136. end;
  3137. end;
  3138. if (not Assigned(ThisClass.AncestorType)) or
  3139. (not (ThisClass.AncestorType.ClassType = TPasClassType)) then
  3140. break;
  3141. ThisClass := TPasClassType(ThisClass.AncestorType);
  3142. end;
  3143. TableEl := CreateTable(BodyElement);
  3144. for i := 0 to List.Count - 1 do
  3145. begin
  3146. Member := TPasElement(List[i]);
  3147. TREl := CreateTR(TableEl);
  3148. ParaEl := CreatePara(CreateTD(TREl));
  3149. case Member.Visibility of
  3150. visPrivate:
  3151. AppendText(ParaEl, 'pv');
  3152. visProtected:
  3153. AppendText(ParaEl, 'pt');
  3154. visPublished:
  3155. AppendText(ParaEl, 'pl');
  3156. end;
  3157. AppendNbSp(ParaEl, 1);
  3158. ParaEl := CreatePara(CreateTD(TREl));
  3159. if (Member.ClassType = TPasProperty) and
  3160. (Length(TPasProperty(Member).WriteAccessorName) = 0) then
  3161. begin
  3162. AppendText(ParaEl, 'ro');
  3163. AppendNbSp(ParaEl, 1);
  3164. end;
  3165. TDEl := CreateTD(TREl);
  3166. TDEl['nowrap'] := 'nowrap';
  3167. ParaEl := CreatePara(TDEl);
  3168. LinkEl := AppendHyperlink(ParaEl, Member);
  3169. if Assigned(LinkEl) then
  3170. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  3171. '''; return false;';
  3172. AppendText(ParaEl, ' (');
  3173. LinkEl := AppendHyperlink(ParaEl, Member.Parent);
  3174. if Assigned(LinkEl) then
  3175. LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
  3176. '''; return false;';
  3177. AppendText(ParaEl, ')');
  3178. end;
  3179. finally
  3180. List.Free;
  3181. end;
  3182. end;
  3183. begin
  3184. case ASubpageIndex of
  3185. 0:
  3186. CreateMainPage;
  3187. PropertiesByInheritanceSubindex:
  3188. CreateInheritanceSubpage(@PropertyFilter);
  3189. PropertiesByNameSubindex:
  3190. CreateSortedSubpage(@PropertyFilter);
  3191. MethodsByInheritanceSubindex:
  3192. CreateInheritanceSubpage(@MethodFilter);
  3193. MethodsByNameSubindex:
  3194. CreateSortedSubpage(@MethodFilter);
  3195. EventsByInheritanceSubindex:
  3196. CreateInheritanceSubpage(@EventFilter);
  3197. EventsByNameSubindex:
  3198. CreateSortedSubpage(@EventFilter);
  3199. end;
  3200. end;
  3201. procedure THTMLWriter.CreateClassMemberPageBody(AElement: TPasElement);
  3202. var
  3203. TableEl, TREl, CodeEl: TDOMElement;
  3204. procedure CreateVarPage(Element: TPasVariable);
  3205. begin
  3206. AppendHyperlink(CodeEl, Element.Parent);
  3207. AppendSym(CodeEl, '.');
  3208. AppendText(CodeEl, Element.Name);
  3209. if Assigned(Element.VarType) then
  3210. begin
  3211. AppendSym(CodeEl, ' : ');
  3212. AppendSym(AppendType(CodeEl, TableEl, Element.VarType, False), ';');
  3213. end;
  3214. end;
  3215. procedure CreateTypePage(Element: TPasType);
  3216. begin
  3217. AppendKw(CodeEl, 'type ');
  3218. AppendHyperlink(CodeEl, Element.Parent);
  3219. AppendSym(CodeEl, '.');
  3220. AppendText(CodeEl, Element.Name);
  3221. AppendSym(CodeEl, ' = ');
  3222. AppendTypeDecl(Element,TableEl,CodeEl)
  3223. end;
  3224. procedure CreateConstPage(Element: TPasConst);
  3225. begin
  3226. AppendKw(CodeEl, 'const ');
  3227. AppendHyperlink(CodeEl, Element.Parent);
  3228. AppendSym(CodeEl, '.');
  3229. AppendText(CodeEl, Element.Name);
  3230. if Assigned(Element.VarType) then
  3231. begin
  3232. AppendSym(CodeEl, ': ');
  3233. AppendType(CodeEl, TableEl, Element.VarType, False);
  3234. end;
  3235. AppendPasSHFragment(CodeEl, ' = ' + Element.Expr.GetDeclaration(True) + ';', 0);
  3236. end;
  3237. procedure CreatePropertyPage(Element: TPasProperty);
  3238. var
  3239. NeedBreak: Boolean;
  3240. T : TPasType;
  3241. begin
  3242. AppendKw(CodeEl, 'property ');
  3243. AppendHyperlink(CodeEl, Element.Parent);
  3244. AppendSym(CodeEl, '.');
  3245. AppendText(CodeEl, Element.Name);
  3246. T:=Element.ResolvedType;
  3247. if Assigned(T) then
  3248. begin
  3249. AppendSym(CodeEl, ' : ');
  3250. AppendType(CodeEl, TableEl, T, False);
  3251. end;
  3252. NeedBreak := False;
  3253. if Length(TPasProperty(Element).IndexValue) <> 0 then
  3254. begin
  3255. CreateEl(CodeEl, 'br');
  3256. AppendNbsp(CodeEl, 2);
  3257. AppendKw(CodeEl, 'index ');
  3258. AppendPasSHFragment(CodeEl, TPasProperty(Element).IndexValue, 0);
  3259. NeedBreak := True;
  3260. end;
  3261. if Length(TPasProperty(Element).ReadAccessorName) <> 0 then
  3262. begin
  3263. CreateEl(CodeEl, 'br');
  3264. AppendNbsp(CodeEl, 2);
  3265. AppendKw(CodeEl, 'read ');
  3266. AppendText(CodeEl, TPasProperty(Element).ReadAccessorName);
  3267. NeedBreak := True;
  3268. end;
  3269. if Length(TPasProperty(Element).WriteAccessorName) <> 0 then
  3270. begin
  3271. CreateEl(CodeEl, 'br');
  3272. AppendNbsp(CodeEl, 2);
  3273. AppendKw(CodeEl, 'write ');
  3274. AppendText(CodeEl, TPasProperty(Element).WriteAccessorName);
  3275. NeedBreak := True;
  3276. end;
  3277. if Length(TPasProperty(Element).StoredAccessorName) <> 0 then
  3278. begin
  3279. CreateEl(CodeEl, 'br');
  3280. AppendNbsp(CodeEl, 2);
  3281. AppendKw(CodeEl, 'stored ');
  3282. AppendText(CodeEl, TPasProperty(Element).StoredAccessorName);
  3283. NeedBreak := True;
  3284. end;
  3285. if Length(TPasProperty(Element).DefaultValue) <> 0 then
  3286. begin
  3287. CreateEl(CodeEl, 'br');
  3288. AppendNbsp(CodeEl, 2);
  3289. AppendKw(CodeEl, 'default ');
  3290. AppendPasSHFragment(CodeEl, TPasProperty(Element).DefaultValue, 0);
  3291. NeedBreak := True;
  3292. end;
  3293. AppendSym(CodeEl, ';');
  3294. if TPasProperty(Element).IsDefault or TPasProperty(Element).IsNodefault then
  3295. begin
  3296. if NeedBreak then
  3297. begin
  3298. CreateEl(CodeEl, 'br');
  3299. AppendNbsp(CodeEl, 2);
  3300. end;
  3301. if TPasProperty(Element).IsDefault then
  3302. AppendKw(CodeEl, 'default')
  3303. else
  3304. AppendKw(CodeEl, 'nodefault');
  3305. AppendSym(CodeEl, ';');
  3306. end;
  3307. end;
  3308. var
  3309. s: String;
  3310. DocNode: TDocNode;
  3311. begin
  3312. AppendMenuBar(-1);
  3313. AppendTitle(AElement.FullName);
  3314. AppendShortDescr(CreatePara(BodyElement), AElement);
  3315. AppendText(CreateH2(BodyElement), SDocDeclaration);
  3316. AppendSourceRef(AElement);
  3317. TableEl := CreateTable(BodyElement);
  3318. TREl := CreateTR(TableEl);
  3319. CodeEl := CreateCode(CreatePara(CreateTD(TREl)));
  3320. AppendText(CodeEl, ' '); // !!!: Workaround for current HTML writer
  3321. if (AElement.Visibility<>visDefault) then
  3322. begin
  3323. s:=VisibilityNames[AElement.Visibility];
  3324. AppendKw(CodeEl, s);
  3325. end;
  3326. AppendText(CodeEl, ' ');
  3327. if AElement is TPasProperty then
  3328. CreatePropertyPage(TPasProperty(AElement))
  3329. else if AElement is TPasConst then
  3330. CreateConstPage(TPasConst(AElement))
  3331. else if (AElement is TPasVariable) then
  3332. CreateVarPage(TPasVariable(AElement))
  3333. else if AElement is TPasProcedureBase then
  3334. AppendProcDecl(CodeEl, TableEl, TPasProcedureBase(AElement))
  3335. else if AElement is TPasType then
  3336. CreateTypePage(TPasType(AElement))
  3337. else
  3338. AppendText(CreateWarning(BodyElement), '<' + AElement.ClassName + '>');
  3339. FinishElementPage(AElement);
  3340. end;
  3341. procedure THTMLWriter.CreateVarPageBody(AVar: TPasVariable);
  3342. var
  3343. TableEl, TREl, TDEl, CodeEl, El: TDOMElement;
  3344. DocNode: TDocNode;
  3345. begin
  3346. AppendMenuBar(-1);
  3347. AppendTitle(AVar.FullName);
  3348. AppendShortDescr(CreatePara(BodyElement), AVar);
  3349. AppendText(CreateH2(BodyElement), SDocDeclaration);
  3350. AppendSourceRef(AVar);
  3351. TableEl := CreateTable(BodyElement);
  3352. TREl := CreateTR(TableEl);
  3353. TDEl := CreateTD(TREl);
  3354. CodeEl := CreateCode(CreatePara(TDEl));
  3355. AppendKw(CodeEl, 'var');
  3356. AppendText(CodeEl, ' ' + AVar.Name);
  3357. if Assigned(AVar.VarType) then
  3358. begin
  3359. AppendSym(CodeEl, ': ');
  3360. El := AppendType(CodeEl, TableEl, AVar.VarType, False);
  3361. end else
  3362. El := CodeEl;
  3363. if Length(AVar.Value) > 0 then
  3364. AppendPasSHFragment(El, ' = ' + AVar.Value + ';', 0)
  3365. else
  3366. AppendSym(El, ';');
  3367. FinishElementPage(AVar);
  3368. end;
  3369. procedure THTMLWriter.CreateProcPageBody(AProc: TPasProcedureBase);
  3370. var
  3371. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  3372. begin
  3373. AppendMenuBar(-1);
  3374. AppendTitle(AProc.Name);
  3375. AppendShortDescr(CreatePara(BodyElement), AProc);
  3376. AppendText(CreateH2(BodyElement), SDocDeclaration);
  3377. AppendSourceRef(AProc);
  3378. TableEl := CreateTable(BodyElement);
  3379. TREl := CreateTR(TableEl);
  3380. TDEl := CreateTD(TREl);
  3381. CodeEl := CreateCode(CreatePara(TDEl));
  3382. AppendProcDecl(CodeEl, TableEl, AProc);
  3383. FinishElementPage(AProc);
  3384. end;
  3385. Function THTMLWriter.InterPretOption(Const Cmd,Arg : String) : boolean;
  3386. begin
  3387. Result:=True;
  3388. if Cmd = '--html-search' then
  3389. SearchPage := Arg
  3390. else if Cmd = '--footer' then
  3391. FooterFile := Arg
  3392. else if Cmd = '--charset' then
  3393. CharSet := Arg
  3394. else if Cmd = '--index-colcount' then
  3395. IndexColCount := StrToIntDef(Arg,IndexColCount)
  3396. else if Cmd = '--image-url' then
  3397. FBaseImageURL := Arg
  3398. else if Cmd = '--css-file' then
  3399. FCSSFile := arg
  3400. else if Cmd = '--footer-date' then
  3401. begin
  3402. FIDF:=True;
  3403. FDateFormat:=Arg;
  3404. end
  3405. else if Cmd = '--disable-menu-brackets' then
  3406. FUseMenuBrackets:=False
  3407. else
  3408. Result:=False;
  3409. end;
  3410. procedure THTMLWriter.WriteDoc;
  3411. begin
  3412. DoLog(SWritingPages, [PageCount]);
  3413. WriteHTMLPages;
  3414. end;
  3415. class procedure THTMLWriter.Usage(List: TStrings);
  3416. begin
  3417. List.add('--footer');
  3418. List.Add(SHTMLUsageFooter);
  3419. List.Add('--footer-date[=Fmt]');
  3420. List.Add(SHTMLUsageFooterDate);
  3421. List.Add('--charset=set');
  3422. List.Add(SHTMLUsageCharset);
  3423. List.Add('--html-search=pagename');
  3424. List.Add(SHTMLHtmlSearch);
  3425. List.Add('--index-colcount=N');
  3426. List.Add(SHTMLIndexColcount);
  3427. List.Add('--image-url=url');
  3428. List.Add(SHTMLImageUrl);
  3429. List.Add('--disable-menu-brackets');
  3430. List.Add(SHTMLDisableMenuBrackets);
  3431. end;
  3432. class procedure THTMLWriter.SplitImport(var AFilename, ALinkPrefix: String);
  3433. var
  3434. i: integer;
  3435. begin
  3436. i := Pos(',', AFilename);
  3437. if i > 0 then
  3438. begin //split into filename and prefix
  3439. ALinkPrefix := Copy(AFilename,i+1,Length(AFilename));
  3440. SetLength(AFilename, i-1);
  3441. end
  3442. else if ALinkPrefix = '' then
  3443. begin //synthesize outdir\pgk.xct, ..\pkg
  3444. ALinkPrefix := '../' + ChangeFileExt(ExtractFileName(AFilename), '');
  3445. AFilename := ChangeFileExt(AFilename, '.xct');
  3446. end;
  3447. end;
  3448. Class Function THTMLWriter.FileNameExtension : String;
  3449. begin
  3450. result:='';
  3451. end;
  3452. // private methods
  3453. function THTMLWriter.GetPageCount: Integer;
  3454. begin
  3455. Result := PageInfos.Count;
  3456. end;
  3457. procedure THTMLWriter.SetOnTest(const AValue: TNotifyEvent);
  3458. begin
  3459. if FOnTest=AValue then exit;
  3460. FOnTest:=AValue;
  3461. end;
  3462. procedure THTMLWriter.CreateAllocator;
  3463. begin
  3464. FAllocator:=TLongNameFileAllocator.Create('.html');
  3465. end;
  3466. procedure THTMWriter.CreateAllocator;
  3467. begin
  3468. FAllocator:=TShortNameFileAllocator.Create('.htm');
  3469. end;
  3470. initialization
  3471. // Do not localize.
  3472. RegisterWriter(THTMLWriter,'html','HTML output using fpdoc.css stylesheet.');
  3473. RegisterWriter(THTMWriter,'htm','HTM (8.3 filenames) output using fpdoc.css stylesheet.');
  3474. RegisterWriter(TCHMHTMLWriter,'chm','Compressed HTML file output using fpdoc.css stylesheet.');
  3475. finalization
  3476. UnRegisterWriter('html');
  3477. UnRegisterWriter('htm');
  3478. UnRegisterWriter('chm');
  3479. end.