dw_newhtml.pp 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405
  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_newhtml;
  15. {$WARN 5024 off : Parameter "$1" not used}
  16. interface
  17. uses Classes, DOM, DOM_HTML, dGlobals, PasTree, dWriter, dw_basehtml, PasWrite;
  18. type
  19. { TNewHTMLWriter }
  20. TNewHTMLWriter = class(TBaseHTMLWriter)
  21. private
  22. FCreateSideMenu: Boolean;
  23. FHeadElement: TDomElement;
  24. FOnTest: TNotifyEvent;
  25. FCSSFile: String;
  26. FCharSet : String;
  27. FHeaderHTML,
  28. FNavigatorHTML,
  29. FFooterHTML: TStringStream;
  30. FTitleElement: TDOMElement;
  31. FIncludeDateInFooter : Boolean;
  32. FUseMenuBrackets: Boolean;
  33. FDateFormat: String;
  34. FIndexColCount : Integer;
  35. FSearchPage : String;
  36. function GetVarDef(aElement: TPasVariable; aPrefixParent: Boolean): string;
  37. procedure SetModuleInfo(aElement: TPasElement; ASubpageIndex: integer);
  38. procedure SetOnTest(const AValue: TNotifyEvent);
  39. protected
  40. function CreateAllocator : TFileAllocator; override;
  41. procedure WriteDocPage(const aFileName: String; aElement: TPasElement; aSubPageIndex: Integer); override;
  42. // General HTML creation
  43. function CreateH1(Parent: TDOMNode): THTMLElement; override;
  44. function CreateH2(Parent: TDOMNode): THTMLElement; override;
  45. function CreateH3(Parent: TDOMNode): THTMLElement; override;
  46. function CreateListColumn1(aParent: THTMLElement): THTMLElement;
  47. function CreateListColumn2(aParent: THTMLElement): THTMLElement;
  48. function CreateListColumns(aParent: THTMLElement): THTMLElement;
  49. function CreateSection(aParent : THTMLElement) : THTMLElement; virtual;
  50. procedure DescrWriteFileEl(const AText: DOMString); override;
  51. procedure DescrWriteVarEl(const AText: DOMString); override;
  52. function AppendPasSHFragment(Parent: TDOMNode; const AText: String; AShFlags: Byte): Byte; override;
  53. function AppendPasSHFragment(Parent: TDOMNode; const AText: String; AShFlags: Byte; aLinkIdentifierMap : TLinkIdentifierMap): Byte; override;
  54. procedure CreateCSSFile; virtual;
  55. procedure AppendTitle(aParent: TDomElement; const AText: AnsiString; Hints : TPasMemberHints = []); virtual;
  56. procedure AppendTitle(aParent: TDomElement; const AText: DOMString; Hints: TPasMemberHints=[]); virtual;
  57. function AppendType(CodeEl: TDOMElement; Element: TPasType): TDOMElement; virtual;
  58. function AppendProcType(CodeEl : TDOMElement; Element: TPasProcedureType; Indent: Integer): TDOMElement; virtual;
  59. procedure AppendProcExt(CodeEl: TDOMElement; Element: TPasProcedure); virtual;
  60. procedure AppendProcDecl(CodeEl: TDOMElement; Element: TPasProcedureBase); virtual;
  61. procedure AppendProcArgsSection(Parent: THTMLElement; Element: TPasProcedureType; SkipResult : Boolean = False); virtual;
  62. procedure AppendShortDescrCell(Parent: TDOMNode; Element: TPasElement); override;
  63. procedure AppendDescrSection(AContext: TPasElement; Parent: TDOMNode; DescrNode: TDOMElement; const ATitle: DOMString); override;
  64. Procedure AppendSeeAlsoSection(AElement: TPasElement; aParent : TDOMElement; DocNode: TDocNode); override;
  65. // Structural elements
  66. procedure AppendMenuBar(ASubpageIndex: Integer);virtual;
  67. procedure AppendTopicMenuBar(Topic : TTopicElement);virtual;
  68. procedure FinishElementPage(AElement: TPasElement; aDescription: Boolean=True); virtual;
  69. procedure AppendFooter;virtual;
  70. procedure AppendSideMenuScript(aHead : THTMLElement);
  71. procedure AppendSideMenu(aMenu: THTMLElement);
  72. // Class
  73. procedure CreateClassMainPage(aClass: TPasClassType);virtual;
  74. procedure CreateClassInheritedSubpage(AClass: TPasClassType; aType: TClassMemberType);
  75. procedure CreateClassSortedSubpage(AClass: TPasClassType; aType : TClassMemberType);virtual;
  76. procedure CreateClassMemberList(aParent: THTMLElement; AClass: TPasClassType; DeclaredOnly: Boolean; AFilter: TMemberFilter);
  77. procedure AppendMemberListSection(aParent: THTMLELement; aClass: TPasClassType; aMemberType : TClassMemberType; aDeclaredOnly: Boolean);
  78. procedure AppendInheritanceTree(aParent: THTMLELement; aClass: TPasClassType);
  79. // Package
  80. procedure CreatePageBody(AElement: TPasElement; ASubpageIndex: Integer); virtual;
  81. procedure CreatePackagePageBody;virtual;
  82. procedure CreatePackageIndex;
  83. procedure CreatePackageClassHierarchy;
  84. procedure CreateClassHierarchyPage(AddUnit : Boolean);
  85. procedure CreateIndexPage(aParent : THTMLElement; L : TStringList); virtual;
  86. // Topic
  87. Procedure CreateTopicPageBody(AElement : TTopicElement);
  88. // Module
  89. procedure CreateModuleMainPage(aModule: TPasModule);virtual;
  90. procedure CreateModuleSimpleSubpage(aModule: TPasModule; ASubpageIndex: Integer; const ATitle: DOMString; AList: TFPList);virtual;
  91. procedure CreateModuleResStringsPage(aModule: TPasModule);virtual;
  92. procedure CreateModulePageBody(AModule: TPasModule; ASubpageIndex: Integer);
  93. procedure CreateModuleIndexPage(AModule: TPasModule); virtual;
  94. // Identifiers
  95. procedure CreateConstPageBody(AConst: TPasConst);
  96. procedure CreateTypePageBody(AType: TPasType);
  97. procedure CreateClassPageBody(AClass: TPasClassType; ASubpageIndex: Integer);
  98. procedure CreateClassMemberPageBody(AElement: TPasElement);
  99. procedure CreateVarPageBody(AVar: TPasVariable);
  100. procedure CreateProcPageBody(AProc: TPasProcedureBase);
  101. Procedure CreateTopicLinks(aParent : THTMLElement; Node : TDocNode; PasElement : TPasElement);
  102. // Type declarations
  103. function GetElementCode(aElement: TPasElement; aSparse: boolean; aFlags: TElementFlags = []): String;
  104. function AppendHighlightedCode(aParent: TDOMNode; aCode: String; const aLanguage: String=''; aMap: TLinkIdentifierMap = Nil): THTMLElement;
  105. function CreateCodeLines(aLines: array of string): string;
  106. procedure AppendTypeDecl(AType: TPasType);
  107. procedure AppendAliasTypeDecl(aType: TPasAliasType);
  108. procedure AppendClassOfTypeDecl(aType: TPasClassOfType);
  109. function AppendCodeBlock(aParent: TDOMNode; const aLanguage: String=''): THTMLElement;
  110. procedure AppendEnumTypeDecl(aType: TPasEnumType);
  111. procedure AppendPointerTypeDecl(aType: TPasPointerType);
  112. procedure AppendProcedureTypeDecl(aType: TPasProcedureType);
  113. procedure AppendRecordTypeDecl(aType: TPasRecordType);
  114. procedure AppendSetTypeDecl(aType: TPasSetType);
  115. procedure AppendTypeAliasTypeDecl(aType: TPasTypeAliasType);
  116. // Main documentation process
  117. Procedure DoWriteDocumentation; override;
  118. Property HeaderHTML : TStringStream Read FHeaderHTML;
  119. Property NavigatorHTML : TStringStream read FNavigatorHTML;
  120. Property FooterHTML : TStringStream read FFooterHTML;
  121. Property CSSFile : String Read FCSSFile;
  122. Property HeadElement : TDomElement Read FHeadElement;
  123. Property TitleElement: TDOMElement Read FTitleElement;
  124. public
  125. // Creating all module hierarchy classes happens here !
  126. constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
  127. // Overrides
  128. Class Function FileNameExtension : String; override;
  129. class procedure Usage(List: TStrings); override;
  130. Class procedure SplitImport(var AFilename, ALinkPrefix: String); override;
  131. Function InterPretOption(Const Cmd,Arg : String) : boolean; override;
  132. // Single-page generation
  133. function CreateHTMLPage(AElement: TPasElement; ASubpageIndex: Integer): TXMLDocument; virtual;
  134. Property SearchPage: String Read FSearchPage Write FSearchPage;
  135. Property IncludeDateInFooter : Boolean Read FIncludeDateInFooter Write FIncludeDateInFooter;
  136. Property DateFormat : String Read FDateFormat Write FDateFormat;
  137. property OnTest: TNotifyEvent read FOnTest write SetOnTest;
  138. Property CharSet : String Read FCharSet Write FCharSet;
  139. Property IndexColCount : Integer Read FIndexColCount write FIndexColCount;
  140. Property CreateSideMenu : Boolean Read FCreateSideMenu Write FCreateSideMenu;
  141. end;
  142. implementation
  143. uses fpdocstrs, SysUtils, HTMWrite, syntax.highlighter, syntax.pascal, fpdocclasstree;
  144. {$i newcss.inc}
  145. constructor TNewHTMLWriter.Create(APackage: TPasPackage; AEngine: TFPDocEngine);
  146. begin
  147. inherited Create(APackage, AEngine);
  148. // should default to true since this is the old behavior
  149. CreateSideMenu:=True;
  150. IndexColCount:=3;
  151. Charset:='iso-8859-1';
  152. FCSSFile:='fpdocs.css';
  153. end;
  154. procedure TNewHTMLWriter.AppendSideMenuScript(aHead: THTMLElement);
  155. Const
  156. SFunc =
  157. ' document.addEventListener("DOMContentLoaded", () => {'+sLinebreak+
  158. ' const toggleButton = document.getElementById("menu-toggle");'+sLinebreak+
  159. ' const sideMenu = document.getElementById("side-menu");'+sLinebreak+
  160. ' const mainContent = document.getElementById("main-content");'+sLinebreak+
  161. ' if (toggleButton && sideMenu && mainContent) {'+sLinebreak+
  162. ' toggleButton.addEventListener("click", () => {'+sLinebreak+
  163. ' sideMenu.classList.toggle("is-expanded");'+sLinebreak+
  164. ' mainContent.classList.toggle("is-shifted");'+sLinebreak+
  165. ' });'+sLinebreak+
  166. ' }'+sLinebreak+
  167. ' });';
  168. Var
  169. SE : THTMLElement;
  170. begin
  171. SE:=Doc.CreateElement('script');
  172. aHead.AppendChild(SE);
  173. AppendText(SE,SFunc);
  174. end;
  175. procedure TNewHTMLWriter.AppendSideMenu(aMenu: THTMLElement);
  176. function AddLink(aParent : THTMLElement; ALinkSubpageIndex: Integer; const AName: String) : THTMLElement;
  177. begin
  178. Result:=CreateLink(aParent, ResolveLinkWithinPackage(Module, ALinkSubpageIndex));
  179. AppendText(Result,aName);
  180. end;
  181. function AddPackageLink(aParent: THTMLElement; ALinkSubpageIndex: Integer; const AName: String) : THTMLElement;
  182. var
  183. lURL : String;
  184. begin
  185. lURL:=ResolveLinkWithinPackage(Package, ALinkSubpageIndex);
  186. Result:=CreateLink(aParent,lURL);
  187. AppendText(Result,aName);
  188. end;
  189. var
  190. lPara,lList,lItem : THTMLElement;
  191. lModules : TStringList;
  192. lModule : TPasModule;
  193. I : Integer;
  194. begin
  195. lPara:=CreateEl(aMenu,'p','menu-label');
  196. AppendText(lPara,SDocPackageLinkTitle);
  197. lList:=CreateEl(aMenu,'ul','menu-list');
  198. lItem:=CreateEl(lList,'li');
  199. if Assigned(Module) then
  200. AddPackageLink(lItem,0, SDocReference);
  201. //El:=AppendHyperlink(lItem, Package) as THTMLELement;
  202. lItem:=CreateEl(lList,'li');
  203. AddPackageLink(lItem,IndexSubIndex, SDocIdentifierIndex);
  204. lItem:=CreateEl(lList,'li');
  205. AddPackageLink(lItem,ClassHierarchySubIndex, SDocPackageClassHierarchy);
  206. lPara:=CreateEl(aMenu,'p','menu-label');
  207. AppendText(lPara,SDocUnits);
  208. lList:=CreateEl(aMenu,'ul','menu-list');
  209. lModules:=TStringList.Create;
  210. try
  211. For I:=0 to Package.Modules.Count-1 do
  212. begin
  213. lModule:=TPasModule(Package.Modules[I]);
  214. lModules.AddObject(lModule.Name,lModule);
  215. end;
  216. lModules.Sort;
  217. For I:=0 to lModules.Count-1 do
  218. begin
  219. lModule:=TPasModule(lModules.Objects[I]);
  220. lItem:=CreateEl(lList,'li');
  221. AppendHyperlink(lItem, lModule);
  222. end;
  223. finally
  224. LModules.Free;
  225. end;
  226. end;
  227. procedure TNewHTMLWriter.SetModuleInfo(aElement : TPasElement; ASubpageIndex : integer);
  228. var
  229. i : integer;
  230. Element : TPasElement;
  231. begin
  232. CurDirectory := Allocator.GetFilename(AElement, ASubpageIndex);
  233. i := Length(CurDirectory);
  234. while (i > 0) and not (CurDirectory[i] in AllowDirectorySeparators) do
  235. Dec(i);
  236. CurDirectory := Copy(CurDirectory, 1, i);
  237. BaseDirectory := Allocator.GetRelativePathToTop(AElement);
  238. if aElement is TPasPackage then
  239. Module:=Nil
  240. else
  241. begin
  242. Element := AElement;
  243. while (Element<>Nil) and (not (Element.ClassType.inheritsfrom(TPasModule))) do
  244. Element := Element.Parent;
  245. Module := TPasModule(Element);
  246. end;
  247. end;
  248. function TNewHTMLWriter.CreateHTMLPage(AElement: TPasElement;
  249. ASubpageIndex: Integer): TXMLDocument;
  250. var
  251. HTMLEl: THTMLHtmlElement;
  252. HeadEl: THTMLHeadElement;
  253. LMain,lMenu,LContent,BodyElement : THTMLElement;
  254. El: TDOMElement;
  255. begin
  256. Result := THTMLDocument.Create;
  257. SetHTMLDocument(THTMLDocument(Result));
  258. Doc.AppendChild(Doc.Impl.CreateDocumentType('html','',''));
  259. HTMLEl := Doc.CreateHtmlElement;
  260. Doc.AppendChild(HTMLEl);
  261. HeadEl := Doc.CreateHeadElement;
  262. FHeadElement:=HeadEl;
  263. HTMLEl.AppendChild(HeadEl);
  264. El := Doc.CreateElement('meta');
  265. HeadEl.AppendChild(El);
  266. El['http-equiv'] := 'Content-Type';
  267. El['content'] := 'text/html; charset=utf-8';
  268. El := Doc.CreateElement('meta');
  269. HeadEl.AppendChild(El);
  270. El['name'] := 'viewport';
  271. El['content'] := 'width=device-width, initial-scale=1';
  272. FTitleElement := Doc.CreateElement('title');
  273. HeadEl.AppendChild(TitleElement);
  274. BodyElement := Doc.CreateElement('body');
  275. BodyElement['class']:='has-navbar-fixed-top';
  276. ContentElement:=BodyElement;
  277. HTMLEl.AppendChild(BodyElement);
  278. SetModuleInfo(aElement,ASubpageIndex);
  279. AppendMenuBar(ASubpageIndex);
  280. if CreateSideMenu then
  281. begin
  282. AppendSideMenuScript(HeadEl);
  283. LMain:=CreateEl(ContentElement,'div');
  284. LMain['id']:='main-layout';
  285. lMenu:=CreateEl(lMain,'aside','is-expanded');
  286. LMenu['id']:='side-menu';
  287. AppendSideMenu(lMenu);
  288. LContent:=CreateEl(lMain,'div','is-shifted');
  289. LContent['id']:='main-content';
  290. ContentElement:=lContent;
  291. end;
  292. CreatePageBody(AElement, ASubpageIndex);
  293. AppendFooter;
  294. El := Doc.CreateElement('link');
  295. HeadEl.AppendChild(El);
  296. El['rel'] := 'stylesheet';
  297. El['type'] := 'text/css';
  298. El['href'] := UTF8Decode(FixHtmlPath(UTF8Encode(Allocator.GetCSSFilename(AElement,'bulma'))));
  299. El := Doc.CreateElement('link');
  300. HeadEl.AppendChild(El);
  301. El['rel'] := 'stylesheet';
  302. El['type'] := 'text/css';
  303. El['href'] := UTF8Decode(FixHtmlPath(UTF8Encode(Allocator.GetCSSFilename(AElement,'fpdocs'))));
  304. end;
  305. procedure TNewHTMLWriter.WriteDocPage(const aFileName: String; aElement: TPasElement; aSubPageIndex: Integer);
  306. Var
  307. PageDoc: TXMLDocument;
  308. FN : String;
  309. begin
  310. PageDoc := CreateHTMLPage(aElement, aSubpageIndex);
  311. try
  312. FN:=GetFileBaseDir(Engine.Output)+aFilename;
  313. //writeln('Element: ',Element.PathName, ' FileName: ', FN);
  314. WriteHTMLFile(PageDoc, FN);
  315. except
  316. on E: Exception do
  317. DoLog(SErrCouldNotCreateFile, [aFileName, e.Message]);
  318. end;
  319. PageDoc.Free;
  320. end;
  321. function TNewHTMLWriter.CreateH1(Parent: TDOMNode): THTMLElement;
  322. begin
  323. Result:=inherited CreateH1(Parent);
  324. Result['class']:='subtitle is-2'
  325. end;
  326. function TNewHTMLWriter.CreateH2(Parent: TDOMNode): THTMLElement;
  327. begin
  328. Result:=inherited CreateH2(Parent);
  329. Result['class']:='subtitle is-4'
  330. end;
  331. function TNewHTMLWriter.CreateH3(Parent: TDOMNode): THTMLElement;
  332. begin
  333. Result:=inherited CreateH3(Parent);
  334. Result['class']:='subtitle is-6'
  335. end;
  336. procedure TNewHTMLWriter.DoWriteDocumentation;
  337. begin
  338. Inherited;
  339. CreateCSSFile;
  340. end;
  341. procedure TNewHTMLWriter.CreateCSSFile;
  342. Var
  343. TempStream: TMemoryStream;
  344. Data : PByte;
  345. begin
  346. TempStream := TMemoryStream.Create;
  347. try
  348. if (FCSSFile<>'') then
  349. begin
  350. if not FileExists(FCSSFile) then
  351. begin
  352. DoLog('Can''t find CSS file "%s"',[FCSSFILE]);
  353. halt(1);
  354. end;
  355. TempStream.LoadFromFile(FCSSFile);
  356. end
  357. else
  358. begin
  359. DoLog('Using built-in CSS file',[]);
  360. Data:=@DefaultNewCSS;
  361. TempStream.WriteBuffer(Data^,SizeOf(DefaultNewCSS));
  362. end;
  363. TempStream.Position := 0;
  364. TempStream.SaveToFile(Engine.output+'fpdocs.css');
  365. finally
  366. TempStream.Free;
  367. end;
  368. end;
  369. { Returns the new CodeEl, which will be the old CodeEl in most cases }
  370. function TNewHTMLWriter.AppendType(CodeEl: TDOMElement; Element: TPasType): TDOMElement;
  371. Var
  372. S : String;
  373. begin
  374. Result := CodeEl;
  375. S:=GetElementCode(Element, False);
  376. // Writeln('Default code for "',Element.ClassName,'"(',Element.FullName,'):',S);
  377. AppendHighlightedCode(ContentElement,S);
  378. end;
  379. function TNewHTMLWriter.AppendProcType(CodeEl: TDOMElement;
  380. Element: TPasProcedureType; Indent: Integer): TDOMElement;
  381. var
  382. i: Integer;
  383. Arg: TPasArgument;
  384. S : String;
  385. begin
  386. if Element.Args.Count > 0 then
  387. begin
  388. AppendSym(CodeEl, '(');
  389. for i := 0 to Element.Args.Count - 1 do
  390. begin
  391. Arg := TPasArgument(Element.Args[i]);
  392. S:=AccessNames[Arg.Access];
  393. if (S<>'') then
  394. AppendKw(CodeEl,S);
  395. AppendText(CodeEl, Arg.Name);
  396. if Assigned(Arg.ArgType) then
  397. begin
  398. AppendSym(CodeEl, ': ');
  399. CodeEl := AppendType(CodeEl, Arg.ArgType);
  400. end;
  401. if Length(Arg.Value) > 0 then
  402. AppendPasSHFragment(CodeEl, ' = ' + Arg.Value, 0);
  403. if i < Element.Args.Count - 1 then
  404. AppendSym(CodeEl, ';');
  405. end;
  406. if Element.InheritsFrom(TPasFunctionType) or Element.IsOfObject then
  407. begin
  408. if Element.InheritsFrom(TPasFunctionType) then
  409. begin
  410. AppendSym(CodeEl, '):');
  411. AppendHyperlink(CodeEl, TPasFunctionType(Element).ResultEl.ResultType);
  412. end else
  413. AppendSym(CodeEl, ')');
  414. if Element.IsOfObject then
  415. begin
  416. AppendText(CodeEl, ' '); // Don't remove
  417. AppendKw(CodeEl, 'of object');
  418. end;
  419. end else
  420. if Indent > 0 then
  421. AppendSym(CodeEl, ')')
  422. else
  423. begin
  424. AppendSym(CodeEl, ')');
  425. end;
  426. end
  427. else
  428. begin
  429. { Procedure or function without arguments }
  430. if Element.InheritsFrom(TPasFunctionType) then
  431. begin
  432. AppendSym(CodeEl, ': ');
  433. AppendHyperlink(CodeEl, TPasFunctionType(Element).ResultEl.ResultType);
  434. end;
  435. if Element.IsOfObject then
  436. AppendKw(CodeEl, ' of object');
  437. end;
  438. Result := CodeEl;
  439. end;
  440. procedure TNewHTMLWriter.AppendProcExt(CodeEl: TDOMElement;
  441. Element: TPasProcedure);
  442. procedure AppendExt(const Ext: String);
  443. begin
  444. AppendKw(CodeEl, ' ' + Ext);
  445. AppendSym(CodeEl, ';');
  446. end;
  447. begin
  448. if Element.IsVirtual then
  449. AppendExt('virtual');
  450. if Element.IsDynamic then
  451. AppendExt('dynamic');
  452. if Element.IsAbstract then
  453. AppendExt('abstract');
  454. if Element.IsOverride then
  455. AppendExt('override');
  456. if Element.IsOverload then
  457. AppendExt('overload');
  458. if Element.IsMessage then
  459. AppendExt('message');
  460. end;
  461. { Used in two places:
  462. - Page for the method of a class
  463. - Page for a standalone procedure or function. }
  464. procedure TNewHTMLWriter.AppendProcDecl(CodeEl: TDOMElement; Element: TPasProcedureBase);
  465. procedure WriteVariant(AProc: TPasProcedure; SkipResult : Boolean);
  466. begin
  467. AppendHighlightedCode(CodeEl,GetElementCode(aProc,False,[efParent]));
  468. end;
  469. var
  470. i,fc: Integer;
  471. P : TPasProcedure;
  472. begin
  473. fc:=0;
  474. if Element.ClassType = TPasOverloadedProc then
  475. for i := 0 to TPasOverloadedProc(Element).Overloads.Count - 1 do
  476. begin
  477. P:=TPasProcedure(TPasOverloadedProc(Element).Overloads[i]);
  478. if (P.ProcType is TPasFunctionType) then
  479. Inc(fc);
  480. WriteVariant(P,fc>1);
  481. end
  482. else
  483. WriteVariant(TPasProcedure(Element),False);
  484. end;
  485. procedure TNewHTMLWriter.AppendProcArgsSection(Parent: THTMLElement;
  486. Element: TPasProcedureType; SkipResult : Boolean = False);
  487. var
  488. HasFullDescr, HaveArgDescr: Boolean;
  489. ResultEl: TPasResultElement;
  490. lColumns, lColumn: THTMLElement;
  491. DocNode: TDocNode;
  492. i: Integer;
  493. Arg: TPasArgument;
  494. begin
  495. HaveArgDescr:=False;
  496. I:=0;
  497. While (I<Element.Args.Count) and not HaveArgDescr do
  498. begin
  499. Arg := TPasArgument(Element.Args[i]);
  500. HaveArgDescr:=Not IsDescrNodeEmpty(Engine.FindShortDescr(Arg));
  501. inc(i);
  502. end;
  503. if HaveArgDescr then
  504. begin
  505. AppendText(CreateH2(Parent), SDocArguments);
  506. for i := 0 to Element.Args.Count - 1 do
  507. begin
  508. lColumns := CreateListColumns(Parent);
  509. Arg := TPasArgument(Element.Args[i]);
  510. if IsDescrNodeEmpty(Engine.FindShortDescr(Arg)) then
  511. continue;
  512. lColumn:=CreateListColumn1(lColumns);
  513. AppendText(lColumn, Arg.Name);
  514. lColumn:=CreateListColumn2(lColumns);
  515. AppendShortDescrCell(lColumn, Arg);
  516. end;
  517. end;
  518. if (Element.ClassType = TPasFunctionType) and not SkipResult then
  519. begin
  520. ResultEl := TPasFunctionType(Element).ResultEl;
  521. DocNode := Engine.FindDocNode(ResultEl);
  522. HasFullDescr := Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr);
  523. if HasFullDescr or
  524. (Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.ShortDescr)) then
  525. begin
  526. AppendText(CreateH2(Parent), SDocFunctionResult);
  527. if HasFullDescr then
  528. AppendDescr(ResultEl, Parent, DocNode.Descr, True)
  529. else
  530. AppendDescr(ResultEl, CreatePara(Parent), DocNode.ShortDescr, False);
  531. end;
  532. end;
  533. end;
  534. procedure TNewHTMLWriter.AppendTopicMenuBar(Topic : TTopicElement);
  535. function AddLink(aParent : THTMLElement; ALinkSubpageIndex: Integer; const AName: String) : THTMLElement;
  536. begin
  537. Result:=CreateLink(aParent, ResolveLinkWithinPackage(Module, ALinkSubpageIndex));
  538. Result['class']:='navbar-item';
  539. AppendText(Result,aName);
  540. end;
  541. function AddPackageLink(aParent: THTMLElement; ALinkSubpageIndex: Integer; const AName: String) : THTMLElement;
  542. begin
  543. Result:=CreateLink(aParent, ResolveLinkWithinPackage(Package, ALinkSubpageIndex));
  544. Result['class']:='navbar-item';
  545. AppendText(Result,aName);
  546. end;
  547. var
  548. El,NavBrand, NavItem, NavEl, NavMenu, NavBar : THTMLElement;
  549. begin
  550. NavEl := CreateEl(ContentElement, 'nav','navbar is-link is-fixed-top');
  551. NavEl['role']:='navigation';
  552. NavEl['aria-label']:='main navigation';
  553. NavBrand:=CreateEl(NavEl,'div');
  554. // We use the brand for the link to the overview
  555. NavBrand['class']:='navbar-brand';
  556. NavItem:=CreateEl(NavBrand,'a');
  557. NavItem['class']:='navbar-item';
  558. if Assigned(Module) then
  559. begin
  560. NavItem['href']:=UTF8Decode(ResolveLinkWithinPackage(Module, 0));
  561. AppendText(NavItem,UTF8Decode(Module.Name));
  562. end
  563. else
  564. begin
  565. NavItem['href']:=UTF8Decode(ResolveLinkWithinPackage(Package, IndexSubIndex));
  566. AppendText(NavItem,UTF8Decode(Package.Name));
  567. end;
  568. // Now the other items follow
  569. NavMenu:=CreateEl(NavEl,'div');
  570. NavMenu['class']:='navbar-menu';
  571. NavBar:=CreateEl(NavMenu,'div');
  572. NavBar['class']:='navbar-start';
  573. if Assigned(Module) then
  574. begin
  575. // AddLink(NavBar,0, 'Unit '+Module.Name);
  576. if Module.InterfaceSection.ResStrings.Count > 0 then
  577. AddLink(NavBar,ResstrSubindex, SDocResStrings);
  578. if Module.InterfaceSection.Consts.Count > 0 then
  579. AddLink(NavBar,ConstsSubindex, SDocConstants);
  580. if Module.InterfaceSection.Types.Count > 0 then
  581. AddLink(NavBar,TypesSubindex, SDocTypes);
  582. if Module.InterfaceSection.Classes.Count > 0 then
  583. AddLink(NavBar,ClassesSubindex, SDocClasses);
  584. if Module.InterfaceSection.Functions.Count > 0 then
  585. AddLink(NavBar,ProcsSubindex, SDocProceduresAndFunctions);
  586. if Module.InterfaceSection.Variables.Count > 0 then
  587. AddLink(NavBar,VarsSubindex, SDocVariables);
  588. AddLink(NavBar,IndexSubIndex,SDocIdentifierIndex);
  589. AppendFragment(NavBar, NavigatorHTML);
  590. end
  591. else
  592. begin
  593. // Index
  594. AddPackageLink(NavBar,IndexSubIndex, SDocIdentifierIndex);
  595. // Class TObject tree
  596. AddPackageLink(NavBar,ClassHierarchySubIndex, SDocPackageClassHierarchy);
  597. AppendFragment(NavBar, NavigatorHTML)
  598. end;
  599. NavBar:=CreateEl(NavMenu,'div');
  600. NavBar['class']:='navbar-end';
  601. if Length(SearchPage) > 0 then
  602. begin
  603. El:=CreateLink(NavBar, SearchPage);
  604. El['class']:='navbar-item';
  605. AppendText(El, SDocSearch);
  606. end;
  607. if Assigned(Module) and Assigned(Package) then // Displays a Package page
  608. begin
  609. El:=AppendHyperlink(NavBar, Package) as THTMLELement;
  610. El['class']:='navbar-item';
  611. end;
  612. AppendFragment(ContentElement,HeaderHTML);
  613. end;
  614. function TNewHTMLWriter.CreateAllocator: TFileAllocator;
  615. begin
  616. Result:=TLongNameFileAllocator.Create('.html');
  617. end;
  618. procedure TNewHTMLWriter.AppendMenuBar(ASubpageIndex: Integer);
  619. function AddLink(aParent : THTMLElement; ALinkSubpageIndex: Integer; const AName: String) : THTMLElement;
  620. begin
  621. Result:=CreateLink(aParent, ResolveLinkWithinPackage(Module, ALinkSubpageIndex));
  622. Result['class']:='navbar-item';
  623. AppendText(Result,aName);
  624. end;
  625. function AddPackageLink(aParent: THTMLElement; ALinkSubpageIndex: Integer; const AName: String) : THTMLElement;
  626. begin
  627. Result:=CreateLink(aParent, ResolveLinkWithinPackage(Package, ALinkSubpageIndex));
  628. Result['class']:='navbar-item';
  629. AppendText(Result,aName);
  630. end;
  631. var
  632. El,NavBrand, NavItem, NavEl, NavMenu, NavBar : THTMLElement;
  633. begin
  634. NavEl := CreateEl(ContentElement, 'nav','navbar is-link is-fixed-top');
  635. NavEl['role']:='navigation';
  636. NavEl['aria-label']:='main navigation';
  637. NavBrand:=CreateEl(NavEl,'div');
  638. // We use the brand for the link to the overview
  639. NavBrand['class']:='navbar-brand';
  640. if CreateSideMenu then
  641. begin
  642. NavItem:=CreateEl(NavBrand,'a','navbar-item');
  643. NavItem['role']:='button';
  644. NavItem['id']:='menu-toggle';
  645. NavItem['aria-label']:='menu';
  646. NavItem['aria-expanded']:='false';
  647. El:=CreateEl(NavItem,'span','burger-icon');
  648. AppendText(El,#$2261); //
  649. end;
  650. NavItem:=CreateEl(NavBrand,'a');
  651. NavItem['class']:='navbar-item';
  652. if Assigned(Module) then
  653. begin
  654. NavItem['href']:=UTF8Decode(ResolveLinkWithinPackage(Module, 0));
  655. AppendText(NavItem, UTF8Decode(Format(SDocUnitMenuTitle,[Module.Name])));
  656. end
  657. else
  658. begin
  659. NavItem['href']:=UTF8Decode(ResolveLinkWithinPackage(Package, IndexSubIndex));
  660. AppendText(NavItem,UTF8Decode(Format(SDocPackageMenuTitle,[Package.Name])));
  661. end;
  662. // Now the other items follow
  663. NavMenu:=CreateEl(NavEl,'div');
  664. NavMenu['class']:='navbar-menu';
  665. NavBar:=CreateEl(NavMenu,'div');
  666. NavBar['class']:='navbar-start';
  667. if Assigned(Module) then
  668. begin
  669. // AddLink(NavBar,0, 'Unit '+Module.Name);
  670. if Module.InterfaceSection.ResStrings.Count > 0 then
  671. AddLink(NavBar,ResstrSubindex, SDocResStrings);
  672. if Module.InterfaceSection.Consts.Count > 0 then
  673. AddLink(NavBar,ConstsSubindex, SDocConstants);
  674. if Module.InterfaceSection.Types.Count > 0 then
  675. AddLink(NavBar,TypesSubindex, SDocTypes);
  676. if Module.InterfaceSection.Classes.Count > 0 then
  677. AddLink(NavBar,ClassesSubindex, SDocClasses);
  678. if Module.InterfaceSection.Functions.Count > 0 then
  679. AddLink(NavBar,ProcsSubindex, SDocProceduresAndFunctions);
  680. if Module.InterfaceSection.Variables.Count > 0 then
  681. AddLink(NavBar,VarsSubindex, SDocVariables);
  682. AddLink(NavBar,IndexSubIndex,SDocIdentifierIndex);
  683. AppendFragment(NavBar, NavigatorHTML);
  684. end
  685. else
  686. begin
  687. // Index
  688. AddPackageLink(NavBar,IndexSubIndex, SDocIdentifierIndex);
  689. // Class TObject tree
  690. AddPackageLink(NavBar,ClassHierarchySubIndex, SDocPackageClassHierarchy);
  691. AppendFragment(NavBar, NavigatorHTML)
  692. end;
  693. NavBar:=CreateEl(NavMenu,'div');
  694. NavBar['class']:='navbar-end';
  695. if Length(SearchPage) > 0 then
  696. begin
  697. El:=CreateLink(NavBar, SearchPage);
  698. El['class']:='navbar-item';
  699. AppendText(El, SDocSearch);
  700. end;
  701. if Assigned(Module) and Assigned(Package) then // Displays a Package page
  702. begin
  703. El:=AppendHyperlink(NavBar, Package) as THTMLELement;
  704. El['class']:='navbar-item';
  705. end;
  706. AppendFragment(ContentElement,HeaderHTML);
  707. end;
  708. procedure TNewHTMLWriter.AppendFooter;
  709. Var
  710. S : String;
  711. lContent,lDateEl,lFooter : TDomElement;
  712. begin
  713. if not (Assigned(FooterHTML) or IncludeDateInFooter) then
  714. exit;
  715. lFooter:=CreateEl(ContentElement, 'footer','footer');
  716. lContent:=CreateEl(lFooter, 'div','has-text-centered');
  717. if Assigned(FooterHTML) then
  718. AppendFragment(lContent, FooterHTML)
  719. else if IncludeDateInFooter then
  720. begin
  721. lDateEl:=CreateEl(lContent,'span','footertext');
  722. If (FDateFormat='') then
  723. S:=DateToStr(Date)
  724. else
  725. S:=FormatDateTime(FDateFormat,Date);
  726. AppendText(lDateEl,Format(SDocDateGenerated,[S]));
  727. end;
  728. end;
  729. function TNewHTMLWriter.CreateSection(aParent: THTMLElement): THTMLElement;
  730. begin
  731. Result:=CreateEl(aParent,'section','section');
  732. end;
  733. procedure TNewHTMLWriter.DescrWriteFileEl(const AText: DOMString);
  734. var
  735. NewEl: TDOMElement;
  736. begin
  737. NewEl := CreateEl(CurOutputNode, 'span');
  738. NewEl['class'] := 'fileref';
  739. AppendText(NewEl, AText);
  740. end;
  741. procedure TNewHTMLWriter.DescrWriteVarEl(const AText: DOMString);
  742. var
  743. NewEl: TDOMElement;
  744. begin
  745. NewEl := CreateEl(CurOutputNode, 'span');
  746. NewEl['class'] := 'identifier';
  747. AppendText(NewEl, AText);
  748. end;
  749. function TNewHTMLWriter.AppendPasSHFragment(Parent: TDOMNode; const AText: String; AShFlags: Byte): Byte;
  750. begin
  751. Result:=AppendPasSHFragment(Parent, AText, AShFlags,Nil);
  752. end;
  753. function TNewHTMLWriter.AppendPasSHFragment(Parent: TDOMNode; const AText: String; AShFlags: Byte;
  754. aLinkIdentifierMap: TLinkIdentifierMap): Byte;
  755. var
  756. El: TDOMElement;
  757. Procedure OutputToken(aToken : TSyntaxToken);
  758. Var
  759. CurParent: TDomNode;
  760. lLink : String;
  761. begin
  762. lLink:='';
  763. If (aToken.Text='') then
  764. exit;
  765. If (el<>Nil) then
  766. CurParent:=El
  767. else
  768. begin
  769. CurParent:=Parent;
  770. if (aToken.Kind=shDefault) and Assigned(aLinkIdentifierMap) then
  771. lLink:=aLinkIdentifierMap.GetLink(aToken.Text);
  772. end;
  773. if lLink<>'' then
  774. CurParent:=CreateLink(CurParent,lLink);
  775. AppendText(CurParent,aToken.Text);
  776. El:=Nil;
  777. end;
  778. Function NewEl(Const ElType,Attr,AttrVal : DOMString) : TDomElement;
  779. begin
  780. Result:=CreateEl(Parent,ElType);
  781. Result[Attr]:=AttrVal;
  782. end;
  783. Function NewSpan(Const AttrVal : DOMString) : TDomElement;
  784. begin
  785. Result:=CreateEl(Parent,'span');
  786. Result['class']:=AttrVal;
  787. end;
  788. var
  789. HL : TPascalSyntaxHighlighter;
  790. Tokens : TSyntaxTokenArray;
  791. T : TSyntaxToken;
  792. begin
  793. Result:=0;
  794. HL:=TPascalSyntaxHighlighter.Create;
  795. Try
  796. Tokens:=HL.Execute(aText);
  797. For T in Tokens do
  798. begin
  799. case T.Kind of
  800. shDefault: El:=Nil;
  801. shInvalid: El:=newel('font','color','red');
  802. shSymbol : El:=newspan('sym');
  803. shKeyword: El:=newspan('kw');
  804. shComment: El:=newspan('cmt');
  805. shDirective: El:=newspan('dir');
  806. shNumbers: El:=newspan('num');
  807. shCharacters: El:=newspan('chr');
  808. shStrings: El:=newspan('str');
  809. shAssembler: El:=newspan('asm');
  810. end;
  811. OutputToken(T);
  812. end;
  813. finally
  814. HL.Free;
  815. end;
  816. end;
  817. procedure TNewHTMLWriter.AppendDescrSection(AContext: TPasElement; Parent: TDOMNode; DescrNode: TDOMElement; const ATitle: DOMString);
  818. var
  819. lContent,lSection : THTMLElement;
  820. begin
  821. if not IsDescrNodeEmpty(DescrNode) then
  822. begin
  823. lSection:=CreateSection(Parent as THTMLElement);
  824. lContent:=CreateEl(lSection,'div','content');
  825. If (ATitle<>'') then // Can be empty for topic.
  826. AppendText(CreateH2(lContent), ATitle);
  827. AppendDescr(AContext, lContent, DescrNode, True);
  828. end;
  829. end;
  830. procedure TNewHTMLWriter.AppendSeeAlsoSection(AElement: TPasElement; aParent: TDOMElement; DocNode: TDocNode);
  831. procedure GetSeeAlsoNodes(aList : TFPList);
  832. var
  833. Node : TDOMNode;
  834. begin
  835. // Get all nodes.
  836. Node:=DocNode.SeeAlso.FirstChild;
  837. While Assigned(Node) do
  838. begin
  839. if (Node.NodeType=ELEMENT_NODE) and (Node.NodeName='link') then
  840. aList.Add(Node);
  841. Node := Node.NextSibling;
  842. end;
  843. end;
  844. procedure AppendSeeAlsoName(aParent : THTMLElement; El : TDOmElement);
  845. var
  846. NewEl : THTMLElement;
  847. l,s,n : domstring;
  848. begin
  849. l:=El['id'];
  850. // Create parent element for link text/id
  851. if Assigned(Engine) and Engine.FalbackSeeAlsoLinks then
  852. s:= ResolveLinkIDUnStrict(UTF8ENcode(l))
  853. else
  854. s:= ResolveLinkID(UTF8ENcode(l));
  855. if Length(s)=0 then
  856. begin
  857. if assigned(module) then
  858. s:=UTF8Decode(module.name)
  859. else
  860. s:='?';
  861. if l='' then l:='<empty>';
  862. if Assigned(AElement) then
  863. N:=UTF8Decode(AElement.PathName)
  864. else
  865. N:='?';
  866. DoLog(SErrUnknownLinkID, [s,N,l]);
  867. LinkUnresolvedInc();
  868. NewEl := CreateEl(aParent,'b')
  869. end
  870. else
  871. NewEl := CreateLink(aParent,s);
  872. // Append link
  873. if Not IsDescrNodeEmpty(El) then
  874. begin
  875. PushOutputNode(NewEl);
  876. Try
  877. ConvertBaseShortList(AElement, El, True)
  878. Finally
  879. PopOutputNode;
  880. end;
  881. end
  882. else
  883. AppendText(NewEl,El['id']);
  884. end;
  885. Procedure AppendLinkShortDescr(aParent : THTMLElement; aDocEl: TDomElement);
  886. var
  887. l : domstring;
  888. DescrEl : TDomElement;
  889. begin
  890. l:=aDocEl['id'];
  891. DescrEl := Engine.FindShortDescr(AElement.GetModule,UTF8Encode(L));
  892. if Not Assigned(DescrEl) then
  893. exit;
  894. aParent['class'] := aParent['class']+' cmt';
  895. PushOutputNode(aParent);
  896. try
  897. ConvertShort(aElement, DescrEl);
  898. finally
  899. PopOutputNode;
  900. end;
  901. end;
  902. var
  903. DocEl : TDOMElement;
  904. lSection, lColumns, lColumn: THTMLElement;
  905. i : integer;
  906. List : TFPList;
  907. begin
  908. if Not (Assigned(DocNode) and Assigned(DocNode.SeeAlso)) then
  909. Exit;
  910. List:=TFPList.Create;
  911. try
  912. GetSeeAlsoNodes(List);
  913. if List.Count=0 then
  914. exit;
  915. lSection:=CreateSection(aParent as THTMLElement);
  916. AppendText(CreateH2(lSection), SDocSeeAlso);
  917. For I:=0 to List.Count-1 do
  918. begin
  919. DocEl:=TDOMElement(List[i]);
  920. lColumns:=CreateListColumns(lSection);
  921. // Name
  922. lColumn:=CreateListColumn1(lColumns);
  923. AppendSeeAlsoName(lColumn,DocEl);
  924. lColumn:=CreateListColumn2(lColumns);
  925. AppendLinkShortDescr(lColumn,DocEl);
  926. end;
  927. finally
  928. List.Free;
  929. end;
  930. end;
  931. procedure TNewHTMLWriter.FinishElementPage(AElement: TPasElement; aDescription : Boolean = True);
  932. var
  933. DocNode: TDocNode;
  934. lSection : THTMLElement;
  935. begin
  936. DocNode := Engine.FindDocNode(AElement);
  937. If Not Assigned(DocNode) then
  938. exit;
  939. // Description
  940. if aDescription and Assigned(DocNode.Descr) then
  941. AppendDescrSection(AElement, ContentElement, DocNode.Descr, UTF8Decode(SDocDescription));
  942. // Append "Errors" section
  943. if Assigned(DocNode.ErrorsDoc) then
  944. AppendDescrSection(AElement, ContentElement, DocNode.ErrorsDoc, UTF8Decode(SDocErrors));
  945. // Append Version info
  946. if Assigned(DocNode.Version) then
  947. AppendDescrSection(AElement, ContentElement, DocNode.Version, UTF8Decode(SDocVersion));
  948. // Append "See also" section
  949. AppendSeeAlsoSection(AElement,ContentElement,DocNode);
  950. // Append examples, if present
  951. lSection:=CreateSection(ContentElement);
  952. AppendExampleSection(AElement,lSection, DocNode);
  953. // Append notes, if present
  954. ConvertNotes(AElement,DocNode.Notes);
  955. end;
  956. procedure TNewHTMLWriter.CreateTopicPageBody(AElement: TTopicElement);
  957. var
  958. DocNode: TDocNode;
  959. lSection : THTMLElement;
  960. begin
  961. AppendTopicMenuBar(AElement);
  962. DocNode:=AElement.TopicNode;
  963. if Assigned(DocNode) then // should always be true, but we're being careful.
  964. begin
  965. lSection:=CreateSection(ContentElement);
  966. AppendShortDescr(AElement,CreateH2(lSection), DocNode);
  967. if Assigned(DocNode.Descr) then
  968. AppendDescrSection(AElement, lSection, DocNode.Descr, '');
  969. AppendSeeAlsoSection(AElement,ContentElement,DocNode);
  970. CreateTopicLinks(ContentElement,DocNode,AElement);
  971. AppendExampleSection(AElement,DocNode);
  972. ConvertNotes(AElement,DocNode.Notes);
  973. end;
  974. end;
  975. procedure TNewHTMLWriter.CreateClassHierarchyPage(AddUnit : Boolean);
  976. type
  977. TypeEN = (NPackage, NModule, NName);
  978. function PushClassElement(aParent : THTMLElement; IsParent : Boolean) : THTMLElement;
  979. Var
  980. H : THTMLElement;
  981. begin
  982. H:=CreateEl(aParent, 'li');
  983. if IsParent then
  984. begin
  985. H['class']:='parent expanded';
  986. H['onclick']:='expandorcollapse(event)';
  987. end;
  988. Result:=H;
  989. end;
  990. Function PushClassList(aParent : THTMLELement) : THTMLElement;
  991. begin
  992. Result:=CreateEl(aParent, 'ul');
  993. Result['class']:='treeview';
  994. end;
  995. function ExtractName(APathName: String; Tp: TypeEN):String;
  996. var
  997. l:TStringList;
  998. begin
  999. Result:= Trim(APathName);
  1000. if Result = '' then exit;
  1001. l:=TStringList.Create;
  1002. try
  1003. l.AddDelimitedText(Result, '.', True);
  1004. if l.Count=3 then
  1005. Result:= l.Strings[Integer(Tp)]
  1006. else
  1007. Result:='';
  1008. finally
  1009. l.free;
  1010. end;
  1011. end;
  1012. Procedure AppendClass(aParent : THTMLElement; EN : TPasElementNode);
  1013. Var
  1014. PE,PM : TPasElement;
  1015. I : Integer;
  1016. El, SubParent : THTMLELement;
  1017. begin
  1018. if not Assigned(EN) then exit;
  1019. PE:=EN.Element;
  1020. SubParent:=PushClassElement(aParent,EN.ChildCount>0);
  1021. if (PE<>Nil) then
  1022. begin
  1023. El:=CreateEl(SubParent, 'span');
  1024. AppendHyperLink(El,PE);
  1025. PM:=PE.GetModule();
  1026. if (PM<>Nil) then
  1027. begin
  1028. AppendText(El,' (');
  1029. AppendHyperLink(El,PM);
  1030. AppendText(el,')');
  1031. end
  1032. end
  1033. else
  1034. AppendText(El,EN.Element.Name);
  1035. if EN.ChildCount>0 then
  1036. begin
  1037. El:=PushClassList(SubParent);
  1038. For I:=0 to EN.ChildCount-1 do
  1039. AppendClass(El,EN.Children[i] as TPasElementNode);
  1040. end;
  1041. end;
  1042. begin
  1043. AppendClass(PushClassList(ContentElement),TreeClass.RootNode);
  1044. end;
  1045. procedure TNewHTMLWriter.CreatePackageClassHierarchy;
  1046. Const
  1047. SFunc = 'function expandorcollapse (event) { '+sLineBreak+
  1048. ' var el = event.target;'+sLineBreak+
  1049. ' if (el) { '+sLineBreak+
  1050. ' el.classList.toggle("expanded");'+sLineBreak+
  1051. ' event.stopPropagation();'+sLineBreak+
  1052. ' }'+sLineBreak+
  1053. '}';
  1054. Var
  1055. S : String;
  1056. SE : THTMLElement;
  1057. begin
  1058. SE := Doc.CreateElement('script');
  1059. AppendText(SE,SFunc);
  1060. HeadElement.AppendChild(SE);
  1061. S:=Package.Name;
  1062. If Length(S)>0 then
  1063. Delete(S,1,1);
  1064. AppendTitle(ContentElement,UTF8Decode(Format(SDocPackageClassHierarchy, [S])));
  1065. CreateClassHierarchyPage(True);
  1066. end;
  1067. procedure TNewHTMLWriter.CreatePageBody(AElement: TPasElement; ASubpageIndex: Integer);
  1068. begin
  1069. if Module=nil then
  1070. begin
  1071. If (ASubPageIndex=0) then
  1072. CreatePackagePageBody
  1073. else if ASubPageIndex=IndexSubIndex then
  1074. CreatePackageIndex
  1075. else if ASubPageIndex=ClassHierarchySubIndex then
  1076. CreatePackageClassHierarchy
  1077. end
  1078. else
  1079. begin
  1080. if AElement.ClassType.inheritsfrom(TPasModule) then
  1081. CreateModulePageBody(TPasModule(AElement), ASubpageIndex)
  1082. else if AElement.Parent.InheritsFrom(TPasClassType) then
  1083. CreateClassMemberPageBody(AElement)
  1084. else if AElement.ClassType = TPasConst then
  1085. CreateConstPageBody(TPasConst(AElement))
  1086. else if AElement.InheritsFrom(TPasClassType) then
  1087. CreateClassPageBody(TPasClassType(AElement), ASubpageIndex)
  1088. else if AElement.InheritsFrom(TPasType) then
  1089. CreateTypePageBody(TPasType(AElement))
  1090. else if AElement.ClassType = TPasVariable then
  1091. CreateVarPageBody(TPasVariable(AElement))
  1092. else if AElement.InheritsFrom(TPasProcedureBase) then
  1093. CreateProcPageBody(TPasProcedureBase(AElement))
  1094. else if AElement.ClassType = TTopicELement then
  1095. CreateTopicPageBody(TTopicElement(AElement))
  1096. else if AElement.ClassType = TPasProperty then
  1097. CreateClassMemberPageBody(TPasProperty(AElement))
  1098. else
  1099. writeln('Unknown classtype: ',AElement.classtype.classname);
  1100. end;
  1101. end;
  1102. procedure TNewHTMLWriter.CreateIndexPage(aParent: THTMLElement; L: TStringList);
  1103. Var
  1104. Lists : Array['A'..'Z'] of TStringList;
  1105. CL : TStringList;
  1106. lColumns, lColumn, EL, el2: TDOMElement;
  1107. E : TPasElement;
  1108. I : Integer;
  1109. S : String;
  1110. C : Char;
  1111. begin
  1112. For C:='A' to 'Z' do
  1113. Lists[C]:=Nil;
  1114. L.Sort;
  1115. Cl:=Nil;
  1116. // Divide over alphabet
  1117. For I:=0 to L.Count-1 do
  1118. begin
  1119. S:=L[i];
  1120. E:=TPasElement(L.Objects[i]);
  1121. If not (E is TPasUnresolvedTypeRef) then
  1122. begin
  1123. If (S<>'') then
  1124. begin
  1125. C:=Upcase(S[1]);
  1126. If C='_' then
  1127. C:='A';
  1128. If (C in ['A'..'Z']) and (Lists[C]=Nil) then
  1129. begin
  1130. CL:=TStringList.Create;
  1131. Lists[C]:=CL;
  1132. end;
  1133. end;
  1134. if assigned(cl) then
  1135. CL.AddObject(S,E);
  1136. end;
  1137. end;
  1138. Try
  1139. // Create a quick jump table to all available letters.
  1140. lColumns := CreateEl(aParent,'div','columns is-multiline');
  1141. for C:='A' to 'Z' do
  1142. If (Lists[C]<>Nil) then
  1143. begin
  1144. lColumn:=CreateEl(lColumns,'div','column is-narrow');
  1145. lColumn:=CreateLink(lColumn,UTF8Decode('#SECTION'+C));
  1146. lColumn['class']:='button is-link';
  1147. AppendText(lColumn,UTF8Decode(C));
  1148. end;
  1149. // Now emit all identifiers.
  1150. For C:='A' to 'Z' do
  1151. begin
  1152. CL:=Lists[C];
  1153. If CL<>Nil then
  1154. begin
  1155. El:=CreateH2(aParent);
  1156. AppendText(El,UTF8Decode(C));
  1157. CreateAnchor(El,UTF8Decode('SECTION'+C));
  1158. El:=CreateEl(aParent,'div');
  1159. EL['style']:='display: block; column-count: 3';
  1160. for I:=0 to CL.Count-1 do
  1161. begin
  1162. E:=TPasElement(CL.Objects[I]);
  1163. El2:=AppendHyperlink(El,E);
  1164. if assigned(EL2) then
  1165. EL2['style']:='display: block;';
  1166. end;
  1167. end; // have List
  1168. end; // For C:=
  1169. Finally
  1170. for C:='A' to 'Z' do
  1171. FreeAndNil(Lists[C]);
  1172. end;
  1173. end;
  1174. procedure TNewHTMLWriter.CreatePackageIndex;
  1175. Var
  1176. L : TStringList;
  1177. I : Integer;
  1178. M : TPasModule;
  1179. S : String;
  1180. lSection : THTMLElement;
  1181. begin
  1182. L:=TStringList.Create;
  1183. try
  1184. L.Capacity:=PageInfos.Count; // Too much, but that doesn't hurt.
  1185. For I:=0 to Package.Modules.Count-1 do
  1186. begin
  1187. M:=TPasModule(Package.Modules[i]);
  1188. L.AddObject(M.Name,M);
  1189. AddModuleIdentifiers(M,L);
  1190. end;
  1191. S:=Package.Name;
  1192. If Length(S)>0 then
  1193. Delete(S,1,1);
  1194. lSection:=CreateSection(ContentElement);
  1195. AppendTitle(lSection,UTF8Decode(Format(SDocPackageIndex, [S])));
  1196. CreateIndexPage(lSection,L);
  1197. Finally
  1198. L.Free;
  1199. end;
  1200. end;
  1201. procedure TNewHTMLWriter.CreatePackagePageBody;
  1202. var
  1203. DocNode: TDocNode;
  1204. lSection, lColumns, lColumn : THTMLElement;
  1205. TableEl, TREl: TDOMElement;
  1206. i: Integer;
  1207. ThisModule: TPasModule;
  1208. L : TStringList;
  1209. begin
  1210. lSection:=CreateSection(ContentElement);
  1211. AppendTitle(lSection,Format(SDocPackageTitle, [Copy(Package.Name, 2, 256)]));
  1212. AppendShortDescr(CreatePara(lSection), Package);
  1213. AppendText(CreateH2(lSection), UTF8Encode(SDocUnits));
  1214. TableEl := CreateTable(lSection);
  1215. L:=TStringList.Create;
  1216. Try
  1217. L.Sorted:=True;
  1218. // Sort modules.
  1219. For I:=0 to Package.Modules.Count-1 do
  1220. L.AddObject(TPasModule(Package.Modules[i]).Name,TPasModule(Package.Modules[i]));
  1221. // Now create table.
  1222. for i:=0 to L.Count - 1 do
  1223. begin
  1224. ThisModule := TPasModule(L.Objects[i]);
  1225. lColumns:=CreateListColumns(lSection);
  1226. lColumn:=CreateListColumn1(lColumns);
  1227. AppendHyperlink(lColumn, ThisModule);
  1228. lColumn:=CreateListColumn2(lColumns);
  1229. AppendShortDescrCell(lColumn, ThisModule);
  1230. end;
  1231. Finally
  1232. L.Free;
  1233. end;
  1234. DocNode := Engine.FindDocNode(Package);
  1235. if Assigned(DocNode) then
  1236. begin
  1237. if Assigned(DocNode.Descr) then
  1238. AppendDescrSection(nil, ContentElement, DocNode.Descr, UTF8Decode(SDocDescription));
  1239. CreateTopicLinks(ContentElement, DocNode,Package);
  1240. end;
  1241. end;
  1242. function TNewHTMLWriter.CreateListColumns(aParent : THTMLElement) : THTMLElement;
  1243. begin
  1244. Result:=CreateEl(aParent,'div','columns list');
  1245. end;
  1246. function TNewHTMLWriter.CreateListColumn1(aParent : THTMLElement) : THTMLElement;
  1247. begin
  1248. Result:=CreateEl(aParent,'div','column is-2 list');
  1249. Result['style']:='overflow:hidden; text-overflow: ellipsis;';
  1250. end;
  1251. function TNewHTMLWriter.CreateListColumn2(aParent : THTMLElement) : THTMLElement;
  1252. begin
  1253. Result:=CreateEl(aParent,'div','column is-10 list');
  1254. end;
  1255. procedure TNewHTMLWriter.CreateTopicLinks (aParent : THTMLElement; Node: TDocNode; PasElement: TPasElement) ;
  1256. var
  1257. DocNode: TDocNode;
  1258. lSection,lColumns,lColumn: THTMLElement;
  1259. HaveTopics : Boolean;
  1260. ThisTopic: TPasElement;
  1261. begin
  1262. DocNode:=Node.FirstChild;
  1263. HaveTopics:=False;
  1264. While Assigned(DocNode) and not HaveTopics do
  1265. begin
  1266. HaveTopics:=DocNode.TopicNode;
  1267. DocNode:=DocNode.NextSibling;
  1268. end;
  1269. if not HaveTopics then
  1270. exit;
  1271. lSection:=CreateSection(aParent);
  1272. AppendText(CreateH2(lSection), UTF8Decode(SDocRelatedTopics));
  1273. DocNode:=Node.FirstChild;
  1274. While Assigned(DocNode) do
  1275. begin
  1276. if DocNode.TopicNode then
  1277. begin
  1278. lColumns:=CreateListColumns(lSection);
  1279. lColumn:=CreateListColumn1(lColumns);
  1280. ThisTopic:=FindTopicElement(DocNode);
  1281. if Assigned(ThisTopic) then
  1282. AppendHyperlink(lColumn, ThisTopic);
  1283. lColumn:=CreateListColumn2(lColumns);
  1284. if Assigned(ThisTopic) then
  1285. AppendShortDescrCell(lColumn, ThisTopic);
  1286. end;
  1287. DocNode:=DocNode.NextSibling;
  1288. end;
  1289. end;
  1290. function TNewHTMLWriter.GetElementCode(aElement: TPasElement; aSparse : boolean; aFlags : TElementFlags = []): String;
  1291. var
  1292. W : TPasWriter;
  1293. S : TStringStream;
  1294. Vis : TPasMemberVisibilities;
  1295. begin
  1296. Vis:=[];
  1297. if Engine.HidePrivate then
  1298. Vis:=Vis+[visPrivate,visStrictPrivate];
  1299. if Engine.HideProtected then
  1300. Vis:=Vis+[visProtected,visStrictProtected];
  1301. W:=nil;
  1302. S:=TStringStream.Create('');
  1303. try
  1304. W:=TPasWriter.Create(S);
  1305. if aSparse then
  1306. W.Options:=W.Options+[woSparse];
  1307. W.SkipVisibilities:=Vis;
  1308. W.WriteElement(aElement,[efSkipSection]+aFlags);
  1309. Result:=S.DataString;
  1310. finally
  1311. S.Free;
  1312. W.Free;
  1313. end;
  1314. end;
  1315. procedure TNewHTMLWriter.CreateModuleIndexPage(AModule: TPasModule);
  1316. Var
  1317. L : TStringList;
  1318. lSection: THTMLElement;
  1319. begin
  1320. L:=TStringList.Create;
  1321. try
  1322. AddModuleIdentifiers(AModule,L);
  1323. lSection:=CreateSection(ContentElement);
  1324. AppendTitle(lSection,Format(SDocModuleIndex, [AModule.Name]));
  1325. PushContentElement(lSection);
  1326. CreateIndexPage(lSection,L);
  1327. PopContentElement;
  1328. Finally
  1329. L.Free;
  1330. end;
  1331. end;
  1332. procedure TNewHTMLWriter.CreateModuleMainPage(aModule : TPasModule);
  1333. var
  1334. lContent,lSection,lColumns,lColumn: THTMLElement;
  1335. i: Integer;
  1336. UnitRef: TPasType;
  1337. DocNode: TDocNode;
  1338. begin
  1339. lSection:=CreateSection(ContentElement);
  1340. AppendTitle(lSection,Format(SDocUnitTitle, [AModule.Name]),AModule.Hints);
  1341. lContent:=CreateEl(lSection,'div','content');
  1342. AppendShortDescr(lContent, AModule);
  1343. if AModule.InterfaceSection.UsesList.Count > 0 then
  1344. begin
  1345. AppendKw(CreateCode(CreatePara(lContent)), 'uses');
  1346. for i := 0 to AModule.InterfaceSection.UsesList.Count - 1 do
  1347. begin
  1348. lColumns:=CreateListColumns(lSection);
  1349. UnitRef := TPasType(AModule.InterfaceSection.UsesList[i]);
  1350. DocNode := Engine.FindDocNode(UnitRef);
  1351. if Assigned(DocNode) and DocNode.IsSkipped then
  1352. continue;
  1353. lColumn:=CreateListColumn1(lColumns);
  1354. AppendHyperlink(lColumn, UnitRef);
  1355. lColumn:=CreateListColumn2(lColumns);
  1356. AppendShortDescrCell(lColumn, UnitRef);
  1357. end;
  1358. end;
  1359. DocNode := Engine.FindDocNode(AModule);
  1360. if Assigned(DocNode) then
  1361. begin
  1362. if Assigned(DocNode.Descr) then
  1363. AppendDescrSection(AModule, ContentElement, DocNode.Descr, UTF8Decode(SDocOverview));
  1364. ConvertNotes(AModule,DocNode.Notes);
  1365. CreateTopicLinks(ContentElement, DocNode,AModule);
  1366. end;
  1367. end;
  1368. procedure TNewHTMLWriter.CreateModuleSimpleSubpage(aModule: TPasModule; ASubpageIndex: Integer; const ATitle: DOMString; AList: TFPList);
  1369. var
  1370. lSection, ColumnsEl, ColumnEl, CodeEl: TDOMElement;
  1371. i, j: Integer;
  1372. Decl: TPasElement;
  1373. SortedList: TFPList;
  1374. DocNode: TDocNode;
  1375. S : String;
  1376. begin
  1377. S:=UTF8Encode(ATitle);
  1378. lSection:=CreateSection(ContentElement);
  1379. AppendTitle(lSection,Format(SDocUnitTitle + ': %s', [AModule.Name, S]));
  1380. SortedList := TFPList.Create;
  1381. try
  1382. for i := 0 to AList.Count - 1 do
  1383. begin
  1384. Decl := TPasElement(AList[i]);
  1385. DocNode := Engine.FindDocNode(Decl);
  1386. if (not Assigned(DocNode)) or (not DocNode.IsSkipped) then
  1387. begin
  1388. j := 0;
  1389. while (j < SortedList.Count) and (CompareText(
  1390. TPasElement(SortedList[j]).PathName, Decl.PathName) < 0) do
  1391. Inc(j);
  1392. SortedList.Insert(j, Decl);
  1393. end;
  1394. end;
  1395. for i := 0 to SortedList.Count - 1 do
  1396. begin
  1397. ColumnsEl := CreateEl(lSection,'div','columns');
  1398. Decl := TPasElement(SortedList[i]);
  1399. ColumnEl := CreateEl(ColumnsEl,'div','column is-one-fifth list');
  1400. ColumnEl['style']:='overflow:hidden; text-overflow: ellipsis;';
  1401. CodeEl := CreateCode(ColumnEl);
  1402. AppendHyperlink(CodeEl, Decl);
  1403. ColumnEl := CreateEl(ColumnsEl,'div','column is-four-fifths list');
  1404. AppendShortDescrCell(ColumnEl, Decl);
  1405. end;
  1406. finally
  1407. SortedList.Free;
  1408. end;
  1409. end;
  1410. procedure TNewHTMLWriter.CreateModuleResStringsPage(aModule : TPasModule);
  1411. var
  1412. lsection,lColumns,lColumn: THTMLElement;
  1413. i: Integer;
  1414. Decl: TPasResString;
  1415. begin
  1416. lSection:=CreateSection(ContentElement);
  1417. AppendTitle(lSection,Format(SDocUnitTitle + ': %s', [AModule.Name, SDocResStrings]));
  1418. for i := 0 to AModule.InterfaceSection.ResStrings.Count - 1 do
  1419. begin
  1420. lColumns:=CreateListColumns(lSection);
  1421. Decl := TPasResString(AModule.InterfaceSection.ResStrings[i]);
  1422. lColumn:=CreateListColumn1(lColumns);
  1423. CreateEl(lColumn, 'a')['name'] := UTF8Decode(LowerCase(Decl.Name));
  1424. AppendText(lColumn, UTF8Decode(Decl.Name));
  1425. lColumn := CreateListColumn2(lColumns);
  1426. AppendText(lColumn, UTF8Decode(Decl.Expr.getDeclaration(true)));
  1427. end;
  1428. end;
  1429. procedure TNewHTMLWriter.CreateModulePageBody(AModule: TPasModule;
  1430. ASubpageIndex: Integer);
  1431. begin
  1432. case ASubpageIndex of
  1433. 0:
  1434. CreateModuleMainPage(aModule);
  1435. ResstrSubindex:
  1436. CreateModuleResStringsPage(aModule);
  1437. ConstsSubindex:
  1438. CreateModuleSimpleSubpage(aModule, ConstsSubindex,UTF8Decode(SDocConstants), AModule.InterfaceSection.Consts);
  1439. TypesSubindex:
  1440. CreateModuleSimpleSubpage(aModule, TypesSubindex,UTF8Decode(SDocTypes), AModule.InterfaceSection.Types);
  1441. ClassesSubindex:
  1442. CreateModuleSimpleSubpage(aModule, ClassesSubindex,UTF8Decode(SDocClasses), AModule.InterfaceSection.Classes);
  1443. ProcsSubindex:
  1444. CreateModuleSimpleSubpage(aModule, ProcsSubindex, UTF8Decode(SDocProceduresAndFunctions), AModule.InterfaceSection.Functions);
  1445. VarsSubindex:
  1446. CreateModuleSimpleSubpage(aModule, VarsSubindex,UTF8Decode(SDocVariables), AModule.InterfaceSection.Variables);
  1447. IndexSubIndex:
  1448. CreateModuleIndexPage(AModule);
  1449. end;
  1450. end;
  1451. procedure TNewHTMLWriter.CreateConstPageBody(AConst: TPasConst);
  1452. var
  1453. Section,CodeEl: THTMLElement;
  1454. begin
  1455. Section:=CreateSection(ContentElement);
  1456. AppendTitle(Section,AConst.Name,AConst.Hints);
  1457. AppendShortDescr(CreatePara(Section), AConst);
  1458. Section:=CreateSection(ContentElement);
  1459. AppendText(CreateH2(Section), UTF8Decode(SDocDeclaration));
  1460. AppendSourceRef(Section,AConst);
  1461. CodeEl := AppendCodeBlock(Section);
  1462. AppendPasSHFragment(CodeEl, GetElementCode(aConst,False),0);
  1463. FinishElementPage(AConst);
  1464. end;
  1465. procedure TNewHTMLWriter.AppendShortDescrCell(Parent: TDOMNode; Element: TPasElement);
  1466. var
  1467. ParaEl: TDOMElement absolute Parent;
  1468. begin
  1469. if Assigned(Engine.FindShortDescr(Element)) then
  1470. begin
  1471. if Parent is TDOMElement then
  1472. ParaEl['class'] := ParaEl['class'] +' cmt';
  1473. AppendShortDescr(Parent, Element);
  1474. end;
  1475. end;
  1476. function TNewHTMLWriter.AppendCodeBlock(aParent : TDOMNode; const aLanguage : String = ''): THTMLElement;
  1477. var
  1478. lLanguage : String;
  1479. begin
  1480. Result:=CreateEl(aParent,'pre','code');
  1481. lLanguage:=aLanguage;
  1482. if lLanguage='' then
  1483. lLanguage:='pascal';
  1484. lLanguage:='code-'+lLanguage;
  1485. Result:=CreateEl(Result,UTF8Decode('code'),UTF8Decode(lLanguage));
  1486. end;
  1487. function TNewHTMLWriter.AppendHighlightedCode(aParent: TDOMNode; aCode: String; const aLanguage: String; aMap: TLinkIdentifierMap
  1488. ): THTMLElement;
  1489. begin
  1490. // Writeln('Code:',aCode);
  1491. Result:=AppendCodeBlock(aParent,aLanguage);
  1492. AppendPasSHFragment(Result, aCode, 0, aMap);
  1493. end;
  1494. function TNewHTMLWriter.CreateCodeLines(aLines: array of string): string;
  1495. var
  1496. i : integer;
  1497. begin
  1498. Result:='';
  1499. if Length(aLines)=0 then
  1500. exit;
  1501. Result:=aLines[0];
  1502. For I:=1 to Length(aLines)-1 do
  1503. Result:=Result+sLineBreak+aLines[i];
  1504. end;
  1505. procedure TNewHTMLWriter.AppendAliasTypeDecl(aType: TPasAliasType);
  1506. begin
  1507. AppendHighlightedCode(ContentElement,CreateCodeLines(['type',' '+aType.GetDeclaration(True)+';']));
  1508. end;
  1509. procedure TNewHTMLWriter.AppendTypeAliasTypeDecl(aType: TPasTypeAliasType);
  1510. var
  1511. CodeEl : THTMLElement;
  1512. begin
  1513. CodeEl:=AppendHighlightedCode(ContentElement,CreateCodeLines(['type',' '+aType.GetDeclaration(True)+';']));
  1514. AppendHyperlink(CodeEl, TPasTypeAliasType(AType).DestType);
  1515. end;
  1516. procedure TNewHTMLWriter.AppendClassOfTypeDecl(aType: TPasClassOfType);
  1517. var
  1518. CodeEl : THTMLElement;
  1519. begin
  1520. CodeEl:=AppendHighlightedCode(ContentElement,CreateCodeLines(['type',' '+aType.GetDeclaration(True)+';']));
  1521. if Assigned(TPasClassOfType(AType).DestType) then
  1522. AppendHyperlink(CodeEl, TPasClassOfType(AType).DestType);
  1523. end;
  1524. procedure TNewHTMLWriter.AppendEnumTypeDecl(aType: TPasEnumType);
  1525. var
  1526. S : String;
  1527. i : integer;
  1528. lColumns,lColumn : THTMLElement;
  1529. EnumValue: TPasEnumValue;
  1530. begin
  1531. S:=aType.GetDeclaration(true);
  1532. AppendHighlightedCode(ContentElement,CreateCodeLines(['type',' '+S]));
  1533. AppendText(CreateH3(ContentElement),'Values');
  1534. for i := 0 to AType.Values.Count - 1 do
  1535. begin
  1536. lColumns := CreateListColumns(ContentElement);
  1537. EnumValue := TPasEnumValue(AType.Values[i]);
  1538. lColumn := CreateListColumn1(lColumns);
  1539. AppendText(lColumn,EnumValue.Name);
  1540. lColumn:= CreateListColumn2(lColumns);
  1541. AppendShortDescrCell(lColumn, EnumValue);
  1542. end;
  1543. end;
  1544. procedure TNewHTMLWriter.AppendPointerTypeDecl(aType: TPasPointerType);
  1545. var
  1546. CodeEl : THTMLElement;
  1547. begin
  1548. CodeEl:=AppendHighlightedCode(ContentElement,CreateCodeLines(['type',' '+aType.GetDeclaration(True)+';']));
  1549. if Assigned(AType.DestType) then
  1550. AppendHyperlink(CodeEl, AType.DestType)
  1551. end;
  1552. procedure TNewHTMLWriter.AppendProcedureTypeDecl(aType: TPasProcedureType);
  1553. begin
  1554. AppendHighlightedCode(ContentElement,CreateCodeLines(['type',' '+aType.GetDeclaration(True)+';']));
  1555. AppendProcArgsSection(ContentElement, AType);
  1556. end;
  1557. procedure TNewHTMLWriter.AppendRecordTypeDecl(aType: TPasRecordType);
  1558. var
  1559. lMap: TLinkIdentifierMap;
  1560. I : Integer;
  1561. begin
  1562. lMap:=TLinkIdentifierMap.Create(Self);
  1563. try
  1564. for I:=0 to aType.Members.Count-1 do
  1565. lMap.AddLink(TPasElement(aType.Members[i]));
  1566. AppendHighlightedCode(ContentElement,GetElementCode(aType,True),'',lMap);
  1567. finally
  1568. lMap.Free;
  1569. end;
  1570. end;
  1571. procedure TNewHTMLWriter.AppendSetTypeDecl(aType: TPasSetType);
  1572. var
  1573. dlEl,ddEl,dtEl,CodeEl : THTMLElement;
  1574. EnumType : TPasEnumType;
  1575. EnumValue : TPasEnumValue;
  1576. I : Integer;
  1577. begin
  1578. CodeEl:=AppendHighlightedCode(ContentElement,CreateCodeLines(['type',' '+aType.GetDeclaration(True)+';']));
  1579. if AType.EnumType.ClassType = TPasEnumType then
  1580. begin
  1581. EnumType:=TPasEnumType(AType.EnumType);
  1582. AppendText(CreateH3(ContentElement),'Values');
  1583. dlEl := CreateEl(ContentElement,'div','columns list');
  1584. for i := 0 to EnumType.Values.Count - 1 do
  1585. begin
  1586. EnumValue := TPasEnumValue(EnumType.Values[i]);
  1587. dtEl := CreateEl(dlEl,'div','column is-2 list');
  1588. AppendText(dtEl,EnumValue.Name);
  1589. ddEl := CreateEl(dlEl,'div','column is-10 list');
  1590. AppendShortDescrCell(ddEl, EnumValue);
  1591. end;
  1592. end
  1593. else
  1594. begin
  1595. AppendHyperlink(CodeEl, TPasSetType(AType).EnumType);
  1596. AppendSym(CodeEl, ';');
  1597. end;
  1598. end;
  1599. procedure TNewHTMLWriter.AppendTypeDecl(AType: TPasType);
  1600. begin
  1601. // Alias
  1602. if AType.ClassType = TPasAliasType then
  1603. AppendAliasTypeDecl(TPasAliasType(aType))
  1604. else if AType.ClassType = TPasClassOfType then
  1605. AppendClassOfTypeDecl(TPasClassOfType(AType))
  1606. else if AType.ClassType = TPasEnumType then
  1607. AppendEnumTypeDecl(TPasEnumType(AType))
  1608. else if AType.ClassType = TPasPointerType then
  1609. AppendPointerTypeDecl(TPasPointerType(aType))
  1610. else if AType.InheritsFrom(TPasProcedureType) then
  1611. AppendProcedureTypeDecl(TPasProcedureType(aType))
  1612. else if AType.ClassType = TPasRecordType then
  1613. AppendRecordTypeDecl(TPasRecordType(aType))
  1614. else if AType.ClassType = TPasSetType then
  1615. AppendSetTypeDecl(TPasSetType(aType))
  1616. else if AType.ClassType = TPasTypeAliasType then
  1617. AppendTypeAliasTypeDecl(TPasTypeAliasType(aType))
  1618. else
  1619. // Probably one of the simple types, which allowed in other places as wel...
  1620. AppendType(ContentElement, TPasType(AType));
  1621. end;
  1622. procedure TNewHTMLWriter.CreateTypePageBody(AType: TPasType);
  1623. var
  1624. Section,CodeEl: THTMLElement;
  1625. DocNode: TDocNode;
  1626. begin
  1627. Section:=CreateSection(ContentElement);
  1628. AppendTitle(Section,AType.Name,AType.Hints);
  1629. AppendShortDescr(CreatePara(section), AType);
  1630. Section:=CreateSection(ContentElement);
  1631. AppendText(CreateH2(section), UTF8Decode(SDocDeclaration));
  1632. AppendSourceRef(Section,AType);
  1633. DocNode := Engine.FindDocNode(AType);
  1634. If Assigned(DocNode) and
  1635. Assigned(DocNode.Node) and
  1636. (Docnode.Node['opaque']='1') then
  1637. begin
  1638. CodeEl := AppendCodeBlock(Section);
  1639. AppendKw(CodeEl, 'type ');
  1640. AppendText(CodeEl, UTF8Decode(AType.Name));
  1641. AppendSym(CodeEl, ' = ');
  1642. AppendText(CodeEl,UTF8Decode(SDocOpaque))
  1643. end
  1644. else
  1645. begin
  1646. PushContentElement(Section);
  1647. try
  1648. AppendTypeDecl(AType);
  1649. finally
  1650. PopContentElement;
  1651. end;
  1652. end;
  1653. FinishElementPage(AType);
  1654. end;
  1655. procedure TNewHTMLWriter.AppendTitle(aParent: TDomElement; const AText: AnsiString; Hints: TPasMemberHints);
  1656. begin
  1657. AppendTitle(AParent,UTF8Decode(aText),Hints);
  1658. end;
  1659. procedure TNewHTMLWriter.AppendTitle(aParent : TDomElement; const AText: DOMString; Hints : TPasMemberHints = []);
  1660. Var
  1661. T : UnicodeString;
  1662. begin
  1663. T:=AText;
  1664. if (Hints<>[]) then
  1665. T:=T+' ('+UTF8Decode(Engine.HintsToStr(Hints))+')';
  1666. AppendText(TitleElement, AText);
  1667. AppendText(CreateH1(aParent), T)
  1668. end;
  1669. procedure TNewHTMLWriter.AppendMemberListSection(aParent: THTMLELement; aClass: TPasClassType; aMemberType: TClassMemberType;
  1670. aDeclaredOnly: Boolean);
  1671. var
  1672. LinkEl,lSection: THTMLELement;
  1673. LinkAll : Boolean;
  1674. begin
  1675. if not HasMembersToShow(aClass,True,GetMemberFilter(aMemberType)) then
  1676. exit;
  1677. linkAll:=aDeclaredOnly and Assigned(aClass.AncestorType) and Not aClass.AncestorType.InheritsFrom(TPasUnresolvedTypeRef);
  1678. lSection:=CreateSection(ContentElement);
  1679. AppendText(CreateH2(lSection),UTF8Decode(GetMemberDocName(aMemberType)));
  1680. CreateAnchor(lsection,UTF8Decode(GetAnchorName(aMemberType)));
  1681. CreateClassMemberList(lSection,AClass,True,GetMemberFilter(aMemberType));
  1682. if LinkAll then
  1683. begin
  1684. LinkEl:=CreateLink(lSection,FixHtmlPath(ResolveLinkWithinPackage(AClass,GetMemberSubIndex(aMemberType))));
  1685. AppendText(LinkEl,SSeeAll+' '+GetMemberDocName(aMemberType));
  1686. end;
  1687. end;
  1688. procedure TNewHTMLWriter.AppendInheritanceTree(aParent : THTMLELement; aClass : TPasClassType);
  1689. procedure AppendInterfaceInfo(ACodeEl : TDomElement ; AThisClass: TPasClassType);
  1690. var
  1691. i:Integer;
  1692. ThisInterface:TPasClassType;
  1693. begin
  1694. if Assigned(AThisClass) and (AThisClass.Interfaces.count>0) then
  1695. begin
  1696. for i:=0 to AThisClass.interfaces.count-1 do
  1697. begin
  1698. ThisInterface:=TPasClassType(AThisClass.Interfaces[i]);
  1699. AppendText(ACodeEl,',');
  1700. AppendHyperlink(ACodeEl, ThisInterface);
  1701. end;
  1702. end;
  1703. end;
  1704. var
  1705. TableEl, TREl, TDEl, CodeEl: TDOMElement;
  1706. ThisClass, PrevClass: TPasType;
  1707. ThisTreeNode: TPasElementNode;
  1708. begin
  1709. TableEl := CreateTable(aParent);
  1710. // Process tree class information
  1711. // First tree class link is to This class
  1712. PrevClass:= nil;
  1713. ThisClass:=aClass;
  1714. ThisClass := AClass; ThisTreeNode := Nil;
  1715. if AClass.ObjKind = okInterface then
  1716. ThisTreeNode := TreeInterface.GetPasElNode(AClass)
  1717. else
  1718. ThisTreeNode := TreeClass.GetPasElNode(AClass);
  1719. Repeat
  1720. TREl := CreateTR(TableEl);
  1721. TDEl := CreateTD_vtop(TREl);
  1722. TDEl['align'] := 'center';
  1723. CodeEl := CreateCode(CreatePara(TDEl));
  1724. // Show class item
  1725. AppendHyperlink(CodeEl, ThisClass);
  1726. if Assigned(PrevClass) and (PrevClass Is TPasClassType) then // Interfaces from prevClass
  1727. AppendInterfaceInfo(CodeEl, TPasClassType(PrevClass));
  1728. TDEl := CreateTD_vtop(TREl);
  1729. AppendShortDescrCell(TDEl, ThisClass);
  1730. if Assigned(ThisTreeNode) then
  1731. if Assigned(ThisTreeNode.ParentNode) then
  1732. begin
  1733. TDEl := CreateTD(CreateTR(TableEl));
  1734. TDEl['align'] := 'center';
  1735. AppendText(TDEl, '|');
  1736. PrevClass:= ThisClass;
  1737. ThisClass := ThisTreeNode.ParentNode.Element;
  1738. ThisTreeNode := ThisTreeNode.ParentNode;
  1739. end
  1740. else
  1741. begin
  1742. ThisClass := nil;
  1743. ThisTreeNode:= nil;
  1744. PrevClass:= nil;
  1745. end
  1746. Until (ThisTreeNode=Nil);
  1747. end;
  1748. procedure TNewHTMLWriter.CreateClassMainPage(aClass : TPasClassType);
  1749. var
  1750. lSection: THTMLElement;
  1751. ParaEl: TDOMElement;
  1752. lMap: TLinkIdentifierMap;
  1753. I : Integer;
  1754. DocNode: TDocNode;
  1755. begin
  1756. // Menu bar
  1757. // Title, short description & navs
  1758. lSection:=CreateSection(ContentElement);
  1759. AppendTitle(lSection,AClass.Name,AClass.Hints);
  1760. ParaEl := CreatePara(lSection);
  1761. AppendShortDescr(CreatePara(lSection), AClass);
  1762. ParaEl:=CreateEl(lSection,'div','tabs');;
  1763. ParaEl:=CreateEl(ParaEl,'ul');
  1764. if HasMembersToShow(aClass,True,@PropertyFilter) then
  1765. AppendText(CreateLink(ParaEl,'#properties'),UTF8Decode(SDocProperties));
  1766. if HasMembersToShow(aClass,True,@MethodFilter) then
  1767. AppendText(CreateLink(ParaEl,'#methods'),UTF8Decode(SDocMethods));
  1768. if HasMembersToShow(aClass,True,@EventFilter) then
  1769. AppendText(CreateLink(ParaEl,'#events'),UTF8Decode(SDocEvents));
  1770. // Declaration
  1771. lSection:=CreateSection(ContentElement);
  1772. AppendText(CreateH2(lSection), UTF8Decode(SDocDeclaration));
  1773. AppendSourceRef(lSection,AClass);
  1774. lMap:=TLinkIdentifierMap.Create(Self);
  1775. try
  1776. if assigned(aClass.AncestorType) then
  1777. lMap.AddLink(aClass.AncestorType);
  1778. if assigned(aClass.Interfaces) then
  1779. for I:=0 to AClass.Interfaces.Count-1 do
  1780. lMap.AddLink(TPasElement(aClass.Interfaces[i]));
  1781. for I:=0 to AClass.Members.Count-1 do
  1782. lMap.AddLink(TPasElement(AClass.Members[i]));
  1783. AppendHighlightedCode(lSection,GetElementCode(aClass,True),'',lMap);
  1784. finally
  1785. lMap.Free;
  1786. end;
  1787. // Inheritance
  1788. lSection:=CreateSection(ContentElement);
  1789. AppendText(CreateH2(lSection), UTF8Decode(SDocInheritance));
  1790. AppendInheritanceTree(lSection,aClass);
  1791. // Description
  1792. DocNode := Engine.FindDocNode(aClass);
  1793. If Assigned(DocNode) and Assigned(DocNode.Descr) then
  1794. begin
  1795. lSection:=CreateSection(ContentElement);
  1796. AppendDescrSection(aClass,lSection,DocNode.Descr,UTF8Decode(SDocDescription));
  1797. end;
  1798. // Properties, methods and events
  1799. AppendMemberListSection(ContentElement,aClass,cmtProperty,True);
  1800. AppendMemberListSection(ContentElement,aClass,cmtMethod,True);
  1801. AppendMemberListSection(ContentElement,aClass,cmtEvent,True);
  1802. AppendMemberListSection(ContentElement,aClass,cmtField,True);
  1803. // The rest
  1804. FinishElementPage(aClass,False);
  1805. end;
  1806. procedure TNewHTMLWriter.CreateClassMemberList(aParent : THTMLElement; AClass: TPasClassType; DeclaredOnly : Boolean; AFilter: TMemberFilter);
  1807. Function GetMemberHints(aMember : TPasElement) : String;
  1808. var
  1809. S : String;
  1810. begin
  1811. S:='';
  1812. case aMember.Visibility of
  1813. visPrivate,
  1814. visStrictPrivate:
  1815. S:='pv';
  1816. visProtected,
  1817. visStrictProtected:
  1818. S:='pt';
  1819. visPublished:
  1820. S:='pl';
  1821. else
  1822. //
  1823. end;
  1824. if (aMember.ClassType = TPasProperty) and
  1825. ((TPasProperty(aMember).WriteAccessorName) = '') then
  1826. begin
  1827. if S<>'' then
  1828. S:=S+',';
  1829. S:=S+'ro';
  1830. end;
  1831. Result:=S;
  1832. end;
  1833. var
  1834. List: TFPList;
  1835. ThisClass: TPasClassType;
  1836. i, j: Integer;
  1837. Member: TPasElement;
  1838. DlEl,DtEl,DdEl: TDOMElement;
  1839. S : String;
  1840. begin
  1841. List := TFPList.Create;
  1842. try
  1843. ThisClass := AClass;
  1844. while Assigned(ThisClass) do
  1845. begin
  1846. for i := 0 to ThisClass.Members.Count - 1 do
  1847. begin
  1848. Member := TPasElement(ThisClass.Members[i]);
  1849. if Engine.ShowElement(Member) and AFilter(Member) then
  1850. begin
  1851. j := 0;
  1852. while (j < List.Count) and
  1853. (CompareText(TPasElement(List[j]).Name, Member.Name) < 0) do
  1854. Inc(j);
  1855. List.Insert(j, Member);
  1856. end;
  1857. end;
  1858. if DeclaredOnly or (Assigned(ThisClass.AncestorType) and not (ThisClass.AncestorType.inheritsfrom(TPasClassType))) then
  1859. ThisClass:=Nil
  1860. else
  1861. ThisClass := TPasClassType(ThisClass.AncestorType);
  1862. end;
  1863. for i := 0 to List.Count - 1 do
  1864. begin
  1865. dlEl := CreateEl(aParent,'div','columns list');
  1866. Member := TPasElement(List[i]);
  1867. dTEl:= CreateEl(dlEl,'div','column list is-2');
  1868. AppendHyperlink(dtEl, Member);
  1869. ddEl:= CreateEl(dlEl,'div','column is-10 list');
  1870. S:=GetMemberHints(Member);
  1871. if S<>'' then
  1872. begin
  1873. S:='{'+S+'}';
  1874. AppendNbSp(dtEl,1);
  1875. AppendText(CreateEl(dtEl,'span','cmt'),S);
  1876. end;
  1877. AppendShortDescr(DdEl,Member);
  1878. end;
  1879. finally
  1880. List.Free;
  1881. end;
  1882. end;
  1883. procedure TNewHTMLWriter.CreateClassSortedSubpage(AClass: TPasClassType; aType: TClassMemberType);
  1884. var
  1885. lSection,TitleEl, linkEl: THTMLElement;
  1886. begin
  1887. lSection:=CreateSection(ContentElement);
  1888. TitleEl:=CreateH1(lSection);
  1889. AppendText(TitleEl, GetMemberOverviewTitle(aType));
  1890. linkEl:=CreateLink(TitleEl,ResolveLinkWithinPackage(aClass,0));
  1891. AppendText(LinkEl, aClass.Name);
  1892. AppendMemberListSection(lSection,aClass,aType,False);
  1893. end;
  1894. procedure TNewHTMLWriter.CreateClassInheritedSubpage(AClass: TPasClassType; aType: TClassMemberType);
  1895. var
  1896. lSection,TitleEl, linkEl: THTMLElement;
  1897. begin
  1898. lSection:=CreateSection(ContentElement);
  1899. TitleEl:=CreateH1(lSection);
  1900. AppendText(TitleEl, GetMemberOverviewTitle(aType));
  1901. linkEl:=CreateLink(TitleEl,ResolveLinkWithinPackage(aClass,0));
  1902. AppendText(LinkEl, aClass.Name);
  1903. AppendMemberListSection(lSection,aClass,aType,False);
  1904. end;
  1905. procedure TNewHTMLWriter.CreateClassPageBody(AClass: TPasClassType; ASubpageIndex: Integer);
  1906. begin
  1907. case ASubpageIndex of
  1908. 0:
  1909. CreateClassMainPage(aClass);
  1910. PropertiesByInheritanceSubindex:
  1911. CreateClassInheritedSubpage(aClass,cmtProperty);
  1912. PropertiesByNameSubindex:
  1913. CreateClassSortedSubpage(aClass,cmtProperty);
  1914. MethodsByInheritanceSubindex:
  1915. CreateClassInheritedSubpage(aClass,cmtMethod);
  1916. MethodsByNameSubindex:
  1917. CreateClassSortedSubpage(aClass,cmtMethod);
  1918. EventsByInheritanceSubindex:
  1919. CreateClassInheritedSubpage(aClass,cmtEvent);
  1920. EventsByNameSubindex:
  1921. CreateClassSortedSubpage(aClass,cmtEvent);
  1922. FieldsByNameSubindex:
  1923. CreateClassSortedSubpage(aClass,cmtField);
  1924. end;
  1925. end;
  1926. function TNewHTMLWriter.GetVarDef(aElement : TPasVariable; aPrefixParent : Boolean) : string;
  1927. begin
  1928. Result:=GetElementCode(aElement,False);
  1929. end;
  1930. procedure TNewHTMLWriter.CreateClassMemberPageBody(AElement: TPasElement);
  1931. var
  1932. CodeBlock : TDOMElement;
  1933. procedure CreateVarPage(Element: TPasVariable);
  1934. var
  1935. S : String;
  1936. begin
  1937. S:=GetElementCode(Element,False);
  1938. AppendCodeBlock(ContentElement,S);
  1939. end;
  1940. procedure CreateTypePage(Element: TPasType);
  1941. var
  1942. S : String;
  1943. begin
  1944. S:=GetElementCode(Element,False);
  1945. AppendCodeBlock(ContentElement,S);
  1946. end;
  1947. procedure CreateConstPage(Element: TPasConst);
  1948. var
  1949. S : String;
  1950. begin
  1951. S:=GetElementCode(Element,False);
  1952. AppendCodeBlock(ContentElement,S);
  1953. end;
  1954. procedure CreatePropertyPage(Element: TPasProperty);
  1955. var
  1956. S : String;
  1957. begin
  1958. S:=GetElementCode(Element,True);
  1959. AppendCodeBlock(ContentElement,S);
  1960. end;
  1961. var
  1962. s: String;
  1963. begin
  1964. AppendTitle(ContentElement,AElement.FullName,AElement.Hints);
  1965. AppendShortDescr(CreatePara(ContentElement), AElement);
  1966. AppendText(CreateH2(ContentElement), SDocDeclaration);
  1967. AppendSourceRef(ContentElement,AElement);
  1968. CodeBlock := AppendCodeBlock(ContentElement);
  1969. if (Assigned(aElement.Parent) and aElement.Parent.InheritsFrom(TPasType)) and (AElement.Visibility<>visDefault) then
  1970. begin
  1971. s:=VisibilityNames[AElement.Visibility];
  1972. AppendKw(CodeBlock, s);
  1973. AppendText(CodeBlock, ' ');
  1974. end;
  1975. if AElement is TPasProperty then
  1976. CreatePropertyPage(TPasProperty(AElement))
  1977. else if AElement is TPasConst then
  1978. CreateConstPage(TPasConst(AElement))
  1979. else if (AElement is TPasVariable) then
  1980. CreateVarPage(TPasVariable(AElement))
  1981. else if AElement is TPasProcedureBase then
  1982. AppendProcDecl(CodeBlock,TPasProcedureBase(AElement))
  1983. else if AElement is TPasType then
  1984. CreateTypePage(TPasType(AElement))
  1985. else
  1986. AppendText(CreateWarning(ContentElement), '<' + AElement.ClassName + '>');
  1987. FinishElementPage(AElement);
  1988. end;
  1989. procedure TNewHTMLWriter.CreateVarPageBody(AVar: TPasVariable);
  1990. var
  1991. lSection,CodeEl: TDOMElement;
  1992. begin
  1993. lSection:=CreateSection(ContentElement);
  1994. AppendTitle(lSection,AVar.FullName,AVar.Hints);
  1995. AppendShortDescr(CreatePara(lSection), AVar);
  1996. AppendText(CreateH2(lSection), SDocDeclaration);
  1997. AppendSourceRef(lSection,AVar);
  1998. CodeEl := AppendCodeBlock(lSection);
  1999. AppendPasSHFragment(CodeEl, GetElementCode(aVar,False),0);
  2000. FinishElementPage(AVar);
  2001. end;
  2002. procedure TNewHTMLWriter.CreateProcPageBody(AProc: TPasProcedureBase);
  2003. var
  2004. lSection,CodeEl: THTMLElement;
  2005. begin
  2006. lSection:=CreateSection(ContentElement);
  2007. AppendTitle(lSection,AProc.Name,AProc.Hints);
  2008. AppendShortDescr(CreatePara(lSection), AProc);
  2009. lSection:=CreateSection(ContentElement);
  2010. AppendText(CreateH2(lSection), SDocDeclaration);
  2011. AppendSourceRef(lSection,AProc);
  2012. CodeEl := CreateCode(lSection);
  2013. AppendProcDecl(CodeEl, AProc);
  2014. if aProc is TPasProcedure then
  2015. if Assigned(TPasProcedure(aProc).ProcType) then
  2016. AppendProcArgsSection(lSection, TPasProcedure(aProc).ProcType);
  2017. FinishElementPage(AProc);
  2018. end;
  2019. function TNewHTMLWriter.InterPretOption ( const Cmd, Arg: String ) : boolean;
  2020. Function ReadFile(aFileName : string) : TstringStream;
  2021. begin
  2022. aFileName:= SetDirSeparators(aFileName);
  2023. try
  2024. if copy(aFileName,1,1)<>'@' then
  2025. Result:=TStringStream.Create(aFileName)
  2026. else
  2027. begin
  2028. Delete(aFileName,1,1);
  2029. Result:=TStringStream.Create('');
  2030. Result.LoadFromFile(aFileName);
  2031. Result.Position:=0;
  2032. end;
  2033. except
  2034. Result.Free;
  2035. Raise;
  2036. end;
  2037. end;
  2038. begin
  2039. Result:=True;
  2040. if Cmd = '--html-search' then
  2041. SearchPage := Arg
  2042. else if Cmd = '--footer' then
  2043. FFooterHTML := ReadFile(Arg)
  2044. else if Cmd = '--header' then
  2045. FHeaderHTML := ReadFile(Arg)
  2046. else if Cmd = '--navigator' then
  2047. FNavigatorHTML := ReadFile(Arg)
  2048. else if Cmd = '--charset' then
  2049. CharSet := Arg
  2050. else if Cmd = '--index-colcount' then
  2051. IndexColCount := StrToIntDef(Arg,IndexColCount)
  2052. else if Cmd = '--image-url' then
  2053. BaseImageURL := Arg
  2054. else if Cmd = '--css-file' then
  2055. FCSSFile := arg
  2056. else if Cmd = '--footer-date' then
  2057. begin
  2058. FIncludeDateInFooter:=True;
  2059. FDateFormat:=Arg;
  2060. end
  2061. else if Cmd = '--disable-menu-brackets' then
  2062. FUseMenuBrackets:=False
  2063. else
  2064. Result:=inherited InterPretOption(Cmd, Arg);
  2065. end;
  2066. class procedure TNewHTMLWriter.Usage(List: TStrings);
  2067. begin
  2068. List.add('--header=file');
  2069. List.Add(SHTMLUsageHeader);
  2070. List.add('--footer=file');
  2071. List.Add(SHTMLUsageFooter);
  2072. List.add('--navigator=file');
  2073. List.Add(SHTMLUsageNavigator);
  2074. List.Add('--footer-date[=Fmt]');
  2075. List.Add(SHTMLUsageFooterDate);
  2076. List.Add('--charset=set');
  2077. List.Add(SHTMLUsageCharset);
  2078. List.Add('--html-search=pagename');
  2079. List.Add(SHTMLHtmlSearch);
  2080. List.Add('--index-colcount=N');
  2081. List.Add(SHTMLIndexColcount);
  2082. List.Add('--image-url=url');
  2083. List.Add(SHTMLImageUrl);
  2084. List.Add('--disable-menu-brackets');
  2085. List.Add(SHTMLDisableMenuBrackets);
  2086. inherited Usage(List);
  2087. end;
  2088. class procedure TNewHTMLWriter.SplitImport(var AFilename, ALinkPrefix: String);
  2089. var
  2090. i: integer;
  2091. begin
  2092. i := Pos(',', AFilename);
  2093. if i > 0 then
  2094. begin //split into filename and prefix
  2095. ALinkPrefix := Copy(AFilename,i+1,Length(AFilename));
  2096. SetLength(AFilename, i-1);
  2097. end
  2098. else if ALinkPrefix = '' then
  2099. begin //synthesize outdir\pgk.xct, ..\pkg
  2100. ALinkPrefix := '../' + ChangeFileExt(ExtractFileName(AFilename), '');
  2101. AFilename := ChangeFileExt(AFilename, '.xct');
  2102. end;
  2103. end;
  2104. class function TNewHTMLWriter.FileNameExtension: String;
  2105. begin
  2106. result:='';
  2107. end;
  2108. // private methods
  2109. procedure TNewHTMLWriter.SetOnTest(const AValue: TNotifyEvent);
  2110. begin
  2111. if FOnTest=AValue then exit;
  2112. FOnTest:=AValue;
  2113. end;
  2114. initialization
  2115. // Do not localize.
  2116. RegisterWriter(TNewHTMLWriter,'newhtml','HTML output using fpdocs.css stylesheet.');
  2117. finalization
  2118. UnRegisterWriter('newhtml');
  2119. end.