dwlinear.pp 30 KB

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