dw_html.pp 112 KB

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