dw_html.pp 108 KB

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