dwlinear.pp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164
  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. // 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. DocNode : TDocNode;
  368. L : TstringList;
  369. begin
  370. PackageName := LowerCase(Copy(Package.Name, 2, 255));
  371. If (Engine.OutPut='') then
  372. Engine.Output:=PackageName+FileNameExtension;
  373. FStream:=TFileStream.Create(Engine.Output,fmCreate);
  374. try
  375. WriteBeginDocument;
  376. ProcessPackage;
  377. L:=TStringList.Create;
  378. Try
  379. L.Sorted:=True;
  380. // Sort modules.
  381. For I:=0 to Package.Modules.Count-1 do
  382. L.AddObject(TPasModule(Package.Modules[i]).Name,TPasModule(Package.Modules[i]));
  383. // Now create table.
  384. for i:=0 to L.Count - 1 do
  385. begin
  386. Module := TPasModule(L.Objects[i]);
  387. ModuleName := LowerCase(Module.Name);
  388. WriteCommentLine;
  389. StartChapter(Format(SDocUnitTitle, [Module.Name]));
  390. WriteLabel(Module);
  391. DocNode:=Engine.FindDocNode(Module);
  392. If Assigned(DocNode) then
  393. ProcessTopics(DocNode,1);
  394. ProcessSection(Module.InterfaceSection);
  395. end;
  396. Finally
  397. L.Free;
  398. end;
  399. WriteEndDocument;
  400. finally
  401. FSTream.Free;
  402. end;
  403. end;
  404. procedure TLinearWriter.ProcessSection(ASection: TPasSection);
  405. begin
  406. With ASection do
  407. begin
  408. SortElementList(UsesList);
  409. SortElementList(Declarations);
  410. SortElementList(ResStrings);
  411. SortElementList(Types);
  412. SortElementList(Consts);
  413. SortElementList(Classes);
  414. SortElementList(Functions);
  415. SortElementList(Variables);
  416. end;
  417. WriteUnitOverView(ASection);
  418. WriteVarsConstsTypes(ASection);
  419. WriteFunctionsAndProcedures(ASection);
  420. WriteClasses(ASection);
  421. end;
  422. procedure TLinearWriter.WriteVarsConstsTypes(ASection: TPasSection);
  423. begin
  424. With Asection do
  425. if (Consts.Count>0) or (Types.Count>0) or
  426. (Variables.Count>0) or (ResStrings.Count>0) then
  427. begin
  428. StartSection(SDocConstsTypesVars, ModuleName+'ConstsTypesVars');
  429. WriteResourceStrings(ASection);
  430. WriteConsts(ASection);
  431. WriteTypes(ASection);
  432. WriteVars(ASection);
  433. end;
  434. end;
  435. procedure TLinearWriter.WriteResourceStrings(ASection: TPasSection);
  436. var
  437. ResStrDecl: TPasResString;
  438. i: Integer;
  439. begin
  440. if ASection.ResStrings.Count > 0 then
  441. begin
  442. StartSubSection(SDocResStrings,ModuleName+'ResStrings');
  443. for i := 0 to ASection.ResStrings.Count - 1 do
  444. begin
  445. ResStrDecl := TPasResString(ASection.ResStrings[i]);
  446. StartListing(false, '');
  447. Writeln(ResStrDecl.GetDeclaration(True));
  448. EndListing;
  449. WriteLabel(ResStrDecl);
  450. WriteIndex(ResStrDecl);
  451. WriteDescr(ResStrDecl);
  452. end;
  453. end;
  454. end;
  455. procedure TLinearWriter.WriteUnitOverview(ASection: TPasSection);
  456. var
  457. i: Integer;
  458. UnitRef: TPasType;
  459. DocNode: TDocNode;
  460. begin
  461. if ASection.UsesList.Count > 0 then
  462. begin
  463. StartSection(SDocUsedUnits);
  464. StartUnitOverview(Module.Name,ModuleName);
  465. for i := 0 to ASection.UsesList.Count - 1 do
  466. begin
  467. UnitRef := TPasType(ASection.UsesList[i]);
  468. WriteUnitEntry(UnitRef);
  469. end;
  470. EndUnitOverview;
  471. end;
  472. DocNode := Engine.FindDocNode(ASection.Parent);
  473. if Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr) then
  474. begin
  475. StartSection(SDocOverview);
  476. WriteDescr(ASection.Parent, DocNode.Descr);
  477. end;
  478. end;
  479. Procedure TLinearWriter.ProcessPackage;
  480. var
  481. DocNode: TDocNode;
  482. begin
  483. DocNode:=Engine.FindDocNode(Package);
  484. if Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr) then
  485. begin
  486. StartSection(SDocOverview);
  487. WriteDescr(Package, DocNode.Descr);
  488. end;
  489. WriteSeeAlso(DocNode);
  490. ProcessTopics(DocNode,1);
  491. end;
  492. Procedure TLinearWriter.ProcessTopics(DocNode : TDocNode; Alevel : Integer);
  493. Var
  494. Node : TDocNode;
  495. begin
  496. If Not Assigned(DocNode) then
  497. Exit;
  498. Node:=DocNode.FirstChild;
  499. While Assigned(Node) do
  500. begin
  501. If Node.TopicNode then
  502. WriteTopicNode(Node,ALevel);
  503. Node:=Node.NextSibling;
  504. end;
  505. end;
  506. Procedure TLinearWriter.WriteTopicNode(Node : TDocNode; Level : Integer);
  507. Var
  508. Element : TTopicElement;
  509. SubNode : TDocNode;
  510. S : String;
  511. begin
  512. Element:=FindTopicElement(Node);
  513. If Not Assigned(Element) then
  514. Exit;
  515. S:=GetDescrString(Element,Node.ShortDescr);
  516. Case Level of
  517. 1 : StartSection(S);
  518. 2 : StartSubSection(S);
  519. 3 : StartSubSubSection(S);
  520. end;
  521. WriteLabel(Element);
  522. If Assigned(Node.Descr) then
  523. WriteDescr(Element,Node.Descr);
  524. WriteSeeAlso(Node);
  525. If Level<3 then
  526. begin
  527. SubNode:=Node.FirstChild;
  528. While Assigned(SubNode) do
  529. begin
  530. If SubNode.TopicNode then
  531. WriteTopicNode(SubNode,Level+1);
  532. SubNode:=SubNode.NextSibling;
  533. end;
  534. end;
  535. end;
  536. procedure TLinearWriter.WriteConsts(ASection: TPasSection);
  537. var
  538. i: Integer;
  539. ConstDecl: TPasConst;
  540. begin
  541. if ASection.Consts.Count > 0 then
  542. begin
  543. StartSubSection(SDocConstants,EscapeText(ModuleName));
  544. for i := 0 to ASection.Consts.Count - 1 do
  545. begin
  546. DescrBeginParaGraph;
  547. ConstDecl := TPasConst(ASection.Consts[i]);
  548. StartListing(False,'');
  549. WriteLn(EscapeText(ConstDecl.GetDeclaration(True)));
  550. EndListing;
  551. WriteLabel(ConstDecl);
  552. WriteIndex(ConstDecl);
  553. WriteDescr(ConstDecl);
  554. DescrEndParaGraph;
  555. end;
  556. end;
  557. end;
  558. procedure TLinearWriter.WriteEnumElements(TypeDecl : TPasEnumType);
  559. Var
  560. EV : TPasEnumValue;
  561. I : Integer;
  562. DocNode : TDocNode;
  563. begin
  564. With TypeDecl do
  565. begin
  566. SortElementList(Values);
  567. DescrBeginTable(2,True);
  568. DescrBeginTableCaption;
  569. Writeln(EscapeText(Format(SDocValuesForEnum,[TypeDecl.Name])));
  570. DescrEndTableCaption;
  571. DescrBeginTableHeadRow;
  572. DescrBeginTableCell;
  573. Writeln(EscapeText(SDocValue));
  574. DescrEndTableCell;
  575. DescrBeginTableCell;
  576. Writeln(EscapeText(SDocExplanation));
  577. DescrEndTableCell;
  578. DescrEndTableHeadRow;
  579. For I:=0 to Values.Count-1 do
  580. begin
  581. EV:=TPasEnumValue(Values[i]);
  582. DescrBeginTableRow;
  583. DescrBeginTableCell;
  584. Writeln(EscapeText(EV.Name));
  585. DescrEndTableCell;
  586. DescrBeginTableCell;
  587. DocNode := Engine.FindDocNode(EV);
  588. if Assigned(DocNode) and (not IsDescrNodeEmpty(DocNode.ShortDescr)) then
  589. WriteDescr(EV,DocNode.ShortDescr);
  590. DescrEndTableCell;
  591. DescrEndTableRow;
  592. end;
  593. DescrEndTable;
  594. end;
  595. end;
  596. procedure TLinearWriter.WriteTypes(ASection: TPasSection);
  597. var
  598. i: Integer;
  599. TypeDecl: TPasType;
  600. DocNode : TDocNode;
  601. begin
  602. if ASection.Types.Count > 0 then
  603. begin
  604. StartSubSection(SDocTypes,ModuleName+'Types');
  605. for i := 0 to ASection.Types.Count - 1 do
  606. begin
  607. DescrBeginParaGraph;
  608. TypeDecl := TPasType(ASection.Types[i]);
  609. StartListing(False,'');
  610. DocNode := Engine.FindDocNode(TypeDecl);
  611. If Assigned(DocNode) and
  612. Assigned(DocNode.Node) and
  613. (Docnode.Node['opaque']='1') then
  614. Writeln(TypeDecl.Name+' = '+SDocOpaque)
  615. else
  616. Writeln(EscapeText(TypeDecl.GetDeclaration(True)));
  617. EndListing;
  618. WriteLabel(TypeDecl);
  619. WriteIndex(TypeDecl);
  620. If TypeDecl is TPasEnumType then
  621. begin
  622. WriteENumElements(TypeDecl as TPasEnumType);
  623. end;
  624. WriteDescr(TypeDecl);
  625. DescrEndParaGraph;
  626. end;
  627. end;
  628. end;
  629. procedure TLinearWriter.WriteVars(ASection: TPasSection);
  630. var
  631. VarDecl: TPasVariable;
  632. i: Integer;
  633. begin
  634. if ASection.Variables.Count > 0 then
  635. begin
  636. StartSubsection(SDocVariables,ModuleName+'Variables');
  637. for i := 0 to ASection.Variables.Count - 1 do
  638. begin
  639. DescrBeginParaGraph;
  640. VarDecl := TPasVariable(ASection.Variables[i]);
  641. StartListing(False,'');
  642. WriteLn(EscapeText(VarDecl.GetDeclaration(True)));
  643. EndListing;
  644. WriteLabel(VarDecl);
  645. WriteIndex(VarDecl);
  646. WriteDescr(VarDecl);
  647. DescrEndParaGraph;
  648. end;
  649. end;
  650. end;
  651. procedure TLinearWriter.WriteProcedure(ProcDecl : TPasProcedureBase);
  652. var
  653. DocNode: TDocNode;
  654. OP : TPasOverloadedProc;
  655. i : integer;
  656. begin
  657. With ProcDecl do
  658. begin
  659. if Not (Assigned(Parent) and Parent.InheritsFrom(TPasClassType)) then
  660. begin
  661. StartSubSection(Name);
  662. WriteLabel(ProcDecl);
  663. WriteIndex(ProcDecl);
  664. end
  665. else
  666. begin // Parent assigned and hence method.
  667. StartSubSection(Parent.Name+'.'+Name);
  668. WriteLabel(ProcDecl);
  669. WriteIndex(Parent.Name+'.'+Name);
  670. end;
  671. StartProcedure;
  672. DocNode := Engine.FindDocNode(ProcDecl);
  673. if Assigned(DocNode) and Assigned(DocNode.ShortDescr) then
  674. begin
  675. StartSynopsis;
  676. WriteDescr(ProcDecl, DocNode.ShortDescr);
  677. end;
  678. StartDeclaration;
  679. StartListing(False);
  680. if ClassType = TPasOverloadedProc then
  681. begin
  682. OP:=TPasOverloadedProc(ProcDecl);
  683. for i := 0 to OP.Overloads.Count - 1 do
  684. begin
  685. WriteLn(TPasProcedure(OP.Overloads[i]).GetDeclaration(True));
  686. end;
  687. end
  688. else
  689. WriteLn(GetDeclaration(True));
  690. EndListing;
  691. If Assigned(Parent) then
  692. begin
  693. StartVisibility;
  694. Writeln(VisibilityNames[Visibility])
  695. end;
  696. if Assigned(DocNode) and Assigned(DocNode.Descr) then
  697. begin
  698. StartDescription;
  699. WriteDescr(ProcDecl);
  700. end;
  701. if Assigned(DocNode) and Assigned(DocNode.ErrorsDoc) then
  702. begin
  703. StartErrors;
  704. WriteDescr(ProcDecl, DocNode.ErrorsDoc);
  705. end;
  706. WriteSeeAlso(DocNode);
  707. EndProcedure;
  708. WriteExample(DocNode);
  709. end;
  710. end;
  711. procedure TLinearWriter.WriteFunctionsAndProcedures(ASection: TPasSection);
  712. var
  713. i: Integer;
  714. begin
  715. if ASection.Functions.Count > 0 then
  716. begin
  717. StartSection(SDocProceduresAndFunctions,ModuleName+'Functions');
  718. for i := 0 to ASection.Functions.Count - 1 do
  719. WriteProcedure(TPasProcedureBase(ASection.Functions[i]));
  720. end;
  721. end;
  722. procedure TLinearWriter.WriteExample(ADocNode: TDocNode);
  723. var
  724. Example: TDOMElement;
  725. S : string;
  726. begin
  727. S:='';
  728. if Assigned(ADocNode) then
  729. begin
  730. Example := ADocNode.FirstExample;
  731. while Assigned(Example) do
  732. begin
  733. if IsExampleNode(Example) then
  734. begin
  735. if (S<>'') then // not first example, start new paragraph
  736. DescrBeginParagraph;
  737. s:=Engine.GetExampleFileName(Example);
  738. if (S<>'') then
  739. WriteExampleFile(S);
  740. if Assigned(Example.NextSibling) then
  741. DescrEndParaGraph;
  742. end;
  743. Example := TDomElement(Example.NextSibling);
  744. end;
  745. end;
  746. end;
  747. procedure TLinearWriter.WriteProperty(PropDecl : TPasProperty);
  748. var
  749. DocNode: TDocNode;
  750. S: String;
  751. begin
  752. With PropDecl do
  753. begin
  754. StartSubSection(Parent.Name+'.'+Name);
  755. WriteLabel(PropDecl);
  756. WriteIndex(Parent.Name+'.'+Name);
  757. StartProperty;
  758. DocNode := Engine.FindDocNode(PropDecl);
  759. if Assigned(DocNode) and Assigned(DocNode.ShortDescr) then
  760. begin
  761. StartSynopsis;
  762. WriteDescr(PropDecl, DocNode.ShortDescr);
  763. end;
  764. StartDeclaration;
  765. StartListing(False);
  766. WriteLn('Property '+GetDeclaration(True));
  767. EndListing;
  768. If Assigned(Parent) then
  769. begin
  770. StartVisibility;
  771. Writeln(VisibilityNames[Visibility])
  772. end;
  773. StartAccess;
  774. Setlength(S,0);
  775. If Length(ReadAccessorName) > 0 then
  776. S:='Read';
  777. if Length(WriteAccessorName) > 0 then
  778. begin
  779. If S<>'' then
  780. S:=S+',';
  781. S:=S+'Write';
  782. end;
  783. Writeln(S);
  784. if Assigned(DocNode) and Assigned(DocNode.Descr) then
  785. begin
  786. StartDescription;
  787. WriteDescr(PropDecl);
  788. end;
  789. if Assigned(DocNode) and Assigned(DocNode.ErrorsDoc) then
  790. begin
  791. StartErrors;
  792. WriteDescr(PropDecl, DocNode.ErrorsDoc);
  793. end;
  794. WriteSeeAlso(DocNode);
  795. EndProperty;
  796. WriteExample(DocNode);
  797. end;
  798. end;
  799. procedure TLinearWriter.WriteSeeAlso(ADocNode: TDocNode);
  800. var
  801. Node: TDOMNode;
  802. s: String;
  803. First : Boolean;
  804. begin
  805. if Not (Assigned(ADocNode) and Assigned(ADocNode.SeeAlso)) then
  806. Exit;
  807. Node := ADocNode.SeeAlso.FirstChild;
  808. First:=True;
  809. while Assigned(Node) do
  810. begin
  811. if IsLinkNode(Node) then
  812. begin
  813. If First then
  814. begin
  815. StartSeealso;
  816. First:=False;
  817. end
  818. else
  819. Writeln(',');
  820. S:=TDomElement(Node)['id'];
  821. DescrBeginLink(S);
  822. Write(EscapeText(S));
  823. DescrEndLink();
  824. end;
  825. Node:=Node.NextSibling;
  826. end;
  827. If Not First then
  828. EndSeeAlso
  829. end;
  830. Function CompareElements(P1,P2 : Pointer) : Integer;
  831. begin
  832. Result:=CompareText(TPasElement(P1).Name,TPasElement(P2).Name);
  833. end;
  834. procedure TLinearWriter.SortElementList(List : TList);
  835. begin
  836. List.Sort(@CompareElements);
  837. end;
  838. Function TLinearWriter.ShowMember(M : TPasElement) : boolean;
  839. begin
  840. Result:=not ((M.Visibility=visPrivate) and Engine.HidePrivate);
  841. If Result then
  842. Result:=Not ((M.Visibility=visProtected) and Engine.HideProtected)
  843. end;
  844. procedure TLinearWriter.WriteClasses(ASection: TPasSection);
  845. var
  846. i: Integer;
  847. begin
  848. if (ASection.Classes.Count > 0) then
  849. for i := 0 to ASection.Classes.Count - 1 do
  850. WriteClassDecl(TPasClassType(ASection.Classes[i]));
  851. end;
  852. procedure TLinearWriter.WriteClassMethodOverview(ClassDecl: TPasClassType);
  853. var
  854. Member : TPasElement;
  855. i : Integer;
  856. L,N,S : String;
  857. DocNode : TDocNode;
  858. List : TStringList;
  859. begin
  860. List:=TStringList.Create;
  861. Try
  862. List.Sorted:=True;
  863. for i := 0 to ClassDecl.Members.Count - 1 do
  864. begin
  865. Member := TPasElement(ClassDecl.Members[i]);
  866. With Member do
  867. if InheritsFrom(TPasProcedureBase) and ShowMember(Member) then
  868. List.AddObject(Member.Name,Member);
  869. end;
  870. If List.Count>0 then
  871. begin
  872. StartSubSection(SDocMethodOverview);
  873. WriteLabel(GetLabel(ClassDecl) + ':Methods');
  874. StartOverview(False);
  875. For I:=0 to List.Count-1 do
  876. begin
  877. Member:=TPasElement(List.Objects[i]);
  878. L:=StripText(GetLabel(Member));
  879. N:=EscapeText(Member.Name);
  880. DocNode := Engine.FindDocNode(Member);
  881. If Assigned(DocNode) then
  882. S:=GetDescrString(Member, DocNode.ShortDescr)
  883. else
  884. S:='';
  885. WriteOverviewMember(L,N,S);
  886. end;
  887. EndOverview;
  888. end;
  889. Finally
  890. List.Free;
  891. end;
  892. end;
  893. constructor TLinearWriter.Create(APackage: TPasPackage; AEngine: TFPDocEngine);
  894. procedure AddLabel(AElement: TPasElement);
  895. begin
  896. Engine.AddLink(AElement.PathName, GetLabel(AElement));
  897. end;
  898. procedure AddList(AElement: TPasElement; AList: TList);
  899. var
  900. i: Integer;
  901. begin
  902. for i := 0 to AList.Count - 1 do
  903. AddLabel(TPasElement(AList[i]));
  904. end;
  905. procedure AddTopicPages(AElement: TPasElement);
  906. var
  907. PreviousTopic,
  908. TopicElement : TTopicElement;
  909. DocNode,
  910. TopicNode : TDocNode;
  911. begin
  912. DocNode:=Engine.FindDocNode(AElement);
  913. If not Assigned(DocNode) then
  914. exit;
  915. TopicNode:=DocNode.FirstChild;
  916. PreviousTopic:=Nil;
  917. While Assigned(TopicNode) do
  918. begin
  919. If TopicNode.TopicNode then
  920. begin
  921. TopicElement:=TTopicElement.Create(TopicNode.Name,AElement);
  922. Topics.Add(TopicElement);
  923. TopicElement.TopicNode:=TopicNode;
  924. TopicElement.Previous:=PreviousTopic;
  925. If Assigned(PreviousTopic) then
  926. PreviousTopic.Next:=TopicElement;
  927. PreviousTopic:=TopicElement;
  928. if AElement is TTopicElement then
  929. TTopicElement(AElement).SubTopics.Add(TopicElement);
  930. Engine.AddLink(TopicElement.PathName, GetLabel(TopicElement));
  931. if AElement is TTopicElement then
  932. TTopicElement(AElement).SubTopics.Add(TopicElement)
  933. else // Only one level of recursion.
  934. AddTopicPages(TopicElement);
  935. end;
  936. TopicNode:=TopicNode.NextSibling;
  937. end;
  938. end;
  939. procedure ScanModule(AModule: TPasModule);
  940. var
  941. i, j, k: Integer;
  942. ClassEl: TPasClassType;
  943. FPEl, AncestorMemberEl: TPasElement;
  944. DocNode: TDocNode;
  945. DidAutolink: Boolean;
  946. begin
  947. AddLabel(AModule);
  948. AddTopicPages(AModule);
  949. with AModule do
  950. begin
  951. AddList(AModule, InterfaceSection.ResStrings);
  952. AddList(AModule, InterfaceSection.Consts);
  953. AddList(AModule, InterfaceSection.Types);
  954. if InterfaceSection.Classes.Count > 0 then
  955. begin
  956. for i := 0 to InterfaceSection.Classes.Count - 1 do
  957. begin
  958. ClassEl := TPasClassType(InterfaceSection.Classes[i]);
  959. AddLabel(ClassEl);
  960. for j := 0 to ClassEl.Members.Count - 1 do
  961. begin
  962. FPEl := TPasElement(ClassEl.Members[j]);
  963. if ((FPEl.Visibility = visPrivate) and Engine.HidePrivate) or
  964. ((FPEl.Visibility = visProtected) and Engine.HideProtected) then
  965. continue;
  966. DocNode := Engine.FindDocNode(FPEl);
  967. if not Assigned(DocNode) then
  968. begin
  969. DidAutolink := False;
  970. if Assigned(ClassEl.AncestorType) and
  971. (ClassEl.AncestorType.ClassType = TPasClassType) then
  972. begin
  973. for k := 0 to TPasClassType(ClassEl.AncestorType).Members.Count - 1 do
  974. begin
  975. AncestorMemberEl :=
  976. TPasElement(TPasClassType(ClassEl.AncestorType).Members[k]);
  977. if AncestorMemberEl.Name = FPEl.Name then
  978. begin
  979. DocNode := Engine.FindDocNode(AncestorMemberEl);
  980. if Assigned(DocNode) then
  981. begin
  982. DidAutolink := True;
  983. Engine.AddLink(FPEl.PathName,
  984. Engine.FindAbsoluteLink(AncestorMemberEl.PathName));
  985. break;
  986. end;
  987. end;
  988. end;
  989. end;
  990. if not DidAutolink then
  991. AddLabel(FPEl);
  992. end else
  993. AddLabel(FPEl);
  994. end;
  995. end;
  996. end;
  997. AddList(AModule, InterfaceSection.Functions);
  998. AddList(AModule, InterfaceSection.Variables);
  999. end;
  1000. end;
  1001. var
  1002. i: Integer;
  1003. begin
  1004. inherited ;
  1005. { Allocate labels for all elements for which we are going to create
  1006. documentation. This is needed for links to work correctly. }
  1007. // Allocate label for the package itself, if a name is given (i.e. <> '#')
  1008. if Length(Package.Name) > 1 then
  1009. begin
  1010. AddLabel(Package);
  1011. AddTopicPages(Package);
  1012. end;
  1013. for i := 0 to Package.Modules.Count - 1 do
  1014. ScanModule(TPasModule(Package.Modules[i]));
  1015. end;
  1016. procedure TLinearWriter.WriteBeginDocument;
  1017. begin
  1018. WriteComment('This file has been created automatically by FPDoc.');
  1019. WriteComment('Linear output (c) 2005 Michael Van Canneyt');
  1020. end;
  1021. procedure TLinearWriter.WriteEndDocument;
  1022. begin
  1023. end;
  1024. end.