dw_html.pp 110 KB

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