dw_latex.pp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527
  1. {
  2. $Id$
  3. FPDoc - Free Pascal Documentation Tool
  4. Copyright (C) 2000 - 2003 by
  5. Areca Systems GmbH / Sebastian Guenther, [email protected]
  6. * LaTeX output generator
  7. See the file COPYING, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. }
  13. unit dw_LaTeX;
  14. {$MODE objfpc}
  15. {$H+}
  16. interface
  17. uses DOM, dGlobals, PasTree;
  18. const
  19. LateXHighLight : Boolean = False;
  20. TexExtension : String = '.tex';
  21. procedure CreateLaTeXDocForPackage(APackage: TPasPackage; AEngine: TFPDocEngine);
  22. implementation
  23. uses SysUtils, Classes, dWriter;
  24. type
  25. TLabelType = (ltConst,ltVar,ltType,ltFunction,ltProcedure,ltClass,
  26. ltChapter,ltSection,ltSubsection,
  27. ltTable,ltFigure);
  28. TLaTeXWriter = class(TFPDocWriter)
  29. protected
  30. f: Text;
  31. FLink: String;
  32. Package: TPasPackage;
  33. PackageName: String;
  34. Module: TPasModule;
  35. ModuleName: String;
  36. FTableCount : Integer;
  37. FInVerbatim : Boolean;
  38. TableRowStartFlag, TableCaptionWritten: Boolean;
  39. function GetLabel(AElement: TPasElement): String;
  40. procedure Write(const s: String);
  41. procedure WriteF(const s: String; const Args: array of const);
  42. procedure WriteLn(const s: String);
  43. procedure WriteLnF(const s: String; const Args: array of const);
  44. // Tex functions
  45. procedure WriteLabel(El: TPasElement);
  46. procedure WriteLabel(const s: String);
  47. procedure WriteIndex(El: TPasElement);
  48. procedure WriteIndex(const s: String);
  49. procedure StartListing(Frames: Boolean; const name: String);
  50. procedure StartListing(Frames: Boolean);
  51. procedure EndListing;
  52. Function EscapeTex(S : String) : String;
  53. Function StripTex(S : String) : String;
  54. procedure WriteCommentLine;
  55. procedure WriteComment(Comment : String);
  56. procedure StartSection(SectionName : String; SectionLabel : String);
  57. procedure StartSection(SectionName : String);
  58. procedure StartSubSection(SubSectionName : String; SubSectionLabel : String);
  59. procedure StartSubSection(SubSectionName : String);
  60. procedure StartChapter(ChapterName : String; ChapterLabel : String);
  61. procedure StartChapter(ChapterName : String);
  62. // Description node conversion
  63. procedure DescrWriteText(const AText: DOMString); override;
  64. procedure DescrBeginBold; override;
  65. procedure DescrEndBold; override;
  66. procedure DescrBeginItalic; override;
  67. procedure DescrEndItalic; override;
  68. procedure DescrBeginEmph; override;
  69. procedure DescrEndEmph; override;
  70. procedure DescrWriteFileEl(const AText: DOMString); override;
  71. procedure DescrWriteKeywordEl(const AText: DOMString); override;
  72. procedure DescrWriteVarEl(const AText: DOMString); override;
  73. procedure DescrBeginLink(const AId: DOMString); override;
  74. procedure DescrEndLink; override;
  75. procedure DescrWriteLinebreak; override;
  76. procedure DescrBeginParagraph; override;
  77. procedure DescrBeginCode(HasBorder: Boolean; const AHighlighterName: String); override;
  78. procedure DescrWriteCodeLine(const ALine: String); override;
  79. procedure DescrEndCode; override;
  80. procedure DescrEndParagraph; override;
  81. procedure DescrBeginOrderedList; override;
  82. procedure DescrEndOrderedList; override;
  83. procedure DescrBeginUnorderedList; override;
  84. procedure DescrEndUnorderedList; override;
  85. procedure DescrBeginDefinitionList; override;
  86. procedure DescrEndDefinitionList; override;
  87. procedure DescrBeginListItem; override;
  88. procedure DescrEndListItem; override;
  89. procedure DescrBeginDefinitionTerm; override;
  90. procedure DescrEndDefinitionTerm; override;
  91. procedure DescrBeginDefinitionEntry; override;
  92. procedure DescrEndDefinitionEntry; override;
  93. procedure DescrBeginSectionTitle; override;
  94. procedure DescrBeginSectionBody; override;
  95. procedure DescrEndSection; override;
  96. procedure DescrBeginRemark; override;
  97. procedure DescrEndRemark; override;
  98. procedure DescrBeginTable(ColCount: Integer; HasBorder: Boolean); override;
  99. procedure DescrEndTable; override;
  100. procedure DescrBeginTableCaption; override;
  101. procedure DescrEndTableCaption; override;
  102. procedure DescrBeginTableHeadRow; override;
  103. procedure DescrEndTableHeadRow; override;
  104. procedure DescrBeginTableRow; override;
  105. procedure DescrEndTableRow; override;
  106. procedure DescrBeginTableCell; override;
  107. procedure DescrEndTableCell; override;
  108. procedure WriteDescr(Element: TPasElement);
  109. procedure WriteDescr(AContext: TPasElement; DescrNode: TDOMElement);
  110. function ConstValue(ConstDecl: TPasConst): String;
  111. procedure ProcessSection(ASection: TPasSection);
  112. // Documentation writing methods.
  113. procedure WriteResourceStrings(ASection: TPasSection);
  114. procedure WriteUnitOverview(ASection: TPasSection);
  115. procedure WriteVarsConstsTypes(ASection: TPasSection);
  116. procedure WriteConsts(ASection: TPasSection);
  117. procedure WriteTypes(ASection: TPasSection);
  118. procedure WriteEnumElements(TypeDecl : TPasEnumType);
  119. procedure WriteVars(ASection: TPasSection);
  120. procedure WriteFunctionsAndProcedures(ASection: TPasSection);
  121. procedure WriteProcedure(ProcDecl: TPasProcedureBase);
  122. procedure WriteClasses(ASection: TPasSection);
  123. procedure WriteClassDecl(ClassDecl: TPasClassType);
  124. procedure WriteClassMethodOverview(ClassDecl: TPasClassType);
  125. procedure WriteClassPropertyOverview(ClassDecl: TPasClassType);
  126. procedure WriteProperty(PropDecl: TPasProperty);
  127. procedure WriteExample(ADocNode: TDocNode);
  128. procedure WriteSeeAlso(ADocNode: TDocNode);
  129. procedure WriteSeeAlso(ADocNode: TDocNode; InList : Boolean);
  130. procedure SortElementList(List : TList);
  131. Function ShowMember(M : TPasElement) : boolean;
  132. Procedure ProcessPackage;
  133. Procedure ProcessTopics(DocNode : TDocNode; Alevel : Integer);
  134. Procedure WriteTopicNode(Node : TDocNode; Level : Integer);
  135. public
  136. constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine);
  137. procedure WriteDoc;
  138. end;
  139. constructor TLaTeXWriter.Create(APackage: TPasPackage; AEngine: TFPDocEngine);
  140. procedure AddLabel(AElement: TPasElement);
  141. begin
  142. Engine.AddLink(AElement.PathName, GetLabel(AElement));
  143. end;
  144. procedure AddList(AElement: TPasElement; AList: TList);
  145. var
  146. i: Integer;
  147. begin
  148. for i := 0 to AList.Count - 1 do
  149. AddLabel(TPasElement(AList[i]));
  150. end;
  151. procedure AddTopicPages(AElement: TPasElement);
  152. var
  153. PreviousTopic,
  154. TopicElement : TTopicElement;
  155. DocNode,
  156. TopicNode : TDocNode;
  157. begin
  158. DocNode:=Engine.FindDocNode(AElement);
  159. If not Assigned(DocNode) then
  160. exit;
  161. TopicNode:=DocNode.FirstChild;
  162. PreviousTopic:=Nil;
  163. While Assigned(TopicNode) do
  164. begin
  165. If TopicNode.TopicNode then
  166. begin
  167. TopicElement:=TTopicElement.Create(TopicNode.Name,AElement);
  168. Topics.Add(TopicElement);
  169. TopicElement.TopicNode:=TopicNode;
  170. TopicElement.Previous:=PreviousTopic;
  171. If Assigned(PreviousTopic) then
  172. PreviousTopic.Next:=TopicElement;
  173. PreviousTopic:=TopicElement;
  174. if AElement is TTopicElement then
  175. TTopicElement(AElement).SubTopics.Add(TopicElement);
  176. Engine.AddLink(TopicElement.PathName, GetLabel(TopicElement));
  177. if AElement is TTopicElement then
  178. TTopicElement(AElement).SubTopics.Add(TopicElement)
  179. else // Only one level of recursion.
  180. AddTopicPages(TopicElement);
  181. end;
  182. TopicNode:=TopicNode.NextSibling;
  183. end;
  184. end;
  185. procedure ScanModule(AModule: TPasModule);
  186. var
  187. i, j, k: Integer;
  188. s: String;
  189. ClassEl: TPasClassType;
  190. FPEl, AncestorMemberEl: TPasElement;
  191. DocNode: TDocNode;
  192. DidAutolink: Boolean;
  193. begin
  194. AddLabel(AModule);
  195. AddTopicPages(AModule);
  196. with AModule do
  197. begin
  198. AddList(AModule, InterfaceSection.ResStrings);
  199. AddList(AModule, InterfaceSection.Consts);
  200. AddList(AModule, InterfaceSection.Types);
  201. if InterfaceSection.Classes.Count > 0 then
  202. begin
  203. for i := 0 to InterfaceSection.Classes.Count - 1 do
  204. begin
  205. ClassEl := TPasClassType(InterfaceSection.Classes[i]);
  206. AddLabel(ClassEl);
  207. for j := 0 to ClassEl.Members.Count - 1 do
  208. begin
  209. FPEl := TPasElement(ClassEl.Members[j]);
  210. if ((FPEl.Visibility = visPrivate) and Engine.HidePrivate) or
  211. ((FPEl.Visibility = visProtected) and Engine.HideProtected) then
  212. continue;
  213. DocNode := Engine.FindDocNode(FPEl);
  214. if not Assigned(DocNode) then
  215. begin
  216. DidAutolink := False;
  217. if Assigned(ClassEl.AncestorType) and
  218. (ClassEl.AncestorType.ClassType = TPasClassType) then
  219. begin
  220. for k := 0 to TPasClassType(ClassEl.AncestorType).Members.Count - 1 do
  221. begin
  222. AncestorMemberEl :=
  223. TPasElement(TPasClassType(ClassEl.AncestorType).Members[k]);
  224. if AncestorMemberEl.Name = FPEl.Name then
  225. begin
  226. DocNode := Engine.FindDocNode(AncestorMemberEl);
  227. if Assigned(DocNode) then
  228. begin
  229. DidAutolink := True;
  230. Engine.AddLink(FPEl.PathName,
  231. Engine.FindAbsoluteLink(AncestorMemberEl.PathName));
  232. break;
  233. end;
  234. end;
  235. end;
  236. end;
  237. if not DidAutolink then
  238. AddLabel(FPEl);
  239. end else
  240. AddLabel(FPEl);
  241. end;
  242. end;
  243. end;
  244. AddList(AModule, InterfaceSection.Functions);
  245. AddList(AModule, InterfaceSection.Variables);
  246. end;
  247. end;
  248. var
  249. i: Integer;
  250. begin
  251. inherited Create(AEngine);
  252. Package := APackage;
  253. { Allocate labels for all elements for which we are going to create
  254. documentation. This is needed for links to work correctly. }
  255. // Allocate label for the package itself, if a name is given (i.e. <> '#')
  256. if Length(Package.Name) > 1 then
  257. begin
  258. AddLabel(Package);
  259. AddTopicPages(Package);
  260. end;
  261. for i := 0 to Package.Modules.Count - 1 do
  262. ScanModule(TPasModule(Package.Modules[i]));
  263. end;
  264. Procedure TLatexWriter.ProcessPackage;
  265. var
  266. i: Integer;
  267. UnitRef: TPasType;
  268. DocNode: TDocNode;
  269. First : Boolean;
  270. begin
  271. DocNode:=Engine.FindDocNode(Package);
  272. if Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr) then
  273. begin
  274. WriteLnF('\section{%s}', [EscapeTex(SDocOverview)]);
  275. WriteDescr(Package, DocNode.Descr);
  276. Writeln('');
  277. end;
  278. WriteSeeAlso(DocNode,True);
  279. ProcessTopics(DocNode,1);
  280. end;
  281. Procedure TlatexWriter.ProcessTopics(DocNode : TDocNode; Alevel : Integer);
  282. Var
  283. Node : TDocNode;
  284. First : Boolean;
  285. begin
  286. If Not Assigned(DocNode) then
  287. Exit;
  288. Node:=DocNode.FirstChild;
  289. First:=True;
  290. While Assigned(Node) do
  291. begin
  292. If Node.TopicNode then
  293. begin
  294. WriteTopicNode(Node,ALevel);
  295. First:=False;
  296. end;
  297. Node:=Node.NextSibling;
  298. end;
  299. end;
  300. Procedure TLatexWriter.WriteTopicNode(Node : TDocNode; Level : Integer);
  301. Var
  302. Element : TTopicElement;
  303. SubNode : TDocNode;
  304. begin
  305. Element:=FindTopicElement(Node);
  306. If Not Assigned(Element) then
  307. Exit;
  308. Case Level of
  309. 1 : Write('\section{');
  310. 2 : Write('\subsection{');
  311. 3 : Write('\subsubsection{');
  312. end;
  313. WriteDescr(Element,Node.ShortDescr);
  314. Writeln('}');
  315. WriteLabel(Element);
  316. If Assigned(Node.Descr) then
  317. WriteDescr(Element,Node.Descr);
  318. WriteSeeAlso(Node,True);
  319. If Level<3 then
  320. begin
  321. SubNode:=Node.FirstChild;
  322. While Assigned(SubNode) do
  323. begin
  324. If SubNode.TopicNode then
  325. WriteTopicNode(SubNode,Level+1);
  326. SubNode:=SubNode.NextSibling;
  327. end;
  328. end;
  329. end;
  330. procedure TLaTeXWriter.WriteDoc;
  331. var
  332. i : Integer;
  333. DocNode : TDocNode;
  334. L : TstringList;
  335. begin
  336. PackageName := LowerCase(Copy(Package.Name, 2, 255));
  337. If (Engine.OutPut='') then
  338. Engine.Output:=PackageName+TexExtension;
  339. Assign(f, Engine.Output);
  340. Rewrite(f);
  341. try
  342. WriteLn('% This file has been created automatically by FPDoc,');
  343. WriteLn('% (c) 2000-2003 by Areca Systems GmbH / Sebastian Guenther ([email protected])');
  344. ProcessPackage;
  345. L:=TStringList.Create;
  346. Try
  347. L.Sorted:=True;
  348. // Sort modules.
  349. For I:=0 to Package.Modules.Count-1 do
  350. L.AddObject(TPasModule(Package.Modules[i]).Name,TPasModule(Package.Modules[i]));
  351. // Now create table.
  352. for i:=0 to L.Count - 1 do
  353. begin
  354. Module := TPasModule(L.Objects[i]);
  355. ModuleName := LowerCase(Module.Name);
  356. WriteLn('');
  357. WriteLnF('\chapter{%s}', [EscapeTex(Format(SDocUnitTitle, [Module.Name]))]);
  358. WriteLabel(Module);
  359. DocNode:=Engine.FindDocNode(Module);
  360. If Assigned(DocNode) then
  361. ProcessTopics(DocNode,1);
  362. ProcessSection(Module.InterfaceSection);
  363. end;
  364. Finally
  365. L.Free;
  366. end;
  367. finally
  368. Close(f);
  369. end;
  370. end;
  371. function TLaTeXWriter.GetLabel(AElement: TPasElement): String;
  372. var
  373. i: Integer;
  374. begin
  375. if AElement.ClassType = TPasUnresolvedTypeRef then
  376. Result := Engine.ResolveLink(Module, AElement.Name)
  377. else
  378. begin
  379. Result := AElement.PathName;
  380. Result := LowerCase(Copy(Result, 2, Length(Result) - 1));
  381. end;
  382. for i := 1 to Length(Result) do
  383. if Result[i] = '.' then
  384. Result[i] := ':';
  385. end;
  386. procedure TLaTeXWriter.Write(const s: String);
  387. begin
  388. System.Write(f, s);
  389. end;
  390. procedure TLaTeXWriter.WriteF(const s: String; const Args: array of const);
  391. begin
  392. System.Write(f, Format(s, Args));
  393. end;
  394. procedure TLaTeXWriter.WriteLn(const s: String);
  395. begin
  396. System.WriteLn(f, s);
  397. end;
  398. procedure TLaTeXWriter.WriteLnF(const s: String; const Args: array of const);
  399. begin
  400. System.WriteLn(f, Format(s, Args));
  401. end;
  402. Function TLatexWriter.EscapeTex(S : String) : String;
  403. var
  404. i: Integer;
  405. begin
  406. if FInVerBatim=True then
  407. Result:=S
  408. else
  409. begin
  410. SetLength(Result, 0);
  411. for i := 1 to Length(S) do
  412. case S[i] of
  413. '&','{','}','#','_','$','%': // Escape these characters
  414. Result := Result + '\' + S[i];
  415. '~','^':
  416. Result := Result + '\'+S[i]+' ';
  417. '\':
  418. Result:=Result+'$\backslash$'
  419. else
  420. Result := Result + S[i];
  421. end;
  422. end;
  423. end;
  424. Function TLatexWriter.StripTex(S : String) : String;
  425. var
  426. I,L: Integer;
  427. begin
  428. SetLength(Result, 0);
  429. for i := 1 to Length(S) do
  430. If not (S[i] in ['&','{','}','#','_','$','%','''','~','^', '\']) then
  431. Result := Result + S[i];
  432. end;
  433. procedure TLaTeXWriter.DescrWriteText(const AText: DOMString);
  434. begin
  435. Write(EscapeTex(AText));
  436. end;
  437. procedure TLaTeXWriter.DescrBeginBold;
  438. begin
  439. Write('\textbf{');
  440. end;
  441. procedure TLaTeXWriter.DescrEndBold;
  442. begin
  443. Write('}');
  444. end;
  445. procedure TLaTeXWriter.DescrBeginItalic;
  446. begin
  447. Write('\textit{');
  448. end;
  449. procedure TLaTeXWriter.DescrEndItalic;
  450. begin
  451. Write('}');
  452. end;
  453. procedure TLaTeXWriter.DescrBeginEmph;
  454. begin
  455. Write('\emph{');
  456. end;
  457. procedure TLaTeXWriter.DescrEndEmph;
  458. begin
  459. Write('}');
  460. end;
  461. procedure TLaTeXWriter.DescrWriteFileEl(const AText: DOMString);
  462. begin
  463. Write('\file{');
  464. DescrWriteText(AText);
  465. Write('}');
  466. end;
  467. procedure TLaTeXWriter.DescrWriteKeywordEl(const AText: DOMString);
  468. begin
  469. Write('\textbf{\\ttfamily ');
  470. DescrWriteText(AText);
  471. Write('}');
  472. end;
  473. procedure TLaTeXWriter.DescrWriteVarEl(const AText: DOMString);
  474. begin
  475. Write('\var{');
  476. DescrWriteText(AText);
  477. Write('}');
  478. end;
  479. procedure TLaTeXWriter.DescrBeginLink(const AId: DOMString);
  480. var
  481. i: Integer;
  482. begin
  483. FLink := Engine.ResolveLink(Module, AId);
  484. // System.WriteLn('Link "', AId, '" => ', FLink);
  485. end;
  486. procedure TLaTeXWriter.DescrEndLink;
  487. begin
  488. WriteF(' (\pageref{%s})',[StripTex(Flink)]);
  489. end;
  490. procedure TLaTeXWriter.DescrWriteLinebreak;
  491. begin
  492. WriteLn('\\');
  493. end;
  494. procedure TLaTeXWriter.DescrBeginParagraph;
  495. begin
  496. // Do nothing
  497. end;
  498. procedure TLaTeXWriter.DescrEndParagraph;
  499. begin
  500. WriteLn('');
  501. WriteLn('');
  502. end;
  503. procedure TLaTeXWriter.DescrBeginCode(HasBorder: Boolean;
  504. const AHighlighterName: String);
  505. begin
  506. StartListing(HasBorder);
  507. end;
  508. procedure TLaTeXWriter.DescrWriteCodeLine(const ALine: String);
  509. begin
  510. WriteLn(ALine);
  511. end;
  512. procedure TLaTeXWriter.DescrEndCode;
  513. begin
  514. EndListing
  515. end;
  516. procedure TLaTeXWriter.DescrBeginOrderedList;
  517. begin
  518. WriteLn('\begin{enumerate}');
  519. end;
  520. procedure TLaTeXWriter.DescrEndOrderedList;
  521. begin
  522. WriteLn('\end{enumerate}');
  523. end;
  524. procedure TLaTeXWriter.DescrBeginUnorderedList;
  525. begin
  526. WriteLn('\begin{itemize}');
  527. end;
  528. procedure TLaTeXWriter.DescrEndUnorderedList;
  529. begin
  530. WriteLn('\end{itemize}');
  531. end;
  532. procedure TLaTeXWriter.DescrBeginDefinitionList;
  533. begin
  534. WriteLn('\begin{description}');
  535. end;
  536. procedure TLaTeXWriter.DescrEndDefinitionList;
  537. begin
  538. WriteLn('\end{description}');
  539. end;
  540. procedure TLaTeXWriter.DescrBeginListItem;
  541. begin
  542. Write('\item ');
  543. end;
  544. procedure TLaTeXWriter.DescrEndListItem;
  545. begin
  546. WriteLn('');
  547. end;
  548. procedure TLaTeXWriter.DescrBeginDefinitionTerm;
  549. begin
  550. Write('\item[');
  551. end;
  552. procedure TLaTeXWriter.DescrEndDefinitionTerm;
  553. begin
  554. WriteLn(']');
  555. end;
  556. procedure TLaTeXWriter.DescrBeginDefinitionEntry;
  557. begin
  558. // Do nothing
  559. end;
  560. procedure TLaTeXWriter.DescrEndDefinitionEntry;
  561. begin
  562. WriteLn('');
  563. end;
  564. procedure TLaTeXWriter.DescrBeginSectionTitle;
  565. begin
  566. Write('\subsection{');
  567. end;
  568. procedure TLaTeXWriter.DescrBeginSectionBody;
  569. begin
  570. WriteLn('}');
  571. end;
  572. procedure TLaTeXWriter.DescrEndSection;
  573. begin
  574. // Do noting
  575. end;
  576. procedure TLaTeXWriter.DescrBeginRemark;
  577. begin
  578. WriteLn('\begin{remark}');
  579. end;
  580. procedure TLaTeXWriter.DescrEndRemark;
  581. begin
  582. WriteLn('\end{remark}');
  583. end;
  584. procedure TLaTeXWriter.DescrBeginTable(ColCount: Integer; HasBorder: Boolean);
  585. var
  586. i: Integer;
  587. begin
  588. // !!!: How do we set the border?
  589. Write('\begin{FPCltable}{');
  590. for i := 1 to ColCount do
  591. Write('l');
  592. write('}{');
  593. TableCaptionWritten:=False;
  594. end;
  595. procedure TLaTeXWriter.DescrEndTable;
  596. begin
  597. WriteLn('\end{FPCltable}');
  598. end;
  599. procedure TLaTeXWriter.DescrBeginTableCaption;
  600. begin
  601. // Do nothing.
  602. end;
  603. procedure TLaTeXWriter.DescrEndTableCaption;
  604. begin
  605. Write('}{table');
  606. Inc(FTableCount);
  607. Write(IntToStr(FTableCount));
  608. Writeln('}');
  609. TableCaptionWritten := True;
  610. end;
  611. procedure TLaTeXWriter.DescrBeginTableHeadRow;
  612. begin
  613. if not TableCaptionWritten then
  614. DescrEndTableCaption;
  615. TableRowStartFlag := True;
  616. end;
  617. procedure TLaTeXWriter.DescrEndTableHeadRow;
  618. begin
  619. WriteLn('\\ \hline');
  620. end;
  621. procedure TLaTeXWriter.DescrBeginTableRow;
  622. begin
  623. if not TableCaptionWritten then
  624. DescrEndTableCaption;
  625. TableRowStartFlag := True;
  626. end;
  627. procedure TLaTeXWriter.DescrEndTableRow;
  628. begin
  629. WriteLn('\\');
  630. end;
  631. procedure TLaTeXWriter.DescrBeginTableCell;
  632. begin
  633. if TableRowStartFlag then
  634. TableRowStartFlag := False
  635. else
  636. Write(' & ');
  637. end;
  638. procedure TLaTeXWriter.DescrEndTableCell;
  639. begin
  640. // Do nothing
  641. end;
  642. procedure TLaTeXWriter.WriteDescr(Element: TPasElement);
  643. var
  644. DocNode: TDocNode;
  645. begin
  646. DocNode := Engine.FindDocNode(Element);
  647. if Assigned(DocNode) then
  648. begin
  649. if not IsDescrNodeEmpty(DocNode.Descr) then
  650. WriteDescr(Element, DocNode.Descr)
  651. else if not IsDescrNodeEmpty(DocNode.ShortDescr) then
  652. WriteDescr(Element, DocNode.ShortDescr);
  653. end;
  654. end;
  655. procedure TLaTeXWriter.WriteDescr(AContext: TPasElement; DescrNode: TDOMElement);
  656. begin
  657. if Assigned(DescrNode) then
  658. ConvertDescr(AContext, DescrNode, False);
  659. end;
  660. function TLaTeXWriter.ConstValue(ConstDecl: TPasConst): String;
  661. begin
  662. if Assigned(ConstDecl) then
  663. Result := ConstDecl.ClassName
  664. else
  665. Result := '<nil>';
  666. end;
  667. procedure TLaTexWriter.WriteUnitOverview(ASection: TPasSection);
  668. var
  669. i: Integer;
  670. UnitRef: TPasType;
  671. DocNode: TDocNode;
  672. begin
  673. if ASection.UsesList.Count > 0 then
  674. begin
  675. WriteLnF('\section{%s}', [SDocUsedUnits]);
  676. WriteLnF('\begin{FPCltable}{lr}{%s}{%s:0units}',
  677. [Format(SDocUsedUnitsByUnitXY, [Module.Name]), ModuleName]);
  678. WriteLn('Name & Page \\ \hline');
  679. for i := 0 to ASection.UsesList.Count - 1 do
  680. begin
  681. UnitRef := TPasType(ASection.UsesList[i]);
  682. WriteLnF('%s\index{unit!%s} & \pageref{%s} \\',
  683. [UnitRef.Name, UnitRef.Name, StripTex(GetLabel(UnitRef))]);
  684. end;
  685. WriteLn('\end{FPCltable}');
  686. end;
  687. DocNode := Engine.FindDocNode(ASection.Parent);
  688. if Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr) then
  689. begin
  690. WriteLnF('\section{%s}', [EscapeTex(SDocOverview)]);
  691. WriteDescr(ASection.Parent, DocNode.Descr);
  692. Writeln('');
  693. end;
  694. end;
  695. procedure TLaTeXWriter.WriteResourceStrings(ASection: TPasSection);
  696. var
  697. ResStrDecl: TPasResString;
  698. i: Integer;
  699. begin
  700. if ASection.ResStrings.Count > 0 then
  701. begin
  702. StartSubSection(SDocResStrings,ModuleName+'ResStrings');
  703. for i := 0 to ASection.ResStrings.Count - 1 do
  704. begin
  705. ResStrDecl := TPasResString(ASection.ResStrings[i]);
  706. StartListing(false, '');
  707. Writeln(ResStrDecl.GetDeclaration(True));
  708. EndListing;
  709. WriteLabel(ResStrDecl);
  710. WriteIndex(ResStrDecl);
  711. WriteDescr(ResStrDecl);
  712. Writeln('');
  713. end;
  714. end;
  715. end;
  716. procedure TLaTeXWriter.WriteConsts(ASection: TPasSection);
  717. var
  718. i: Integer;
  719. ConstDecl: TPasConst;
  720. begin
  721. if ASection.Consts.Count > 0 then
  722. begin
  723. WriteLnF('\subsection{%s}\label{suse:%sConstants}',
  724. [EscapeTex(SDocConstants), EscapeTex(ModuleName)]);
  725. for i := 0 to ASection.Consts.Count - 1 do
  726. begin
  727. ConstDecl := TPasConst(ASection.Consts[i]);
  728. StartListing(False);
  729. WriteLn(EscapeTex(ConstDecl.GetDeclaration(True)));
  730. EndListing;
  731. WriteLabel(ConstDecl);
  732. WriteIndex(ConstDecl);
  733. WriteDescr(ConstDecl);
  734. end;
  735. end;
  736. end;
  737. procedure TLaTeXWriter.WriteEnumElements(TypeDecl : TPasEnumType);
  738. Var
  739. EV : TPasEnumValue;
  740. I : Integer;
  741. DocNode : TDocNode;
  742. begin
  743. With TypeDecl do
  744. begin
  745. SortElementList(Values);
  746. DescrBeginTable(2,True);
  747. DescrBeginTableCaption;
  748. Writeln(EscapeTex(Format(SDocValuesForEnum,[TypeDecl.Name])));
  749. DescrEndTableCaption;
  750. DescrBeginTableHeadRow;
  751. DescrBeginTableCell;
  752. Writeln(EscapeTex(SDocValue));
  753. DescrEndTableCell;
  754. DescrBeginTableCell;
  755. Writeln(EscapeTex(SDocExplanation));
  756. DescrEndTableCell;
  757. DescrEndTableHeadRow;
  758. For I:=0 to Values.Count-1 do
  759. begin
  760. EV:=TPasEnumValue(Values[i]);
  761. DescrBeginTableRow;
  762. DescrBeginTableCell;
  763. Writeln(EscapeTex(EV.Name));
  764. DescrEndTableCell;
  765. DescrBeginTableCell;
  766. DocNode := Engine.FindDocNode(EV);
  767. if Assigned(DocNode) and (not IsDescrNodeEmpty(DocNode.ShortDescr)) then
  768. WriteDescr(EV,DocNode.ShortDescr);
  769. DescrEndTableCell;
  770. DescrEndTableRow;
  771. end;
  772. DescrEndTable;
  773. end;
  774. end;
  775. procedure TLaTeXWriter.WriteTypes(ASection: TPasSection);
  776. var
  777. i: Integer;
  778. TypeDecl: TPasType;
  779. begin
  780. if ASection.Types.Count > 0 then
  781. begin
  782. StartSubSection(SDocTypes,ModuleName+'Types');
  783. for i := 0 to ASection.Types.Count - 1 do
  784. begin
  785. TypeDecl := TPasType(ASection.Types[i]);
  786. StartListing(False);
  787. Writeln(EscapeTex(TypeDecl.GetDeclaration(True)));
  788. EndListing;
  789. WriteLabel(TypeDecl);
  790. WriteIndex(TypeDecl);
  791. If TypeDecl is TPasEnumType then
  792. begin
  793. WriteENumElements(TypeDecl as TPasEnumType);
  794. end;
  795. WriteDescr(TypeDecl);
  796. end;
  797. end;
  798. end;
  799. procedure TLaTeXWriter.WriteVars(ASection: TPasSection);
  800. var
  801. VarDecl: TPasVariable;
  802. i: Integer;
  803. begin
  804. if ASection.Variables.Count > 0 then
  805. begin
  806. StartSubsection(SDocVariables,ModuleName+'Variables');
  807. for i := 0 to ASection.Variables.Count - 1 do
  808. begin
  809. VarDecl := TPasVariable(ASection.Variables[i]);
  810. StartListing(False);
  811. WriteLn(EscapeTex(VarDecl.GetDeclaration(True)));
  812. EndListing;
  813. WriteLabel(VarDecl);
  814. WriteIndex(VarDecl);
  815. WriteDescr(VarDecl);
  816. end;
  817. end;
  818. end;
  819. procedure TLaTeXWriter.WriteVarsConstsTypes(ASection: TPasSection);
  820. begin
  821. With Asection do
  822. if (Consts.Count > 0) or
  823. (Types.Count > 0) or
  824. (Variables.Count > 0) or
  825. (ResStrings.Count>0) then
  826. begin
  827. StartSection(SDocConstsTypesVars, ModuleName+'ConstsTypesVars');
  828. WriteResourceStrings(ASection);
  829. WriteConsts(ASection);
  830. WriteTypes(ASection);
  831. WriteVars(ASection);
  832. end;
  833. end;
  834. const
  835. SVisibility: array[TPasMemberVisibility] of string =
  836. ('Default', 'Private', 'Protected', 'Public',
  837. 'Published', 'Automated');
  838. procedure TLatexWriter.WriteProcedure(ProcDecl : TPasProcedureBase);
  839. var
  840. DocNode: TDocNode;
  841. OP : TPasOverloadedProc;
  842. i : integer;
  843. begin
  844. With ProcDecl do
  845. begin
  846. if Not (Assigned(Parent) and Parent.InheritsFrom(TPasClassType)) then
  847. begin
  848. StartSubSection(Name);
  849. WriteLabel(ProcDecl);
  850. WriteIndex(ProcDecl);
  851. end
  852. else
  853. begin // Parent assigned and hence method.
  854. StartSubSection(Parent.Name+'.'+Name);
  855. WriteLabel(ProcDecl);
  856. WriteIndex(Parent.Name+'.'+Name);
  857. end;
  858. Writeln('\begin{FPCList}');
  859. DocNode := Engine.FindDocNode(ProcDecl);
  860. if Assigned(DocNode) and Assigned(DocNode.ShortDescr) then
  861. begin
  862. Writeln('\Synopsis');
  863. WriteDescr(ProcDecl, DocNode.ShortDescr);
  864. end;
  865. Writeln('\Declaration ');
  866. StartListing(False);
  867. if ClassType = TPasOverloadedProc then
  868. begin
  869. OP:=TPasOverloadedProc(ProcDecl);
  870. for i := 0 to OP.Overloads.Count - 1 do
  871. begin
  872. WriteLn(TPasProcedure(OP.Overloads[i]).GetDeclaration(True));
  873. end;
  874. end
  875. else
  876. WriteLn(GetDeclaration(True));
  877. EndListing;
  878. If Assigned(Parent) then
  879. begin
  880. Writeln('\Visibility');
  881. Writeln(VisibilityNames[Visibility])
  882. end;
  883. if Assigned(DocNode) and Assigned(DocNode.Descr) then
  884. begin
  885. Writeln('\Description');
  886. WriteDescr(ProcDecl);
  887. end;
  888. if Assigned(DocNode) and Assigned(DocNode.ErrorsDoc) then
  889. begin
  890. Writeln('\Errors');
  891. WriteDescr(ProcDecl, DocNode.ErrorsDoc);
  892. end;
  893. WriteSeeAlso(DocNode);
  894. Writeln('\end{FPCList}');
  895. WriteExample(DocNode);
  896. end;
  897. end;
  898. procedure TLaTeXWriter.WriteFunctionsAndProcedures(ASection: TPasSection);
  899. var
  900. i: Integer;
  901. begin
  902. if ASection.Functions.Count > 0 then
  903. begin
  904. StartSection(SDocProceduresAndFunctions,ModuleName+'Functions');
  905. for i := 0 to ASection.Functions.Count - 1 do
  906. WriteProcedure(TPasProcedureBase(ASection.Functions[i]));
  907. end;
  908. end;
  909. procedure TlatexWriter.WriteExample(ADocNode: TDocNode);
  910. var
  911. Example: TDOMElement;
  912. S : string;
  913. begin
  914. if Assigned(ADocNode) then
  915. begin
  916. Example := ADocNode.FirstExample;
  917. while Assigned(Example) do
  918. begin
  919. if (Example.NodeType = ELEMENT_NODE) and (Example.NodeName = 'example') then
  920. begin
  921. if (S<>'') then // not first example, start new paragraph
  922. WriteLn('');
  923. s:=Engine.GetExampleFileName(Example);
  924. If (s<>'') then
  925. WritelnF('\FPCexample{%s}', [ChangeFileExt(S,'')]);
  926. if Assigned(Example.NextSibling) then
  927. WriteLn('');
  928. end;
  929. Example := TDomElement(Example.NextSibling);
  930. end;
  931. end;
  932. end;
  933. procedure TLateXWriter.WriteSeeAlso(ADocNode: TDocNode);
  934. begin
  935. WriteSeeAlso(ADocNode,False);
  936. end;
  937. procedure TLateXWriter.WriteSeeAlso(ADocNode: TDocNode; InList : Boolean);
  938. var
  939. Node: TDOMNode;
  940. s: String;
  941. First : Boolean;
  942. begin
  943. if Not (Assigned(ADocNode) and Assigned(ADocNode.SeeAlso)) then
  944. Exit;
  945. Node := ADocNode.SeeAlso.FirstChild;
  946. First:=True;
  947. while Assigned(Node) do
  948. begin
  949. if (Node.NodeType = ELEMENT_NODE) and
  950. (Node.NodeName = 'link') then
  951. begin
  952. If First then
  953. begin
  954. If InList then
  955. begin
  956. Writeln('');
  957. Writeln('\begin{FPCList}');
  958. end;
  959. Writeln('\SeeAlso');
  960. First:=False;
  961. end
  962. else
  963. Writeln(',');
  964. S:=TDomElement(Node)['id'];
  965. DescrBeginLink(S);
  966. Writeln(EscapeTex(S));
  967. DescrEndLink();
  968. end;
  969. Node:=Node.NextSibling;
  970. end;
  971. If Inlist and Not First then
  972. Writeln('\end{FPCList}');
  973. end;
  974. procedure TLaTeXWriter.WriteClasses(ASection: TPasSection);
  975. var
  976. i: Integer;
  977. begin
  978. if (ASection.Classes.Count > 0) then
  979. begin
  980. for i := 0 to ASection.Classes.Count - 1 do
  981. WriteClassDecl(TPasClassType(ASection.Classes[i]));
  982. end;
  983. end;
  984. procedure TLaTeXWriter.ProcessSection(ASection: TPasSection);
  985. begin
  986. With ASection do
  987. begin
  988. SortElementList(UsesList);
  989. SortElementList(Declarations);
  990. SortElementList(ResStrings);
  991. SortElementList(Types);
  992. SortElementList(Consts);
  993. SortElementList(Classes);
  994. SortElementList(Functions);
  995. SortElementList(Variables);
  996. end;
  997. WriteUnitOverView(ASection);
  998. WriteVarsConstsTypes(ASection);
  999. WriteFunctionsAndProcedures(ASection);
  1000. WriteClasses(ASection);
  1001. end;
  1002. Function TLatexWriter.ShowMember(M : TPasElement) : boolean;
  1003. begin
  1004. Result:=not ((M.Visibility=visPrivate) and Engine.HidePrivate);
  1005. If Result then
  1006. Result:=Not ((M.Visibility=visProtected) and Engine.HideProtected)
  1007. end;
  1008. procedure TLatexWriter.WriteClassMethodOverview(ClassDecl : TPasClassType);
  1009. var
  1010. Member: TPasElement;
  1011. i, j: Integer;
  1012. s: String;
  1013. Arg: TPasArgument;
  1014. DocNode: TDocNode;
  1015. List : TStringList;
  1016. begin
  1017. List:=TStringList.Create;
  1018. Try
  1019. List.Sorted:=True;
  1020. for i := 0 to ClassDecl.Members.Count - 1 do
  1021. begin
  1022. Member := TPasElement(ClassDecl.Members[i]);
  1023. With Member do
  1024. if InheritsFrom(TPasProcedureBase) and ShowMember(Member) then
  1025. List.AddObject(Member.Name,Member);
  1026. end;
  1027. If List.Count>0 then
  1028. begin
  1029. StartSubSection(SDocMethodOverview);
  1030. WriteLabel(GetLabel(ClassDecl) + ':Methods');
  1031. WriteLn('\begin{tabularx}{\textwidth}{llX}');
  1032. WriteLnF('%s & %s & %s \\ \hline', [EscapeTex(SDocPage), EscapeTex(SDocMethod), EscapeTex(SDocDescription)]);
  1033. For I:=0 to List.Count-1 do
  1034. begin
  1035. Member:=TPasElement(List.Objects[i]);
  1036. DocNode := Engine.FindDocNode(Member);
  1037. WriteF('\pageref{%s} & %s & ',[StripTex(GetLabel(Member)), EscapeTex(Member.Name)]);
  1038. if Assigned(DocNode) and Assigned(DocNode.ShortDescr) then
  1039. WriteDescr(Member, DocNode.ShortDescr);
  1040. WriteLn('\\');
  1041. end;
  1042. WriteLn('\hline');
  1043. WriteLn('\end{tabularx}');
  1044. end;
  1045. Finally
  1046. List.Free;
  1047. end;
  1048. end;
  1049. procedure TLatexWriter.WriteClassPropertyOverview(ClassDecl : TPasClassType);
  1050. var
  1051. Member: TPasElement;
  1052. i, j: Integer;
  1053. s: String;
  1054. Arg: TPasArgument;
  1055. DocNode: TDocNode;
  1056. List : TStringList;
  1057. begin
  1058. // Write property overview
  1059. List:=TStringList.Create;
  1060. Try
  1061. List.Sorted:=True;
  1062. for i := 0 to ClassDecl.Members.Count - 1 do
  1063. begin
  1064. Member := TPasElement(ClassDecl.Members[i]);
  1065. With Member do
  1066. if InheritsFrom(TPasProperty) and SHowMember(Member) then
  1067. List.AddObject(Member.Name,Member)
  1068. end;
  1069. If (List.Count>0) then
  1070. begin
  1071. StartSubSection(SDocPropertyOverview);
  1072. WriteLabel(GetLabel(ClassDecl) + ':Properties');
  1073. WriteLn('\begin{tabularx}{\textwidth}{lllX}');
  1074. WriteLnF('%s & %s & %s & %s \\ \hline',
  1075. [EscapeTex(SDocPage), EscapeTex(SDocProperty), EscapeTex(SDocAccess), EscapeTex(SDocDescription)]);
  1076. For I:=0 to List.Count-1 do
  1077. begin
  1078. Member:=TPasElement(List.objects[i]);
  1079. WriteF('\pageref{%s} & %s & ', [StripTex(GetLabel(Member)), EscapeTex(Member.Name)]);
  1080. setlength(S,0);
  1081. if Length(TPasProperty(Member).ReadAccessorName) > 0 then
  1082. s := s + 'r';
  1083. if Length(TPasProperty(Member).WriteAccessorName) > 0 then
  1084. s := s + 'w';
  1085. if Length(TPasProperty(Member).StoredAccessorName) > 0 then
  1086. s := s + 's';
  1087. Write(s + ' & ');
  1088. DocNode := Engine.FindDocNode(Member);
  1089. if Assigned(DocNode) and Assigned(DocNode.ShortDescr) then
  1090. WriteDescr(Member, DocNode.ShortDescr);
  1091. WriteLn('\\');
  1092. end;
  1093. WriteLn('\hline');
  1094. WriteLn('\end{tabularx}');
  1095. end;
  1096. Finally
  1097. List.Free;
  1098. end;
  1099. end;
  1100. procedure TLaTeXWriter.WriteClassDecl(ClassDecl: TPasClassType);
  1101. var
  1102. DocNode: TDocNode;
  1103. Vis: TPasMemberVisibilities;
  1104. Member: TPasElement;
  1105. i: Integer;
  1106. begin
  1107. StartSection(ClassDecl.Name);
  1108. WriteLabel(ClassDecl);
  1109. WriteIndex(ClassDecl);
  1110. DocNode := Engine.FindDocNode(ClassDecl);
  1111. if Assigned(DocNode) and ((not IsDescrNodeEmpty(DocNode.Descr)) or
  1112. (not IsDescrNodeEmpty(DocNode.ShortDescr))) then
  1113. begin
  1114. StartSubSection(SDocDescription);
  1115. WriteDescr(ClassDecl);
  1116. end;
  1117. // Write method overview
  1118. WriteClassMethodOverView(ClassDecl);
  1119. // Write Property Overview;
  1120. WriteClassPropertyOverView(ClassDecl);
  1121. // Write method & property descriptions
  1122. // Determine visibilities
  1123. Vis := AllVisibilities;
  1124. if Engine.HidePrivate then
  1125. Exclude(Vis,visPrivate);
  1126. if Engine.HideProtected then
  1127. Exclude(Vis,visProtected);
  1128. for i := 0 to ClassDecl.Members.Count - 1 do
  1129. begin
  1130. Member := TPasElement(ClassDecl.Members[i]);
  1131. if ((Member.InheritsFrom(TPasProcedureBase)) and
  1132. (Member.Visibility in Vis)) then
  1133. WriteProcedure(TPasProcedureBase(Member));
  1134. end;
  1135. // properties.
  1136. for i := 0 to ClassDecl.Members.Count - 1 do
  1137. begin
  1138. Member := TPasElement(ClassDecl.Members[i]);
  1139. if ((Member.InheritsFrom(TPasProperty)) and
  1140. (Member.Visibility in Vis)) then
  1141. WriteProperty(TPasProperty(Member));
  1142. end;
  1143. end;
  1144. procedure TLaTexWriter.WriteProperty(PropDecl : TPasProperty);
  1145. var
  1146. DocNode: TDocNode;
  1147. S: String;
  1148. begin
  1149. With PropDecl do
  1150. begin
  1151. StartSubSection(Parent.Name+'.'+Name);
  1152. WriteLabel(PropDecl);
  1153. WriteIndex(Parent.Name+'.'+Name);
  1154. Writeln('\begin{FPCList}');
  1155. DocNode := Engine.FindDocNode(PropDecl);
  1156. if Assigned(DocNode) and Assigned(DocNode.ShortDescr) then
  1157. begin
  1158. Writeln('\Synopsis');
  1159. WriteDescr(PropDecl, DocNode.ShortDescr);
  1160. end;
  1161. Writeln('\Declaration ');
  1162. StartListing(False);
  1163. WriteLn('Property '+GetDeclaration(True));
  1164. EndListing;
  1165. If Assigned(Parent) then
  1166. begin
  1167. Writeln('\Visibility');
  1168. Writeln(VisibilityNames[Visibility])
  1169. end;
  1170. Writeln('\Access');
  1171. Setlength(S,0);
  1172. If Length(ReadAccessorName) > 0 then
  1173. S:='Read';
  1174. if Length(WriteAccessorName) > 0 then
  1175. begin
  1176. If S<>'' then
  1177. S:=S+',';
  1178. S:=S+'Write';
  1179. end;
  1180. Writeln(S);
  1181. if Assigned(DocNode) and Assigned(DocNode.Descr) then
  1182. begin
  1183. Writeln('\Description');
  1184. WriteDescr(PropDecl);
  1185. end;
  1186. if Assigned(DocNode) and Assigned(DocNode.ErrorsDoc) then
  1187. begin
  1188. Writeln('\Errors');
  1189. WriteDescr(PropDecl, DocNode.ErrorsDoc);
  1190. end;
  1191. WriteSeeAlso(DocNode);
  1192. Writeln('\end{FPCList}');
  1193. WriteExample(DocNode);
  1194. end;
  1195. end;
  1196. Function CompareElements(P1,P2 : Pointer) : Integer;
  1197. begin
  1198. Result:=CompareText(TPasElement(P1).Name,TPasElement(P2).Name);
  1199. end;
  1200. procedure TLaTeXWriter.SortElementList(List : TList);
  1201. begin
  1202. List.Sort(@CompareElements)
  1203. end;
  1204. procedure TLaTeXWriter.WriteLabel(El: TPasElement);
  1205. begin
  1206. WriteLabel(GetLabel(El));
  1207. end;
  1208. procedure TLaTeXWriter.WriteLabel(const s: String);
  1209. begin
  1210. WriteLnF('\label{%s}', [LowerCase(StripTex(s))]);
  1211. end;
  1212. procedure TLaTeXWriter.WriteIndex(El : TPasElement);
  1213. begin
  1214. WriteIndex(El.Name);
  1215. end;
  1216. procedure TLaTeXWriter.WriteIndex(const s : String);
  1217. begin
  1218. Write('\index{');
  1219. Write(EscapeTex(s));
  1220. Writeln('}');
  1221. end;
  1222. procedure TLaTeXWriter.StartListing(Frames: Boolean; const name: String);
  1223. begin
  1224. FInVerbatim:=True;
  1225. if Not LaTexHighLight then
  1226. begin
  1227. Writeln('');
  1228. Writeln('\begin{verbatim}');
  1229. end
  1230. else
  1231. if Frames then
  1232. Writelnf('\begin{lstlisting}{%s}',[StripTex(Name)])
  1233. else
  1234. Writelnf('\begin{lstlisting}[frame=]{%s}',[StripTex(Name)]);
  1235. end;
  1236. procedure TLaTeXWriter.StartListing(Frames : Boolean);
  1237. begin
  1238. StartListing(Frames,'');
  1239. end;
  1240. procedure TLaTeXWriter.EndListing;
  1241. begin
  1242. FInVerbatim:=False;
  1243. If LaTexHighLight then
  1244. Writeln('\end{lstlisting}')
  1245. else
  1246. Writeln('\end{verbatim}')
  1247. end;
  1248. procedure TLatexWriter.WriteCommentLine;
  1249. const
  1250. CommentLine =
  1251. '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%';
  1252. begin
  1253. Writeln(CommentLine);
  1254. end;
  1255. procedure TLatexWriter.WriteComment(Comment : String);
  1256. begin
  1257. Write('% ');
  1258. Writeln(Comment);
  1259. end;
  1260. procedure TLatexWriter.StartSection(SectionName : String; SectionLabel : String);
  1261. begin
  1262. StartSection(SectionName);
  1263. WriteLabel(SectionLabel);
  1264. end;
  1265. procedure TLatexWriter.StartSection(SectionName : String);
  1266. begin
  1267. Writeln('');
  1268. WriteCommentLine;
  1269. WriteComment(SectionName);
  1270. Writeln('\section{'+EscapeTex(SectionName)+'}');
  1271. end;
  1272. procedure TLatexWriter.StartSubSection(SubSectionName : String; SubSectionLabel : String);
  1273. begin
  1274. StartSubSection(SubSectionName);
  1275. WriteLabel(SubsectionLabel);
  1276. end;
  1277. procedure TLatexWriter.StartSubSection(SubSectionName : String);
  1278. begin
  1279. Writeln('');
  1280. WriteComment(SubsectionName);
  1281. Writeln('\subsection{'+EscapeTex(SubSectionName)+'}');
  1282. end;
  1283. procedure TLatexWriter.StartChapter(ChapterName : String; ChapterLabel : String);
  1284. begin
  1285. StartChapter(ChapterName);
  1286. WriteLabel(ChapterLabel);
  1287. end;
  1288. procedure TLatexWriter.StartChapter(ChapterName : String);
  1289. begin
  1290. Writeln('');
  1291. WriteCommentLine;
  1292. WriteComment(ChapterName);
  1293. WriteCommentLine;
  1294. Writeln('\chapter{'+EscapeTex(ChapterName)+'}');
  1295. end;
  1296. procedure CreateLaTeXDocForPackage(APackage: TPasPackage; AEngine: TFPDocEngine);
  1297. var
  1298. Writer: TLaTeXWriter;
  1299. begin
  1300. Writer := TLaTeXWriter.Create(APackage, AEngine);
  1301. try
  1302. Writer.WriteDoc;
  1303. finally
  1304. Writer.Free;
  1305. end;
  1306. end;
  1307. end.
  1308. {
  1309. $Log$
  1310. Revision 1.7 2004-11-15 18:01:16 michael
  1311. + Example fixes, and more escape seqences
  1312. Revision 1.6 2004/07/23 23:39:48 michael
  1313. + Some fixes in verbatim writing
  1314. Revision 1.5 2004/06/06 10:53:02 michael
  1315. + Added Topic support
  1316. Revision 1.4 2003/03/18 19:28:44 michael
  1317. + Some changes to output handling, more suitable for tex output
  1318. Revision 1.3 2003/03/18 19:12:29 michael
  1319. + More EscapeTex calls needed
  1320. Revision 1.2 2003/03/18 01:11:51 michael
  1321. + Some fixes to deal with illegal tex characters
  1322. Revision 1.1 2003/03/17 23:03:20 michael
  1323. + Initial import in CVS
  1324. Revision 1.13 2003/03/13 22:02:13 sg
  1325. * New version with many bugfixes and our own parser (now independent of the
  1326. compiler source)
  1327. Revision 1.12 2002/10/20 22:49:31 michael
  1328. + Sorted all overviews. Added table with enumeration values for enumerated types.
  1329. Revision 1.11 2002/05/24 00:13:22 sg
  1330. * much improved new version, including many linking and output fixes
  1331. Revision 1.10 2002/03/12 10:58:36 sg
  1332. * reworked linking engine and internal structure
  1333. Revision 1.9 2002/01/20 11:19:55 michael
  1334. + Added link attribute and property to TFPElement
  1335. Revision 1.8 2002/01/08 13:00:06 michael
  1336. + Added correct array handling and syntax highlighting is now optional
  1337. Revision 1.7 2002/01/08 08:22:40 michael
  1338. + Implemented latex writer
  1339. Revision 1.6 2001/12/17 14:41:42 michael
  1340. + Split out of latex writer
  1341. Revision 1.5 2001/12/17 13:41:18 jonas
  1342. * OsPathSeparator -> PathDelim
  1343. }