dw_html.pp 111 KB

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