dw_html.pp 108 KB

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