dwlinear.pp 30 KB

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