2
0

dw_html.pp 107 KB

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