dw_html.pp 112 KB

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