dwlinear.pp 30 KB

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