dw_html.pp 111 KB

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