dw_html.pp 107 KB

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