dwlinear.pp 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516
  1. {$mode objfpc}
  2. {$H+}
  3. unit dwlinear;
  4. {$WARN 5024 off : Parameter "$1" not used}
  5. interface
  6. uses
  7. Classes, SysUtils, DGlobals, dWriter, pastree, dom;
  8. Type
  9. { TLinearWriter }
  10. TLinearWriter = Class(TFPDocWriter)
  11. FStream : TStream;
  12. PackageName: String;
  13. Module: TPasModule;
  14. FLastURL : DomString;
  15. private
  16. FDupLinkedDoc: Boolean;
  17. Protected
  18. ModuleName: String;
  19. // Writing support.
  20. procedure Write(const s: String); virtual;
  21. procedure WriteLn(const s: String); virtual;
  22. procedure WriteF(const s: String; const Args: array of const); virtual;
  23. procedure WriteLnF(const s: String; const Args: array of const); virtual;
  24. Function PushWriteContext(S : TStream) : TStream;
  25. Procedure PopWriteContext(S : TSTream);
  26. procedure WriteLabel(El: TPasElement);
  27. procedure WriteIndex(El: TPasElement);
  28. procedure WriteTypeDecl(El: TPasElement); virtual;
  29. procedure WriteVariableDecl(El: TPasElement); virtual;
  30. procedure WriteConstDecl(El: TPasElement); virtual;
  31. // Auxiliary routines
  32. procedure DescrBeginURL(const AURL: DOMString); override; // Provides a default implementation
  33. procedure DescrEndURL; override;
  34. procedure SortElementList(List : TFPList);
  35. procedure StartListing(Frames: Boolean);
  36. Function ShowMember(M : TPasElement) : boolean;
  37. procedure StartChapter(ChapterName : String; ChapterLabel : String); virtual;
  38. procedure StartSection(SectionName : String; SectionLabel : String); virtual;
  39. procedure StartSubSection(SubSectionName : String; SubSectionLabel : String); virtual;
  40. procedure StartSubSubSection(SubSubSectionName : String; SubSubSectionLabel : String); virtual;
  41. Function GetDescrString(AContext: TPasElement; DescrNode: TDOMElement) : String;
  42. function ConstValue(ConstDecl: TPasConst): String; virtual;
  43. procedure ProcessSection(ASection: TPasSection); virtual;
  44. // Procedures which MAY be overridden in descendents
  45. procedure WriteBeginDocument; virtual;
  46. procedure WriteEndDocument; virtual;
  47. Function EscapeText(S : UnicodeString) : AnsiString; overload;
  48. Function EscapeText(S : AnsiString) : AnsiString; virtual; overload;
  49. Function StripText(S : String) : String; virtual;
  50. Procedure StartProcedure; Virtual;
  51. Procedure EndProcedure; Virtual;
  52. Procedure StartProperty; Virtual;
  53. Procedure EndProperty; Virtual;
  54. Procedure StartSynopsis; Virtual;
  55. Procedure StartDeclaration; Virtual;
  56. Procedure StartVisibility; Virtual;
  57. Procedure StartDescription; Virtual;
  58. Procedure StartAccess; Virtual;
  59. Procedure StartErrors; Virtual;
  60. Procedure StartVersion; Virtual;
  61. Procedure StartSeealso; Virtual;
  62. Procedure EndSeealso; Virtual;
  63. // Procedures which MUST be overridden in descendents;
  64. procedure WriteCommentLine; virtual; abstract;
  65. procedure WriteComment(Comment : String); virtual; abstract;
  66. function GetLabel(AElement: TPasElement): String; virtual; abstract;
  67. procedure WriteLabel(Const S : String); virtual; abstract;
  68. procedure WriteIndex(Const S : String); virtual; abstract;
  69. procedure WriteType(const s: string); virtual;
  70. procedure WriteVariable(const s: string); virtual;
  71. procedure WriteConstant(const s: string); virtual;
  72. procedure StartChapter(ChapterName : String); virtual; abstract;
  73. procedure StartSection(SectionName : String); virtual; abstract;
  74. procedure StartSubSection(SubSectionName : String); virtual; abstract;
  75. procedure StartSubSubSection(SubSubSectionName : String); virtual; abstract;
  76. procedure StartListing(Frames: Boolean; const name: String); virtual; abstract;
  77. procedure EndListing; virtual; abstract;
  78. Procedure WriteExampleFile(FN : String); virtual; abstract;
  79. procedure StartOverview(Const What : String; WithAccess : Boolean); virtual; Abstract;
  80. procedure EndOverview; virtual; Abstract;
  81. procedure WriteOverviewMember(const ALabel,AName,Access,ADescr : String); virtual; Abstract;
  82. procedure WriteOverviewMember(const ALabel,AName,ADescr : String); virtual; Abstract;
  83. procedure StartUnitOverview(AModuleName,AModuleLabel : String);virtual; Abstract;
  84. procedure WriteUnitEntry(UnitRef : TPasType);virtual; Abstract;
  85. procedure EndUnitOverview; virtual; Abstract;
  86. Property LastURL : DomString Read FLastURL Write FLastURL;
  87. // Overriden from fpdocwriter;
  88. procedure DescrWriteText(const AText: DOMString); override;
  89. // Actual writing happens here.
  90. Procedure DoWriteDocumentation; override;
  91. Public
  92. Constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
  93. function InterpretOption(const Cmd, Arg: String): Boolean; override;
  94. class procedure Usage(List: TStrings); override;
  95. // Linear Documentation writing methods.
  96. Procedure ProcessPackage;
  97. Procedure ProcessTopics(DocNode : TDocNode; Alevel : Integer);
  98. procedure WriteResourceStrings(ASection: TPasSection);
  99. procedure WriteUnitOverview(ASection: TPasSection);
  100. procedure WriteVarsConstsTypes(ASection: TPasSection);
  101. procedure WriteConsts(ASection: TPasSection);
  102. procedure WriteTypes(ASection: TPasSection); virtual;
  103. procedure WriteEnumElements(TypeDecl : TPasEnumType);
  104. procedure WriteVars(ASection: TPasSection);
  105. procedure WriteFunctionsAndProcedures(ASection: TPasSection);
  106. procedure WriteProcedure(ProcDecl: TPasProcedureBase);
  107. procedure WriteClasses(ASection: TPasSection);
  108. Procedure WriteExtendedRecords(Asection : TPasSection);
  109. procedure WriteClassDecl(ClassDecl: TPasClassType);
  110. procedure WriteMethodOverview(AParent: TPasType; Members : TFPList);
  111. procedure WritePropertyOverview(AParent: TPasType; Members : TFPList);
  112. procedure WriteClassInterfacesOverview(ClassDecl: TPasClassType);
  113. procedure WriteClassInheritanceOverview(ClassDecl: TPasClassType); virtual;
  114. procedure WriteProperty(PropDecl: TPasProperty);
  115. procedure WriteExample(ADocNode: TDocNode);
  116. procedure WriteSeeAlso(ADocNode: TDocNode);
  117. Procedure WriteTopicNode(Node : TDocNode; Level : Integer);
  118. end;
  119. implementation
  120. uses fpdocstrs;
  121. const
  122. cDupLinkedDocParam = '--duplinkeddoc';
  123. { TLinearWriter }
  124. { ---------------------------------------------------------------------
  125. Writing support
  126. ---------------------------------------------------------------------}
  127. function TLinearWriter.PushWriteContext(S: TStream): TStream;
  128. begin
  129. Result:=FStream;
  130. FStream:=S;
  131. end;
  132. procedure TLinearWriter.PopWriteContext(S: TSTream);
  133. begin
  134. FStream:=S;
  135. end;
  136. procedure TLinearWriter.Write(const s: String);
  137. Var
  138. L : Integer;
  139. begin
  140. L:=Length(S);
  141. If (L>0) then
  142. FStream.Write(PChar(S)^,L);
  143. end;
  144. procedure TLinearWriter.WriteF(const s: String; const Args: array of const);
  145. begin
  146. Write(Format(S,Args));
  147. end;
  148. procedure TLinearWriter.WriteLn(const s: String);
  149. begin
  150. Write(S);
  151. Write(LineEnding);
  152. end;
  153. procedure TLinearWriter.WriteLnF(const s: String; const Args: array of const);
  154. begin
  155. Write(Format(S,Args));
  156. Write(LineEnding);
  157. end;
  158. procedure TLinearWriter.DescrWriteText(const AText: DOMString);
  159. begin
  160. Write(EscapeText(AText));
  161. end;
  162. function TLinearWriter.GetDescrString(AContext: TPasElement;
  163. DescrNode: TDOMElement): String;
  164. Var
  165. S : TStringStream;
  166. F : TStream;
  167. begin
  168. Result:='';
  169. if Assigned(DescrNode) then
  170. begin
  171. S:=TStringStream.Create('');
  172. Try
  173. F:=PushWriteContext(S);
  174. Try
  175. ConvertDescr(AContext, DescrNode, False);
  176. Result:=S.DataString;
  177. FInally
  178. PopWriteContext(F);
  179. end;
  180. finally
  181. S.FRee;
  182. end;
  183. end;
  184. end;
  185. { ---------------------------------------------------------------------
  186. Auxiliary routines
  187. ---------------------------------------------------------------------}
  188. procedure TLinearWriter.WriteLabel(El: TPasElement);
  189. begin
  190. WriteLabel(GetLabel(El));
  191. end;
  192. procedure TLinearWriter.WriteIndex(El: TPasElement);
  193. begin
  194. WriteIndex(EL.Name);
  195. end;
  196. procedure TLinearWriter.WriteTypeDecl(El: TPasElement);
  197. begin
  198. WriteType(El.Name);
  199. end;
  200. procedure TLinearWriter.WriteVariableDecl(El: TPasElement);
  201. begin
  202. WriteVariable(El.Name);
  203. end;
  204. procedure TLinearWriter.WriteConstDecl(El: TPasElement);
  205. begin
  206. WriteConstant(El.Name);
  207. end;
  208. procedure TLinearWriter.DescrBeginURL(const AURL: DOMString);
  209. begin
  210. FLastURL:=AURL;
  211. end;
  212. procedure TLinearWriter.DescrEndURL;
  213. begin
  214. If (FLastURL<>'') then
  215. Writeln(Format(SSeeURL,[EscapeText(FLastURL)]));
  216. FLastURL:='';
  217. end;
  218. procedure TLinearWriter.StartListing(Frames: Boolean);
  219. begin
  220. StartListing(Frames,'');
  221. end;
  222. procedure TLinearWriter.StartChapter(ChapterName: String; ChapterLabel: String);
  223. begin
  224. StartChapter(ChapterName);
  225. WriteLabel(ChapterLabel);
  226. end;
  227. procedure TLinearWriter.StartSection(SectionName: String; SectionLabel: String);
  228. begin
  229. StartSection(SectionName);
  230. WriteLabel(SectionLabel);
  231. end;
  232. procedure TLinearWriter.StartSubSection(SubSectionName: String; SubSectionLabel: String);
  233. begin
  234. StartSubSection(SubSectionName);
  235. WriteLabel(SubSectionLabel);
  236. end;
  237. procedure TLinearWriter.StartSubSubSection(SubSubSectionName: String;
  238. SubSubSectionLabel: String);
  239. begin
  240. StartSubSubSection(SubSubSectionName);
  241. WriteLabel(SubSubSectionLabel);
  242. end;
  243. { ---------------------------------------------------------------------
  244. Default implementations, may be overridden in descendents
  245. ---------------------------------------------------------------------}
  246. function TLinearWriter.EscapeText(S: AnsiString): AnsiString;
  247. begin
  248. Result:=S;
  249. end;
  250. function TLinearWriter.StripText(S: String): String;
  251. begin
  252. Result:=S;
  253. end;
  254. procedure TLinearWriter.StartProcedure;
  255. begin
  256. Writeln(SDocProcedure+':');
  257. end;
  258. procedure TLinearWriter.StartSynopsis;
  259. begin
  260. Writeln('');
  261. Writeln(SDocSynopsis+':');
  262. end;
  263. procedure TLinearWriter.StartDeclaration;
  264. begin
  265. Writeln('');
  266. Writeln(SDocDeclaration+':');
  267. end;
  268. procedure TLinearWriter.StartVisibility;
  269. begin
  270. Writeln('');
  271. Writeln(SDocVisibility+':');
  272. end;
  273. procedure TLinearWriter.StartDescription;
  274. begin
  275. Writeln('');
  276. Writeln(SDocDescription+':');
  277. end;
  278. procedure TLinearWriter.StartAccess;
  279. begin
  280. Writeln('');
  281. Writeln(SDocAccess+':');
  282. end;
  283. procedure TLinearWriter.StartErrors;
  284. begin
  285. Writeln('');
  286. Writeln(SDocErrors+':');
  287. end;
  288. procedure TLinearWriter.StartVersion;
  289. begin
  290. Writeln('');
  291. Writeln(SDocVersion+':');
  292. end;
  293. procedure TLinearWriter.StartSeealso;
  294. begin
  295. Writeln('');
  296. Writeln(SDocSeeAlso+':');
  297. end;
  298. procedure TLinearWriter.StartProperty;
  299. begin
  300. Writeln('');
  301. Writeln(SDocProperty+':');
  302. end;
  303. procedure TLinearWriter.EndProcedure;
  304. begin
  305. Writeln('');
  306. end;
  307. procedure TLinearWriter.EndProperty;
  308. begin
  309. Writeln('');
  310. end;
  311. procedure TLinearWriter.EndSeealso;
  312. begin
  313. Writeln('');
  314. end;
  315. procedure TLinearWriter.WriteType(const s: string);
  316. begin
  317. // do nothing
  318. end;
  319. procedure TLinearWriter.WriteVariable(const s: string);
  320. begin
  321. // do nothing
  322. end;
  323. procedure TLinearWriter.WriteConstant(const s: string);
  324. begin
  325. // do nothing
  326. end;
  327. procedure TLinearWriter.WriteClassDecl(ClassDecl: TPasClassType);
  328. var
  329. DocNode: TDocNode;
  330. Member: TPasElement;
  331. i: Integer;
  332. begin
  333. DocNode := Engine.FindDocNode(ClassDecl);
  334. if Assigned(DocNode) and DocNode.IsSkipped then
  335. Exit;
  336. StartSection(ClassDecl.Name);
  337. WriteLabel(ClassDecl);
  338. WriteIndex(ClassDecl);
  339. if Assigned(DocNode) and ((not IsDescrNodeEmpty(DocNode.Descr)) or
  340. (not IsDescrNodeEmpty(DocNode.ShortDescr))) then
  341. begin
  342. StartSubSection(SDocDescription);
  343. WriteDescr(ClassDecl,DocNode);
  344. If Assigned(DocNode.Version) then
  345. begin
  346. StartSubSection(SDocVersion);
  347. WriteDescr(ClassDecl,DocNode.Version);
  348. end;
  349. if Assigned(DocNode.SeeAlso) then
  350. begin
  351. WriteSeeAlso(DocNode);
  352. end;
  353. ConvertNotes(ClassDecl,DocNode.Notes);
  354. end;
  355. // graemeg: this must move above SeeAlso, Version and Notes written above.
  356. // Write Class Hierarchy (Inheritance) Overview;
  357. WriteClassInheritanceOverView(ClassDecl);
  358. // Write Interfaces Overview;
  359. if assigned(ClassDecl.Interfaces) then
  360. WriteClassInterfacesOverView(ClassDecl);
  361. // Write method overview
  362. WriteMethodOverView(ClassDecl,ClassDecl.Members);
  363. // Write Property Overview;
  364. WritePropertyOverView(ClassDecl,ClassDecl.Members);
  365. // Write method & property descriptions
  366. // Determine visibilities
  367. for i := 0 to ClassDecl.Members.Count - 1 do
  368. begin
  369. Member := TPasElement(ClassDecl.Members[i]);
  370. if Member.InheritsFrom(TPasProcedureBase) and Engine.ShowElement(Member) then
  371. WriteProcedure(TPasProcedureBase(Member));
  372. end;
  373. // properties.
  374. for i := 0 to ClassDecl.Members.Count - 1 do
  375. begin
  376. Member := TPasElement(ClassDecl.Members[i]);
  377. if Member.InheritsFrom(TPasProperty) and Engine.ShowElement(Member) then
  378. WriteProperty(TPasProperty(Member));
  379. end;
  380. end;
  381. procedure TLinearWriter.WritePropertyOverview(AParent: TPasType; Members : TFPList);
  382. var
  383. Member: TPasElement;
  384. i: Integer;
  385. L,N,S,A: String;
  386. DocNode: TDocNode;
  387. List : TStringList;
  388. lNode: TDocNode;
  389. begin
  390. // Write property overview
  391. List:=TStringList.Create;
  392. Try
  393. List.Sorted:=True;
  394. for i := 0 to Members.Count - 1 do
  395. begin
  396. Member := TPasElement(Members[i]);
  397. With Member do
  398. if InheritsFrom(TPasProperty) and SHowMember(Member) then
  399. List.AddObject(Member.Name,Member)
  400. end;
  401. If (List.Count>0) then
  402. begin
  403. StartSubSection(SDocPropertyOverview);
  404. WriteLabel(GetLabel(AParent) + ':Properties');
  405. StartOverView(SDocProperties,True);
  406. For I:=0 to List.Count-1 do
  407. begin
  408. Member:=TPasElement(List.objects[i]);
  409. L:=StripText(GetLabel(Member));
  410. N:=EscapeText(Member.Name);
  411. DocNode := Engine.FindDocNode(Member);
  412. if Assigned(DocNode) and DocNode.IsSkipped then
  413. Continue;
  414. if Assigned(DocNode) then
  415. begin
  416. if FDupLinkedDoc and (DocNode.Link <> '') then
  417. begin
  418. lNode := Engine.FindLinkedNode(DocNode);
  419. if not Assigned(lNode) then
  420. lNode := DocNode;
  421. end
  422. else
  423. lNode := DocNode;
  424. S := GetDescrString(Member, lNode.ShortDescr);
  425. end
  426. else
  427. S := '';
  428. A:='';
  429. if Length(TPasProperty(Member).ReadAccessorName) > 0 then
  430. a := a + 'r';
  431. if Length(TPasProperty(Member).WriteAccessorName) > 0 then
  432. a := a + 'w';
  433. if Length(TPasProperty(Member).StoredAccessorName) > 0 then
  434. a := a + 's';
  435. WriteOverviewMember(L,N,A,S);
  436. S := '';
  437. end;
  438. EndOverview;
  439. end;
  440. Finally
  441. List.Free;
  442. end;
  443. end;
  444. procedure TLinearWriter.WriteClassInterfacesOverview(ClassDecl: TPasClassType);
  445. var
  446. lInterface: TPasElement;
  447. i: Integer;
  448. L,N,S: String;
  449. DocNode: TDocNode;
  450. List : TStringList;
  451. lNode: TDocNode;
  452. begin
  453. // Write Interfaces overview
  454. List:=TStringList.Create;
  455. try
  456. List.Sorted:=True;
  457. for i := 0 to ClassDecl.Interfaces.Count-1 do
  458. begin
  459. lInterface := TPasElement(ClassDecl.Interfaces[i]);
  460. List.AddObject(lInterface.Name,lInterface);
  461. end;
  462. if (List.Count>0) then
  463. begin
  464. StartSubSection(SDocInterfacesOverview);
  465. WriteLabel(GetLabel(ClassDecl) + ':Interfaces');
  466. StartOverView(SDocInterface,False);
  467. for i := 0 to List.Count-1 do
  468. begin
  469. lInterface := TPasElement(List.Objects[i]);
  470. L := StripText(GetLabel(lInterface));
  471. N := EscapeText(lInterface.Name);
  472. DocNode := Engine.FindDocNode(lInterface);
  473. if Assigned(DocNode) and DocNode.IsSkipped then
  474. Continue;
  475. if Assigned(DocNode) then
  476. begin
  477. if FDupLinkedDoc and (DocNode.Link <> '') then
  478. begin
  479. lNode := Engine.FindLinkedNode(DocNode);
  480. if not Assigned(lNode) then
  481. lNode := DocNode;
  482. end
  483. else
  484. lNode := DocNode;
  485. S := GetDescrString(lInterface, lNode.ShortDescr);
  486. end
  487. else
  488. S := '';
  489. WriteOverviewMember(L,N,S);
  490. S := '';
  491. end;
  492. EndOverview;
  493. end;
  494. finally
  495. List.Free;
  496. end;
  497. end;
  498. procedure TLinearWriter.WriteClassInheritanceOverview(ClassDecl: TPasClassType);
  499. begin
  500. { Do nothing by default. This will be implemented by descendant writers. See
  501. the IPF Writer for an example. }
  502. end;
  503. function TLinearWriter.ConstValue(ConstDecl: TPasConst): String;
  504. begin
  505. if Assigned(ConstDecl) then
  506. Result := ConstDecl.ClassName
  507. else
  508. Result := '<nil>';
  509. end;
  510. procedure TLinearWriter.DoWriteDocumentation;
  511. var
  512. i : Integer;
  513. L : TstringList;
  514. begin
  515. PackageName := LowerCase(Copy(Package.Name, 2, 255));
  516. If (Engine.OutPut='') then
  517. Engine.Output:=PackageName+FileNameExtension
  518. else if (ExtractFileExt(Engine.output)='') and (FileNameExtension<>'') then
  519. Engine.Output:=ChangeFileExt(Engine.output,FileNameExtension);
  520. FStream:=TFileStream.Create(Engine.Output,fmCreate);
  521. try
  522. WriteBeginDocument;
  523. ProcessPackage;
  524. L:=TStringList.Create;
  525. Try
  526. L.Sorted:=True;
  527. // Sort modules.
  528. For I:=0 to Package.Modules.Count-1 do
  529. L.AddObject(TPasModule(Package.Modules[i]).Name,TPasModule(Package.Modules[i]));
  530. // Now create table.
  531. for i:=0 to L.Count - 1 do
  532. begin
  533. Module := TPasModule(L.Objects[i]);
  534. ModuleName := LowerCase(Module.Name);
  535. WriteCommentLine;
  536. StartChapter(Format(SDocUnitTitle, [Module.Name]));
  537. WriteLabel(Module);
  538. // extra Topics now get processed in ProcessSection()
  539. ProcessSection(Module.InterfaceSection);
  540. end;
  541. Finally
  542. L.Free;
  543. end;
  544. WriteEndDocument;
  545. finally
  546. FSTream.Free;
  547. end;
  548. end;
  549. procedure TLinearWriter.ProcessSection(ASection: TPasSection);
  550. var
  551. DocNode: TDocNode;
  552. begin
  553. With ASection do
  554. begin
  555. SortElementList(UsesList);
  556. SortElementList(Declarations);
  557. SortElementList(ResStrings);
  558. SortElementList(Types);
  559. SortElementList(Consts);
  560. SortElementList(Classes);
  561. SortElementList(Functions);
  562. SortElementList(Variables);
  563. end;
  564. WriteUnitOverView(ASection);
  565. // Now process unit (extra) Topics
  566. DocNode:=Engine.FindDocNode(Module);
  567. If Assigned(DocNode) then
  568. ProcessTopics(DocNode,1);
  569. WriteVarsConstsTypes(ASection);
  570. WriteFunctionsAndProcedures(ASection);
  571. WriteExtendedRecords(ASection);
  572. WriteClasses(ASection);
  573. end;
  574. procedure TLinearWriter.WriteVarsConstsTypes(ASection: TPasSection);
  575. begin
  576. With Asection do
  577. if (Consts.Count>0) or (Types.Count>0) or
  578. (Variables.Count>0) or (ResStrings.Count>0) then
  579. begin
  580. StartSection(SDocConstsTypesVars, ModuleName+'ConstsTypesVars');
  581. WriteResourceStrings(ASection);
  582. WriteConsts(ASection);
  583. WriteTypes(ASection);
  584. WriteVars(ASection);
  585. end;
  586. end;
  587. procedure TLinearWriter.WriteResourceStrings(ASection: TPasSection);
  588. var
  589. ResStrDecl: TPasResString;
  590. i: Integer;
  591. DocNode : TDocNode;
  592. begin
  593. if ASection.ResStrings.Count > 0 then
  594. begin
  595. StartSubSection(SDocResStrings,ModuleName+'ResStrings');
  596. for i := 0 to ASection.ResStrings.Count - 1 do
  597. begin
  598. ResStrDecl := TPasResString(ASection.ResStrings[i]);
  599. StartListing(false, '');
  600. DescrWriteText(UTF8Decode(ResStrDecl.GetDeclaration(True))); // instead of WriteLn() so we can do further processing like manual line wrapping in descendants
  601. EndListing;
  602. WriteLabel(ResStrDecl);
  603. WriteIndex(ResStrDecl);
  604. DocNode:=WriteDescr(ResStrDecl);
  605. If Assigned(DocNode) and Assigned(DocNode.Version) then
  606. begin
  607. Writeln(Format('%s : ',[SDocVersion]));
  608. WriteDescr(ResStrDecl, DocNode.Version);
  609. end;
  610. end;
  611. end;
  612. end;
  613. procedure TLinearWriter.WriteUnitOverview(ASection: TPasSection);
  614. var
  615. i: Integer;
  616. UnitRef: TPasType;
  617. DocNode: TDocNode;
  618. begin
  619. if ASection.UsesList.Count > 0 then
  620. begin
  621. StartSection(SDocUsedUnits);
  622. StartUnitOverview(Module.Name,ModuleName);
  623. for i := 0 to ASection.UsesList.Count - 1 do
  624. begin
  625. UnitRef := TPasType(ASection.UsesList[i]);
  626. WriteUnitEntry(UnitRef);
  627. end;
  628. EndUnitOverview;
  629. end;
  630. DocNode := Engine.FindDocNode(ASection.Parent);
  631. if Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr) then
  632. begin
  633. StartSection(SDocOverview);
  634. WriteDescr(ASection.Parent, DocNode.Descr);
  635. ConvertNotes(ASection.Parent,DocNode.Notes);
  636. end;
  637. end;
  638. procedure TLinearWriter.ProcessPackage;
  639. var
  640. DocNode: TDocNode;
  641. begin
  642. DocNode:=Engine.FindDocNode(Package);
  643. if not Assigned(DocNode) then
  644. exit;
  645. if Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr) then
  646. begin
  647. StartSection(SDocOverview);
  648. WriteDescr(Package, DocNode.Descr);
  649. end;
  650. WriteSeeAlso(DocNode);
  651. ConvertNotes(Nil,DocNode.Notes);
  652. ProcessTopics(DocNode,1);
  653. end;
  654. procedure TLinearWriter.ProcessTopics(DocNode: TDocNode; Alevel: Integer);
  655. Var
  656. Node : TDocNode;
  657. begin
  658. If Not Assigned(DocNode) then
  659. Exit;
  660. Node:=DocNode.FirstChild;
  661. While Assigned(Node) do
  662. begin
  663. If Node.TopicNode then
  664. WriteTopicNode(Node,ALevel);
  665. Node:=Node.NextSibling;
  666. end;
  667. end;
  668. procedure TLinearWriter.WriteTopicNode(Node: TDocNode; Level: Integer);
  669. Var
  670. Element : TTopicElement;
  671. SubNode : TDocNode;
  672. S : String;
  673. begin
  674. Element:=FindTopicElement(Node);
  675. If Not Assigned(Element) then
  676. Exit;
  677. S:=GetDescrString(Element,Node.ShortDescr);
  678. Case Level of
  679. 1 : StartSection(S);
  680. 2 : StartSubSection(S);
  681. 3 : StartSubSubSection(S);
  682. end;
  683. WriteLabel(Element);
  684. If Assigned(Node.Descr) then
  685. WriteDescr(Element,Node.Descr);
  686. WriteSeeAlso(Node);
  687. ConvertNotes(Element,Node.Notes);
  688. If Level<3 then
  689. begin
  690. SubNode:=Node.FirstChild;
  691. While Assigned(SubNode) do
  692. begin
  693. If SubNode.TopicNode then
  694. WriteTopicNode(SubNode,Level+1);
  695. SubNode:=SubNode.NextSibling;
  696. end;
  697. end;
  698. WriteExample(Node);
  699. end;
  700. procedure TLinearWriter.WriteConsts(ASection: TPasSection);
  701. var
  702. i: Integer;
  703. ConstDecl: TPasConst;
  704. begin
  705. if ASection.Consts.Count > 0 then
  706. begin
  707. StartSubSection(SDocConstants,EscapeText(ModuleName));
  708. for i := 0 to ASection.Consts.Count - 1 do
  709. begin
  710. DescrBeginParaGraph;
  711. ConstDecl := TPasConst(ASection.Consts[i]);
  712. WriteConstDecl(ConstDecl);
  713. StartListing(False,'');
  714. WriteLn(EscapeText(ConstDecl.GetDeclaration(True)));
  715. EndListing;
  716. WriteLabel(ConstDecl);
  717. WriteIndex(ConstDecl);
  718. WriteDescr(ConstDecl);
  719. DescrEndParaGraph;
  720. end;
  721. end;
  722. end;
  723. procedure TLinearWriter.WriteEnumElements(TypeDecl : TPasEnumType);
  724. Var
  725. EV : TPasEnumValue;
  726. I : Integer;
  727. DocNode : TDocNode;
  728. begin
  729. With TypeDecl do
  730. begin
  731. SortElementList(Values);
  732. DescrBeginTable(2,True);
  733. DescrBeginTableCaption;
  734. Writeln(EscapeText(Format(SDocValuesForEnum,[TypeDecl.Name])));
  735. DescrEndTableCaption;
  736. DescrBeginTableHeadRow;
  737. DescrBeginTableCell;
  738. Writeln(EscapeText(SDocValue));
  739. DescrEndTableCell;
  740. DescrBeginTableCell;
  741. Writeln(EscapeText(SDocExplanation));
  742. DescrEndTableCell;
  743. DescrEndTableHeadRow;
  744. For I:=0 to Values.Count-1 do
  745. begin
  746. EV:=TPasEnumValue(Values[i]);
  747. DescrBeginTableRow;
  748. DescrBeginTableCell;
  749. Writeln(EscapeText(EV.Name));
  750. DescrEndTableCell;
  751. DescrBeginTableCell;
  752. DocNode := Engine.FindDocNode(EV);
  753. if Assigned(DocNode) and (not IsDescrNodeEmpty(DocNode.ShortDescr)) then
  754. WriteDescr(EV,DocNode.ShortDescr);
  755. DescrEndTableCell;
  756. DescrEndTableRow;
  757. end;
  758. DescrEndTable;
  759. end;
  760. end;
  761. procedure TLinearWriter.WriteTypes(ASection: TPasSection);
  762. var
  763. i: Integer;
  764. TypeDecl: TPasType;
  765. DocNode : TDocNode;
  766. begin
  767. if ASection.Types.Count > 0 then
  768. begin
  769. StartSubSection(SDocTypes,ModuleName+'Types');
  770. for i := 0 to ASection.Types.Count - 1 do
  771. begin
  772. TypeDecl := TPasType(ASection.Types[i]);
  773. DocNode := Engine.FindDocNode(TypeDecl);
  774. if Assigned(DocNode) and DocNode.IsSkipped then
  775. Continue;
  776. if not ((TypeDecl is TPasRecordType) and TPasRecordType(TypeDecl).IsAdvancedRecord) then
  777. begin
  778. DescrBeginParagraph;
  779. WriteTypeDecl(TypeDecl);
  780. StartListing(False,'');
  781. If Assigned(DocNode) and
  782. Assigned(DocNode.Node) and
  783. (Docnode.Node['opaque']='1') then
  784. Writeln(TypeDecl.Name+' = '+SDocOpaque)
  785. else
  786. begin
  787. Writeln(EscapeText(TypeDecl.GetDeclaration(True)));
  788. end;
  789. EndListing;
  790. WriteLabel(TypeDecl);
  791. WriteIndex(TypeDecl);
  792. If TypeDecl is TPasEnumType then
  793. WriteENumElements(TypeDecl as TPasEnumType)
  794. else If (TypeDecl is TPasSetType)
  795. and (TPasSetType(TypeDecl).EnumType is TPasEnumType)
  796. and (TPasSetType(TypeDecl).EnumType.Name='') then
  797. WriteENumElements(TPasSetType(TypeDecl).EnumType as TPasEnumType);
  798. WriteDescr(TypeDecl,DocNode);
  799. If Assigned(DocNode) and Assigned(DocNode.Version) then
  800. begin
  801. Writeln(Format('%s : ',[SDocVersion]));
  802. WriteDescr(TypeDecl, DocNode.Version);
  803. end;
  804. if Assigned(DocNode) and assigned(DocNode.Notes) then
  805. ConvertNotes(TypeDecl,DocNode.Notes);
  806. DescrEndParagraph;
  807. end;
  808. end;
  809. end;
  810. end;
  811. procedure TLinearWriter.WriteVars(ASection: TPasSection);
  812. var
  813. VarDecl: TPasVariable;
  814. i: Integer;
  815. DocNode : TDocNode;
  816. begin
  817. if ASection.Variables.Count > 0 then
  818. begin
  819. StartSubsection(SDocVariables,ModuleName+'Variables');
  820. for i := 0 to ASection.Variables.Count - 1 do
  821. begin
  822. DescrBeginParaGraph;
  823. VarDecl := TPasVariable(ASection.Variables[i]);
  824. WriteVariableDecl(VarDecl);
  825. StartListing(False,'');
  826. WriteLn(EscapeText(VarDecl.GetDeclaration(True)));
  827. EndListing;
  828. WriteLabel(VarDecl);
  829. WriteIndex(VarDecl);
  830. DocNode:=WriteDescr(VarDecl);
  831. If Assigned(DocNode) and Assigned(DocNode.Version) then
  832. begin
  833. Writeln(Format('%s : ',[SDocVersion]));
  834. WriteDescr(VarDecl, DocNode.Version);
  835. ConvertNotes(VarDecl,DocNode.Notes);
  836. end;
  837. DescrEndParaGraph;
  838. end;
  839. end;
  840. end;
  841. procedure TLinearWriter.WriteProcedure(ProcDecl : TPasProcedureBase);
  842. var
  843. DocNode: TDocNode;
  844. OP : TPasOverloadedProc;
  845. i : integer;
  846. begin
  847. With ProcDecl do
  848. begin
  849. DocNode := Engine.FindDocNode(ProcDecl);
  850. if Assigned(DocNode) and DocNode.IsSkipped then
  851. Exit;
  852. if Not (Assigned(Parent) and ((Parent.InheritsFrom(TPasClassType)) or Parent.InheritsFrom(TPasRecordType))) then
  853. begin
  854. StartSubSection(Name);
  855. WriteLabel(ProcDecl);
  856. WriteIndex(ProcDecl);
  857. end
  858. else
  859. begin // Parent assigned and hence method.
  860. StartSubSection(Parent.Name+'.'+Name);
  861. WriteLabel(ProcDecl);
  862. WriteIndex(Parent.Name+'.'+Name);
  863. end;
  864. StartProcedure;
  865. if Assigned(DocNode) and Assigned(DocNode.ShortDescr) then
  866. begin
  867. StartSynopsis;
  868. WriteDescr(ProcDecl, DocNode.ShortDescr);
  869. end;
  870. StartDeclaration;
  871. StartListing(False);
  872. if ClassType = TPasOverloadedProc then
  873. begin
  874. OP:=TPasOverloadedProc(ProcDecl);
  875. for i := 0 to OP.Overloads.Count - 1 do
  876. begin
  877. WriteLn(TPasProcedure(OP.Overloads[i]).GetDeclaration(True));
  878. end;
  879. end
  880. else
  881. WriteLn(GetDeclaration(True));
  882. EndListing;
  883. If Assigned(Parent) then
  884. begin
  885. StartVisibility;
  886. Writeln(VisibilityNames[Visibility])
  887. end;
  888. if Assigned(DocNode) then
  889. begin
  890. If Assigned(DocNode.Descr) then
  891. begin
  892. StartDescription;
  893. WriteDescr(ProcDecl);
  894. end;
  895. if Assigned(DocNode.ErrorsDoc) and (DocNode.ErrorsDoc.HasChildNodes) then
  896. begin
  897. StartErrors;
  898. WriteDescr(ProcDecl, DocNode.ErrorsDoc);
  899. end;
  900. if Assigned(DocNode.Version) then
  901. begin
  902. StartVersion;
  903. WriteDescr(ProcDecl, DocNode.Version);
  904. end;
  905. WriteSeeAlso(DocNode);
  906. EndProcedure;
  907. WriteExample(DocNode);
  908. ConvertNotes(ProcDecl,DocNode.Notes);
  909. end
  910. else
  911. EndProcedure;
  912. end;
  913. end;
  914. procedure TLinearWriter.WriteFunctionsAndProcedures(ASection: TPasSection);
  915. var
  916. i: Integer;
  917. begin
  918. if ASection.Functions.Count > 0 then
  919. begin
  920. StartSection(SDocProceduresAndFunctions,ModuleName+'Functions');
  921. for i := 0 to ASection.Functions.Count - 1 do
  922. WriteProcedure(TPasProcedureBase(ASection.Functions[i]));
  923. end;
  924. end;
  925. procedure TLinearWriter.WriteExample(ADocNode: TDocNode);
  926. var
  927. Example: TDOMElement;
  928. S : string;
  929. begin
  930. S:='';
  931. if Assigned(ADocNode) then
  932. begin
  933. Example := ADocNode.FirstExample;
  934. while Assigned(Example) do
  935. begin
  936. if IsExampleNode(Example) then
  937. begin
  938. if (S<>'') then // not first example, start new paragraph
  939. DescrBeginParagraph;
  940. s:=Engine.GetExampleFileName(Example);
  941. if (S<>'') then
  942. WriteExampleFile(S);
  943. if Assigned(Example.NextSibling) then
  944. DescrEndParaGraph;
  945. end;
  946. Example := TDomElement(Example.NextSibling);
  947. end;
  948. end;
  949. end;
  950. procedure TLinearWriter.WriteProperty(PropDecl : TPasProperty);
  951. var
  952. DocNode: TDocNode;
  953. S: String;
  954. lNode: TDocNode;
  955. begin
  956. With PropDecl do
  957. begin
  958. DocNode := Engine.FindDocNode(PropDecl);
  959. if Assigned(DocNode) and DocNode.IsSkipped then
  960. Exit;
  961. StartSubSection(Parent.Name+'.'+Name);
  962. WriteLabel(PropDecl);
  963. WriteIndex(Parent.Name+'.'+Name);
  964. StartProperty;
  965. if Assigned(DocNode) then
  966. begin
  967. if FDupLinkedDoc and (DocNode.Link <> '') then
  968. begin
  969. lNode := Engine.FindLinkedNode(DocNode);
  970. if not Assigned(lNode) then
  971. lNode := DocNode;
  972. end
  973. else
  974. lNode := DocNode;
  975. if Assigned(lNode.ShortDescr) then
  976. begin
  977. StartSynopsis;
  978. WriteDescr(PropDecl, lNode.ShortDescr);
  979. end;
  980. end;
  981. StartDeclaration;
  982. StartListing(False);
  983. WriteLn('Property '+GetDeclaration(True));
  984. EndListing;
  985. If Assigned(Parent) then
  986. begin
  987. StartVisibility;
  988. Writeln(VisibilityNames[Visibility])
  989. end;
  990. StartAccess;
  991. S:='';
  992. If Length(ReadAccessorName) > 0 then
  993. S:='Read';
  994. if Length(WriteAccessorName) > 0 then
  995. begin
  996. If S<>'' then
  997. S:=S+',';
  998. S:=S+'Write';
  999. end;
  1000. Writeln(S);
  1001. if Assigned(DocNode) then
  1002. begin
  1003. if Assigned(lNode.Descr) then // lNode will be assigned if DocNode exists
  1004. begin
  1005. StartDescription;
  1006. WriteDescr(PropDecl, lNode);
  1007. end;
  1008. if Assigned(lNode.ErrorsDoc) and (lNode.ErrorsDoc.HasChildNodes) then
  1009. begin
  1010. StartErrors;
  1011. WriteDescr(PropDecl, DocNode.ErrorsDoc);
  1012. end;
  1013. if Assigned(lNode.Version) then
  1014. begin
  1015. StartVersion;
  1016. WriteDescr(PropDecl, lNode.Version);
  1017. end;
  1018. WriteSeeAlso(lNode);
  1019. ConvertNotes(PropDecl,lNode.Notes);
  1020. EndProperty;
  1021. WriteExample(lNode);
  1022. end
  1023. else
  1024. EndProperty;
  1025. end;
  1026. end;
  1027. procedure TLinearWriter.WriteSeeAlso(ADocNode: TDocNode);
  1028. var
  1029. Node: TDOMNode;
  1030. s: DOMString;
  1031. First : Boolean;
  1032. begin
  1033. if Not (Assigned(ADocNode) and Assigned(ADocNode.SeeAlso)) then
  1034. Exit;
  1035. Node := ADocNode.SeeAlso.FirstChild;
  1036. First:=True;
  1037. while Assigned(Node) do
  1038. begin
  1039. if IsLinkNode(Node) then
  1040. begin
  1041. If First then
  1042. begin
  1043. StartSeealso;
  1044. First:=False;
  1045. end
  1046. else
  1047. Writeln(',');
  1048. S:=TDomElement(Node)['id'];
  1049. DescrBeginLink(S);
  1050. if Node.FirstChild <> nil then
  1051. s := Node.FirstChild.NodeValue;
  1052. Write(EscapeText(S));
  1053. DescrEndLink();
  1054. end;
  1055. Node:=Node.NextSibling;
  1056. end;
  1057. If Not First then
  1058. EndSeeAlso
  1059. end;
  1060. Function CompareElements(P1,P2 : Pointer) : Integer;
  1061. begin
  1062. Result:=CompareText(TPasElement(P1).Name,TPasElement(P2).Name);
  1063. end;
  1064. procedure TLinearWriter.SortElementList(List : TFPList);
  1065. begin
  1066. List.Sort(@CompareElements);
  1067. end;
  1068. function TLinearWriter.ShowMember(M: TPasElement): boolean;
  1069. begin
  1070. Result:=Engine.ShowElement(M);
  1071. end;
  1072. procedure TLinearWriter.WriteClasses(ASection: TPasSection);
  1073. var
  1074. i: Integer;
  1075. begin
  1076. if (ASection.Classes.Count > 0) then
  1077. for i := 0 to ASection.Classes.Count - 1 do
  1078. WriteClassDecl(TPasClassType(ASection.Classes[i]));
  1079. end;
  1080. procedure TLinearWriter.WriteExtendedRecords(Asection: TPasSection);
  1081. var
  1082. i,j : Integer;
  1083. Recdecl : TPasRecordType;
  1084. DocNode : TDocNode;
  1085. Member : TPasElement;
  1086. begin
  1087. if (ASection.Types.Count > 0) then
  1088. for i := 0 to ASection.Types.Count - 1 do
  1089. begin
  1090. If TPasElement(ASection.Types[i]) is TPasRecordType then
  1091. begin
  1092. Recdecl:=TPasRecordType(ASection.Types[i]);
  1093. if RecDecl.IsAdvancedRecord then
  1094. begin
  1095. StartSection(RecDecl.Name);
  1096. DescrBeginParagraph;
  1097. WriteTypeDecl(RecDecl);
  1098. StartListing(False,'');
  1099. DocNode := Engine.FindDocNode(RecDecl);
  1100. If Assigned(DocNode) and
  1101. Assigned(DocNode.Node) and
  1102. (Docnode.Node['opaque']='1') then
  1103. Writeln(RecDecl.Name+' = '+SDocOpaque)
  1104. else
  1105. begin
  1106. Writeln(EscapeText(RecDecl.GetDeclaration(True)));
  1107. end;
  1108. EndListing;
  1109. WriteLabel(RecDecl);
  1110. WriteIndex(RecDecl);
  1111. WriteDescr(RecDecl,DocNode);
  1112. If Assigned(DocNode) and Assigned(DocNode.Version) then
  1113. begin
  1114. Writeln(Format('%s : ',[SDocVersion]));
  1115. WriteDescr(RecDecl, DocNode.Version);
  1116. end;
  1117. if Assigned(DocNode) and assigned(DocNode.Notes) then
  1118. ConvertNotes(RecDecl,DocNode.Notes);
  1119. DescrEndParagraph;
  1120. WriteMethodOverView(Recdecl,Recdecl.Members);
  1121. WritePropertyOverView(Recdecl,Recdecl.Members);
  1122. for J := 0 to Recdecl.Members.Count - 1 do
  1123. begin
  1124. Member := TPasElement(Recdecl.Members[j]);
  1125. if Member.InheritsFrom(TPasProcedureBase) and Engine.ShowElement(Member) then
  1126. WriteProcedure(TPasProcedureBase(Member));
  1127. end;
  1128. for j := 0 to Recdecl.Members.Count - 1 do
  1129. begin
  1130. Member := TPasElement(Recdecl.Members[j]);
  1131. if Member.InheritsFrom(TPasProperty) and Engine.ShowElement(Member) then
  1132. WriteProperty(TPasProperty(Member));
  1133. end;
  1134. end;
  1135. end;
  1136. end;
  1137. end;
  1138. procedure TLinearWriter.WriteMethodOverview(AParent: TPasType; Members : TFPList);
  1139. var
  1140. Member : TPasElement;
  1141. i : Integer;
  1142. L,N,S : String;
  1143. DocNode : TDocNode;
  1144. List : TStringList;
  1145. begin
  1146. List:=TStringList.Create;
  1147. Try
  1148. List.Sorted:=True;
  1149. for i := 0 to Members.Count - 1 do
  1150. begin
  1151. Member := TPasElement(Members[i]);
  1152. With Member do
  1153. if InheritsFrom(TPasProcedureBase) and ShowMember(Member) then
  1154. List.AddObject(Member.Name,Member);
  1155. end;
  1156. If List.Count>0 then
  1157. begin
  1158. StartSubSection(SDocMethodOverview);
  1159. WriteLabel(GetLabel(AParent) + ':Methods');
  1160. StartOverview(SDocMethod,False);
  1161. For I:=0 to List.Count-1 do
  1162. begin
  1163. Member:=TPasElement(List.Objects[i]);
  1164. L:=StripText(GetLabel(Member));
  1165. N:=EscapeText(Member.Name);
  1166. DocNode := Engine.FindDocNode(Member);
  1167. if Assigned(DocNode) and DocNode.IsSkipped then
  1168. Continue;
  1169. If Assigned(DocNode) then
  1170. S:=GetDescrString(Member, DocNode.ShortDescr)
  1171. else
  1172. S:='';
  1173. WriteOverviewMember(L,N,S);
  1174. end;
  1175. EndOverview;
  1176. end;
  1177. Finally
  1178. List.Free;
  1179. end;
  1180. end;
  1181. constructor TLinearWriter.Create(APackage: TPasPackage; AEngine: TFPDocEngine);
  1182. procedure AddLabel(AElement: TPasElement);
  1183. begin
  1184. Engine.AddLink(AElement.PathName, GetLabel(AElement));
  1185. end;
  1186. procedure AddList(AElement: TPasElement; AList: TFPList);
  1187. var
  1188. i,j: Integer;
  1189. R : TPasRecordType;
  1190. FPEl : TPaselement;
  1191. DocNode: TDocNode;
  1192. begin
  1193. for i := 0 to AList.Count - 1 do
  1194. begin
  1195. AddLabel(TPasElement(AList[i]));
  1196. if (TObject(AList[i]) is TPasRecordType) then
  1197. begin
  1198. R:=TObject(AList[I]) as TPasRecordType;
  1199. For J:=0 to R.Members.Count-1 do
  1200. begin
  1201. FPEl:=TPasElement(R.Members[J]);
  1202. if ((FPEL is TPasProperty) or (FPEL is TPasProcedureBase))
  1203. and Engine.ShowElement(FPEl) then
  1204. begin
  1205. DocNode := Engine.FindDocNode(FPEl);
  1206. if Assigned(DocNode) then
  1207. AddLabel(FPEl);
  1208. end;
  1209. end;
  1210. end;
  1211. end;
  1212. end;
  1213. procedure AddTopicPages(AElement: TPasElement);
  1214. var
  1215. PreviousTopic,
  1216. TopicElement : TTopicElement;
  1217. DocNode,
  1218. TopicNode : TDocNode;
  1219. begin
  1220. DocNode:=Engine.FindDocNode(AElement);
  1221. If not Assigned(DocNode) then
  1222. exit;
  1223. TopicNode:=DocNode.FirstChild;
  1224. PreviousTopic:=Nil;
  1225. While Assigned(TopicNode) do
  1226. begin
  1227. If TopicNode.TopicNode then
  1228. begin
  1229. TopicElement:=TTopicElement.Create(TopicNode.Name,AElement);
  1230. Topics.Add(TopicElement);
  1231. TopicElement.TopicNode:=TopicNode;
  1232. TopicElement.Previous:=PreviousTopic;
  1233. If Assigned(PreviousTopic) then
  1234. PreviousTopic.Next:=TopicElement;
  1235. PreviousTopic:=TopicElement;
  1236. if AElement is TTopicElement then
  1237. TTopicElement(AElement).SubTopics.Add(TopicElement);
  1238. Engine.AddLink(TopicElement.PathName, GetLabel(TopicElement));
  1239. if AElement is TTopicElement then
  1240. TTopicElement(AElement).SubTopics.Add(TopicElement)
  1241. else // Only one level of recursion.
  1242. AddTopicPages(TopicElement);
  1243. end;
  1244. TopicNode:=TopicNode.NextSibling;
  1245. end;
  1246. end;
  1247. procedure ScanModule(AModule: TPasModule);
  1248. var
  1249. i, j, k: Integer;
  1250. ClassEl: TPasClassType;
  1251. FPEl, AncestorMemberEl: TPasElement;
  1252. DocNode: TDocNode;
  1253. DidAutolink: Boolean;
  1254. begin
  1255. AddLabel(AModule);
  1256. AddTopicPages(AModule);
  1257. with AModule do
  1258. begin
  1259. AddList(AModule, InterfaceSection.ResStrings);
  1260. AddList(AModule, InterfaceSection.Consts);
  1261. AddList(AModule, InterfaceSection.Types);
  1262. if InterfaceSection.Classes.Count > 0 then
  1263. begin
  1264. for i := 0 to InterfaceSection.Classes.Count - 1 do
  1265. begin
  1266. ClassEl := TPasClassType(InterfaceSection.Classes[i]);
  1267. AddLabel(ClassEl);
  1268. for j := 0 to ClassEl.Members.Count - 1 do
  1269. begin
  1270. FPEl := TPasElement(ClassEl.Members[j]);
  1271. if Not Engine.ShowElement(FPEl) then
  1272. continue;
  1273. DocNode := Engine.FindDocNode(FPEl);
  1274. if not Assigned(DocNode) then
  1275. begin
  1276. DidAutolink := False;
  1277. if Assigned(ClassEl.AncestorType) and
  1278. (ClassEl.AncestorType.ClassType = TPasClassType) then
  1279. begin
  1280. for k := 0 to TPasClassType(ClassEl.AncestorType).Members.Count - 1 do
  1281. begin
  1282. AncestorMemberEl :=
  1283. TPasElement(TPasClassType(ClassEl.AncestorType).Members[k]);
  1284. if AncestorMemberEl.Name = FPEl.Name then
  1285. begin
  1286. DocNode := Engine.FindDocNode(AncestorMemberEl);
  1287. if Assigned(DocNode) then
  1288. begin
  1289. DidAutolink := True;
  1290. Engine.AddLink(FPEl.PathName,
  1291. Engine.FindAbsoluteLink(AncestorMemberEl.PathName));
  1292. break;
  1293. end;
  1294. end;
  1295. end;
  1296. end;
  1297. if not DidAutolink then
  1298. AddLabel(FPEl);
  1299. end else
  1300. AddLabel(FPEl);
  1301. end;
  1302. end;
  1303. end;
  1304. AddList(AModule, InterfaceSection.Functions);
  1305. AddList(AModule, InterfaceSection.Variables);
  1306. end;
  1307. end;
  1308. var
  1309. i: Integer;
  1310. begin
  1311. inherited ;
  1312. FDupLinkedDoc := False; // by default we don't duplicate linked element documentation
  1313. { Allocate labels for all elements for which we are going to create
  1314. documentation. This is needed for links to work correctly. }
  1315. // Allocate label for the package itself, if a name is given (i.e. <> '#')
  1316. if Length(Package.Name) > 1 then
  1317. begin
  1318. AddLabel(Package);
  1319. AddTopicPages(Package);
  1320. end;
  1321. for i := 0 to Package.Modules.Count - 1 do
  1322. ScanModule(TPasModule(Package.Modules[i]));
  1323. end;
  1324. procedure TLinearWriter.WriteBeginDocument;
  1325. begin
  1326. WriteComment('This file has been created automatically by FPDoc.');
  1327. WriteComment('Linear output (c) 2005 Michael Van Canneyt');
  1328. end;
  1329. procedure TLinearWriter.WriteEndDocument;
  1330. begin
  1331. // do nothing
  1332. end;
  1333. function TLinearWriter.EscapeText(S: UnicodeString): AnsiString;
  1334. begin
  1335. Result:=EscapeText(UTF8Encode(S));
  1336. end;
  1337. function TLinearWriter.InterpretOption(const Cmd, Arg: String): Boolean;
  1338. begin
  1339. Result := True;
  1340. if Cmd = cDupLinkedDocParam then
  1341. begin
  1342. FDupLinkedDoc := True;
  1343. end
  1344. else
  1345. Result := False;
  1346. end;
  1347. class procedure TLinearWriter.Usage(List: TStrings);
  1348. begin
  1349. List.Add(cDupLinkedDocParam);
  1350. List.Add(SLinearUsageDupLinkedDocsP1);
  1351. List.Add('');
  1352. List.Add(SLinearUsageDupLinkedDocsP2);
  1353. end;
  1354. end.