dwlinear.pp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236
  1. {$mode objfpc}
  2. {$H+}
  3. unit dwlinear;
  4. interface
  5. uses
  6. Classes, SysUtils, DGlobals, dWriter, pastree, dom;
  7. Type
  8. { TLinearWriter }
  9. TLinearWriter = Class(TFPDocWriter)
  10. FStream : TStream;
  11. PackageName: String;
  12. Module: TPasModule;
  13. ModuleName: String;
  14. FLastURL : DomString;
  15. private
  16. Protected
  17. // Writing support.
  18. procedure Write(const s: String); virtual;
  19. procedure WriteLn(const s: String); virtual;
  20. procedure WriteF(const s: String; const Args: array of const);
  21. procedure WriteLnF(const s: String; const Args: array of const);
  22. Function PushWriteContext(S : TStream) : TStream;
  23. Procedure PopWriteContext(S : TSTream);
  24. procedure WriteLabel(El: TPasElement);
  25. procedure WriteIndex(El: TPasElement);
  26. // Auxiliary routines
  27. procedure DescrBeginURL(const AURL: DOMString); override; // Provides a default implementation
  28. procedure DescrEndURL; override;
  29. procedure SortElementList(List : TList);
  30. procedure StartListing(Frames: Boolean);
  31. Function ShowMember(M : TPasElement) : boolean;
  32. procedure StartChapter(ChapterName : String; ChapterLabel : String); virtual;
  33. procedure StartSection(SectionName : String; SectionLabel : String); virtual;
  34. procedure StartSubSection(SubSectionName : String; SubSectionLabel : String); virtual;
  35. procedure StartSubSubSection(SubSubSectionName : String; SubSubSectionLabel : String); virtual;
  36. Function GetDescrString(AContext: TPasElement; DescrNode: TDOMElement) : String;
  37. function ConstValue(ConstDecl: TPasConst): String; virtual;
  38. procedure ProcessSection(ASection: TPasSection); virtual;
  39. // Procedures which MAY be overridden in descendents
  40. procedure WriteBeginDocument; virtual;
  41. procedure WriteEndDocument; virtual;
  42. Function EscapeText(S : String) : String; virtual;
  43. Function StripText(S : String) : String; virtual;
  44. Procedure StartProcedure; Virtual;
  45. Procedure EndProcedure; Virtual;
  46. Procedure StartProperty; Virtual;
  47. Procedure EndProperty; Virtual;
  48. Procedure StartSynopsis; Virtual;
  49. Procedure StartDeclaration; Virtual;
  50. Procedure StartVisibility; Virtual;
  51. Procedure StartDescription; Virtual;
  52. Procedure StartAccess; Virtual;
  53. Procedure StartErrors; Virtual;
  54. Procedure StartVersion; Virtual;
  55. Procedure StartSeealso; Virtual;
  56. Procedure EndSeealso; Virtual;
  57. // Procedures which MUST be overridden in descendents;
  58. procedure WriteCommentLine; virtual; abstract;
  59. procedure WriteComment(Comment : String); virtual; abstract;
  60. function GetLabel(AElement: TPasElement): String; virtual; abstract;
  61. procedure WriteLabel(Const S : String); virtual; abstract;
  62. procedure WriteIndex(Const S : String); virtual; abstract;
  63. procedure StartChapter(ChapterName : String); virtual; abstract;
  64. procedure StartSection(SectionName : String); virtual; abstract;
  65. procedure StartSubSection(SubSectionName : String); virtual; abstract;
  66. procedure StartSubSubSection(SubSubSectionName : String); virtual; abstract;
  67. procedure StartListing(Frames: Boolean; const name: String); virtual; abstract;
  68. procedure EndListing; virtual; abstract;
  69. Procedure WriteExampleFile(FN : String); virtual; abstract;
  70. procedure StartOverview(WithAccess : Boolean); virtual; Abstract;
  71. procedure EndOverview; virtual; Abstract;
  72. procedure WriteOverviewMember(ALabel,AName,Access,ADescr : String); virtual; Abstract;
  73. procedure WriteOverviewMember(ALabel,AName,ADescr : String); virtual; Abstract;
  74. procedure StartUnitOverview(AModuleName,AModuleLabel : String);virtual; Abstract;
  75. procedure WriteUnitEntry(UnitRef : TPasType);virtual; Abstract;
  76. procedure EndUnitOverview; virtual; Abstract;
  77. Class Function FileNameExtension : String;virtual; Abstract;
  78. Property LastURL : DomString Read FLastURL Write FLastURL;
  79. Public
  80. Constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
  81. procedure WriteDoc; override;
  82. // Linear Documentation writing methods.
  83. Procedure ProcessPackage;
  84. Procedure ProcessTopics(DocNode : TDocNode; Alevel : Integer);
  85. procedure WriteResourceStrings(ASection: TPasSection);
  86. procedure WriteUnitOverview(ASection: TPasSection);
  87. procedure WriteVarsConstsTypes(ASection: TPasSection);
  88. procedure WriteConsts(ASection: TPasSection);
  89. procedure WriteTypes(ASection: TPasSection);
  90. procedure WriteEnumElements(TypeDecl : TPasEnumType);
  91. procedure WriteVars(ASection: TPasSection);
  92. procedure WriteFunctionsAndProcedures(ASection: TPasSection);
  93. procedure WriteProcedure(ProcDecl: TPasProcedureBase);
  94. procedure WriteClasses(ASection: TPasSection);
  95. procedure WriteClassDecl(ClassDecl: TPasClassType);
  96. procedure WriteClassMethodOverview(ClassDecl: TPasClassType);
  97. procedure WriteClassPropertyOverview(ClassDecl: TPasClassType);
  98. procedure WriteProperty(PropDecl: TPasProperty);
  99. procedure WriteExample(ADocNode: TDocNode);
  100. procedure WriteSeeAlso(ADocNode: TDocNode);
  101. Procedure WriteTopicNode(Node : TDocNode; Level : Integer);
  102. // Overriden from fpdocwriter;
  103. procedure DescrWriteText(const AText: DOMString); override;
  104. end;
  105. implementation
  106. { TLinearWriter }
  107. { ---------------------------------------------------------------------
  108. Writing support
  109. ---------------------------------------------------------------------}
  110. Function TLinearWriter.PushWriteContext(S : TStream) : TStream;
  111. begin
  112. Result:=FStream;
  113. FStream:=S;
  114. end;
  115. Procedure TLinearWriter.PopWriteContext(S : TSTream);
  116. begin
  117. FStream:=S;
  118. end;
  119. procedure TLinearWriter.Write(const s: String);
  120. Var
  121. L : Integer;
  122. begin
  123. L:=Length(S);
  124. If (L>0) then
  125. FStream.Write(PChar(S)^,L);
  126. end;
  127. procedure TLinearWriter.WriteF(const s: String; const Args: array of const);
  128. begin
  129. Write(Format(S,Args));
  130. end;
  131. procedure TLinearWriter.WriteLn(const s: String);
  132. begin
  133. Write(S);
  134. Write(LineEnding);
  135. end;
  136. procedure TLinearWriter.WriteLnF(const s: String; const Args: array of const);
  137. begin
  138. Write(Format(S,Args));
  139. Write(LineEnding);
  140. end;
  141. procedure TLinearWriter.DescrWriteText(const AText: DOMString);
  142. begin
  143. self.Write(EscapeText(AText));
  144. end;
  145. Function TLinearWriter.GetDescrString(AContext: TPasElement; DescrNode: TDOMElement) : String;
  146. Var
  147. S : TStringStream;
  148. F : TStream;
  149. begin
  150. Result:='';
  151. if Assigned(DescrNode) then
  152. begin
  153. S:=TStringStream.Create('');
  154. Try
  155. F:=PushWriteContext(S);
  156. Try
  157. ConvertDescr(AContext, DescrNode, False);
  158. Result:=S.DataString;
  159. FInally
  160. PopWriteContext(F);
  161. end;
  162. finally
  163. S.FRee;
  164. end;
  165. end;
  166. end;
  167. { ---------------------------------------------------------------------
  168. Auxiliary routines
  169. ---------------------------------------------------------------------}
  170. procedure TLinearWriter.WriteLabel(El: TPasElement);
  171. begin
  172. WriteLabel(GetLabel(El));
  173. end;
  174. procedure TLinearWriter.WriteIndex(El: TPasElement);
  175. begin
  176. WriteIndex(EL.Name);
  177. end;
  178. procedure TLinearWriter.DescrBeginURL(const AURL: DOMString);
  179. begin
  180. FLastURL:=AURL;
  181. end;
  182. procedure TLinearWriter.DescrEndURL;
  183. begin
  184. If (FLastURL<>'') then
  185. Writeln(Format(SSeeURL,[EscapeText(FLastURL)]));
  186. FLastURL:='';
  187. end;
  188. procedure TLinearWriter.StartListing(Frames: Boolean);
  189. begin
  190. StartListing(Frames,'');
  191. end;
  192. procedure TLinearWriter.StartChapter(ChapterName: String; ChapterLabel: String);
  193. begin
  194. StartChapter(ChapterName);
  195. WriteLabel(ChapterLabel);
  196. end;
  197. procedure TLinearWriter.StartSection(SectionName: String; SectionLabel: String);
  198. begin
  199. StartSection(SectionName);
  200. WriteLabel(SectionLabel);
  201. end;
  202. procedure TLinearWriter.StartSubSection(SubSectionName: String; SubSectionLabel: String);
  203. begin
  204. StartSubSection(SubSectionName);
  205. WriteLabel(SubSectionLabel);
  206. end;
  207. procedure TLinearWriter.StartSubSubSection(SubSubSectionName: String;
  208. SubSubSectionLabel: String);
  209. begin
  210. StartSubSubSection(SubSubSectionName);
  211. WriteLabel(SubSubSectionLabel);
  212. end;
  213. { ---------------------------------------------------------------------
  214. Default implementations, may be overridden in descendents
  215. ---------------------------------------------------------------------}
  216. Function TLinearWriter.EscapeText(S : String) : String;
  217. begin
  218. Result:=S;
  219. end;
  220. Function TLinearWriter.StripText(S : String) : String;
  221. begin
  222. Result:=S;
  223. end;
  224. Procedure TLinearWriter.StartProcedure;
  225. begin
  226. Writeln(SDocProcedure+':');
  227. end;
  228. Procedure TLinearWriter.StartSynopsis;
  229. begin
  230. Writeln('');
  231. Writeln(SDocSynopsis+':');
  232. end;
  233. Procedure TLinearWriter.StartDeclaration;
  234. begin
  235. Writeln('');
  236. Writeln(SDocDeclaration+':');
  237. end;
  238. Procedure TLinearWriter.StartVisibility;
  239. begin
  240. Writeln('');
  241. Writeln(SDocVisibility+':');
  242. end;
  243. Procedure TLinearWriter.StartDescription;
  244. begin
  245. Writeln('');
  246. Writeln(SDocDescription+':');
  247. end;
  248. Procedure TLinearWriter.StartAccess;
  249. begin
  250. Writeln('');
  251. Writeln(SDocAccess+':');
  252. end;
  253. Procedure TLinearWriter.StartErrors;
  254. begin
  255. Writeln('');
  256. Writeln(SDocErrors+':');
  257. end;
  258. Procedure TLinearWriter.StartVersion;
  259. begin
  260. Writeln('');
  261. Writeln(SDocVersion+':');
  262. end;
  263. Procedure TLinearWriter.StartSeealso;
  264. begin
  265. Writeln('');
  266. Writeln(SDocSeeAlso+':');
  267. end;
  268. Procedure TLinearWriter.StartProperty;
  269. begin
  270. Writeln('');
  271. Writeln(SDocProperty+':');
  272. end;
  273. Procedure TLinearWriter.EndProcedure;
  274. begin
  275. Writeln('');
  276. end;
  277. Procedure TLinearWriter.EndProperty;
  278. begin
  279. Writeln('');
  280. end;
  281. procedure TLinearWriter.EndSeealso;
  282. begin
  283. Writeln('');
  284. end;
  285. procedure TLinearWriter.WriteClassDecl(ClassDecl: TPasClassType);
  286. var
  287. DocNode: TDocNode;
  288. Vis: TPasMemberVisibilities;
  289. Member: TPasElement;
  290. i: Integer;
  291. begin
  292. StartSection(ClassDecl.Name);
  293. WriteLabel(ClassDecl);
  294. WriteIndex(ClassDecl);
  295. DocNode := Engine.FindDocNode(ClassDecl);
  296. if Assigned(DocNode) and ((not IsDescrNodeEmpty(DocNode.Descr)) or
  297. (not IsDescrNodeEmpty(DocNode.ShortDescr))) then
  298. begin
  299. StartSubSection(SDocDescription);
  300. WriteDescr(ClassDecl,DocNode);
  301. If Assigned(DocNode.Version) then
  302. begin
  303. StartSubSection(SDocVersion);
  304. WriteDescr(ClassDecl,DocNode.Version);
  305. end;
  306. end;
  307. // Write method overview
  308. WriteClassMethodOverView(ClassDecl);
  309. // Write Property Overview;
  310. WriteClassPropertyOverView(ClassDecl);
  311. // Write method & property descriptions
  312. // Determine visibilities
  313. Vis := AllVisibilities;
  314. if Engine.HidePrivate then
  315. Exclude(Vis,visPrivate);
  316. if Engine.HideProtected then
  317. Exclude(Vis,visProtected);
  318. for i := 0 to ClassDecl.Members.Count - 1 do
  319. begin
  320. Member := TPasElement(ClassDecl.Members[i]);
  321. if ((Member.InheritsFrom(TPasProcedureBase)) and
  322. (Member.Visibility in Vis)) then
  323. WriteProcedure(TPasProcedureBase(Member));
  324. end;
  325. // properties.
  326. for i := 0 to ClassDecl.Members.Count - 1 do
  327. begin
  328. Member := TPasElement(ClassDecl.Members[i]);
  329. if ((Member.InheritsFrom(TPasProperty)) and
  330. (Member.Visibility in Vis)) then
  331. WriteProperty(TPasProperty(Member));
  332. end;
  333. end;
  334. procedure TLinearWriter.WriteClassPropertyOverview(ClassDecl : TPasClassType);
  335. var
  336. Member: TPasElement;
  337. i: Integer;
  338. L,N,S,A: String;
  339. DocNode: TDocNode;
  340. List : TStringList;
  341. begin
  342. // Write property overview
  343. List:=TStringList.Create;
  344. Try
  345. List.Sorted:=True;
  346. for i := 0 to ClassDecl.Members.Count - 1 do
  347. begin
  348. Member := TPasElement(ClassDecl.Members[i]);
  349. With Member do
  350. if InheritsFrom(TPasProperty) and SHowMember(Member) then
  351. List.AddObject(Member.Name,Member)
  352. end;
  353. If (List.Count>0) then
  354. begin
  355. StartSubSection(SDocPropertyOverview);
  356. WriteLabel(GetLabel(ClassDecl) + ':Properties');
  357. StartOverView(True);
  358. For I:=0 to List.Count-1 do
  359. begin
  360. Member:=TPasElement(List.objects[i]);
  361. L:=StripText(GetLabel(Member));
  362. N:=EscapeText(Member.Name);
  363. DocNode := Engine.FindDocNode(Member);
  364. If Assigned(DocNode) then
  365. S:=GetDescrString(Member, DocNode.ShortDescr)
  366. else
  367. S:='';
  368. A:='';
  369. if Length(TPasProperty(Member).ReadAccessorName) > 0 then
  370. a := a + 'r';
  371. if Length(TPasProperty(Member).WriteAccessorName) > 0 then
  372. a := a + 'w';
  373. if Length(TPasProperty(Member).StoredAccessorName) > 0 then
  374. a := a + 's';
  375. WriteOverviewMember(L,N,A,S);
  376. end;
  377. EndOverview;
  378. end;
  379. Finally
  380. List.Free;
  381. end;
  382. end;
  383. function TLinearWriter.ConstValue(ConstDecl: TPasConst): String;
  384. begin
  385. if Assigned(ConstDecl) then
  386. Result := ConstDecl.ClassName
  387. else
  388. Result := '<nil>';
  389. end;
  390. procedure TLinearWriter.WriteDoc;
  391. var
  392. i : Integer;
  393. L : TstringList;
  394. begin
  395. PackageName := LowerCase(Copy(Package.Name, 2, 255));
  396. If (Engine.OutPut='') then
  397. Engine.Output:=PackageName+FileNameExtension;
  398. FStream:=TFileStream.Create(Engine.Output,fmCreate);
  399. try
  400. WriteBeginDocument;
  401. ProcessPackage;
  402. L:=TStringList.Create;
  403. Try
  404. L.Sorted:=True;
  405. // Sort modules.
  406. For I:=0 to Package.Modules.Count-1 do
  407. L.AddObject(TPasModule(Package.Modules[i]).Name,TPasModule(Package.Modules[i]));
  408. // Now create table.
  409. for i:=0 to L.Count - 1 do
  410. begin
  411. Module := TPasModule(L.Objects[i]);
  412. ModuleName := LowerCase(Module.Name);
  413. WriteCommentLine;
  414. StartChapter(Format(SDocUnitTitle, [Module.Name]));
  415. WriteLabel(Module);
  416. // extra Topics now get processed in ProcessSection()
  417. ProcessSection(Module.InterfaceSection);
  418. end;
  419. Finally
  420. L.Free;
  421. end;
  422. WriteEndDocument;
  423. finally
  424. FSTream.Free;
  425. end;
  426. end;
  427. procedure TLinearWriter.ProcessSection(ASection: TPasSection);
  428. var
  429. DocNode: TDocNode;
  430. begin
  431. With ASection do
  432. begin
  433. SortElementList(UsesList);
  434. SortElementList(Declarations);
  435. SortElementList(ResStrings);
  436. SortElementList(Types);
  437. SortElementList(Consts);
  438. SortElementList(Classes);
  439. SortElementList(Functions);
  440. SortElementList(Variables);
  441. end;
  442. WriteUnitOverView(ASection);
  443. // Now process unit (extra) Topics
  444. DocNode:=Engine.FindDocNode(Module);
  445. If Assigned(DocNode) then
  446. ProcessTopics(DocNode,1);
  447. WriteVarsConstsTypes(ASection);
  448. WriteFunctionsAndProcedures(ASection);
  449. WriteClasses(ASection);
  450. end;
  451. procedure TLinearWriter.WriteVarsConstsTypes(ASection: TPasSection);
  452. begin
  453. With Asection do
  454. if (Consts.Count>0) or (Types.Count>0) or
  455. (Variables.Count>0) or (ResStrings.Count>0) then
  456. begin
  457. StartSection(SDocConstsTypesVars, ModuleName+'ConstsTypesVars');
  458. WriteResourceStrings(ASection);
  459. WriteConsts(ASection);
  460. WriteTypes(ASection);
  461. WriteVars(ASection);
  462. end;
  463. end;
  464. procedure TLinearWriter.WriteResourceStrings(ASection: TPasSection);
  465. var
  466. ResStrDecl: TPasResString;
  467. i: Integer;
  468. DocNode : TDocNode;
  469. begin
  470. if ASection.ResStrings.Count > 0 then
  471. begin
  472. StartSubSection(SDocResStrings,ModuleName+'ResStrings');
  473. for i := 0 to ASection.ResStrings.Count - 1 do
  474. begin
  475. ResStrDecl := TPasResString(ASection.ResStrings[i]);
  476. StartListing(false, '');
  477. Writeln(ResStrDecl.GetDeclaration(True));
  478. EndListing;
  479. WriteLabel(ResStrDecl);
  480. WriteIndex(ResStrDecl);
  481. DocNode:=WriteDescr(ResStrDecl);
  482. If Assigned(DocNode) and Assigned(DocNode.Version) then
  483. begin
  484. Writeln(Format('%s : ',[SDocVersion]));
  485. WriteDescr(ResStrDecl, DocNode.Version);
  486. end;
  487. end;
  488. end;
  489. end;
  490. procedure TLinearWriter.WriteUnitOverview(ASection: TPasSection);
  491. var
  492. i: Integer;
  493. UnitRef: TPasType;
  494. DocNode: TDocNode;
  495. begin
  496. if ASection.UsesList.Count > 0 then
  497. begin
  498. StartSection(SDocUsedUnits);
  499. StartUnitOverview(Module.Name,ModuleName);
  500. for i := 0 to ASection.UsesList.Count - 1 do
  501. begin
  502. UnitRef := TPasType(ASection.UsesList[i]);
  503. WriteUnitEntry(UnitRef);
  504. end;
  505. EndUnitOverview;
  506. end;
  507. DocNode := Engine.FindDocNode(ASection.Parent);
  508. if Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr) then
  509. begin
  510. StartSection(SDocOverview);
  511. WriteDescr(ASection.Parent, DocNode.Descr);
  512. end;
  513. end;
  514. Procedure TLinearWriter.ProcessPackage;
  515. var
  516. DocNode: TDocNode;
  517. begin
  518. DocNode:=Engine.FindDocNode(Package);
  519. if Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr) then
  520. begin
  521. StartSection(SDocOverview);
  522. WriteDescr(Package, DocNode.Descr);
  523. end;
  524. WriteSeeAlso(DocNode);
  525. ProcessTopics(DocNode,1);
  526. end;
  527. Procedure TLinearWriter.ProcessTopics(DocNode : TDocNode; Alevel : Integer);
  528. Var
  529. Node : TDocNode;
  530. begin
  531. If Not Assigned(DocNode) then
  532. Exit;
  533. Node:=DocNode.FirstChild;
  534. While Assigned(Node) do
  535. begin
  536. If Node.TopicNode then
  537. WriteTopicNode(Node,ALevel);
  538. Node:=Node.NextSibling;
  539. end;
  540. end;
  541. Procedure TLinearWriter.WriteTopicNode(Node : TDocNode; Level : Integer);
  542. Var
  543. Element : TTopicElement;
  544. SubNode : TDocNode;
  545. S : String;
  546. begin
  547. Element:=FindTopicElement(Node);
  548. If Not Assigned(Element) then
  549. Exit;
  550. S:=GetDescrString(Element,Node.ShortDescr);
  551. Case Level of
  552. 1 : StartSection(S);
  553. 2 : StartSubSection(S);
  554. 3 : StartSubSubSection(S);
  555. end;
  556. WriteLabel(Element);
  557. If Assigned(Node.Descr) then
  558. WriteDescr(Element,Node.Descr);
  559. WriteSeeAlso(Node);
  560. If Level<3 then
  561. begin
  562. SubNode:=Node.FirstChild;
  563. While Assigned(SubNode) do
  564. begin
  565. If SubNode.TopicNode then
  566. WriteTopicNode(SubNode,Level+1);
  567. SubNode:=SubNode.NextSibling;
  568. end;
  569. end;
  570. WriteExample(Node);
  571. end;
  572. procedure TLinearWriter.WriteConsts(ASection: TPasSection);
  573. var
  574. i: Integer;
  575. ConstDecl: TPasConst;
  576. begin
  577. if ASection.Consts.Count > 0 then
  578. begin
  579. StartSubSection(SDocConstants,EscapeText(ModuleName));
  580. for i := 0 to ASection.Consts.Count - 1 do
  581. begin
  582. DescrBeginParaGraph;
  583. ConstDecl := TPasConst(ASection.Consts[i]);
  584. StartListing(False,'');
  585. WriteLn(EscapeText(ConstDecl.GetDeclaration(True)));
  586. EndListing;
  587. WriteLabel(ConstDecl);
  588. WriteIndex(ConstDecl);
  589. WriteDescr(ConstDecl);
  590. DescrEndParaGraph;
  591. end;
  592. end;
  593. end;
  594. procedure TLinearWriter.WriteEnumElements(TypeDecl : TPasEnumType);
  595. Var
  596. EV : TPasEnumValue;
  597. I : Integer;
  598. DocNode : TDocNode;
  599. begin
  600. With TypeDecl do
  601. begin
  602. SortElementList(Values);
  603. DescrBeginTable(2,True);
  604. DescrBeginTableCaption;
  605. Writeln(EscapeText(Format(SDocValuesForEnum,[TypeDecl.Name])));
  606. DescrEndTableCaption;
  607. DescrBeginTableHeadRow;
  608. DescrBeginTableCell;
  609. Writeln(EscapeText(SDocValue));
  610. DescrEndTableCell;
  611. DescrBeginTableCell;
  612. Writeln(EscapeText(SDocExplanation));
  613. DescrEndTableCell;
  614. DescrEndTableHeadRow;
  615. For I:=0 to Values.Count-1 do
  616. begin
  617. EV:=TPasEnumValue(Values[i]);
  618. DescrBeginTableRow;
  619. DescrBeginTableCell;
  620. Writeln(EscapeText(EV.Name));
  621. DescrEndTableCell;
  622. DescrBeginTableCell;
  623. DocNode := Engine.FindDocNode(EV);
  624. if Assigned(DocNode) and (not IsDescrNodeEmpty(DocNode.ShortDescr)) then
  625. WriteDescr(EV,DocNode.ShortDescr);
  626. DescrEndTableCell;
  627. DescrEndTableRow;
  628. end;
  629. DescrEndTable;
  630. end;
  631. end;
  632. procedure TLinearWriter.WriteTypes(ASection: TPasSection);
  633. var
  634. i: Integer;
  635. TypeDecl: TPasType;
  636. DocNode : TDocNode;
  637. begin
  638. if ASection.Types.Count > 0 then
  639. begin
  640. StartSubSection(SDocTypes,ModuleName+'Types');
  641. for i := 0 to ASection.Types.Count - 1 do
  642. begin
  643. DescrBeginParaGraph;
  644. TypeDecl := TPasType(ASection.Types[i]);
  645. StartListing(False,'');
  646. DocNode := Engine.FindDocNode(TypeDecl);
  647. If Assigned(DocNode) and
  648. Assigned(DocNode.Node) and
  649. (Docnode.Node['opaque']='1') then
  650. Writeln(TypeDecl.Name+' = '+SDocOpaque)
  651. else
  652. Writeln(EscapeText(TypeDecl.GetDeclaration(True)));
  653. EndListing;
  654. WriteLabel(TypeDecl);
  655. WriteIndex(TypeDecl);
  656. If TypeDecl is TPasEnumType then
  657. begin
  658. WriteENumElements(TypeDecl as TPasEnumType);
  659. end;
  660. WriteDescr(TypeDecl);
  661. If Assigned(DocNode) and Assigned(DocNode.Version) then
  662. begin
  663. Writeln(Format('%s : ',[SDocVersion]));
  664. WriteDescr(TypeDecl, DocNode.Version);
  665. end;
  666. DescrEndParaGraph;
  667. end;
  668. end;
  669. end;
  670. procedure TLinearWriter.WriteVars(ASection: TPasSection);
  671. var
  672. VarDecl: TPasVariable;
  673. i: Integer;
  674. DocNode : TDocNode;
  675. begin
  676. if ASection.Variables.Count > 0 then
  677. begin
  678. StartSubsection(SDocVariables,ModuleName+'Variables');
  679. for i := 0 to ASection.Variables.Count - 1 do
  680. begin
  681. DescrBeginParaGraph;
  682. VarDecl := TPasVariable(ASection.Variables[i]);
  683. StartListing(False,'');
  684. WriteLn(EscapeText(VarDecl.GetDeclaration(True)));
  685. EndListing;
  686. WriteLabel(VarDecl);
  687. WriteIndex(VarDecl);
  688. DocNode:=WriteDescr(VarDecl);
  689. If Assigned(DocNode) and Assigned(DocNode.Version) then
  690. begin
  691. Writeln(Format('%s : ',[SDocVersion]));
  692. WriteDescr(VarDecl, DocNode.Version);
  693. end;
  694. DescrEndParaGraph;
  695. end;
  696. end;
  697. end;
  698. procedure TLinearWriter.WriteProcedure(ProcDecl : TPasProcedureBase);
  699. var
  700. DocNode: TDocNode;
  701. OP : TPasOverloadedProc;
  702. i : integer;
  703. begin
  704. With ProcDecl do
  705. begin
  706. if Not (Assigned(Parent) and Parent.InheritsFrom(TPasClassType)) then
  707. begin
  708. StartSubSection(Name);
  709. WriteLabel(ProcDecl);
  710. WriteIndex(ProcDecl);
  711. end
  712. else
  713. begin // Parent assigned and hence method.
  714. StartSubSection(Parent.Name+'.'+Name);
  715. WriteLabel(ProcDecl);
  716. WriteIndex(Parent.Name+'.'+Name);
  717. end;
  718. StartProcedure;
  719. DocNode := Engine.FindDocNode(ProcDecl);
  720. if Assigned(DocNode) and Assigned(DocNode.ShortDescr) then
  721. begin
  722. StartSynopsis;
  723. WriteDescr(ProcDecl, DocNode.ShortDescr);
  724. end;
  725. StartDeclaration;
  726. StartListing(False);
  727. if ClassType = TPasOverloadedProc then
  728. begin
  729. OP:=TPasOverloadedProc(ProcDecl);
  730. for i := 0 to OP.Overloads.Count - 1 do
  731. begin
  732. WriteLn(TPasProcedure(OP.Overloads[i]).GetDeclaration(True));
  733. end;
  734. end
  735. else
  736. WriteLn(GetDeclaration(True));
  737. EndListing;
  738. If Assigned(Parent) then
  739. begin
  740. StartVisibility;
  741. Writeln(VisibilityNames[Visibility])
  742. end;
  743. if Assigned(DocNode) then
  744. begin
  745. If Assigned(DocNode.Descr) then
  746. begin
  747. StartDescription;
  748. WriteDescr(ProcDecl);
  749. end;
  750. if Assigned(DocNode.ErrorsDoc) then
  751. begin
  752. StartErrors;
  753. WriteDescr(ProcDecl, DocNode.ErrorsDoc);
  754. end;
  755. if Assigned(DocNode.Version) then
  756. begin
  757. StartVersion;
  758. WriteDescr(ProcDecl, DocNode.Version);
  759. end;
  760. WriteSeeAlso(DocNode);
  761. EndProcedure;
  762. WriteExample(DocNode);
  763. end
  764. else
  765. EndProcedure;
  766. end;
  767. end;
  768. procedure TLinearWriter.WriteFunctionsAndProcedures(ASection: TPasSection);
  769. var
  770. i: Integer;
  771. begin
  772. if ASection.Functions.Count > 0 then
  773. begin
  774. StartSection(SDocProceduresAndFunctions,ModuleName+'Functions');
  775. for i := 0 to ASection.Functions.Count - 1 do
  776. WriteProcedure(TPasProcedureBase(ASection.Functions[i]));
  777. end;
  778. end;
  779. procedure TLinearWriter.WriteExample(ADocNode: TDocNode);
  780. var
  781. Example: TDOMElement;
  782. S : string;
  783. begin
  784. S:='';
  785. if Assigned(ADocNode) then
  786. begin
  787. Example := ADocNode.FirstExample;
  788. while Assigned(Example) do
  789. begin
  790. if IsExampleNode(Example) then
  791. begin
  792. if (S<>'') then // not first example, start new paragraph
  793. DescrBeginParagraph;
  794. s:=Engine.GetExampleFileName(Example);
  795. if (S<>'') then
  796. WriteExampleFile(S);
  797. if Assigned(Example.NextSibling) then
  798. DescrEndParaGraph;
  799. end;
  800. Example := TDomElement(Example.NextSibling);
  801. end;
  802. end;
  803. end;
  804. procedure TLinearWriter.WriteProperty(PropDecl : TPasProperty);
  805. var
  806. DocNode: TDocNode;
  807. S: String;
  808. begin
  809. With PropDecl do
  810. begin
  811. StartSubSection(Parent.Name+'.'+Name);
  812. WriteLabel(PropDecl);
  813. WriteIndex(Parent.Name+'.'+Name);
  814. StartProperty;
  815. DocNode := Engine.FindDocNode(PropDecl);
  816. if Assigned(DocNode) and Assigned(DocNode.ShortDescr) then
  817. begin
  818. StartSynopsis;
  819. WriteDescr(PropDecl, DocNode.ShortDescr);
  820. end;
  821. StartDeclaration;
  822. StartListing(False);
  823. WriteLn('Property '+GetDeclaration(True));
  824. EndListing;
  825. If Assigned(Parent) then
  826. begin
  827. StartVisibility;
  828. Writeln(VisibilityNames[Visibility])
  829. end;
  830. StartAccess;
  831. Setlength(S,0);
  832. If Length(ReadAccessorName) > 0 then
  833. S:='Read';
  834. if Length(WriteAccessorName) > 0 then
  835. begin
  836. If S<>'' then
  837. S:=S+',';
  838. S:=S+'Write';
  839. end;
  840. Writeln(S);
  841. if Assigned(DocNode) then
  842. begin
  843. if Assigned(DocNode.Descr) then
  844. begin
  845. StartDescription;
  846. WriteDescr(PropDecl);
  847. end;
  848. if Assigned(DocNode.ErrorsDoc) then
  849. begin
  850. StartErrors;
  851. WriteDescr(PropDecl, DocNode.ErrorsDoc);
  852. end;
  853. if Assigned(DocNode.Version) then
  854. begin
  855. StartVersion;
  856. WriteDescr(PropDecl, DocNode.Version);
  857. end;
  858. WriteSeeAlso(DocNode);
  859. EndProperty;
  860. WriteExample(DocNode);
  861. end
  862. else
  863. EndProperty;
  864. end;
  865. end;
  866. procedure TLinearWriter.WriteSeeAlso(ADocNode: TDocNode);
  867. var
  868. Node: TDOMNode;
  869. s: String;
  870. First : Boolean;
  871. begin
  872. if Not (Assigned(ADocNode) and Assigned(ADocNode.SeeAlso)) then
  873. Exit;
  874. Node := ADocNode.SeeAlso.FirstChild;
  875. First:=True;
  876. while Assigned(Node) do
  877. begin
  878. if IsLinkNode(Node) then
  879. begin
  880. If First then
  881. begin
  882. StartSeealso;
  883. First:=False;
  884. end
  885. else
  886. Writeln(',');
  887. S:=TDomElement(Node)['id'];
  888. DescrBeginLink(S);
  889. Write(EscapeText(S));
  890. DescrEndLink();
  891. end;
  892. Node:=Node.NextSibling;
  893. end;
  894. If Not First then
  895. EndSeeAlso
  896. end;
  897. Function CompareElements(P1,P2 : Pointer) : Integer;
  898. begin
  899. Result:=CompareText(TPasElement(P1).Name,TPasElement(P2).Name);
  900. end;
  901. procedure TLinearWriter.SortElementList(List : TList);
  902. begin
  903. List.Sort(@CompareElements);
  904. end;
  905. Function TLinearWriter.ShowMember(M : TPasElement) : boolean;
  906. begin
  907. Result:=not ((M.Visibility=visPrivate) and Engine.HidePrivate);
  908. If Result then
  909. Result:=Not ((M.Visibility=visProtected) and Engine.HideProtected)
  910. end;
  911. procedure TLinearWriter.WriteClasses(ASection: TPasSection);
  912. var
  913. i: Integer;
  914. begin
  915. if (ASection.Classes.Count > 0) then
  916. for i := 0 to ASection.Classes.Count - 1 do
  917. WriteClassDecl(TPasClassType(ASection.Classes[i]));
  918. end;
  919. procedure TLinearWriter.WriteClassMethodOverview(ClassDecl: TPasClassType);
  920. var
  921. Member : TPasElement;
  922. i : Integer;
  923. L,N,S : String;
  924. DocNode : TDocNode;
  925. List : TStringList;
  926. begin
  927. List:=TStringList.Create;
  928. Try
  929. List.Sorted:=True;
  930. for i := 0 to ClassDecl.Members.Count - 1 do
  931. begin
  932. Member := TPasElement(ClassDecl.Members[i]);
  933. With Member do
  934. if InheritsFrom(TPasProcedureBase) and ShowMember(Member) then
  935. List.AddObject(Member.Name,Member);
  936. end;
  937. If List.Count>0 then
  938. begin
  939. StartSubSection(SDocMethodOverview);
  940. WriteLabel(GetLabel(ClassDecl) + ':Methods');
  941. StartOverview(False);
  942. For I:=0 to List.Count-1 do
  943. begin
  944. Member:=TPasElement(List.Objects[i]);
  945. L:=StripText(GetLabel(Member));
  946. N:=EscapeText(Member.Name);
  947. DocNode := Engine.FindDocNode(Member);
  948. If Assigned(DocNode) then
  949. S:=GetDescrString(Member, DocNode.ShortDescr)
  950. else
  951. S:='';
  952. WriteOverviewMember(L,N,S);
  953. end;
  954. EndOverview;
  955. end;
  956. Finally
  957. List.Free;
  958. end;
  959. end;
  960. constructor TLinearWriter.Create(APackage: TPasPackage; AEngine: TFPDocEngine);
  961. procedure AddLabel(AElement: TPasElement);
  962. begin
  963. Engine.AddLink(AElement.PathName, GetLabel(AElement));
  964. end;
  965. procedure AddList(AElement: TPasElement; AList: TList);
  966. var
  967. i: Integer;
  968. begin
  969. for i := 0 to AList.Count - 1 do
  970. AddLabel(TPasElement(AList[i]));
  971. end;
  972. procedure AddTopicPages(AElement: TPasElement);
  973. var
  974. PreviousTopic,
  975. TopicElement : TTopicElement;
  976. DocNode,
  977. TopicNode : TDocNode;
  978. begin
  979. DocNode:=Engine.FindDocNode(AElement);
  980. If not Assigned(DocNode) then
  981. exit;
  982. TopicNode:=DocNode.FirstChild;
  983. PreviousTopic:=Nil;
  984. While Assigned(TopicNode) do
  985. begin
  986. If TopicNode.TopicNode then
  987. begin
  988. TopicElement:=TTopicElement.Create(TopicNode.Name,AElement);
  989. Topics.Add(TopicElement);
  990. TopicElement.TopicNode:=TopicNode;
  991. TopicElement.Previous:=PreviousTopic;
  992. If Assigned(PreviousTopic) then
  993. PreviousTopic.Next:=TopicElement;
  994. PreviousTopic:=TopicElement;
  995. if AElement is TTopicElement then
  996. TTopicElement(AElement).SubTopics.Add(TopicElement);
  997. Engine.AddLink(TopicElement.PathName, GetLabel(TopicElement));
  998. if AElement is TTopicElement then
  999. TTopicElement(AElement).SubTopics.Add(TopicElement)
  1000. else // Only one level of recursion.
  1001. AddTopicPages(TopicElement);
  1002. end;
  1003. TopicNode:=TopicNode.NextSibling;
  1004. end;
  1005. end;
  1006. procedure ScanModule(AModule: TPasModule);
  1007. var
  1008. i, j, k: Integer;
  1009. ClassEl: TPasClassType;
  1010. FPEl, AncestorMemberEl: TPasElement;
  1011. DocNode: TDocNode;
  1012. DidAutolink: Boolean;
  1013. begin
  1014. AddLabel(AModule);
  1015. AddTopicPages(AModule);
  1016. with AModule do
  1017. begin
  1018. AddList(AModule, InterfaceSection.ResStrings);
  1019. AddList(AModule, InterfaceSection.Consts);
  1020. AddList(AModule, InterfaceSection.Types);
  1021. if InterfaceSection.Classes.Count > 0 then
  1022. begin
  1023. for i := 0 to InterfaceSection.Classes.Count - 1 do
  1024. begin
  1025. ClassEl := TPasClassType(InterfaceSection.Classes[i]);
  1026. AddLabel(ClassEl);
  1027. for j := 0 to ClassEl.Members.Count - 1 do
  1028. begin
  1029. FPEl := TPasElement(ClassEl.Members[j]);
  1030. if ((FPEl.Visibility = visPrivate) and Engine.HidePrivate) or
  1031. ((FPEl.Visibility = visProtected) and Engine.HideProtected) then
  1032. continue;
  1033. DocNode := Engine.FindDocNode(FPEl);
  1034. if not Assigned(DocNode) then
  1035. begin
  1036. DidAutolink := False;
  1037. if Assigned(ClassEl.AncestorType) and
  1038. (ClassEl.AncestorType.ClassType = TPasClassType) then
  1039. begin
  1040. for k := 0 to TPasClassType(ClassEl.AncestorType).Members.Count - 1 do
  1041. begin
  1042. AncestorMemberEl :=
  1043. TPasElement(TPasClassType(ClassEl.AncestorType).Members[k]);
  1044. if AncestorMemberEl.Name = FPEl.Name then
  1045. begin
  1046. DocNode := Engine.FindDocNode(AncestorMemberEl);
  1047. if Assigned(DocNode) then
  1048. begin
  1049. DidAutolink := True;
  1050. Engine.AddLink(FPEl.PathName,
  1051. Engine.FindAbsoluteLink(AncestorMemberEl.PathName));
  1052. break;
  1053. end;
  1054. end;
  1055. end;
  1056. end;
  1057. if not DidAutolink then
  1058. AddLabel(FPEl);
  1059. end else
  1060. AddLabel(FPEl);
  1061. end;
  1062. end;
  1063. end;
  1064. AddList(AModule, InterfaceSection.Functions);
  1065. AddList(AModule, InterfaceSection.Variables);
  1066. end;
  1067. end;
  1068. var
  1069. i: Integer;
  1070. begin
  1071. inherited ;
  1072. { Allocate labels for all elements for which we are going to create
  1073. documentation. This is needed for links to work correctly. }
  1074. // Allocate label for the package itself, if a name is given (i.e. <> '#')
  1075. if Length(Package.Name) > 1 then
  1076. begin
  1077. AddLabel(Package);
  1078. AddTopicPages(Package);
  1079. end;
  1080. for i := 0 to Package.Modules.Count - 1 do
  1081. ScanModule(TPasModule(Package.Modules[i]));
  1082. end;
  1083. procedure TLinearWriter.WriteBeginDocument;
  1084. begin
  1085. WriteComment('This file has been created automatically by FPDoc.');
  1086. WriteComment('Linear output (c) 2005 Michael Van Canneyt');
  1087. end;
  1088. procedure TLinearWriter.WriteEndDocument;
  1089. begin
  1090. end;
  1091. end.