dwlinear.pp 30 KB

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