dwlinear.pp 30 KB

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