dw_html.pp 110 KB

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