dw_latex.pp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  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. {$mode objfpc}
  14. {$H+}
  15. unit dw_LaTeX;
  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, dwLinear;
  24. Type
  25. { TLaTeXWriter }
  26. TLaTeXWriter = class(TLinearWriter)
  27. protected
  28. FLink: String;
  29. FTableCount : Integer;
  30. FInVerbatim : Boolean;
  31. Inlist,
  32. TableRowStartFlag,
  33. TableCaptionWritten: Boolean;
  34. // Linear documentation methods overrides;
  35. procedure WriteLabel(Const S : String); override;
  36. procedure WriteIndex(Const S : String); override;
  37. Procedure WriteExampleFile(FN : String); override;
  38. Procedure StartProcedure; override;
  39. Procedure EndProcedure; override;
  40. Procedure StartProperty; override;
  41. Procedure EndProperty; override;
  42. Procedure StartSynopsis; override;
  43. Procedure StartDeclaration; override;
  44. Procedure StartVisibility; override;
  45. Procedure StartDescription; override;
  46. Procedure StartAccess; override;
  47. Procedure StartErrors; override;
  48. Procedure StartSeealso; override;
  49. Procedure EndSeealso; override;
  50. procedure StartUnitOverview(AModuleName,AModuleLabel : String);override;
  51. procedure WriteUnitEntry(UnitRef : TPasType); override;
  52. Procedure EndUnitOverview; override;
  53. function GetLabel(AElement: TPasElement): String; override;
  54. procedure StartListing(Frames: Boolean; const name: String); override;
  55. procedure EndListing; override;
  56. Function EscapeText(S : String) : String; override;
  57. Function StripText(S : String) : String; override;
  58. procedure WriteCommentLine; override;
  59. procedure WriteComment(Comment : String);override;
  60. procedure StartSection(SectionName : String);override;
  61. procedure StartSubSection(SubSectionName : String);override;
  62. procedure StartSubSubSection(SubSubSectionName : String);override;
  63. procedure StartChapter(ChapterName : String); override;
  64. procedure StartOverview(WithAccess : Boolean); override;
  65. procedure EndOverview; override;
  66. procedure WriteOverviewMember(ALabel,AName,Access,ADescr : String); override;
  67. procedure WriteOverviewMember(ALabel,AName,ADescr : String); override;
  68. Class Function FileNameExtension : String; override;
  69. // Description node conversion
  70. procedure DescrBeginBold; override;
  71. procedure DescrEndBold; override;
  72. procedure DescrBeginItalic; override;
  73. procedure DescrEndItalic; override;
  74. procedure DescrBeginEmph; override;
  75. procedure DescrEndEmph; override;
  76. procedure DescrWriteFileEl(const AText: DOMString); override;
  77. procedure DescrWriteKeywordEl(const AText: DOMString); override;
  78. procedure DescrWriteVarEl(const AText: DOMString); override;
  79. procedure DescrBeginLink(const AId: DOMString); override;
  80. procedure DescrEndLink; override;
  81. procedure DescrWriteLinebreak; override;
  82. procedure DescrBeginParagraph; override;
  83. procedure DescrBeginCode(HasBorder: Boolean; const AHighlighterName: String); override;
  84. procedure DescrWriteCodeLine(const ALine: String); override;
  85. procedure DescrEndCode; override;
  86. procedure DescrEndParagraph; override;
  87. procedure DescrBeginOrderedList; override;
  88. procedure DescrEndOrderedList; override;
  89. procedure DescrBeginUnorderedList; override;
  90. procedure DescrEndUnorderedList; override;
  91. procedure DescrBeginDefinitionList; override;
  92. procedure DescrEndDefinitionList; override;
  93. procedure DescrBeginListItem; override;
  94. procedure DescrEndListItem; override;
  95. procedure DescrBeginDefinitionTerm; override;
  96. procedure DescrEndDefinitionTerm; override;
  97. procedure DescrBeginDefinitionEntry; override;
  98. procedure DescrEndDefinitionEntry; override;
  99. procedure DescrBeginSectionTitle; override;
  100. procedure DescrBeginSectionBody; override;
  101. procedure DescrEndSection; override;
  102. procedure DescrBeginRemark; override;
  103. procedure DescrEndRemark; override;
  104. procedure DescrBeginTable(ColCount: Integer; HasBorder: Boolean); override;
  105. procedure DescrEndTable; override;
  106. procedure DescrBeginTableCaption; override;
  107. procedure DescrEndTableCaption; override;
  108. procedure DescrBeginTableHeadRow; override;
  109. procedure DescrEndTableHeadRow; override;
  110. procedure DescrBeginTableRow; override;
  111. procedure DescrEndTableRow; override;
  112. procedure DescrBeginTableCell; override;
  113. procedure DescrEndTableCell; override;
  114. end;
  115. function TLaTeXWriter.GetLabel(AElement: TPasElement): String;
  116. var
  117. i: Integer;
  118. begin
  119. if AElement.ClassType = TPasUnresolvedTypeRef then
  120. Result := Engine.ResolveLink(Module, AElement.Name)
  121. else
  122. begin
  123. Result := AElement.PathName;
  124. Result := LowerCase(Copy(Result, 2, Length(Result) - 1));
  125. end;
  126. for i := 1 to Length(Result) do
  127. if Result[i] = '.' then
  128. Result[i] := ':';
  129. end;
  130. Function TLatexWriter.EscapeText(S : String) : String;
  131. var
  132. i: Integer;
  133. begin
  134. if FInVerBatim=True then
  135. Result:=S
  136. else
  137. begin
  138. SetLength(Result, 0);
  139. for i := 1 to Length(S) do
  140. case S[i] of
  141. '&','{','}','#','_','$','%': // Escape these characters
  142. Result := Result + '\' + S[i];
  143. '~','^':
  144. Result := Result + '\'+S[i]+' ';
  145. '\':
  146. Result:=Result+'$\backslash$'
  147. else
  148. Result := Result + S[i];
  149. end;
  150. end;
  151. end;
  152. Function TLatexWriter.StripText(S : String) : String;
  153. var
  154. I: Integer;
  155. begin
  156. SetLength(Result, 0);
  157. for i := 1 to Length(S) do
  158. If not (S[i] in ['&','{','}','#','_','$','%','''','~','^', '\']) then
  159. Result := Result + S[i];
  160. end;
  161. procedure TLaTeXWriter.DescrBeginBold;
  162. begin
  163. Write('\textbf{');
  164. end;
  165. procedure TLaTeXWriter.DescrEndBold;
  166. begin
  167. Write('}');
  168. end;
  169. procedure TLaTeXWriter.DescrBeginItalic;
  170. begin
  171. Write('\textit{');
  172. end;
  173. procedure TLaTeXWriter.DescrEndItalic;
  174. begin
  175. Write('}');
  176. end;
  177. procedure TLaTeXWriter.DescrBeginEmph;
  178. begin
  179. Write('\emph{');
  180. end;
  181. procedure TLaTeXWriter.DescrEndEmph;
  182. begin
  183. Write('}');
  184. end;
  185. procedure TLaTeXWriter.DescrWriteFileEl(const AText: DOMString);
  186. begin
  187. Write('\file{');
  188. DescrWriteText(AText);
  189. Write('}');
  190. end;
  191. procedure TLaTeXWriter.DescrWriteKeywordEl(const AText: DOMString);
  192. begin
  193. Write('\textbf{\\ttfamily ');
  194. DescrWriteText(AText);
  195. Write('}');
  196. end;
  197. procedure TLaTeXWriter.DescrWriteVarEl(const AText: DOMString);
  198. begin
  199. Write('\var{');
  200. DescrWriteText(AText);
  201. Write('}');
  202. end;
  203. procedure TLaTeXWriter.DescrBeginLink(const AId: DOMString);
  204. begin
  205. FLink := Engine.ResolveLink(Module, AId);
  206. // System.WriteLn('Link "', AId, '" => ', FLink);
  207. end;
  208. procedure TLaTeXWriter.DescrEndLink;
  209. begin
  210. WriteF(' (\pageref{%s})',[StripText(Flink)]);
  211. end;
  212. procedure TLaTeXWriter.DescrWriteLinebreak;
  213. begin
  214. WriteLn('\\');
  215. end;
  216. procedure TLaTeXWriter.DescrBeginParagraph;
  217. begin
  218. // Do nothing
  219. end;
  220. procedure TLaTeXWriter.DescrEndParagraph;
  221. begin
  222. WriteLn('');
  223. WriteLn('');
  224. end;
  225. procedure TLaTeXWriter.DescrBeginCode(HasBorder: Boolean;
  226. const AHighlighterName: String);
  227. begin
  228. StartListing(HasBorder,'');
  229. end;
  230. procedure TLaTeXWriter.DescrWriteCodeLine(const ALine: String);
  231. begin
  232. WriteLn(ALine);
  233. end;
  234. procedure TLaTeXWriter.DescrEndCode;
  235. begin
  236. EndListing
  237. end;
  238. procedure TLaTeXWriter.DescrBeginOrderedList;
  239. begin
  240. WriteLn('\begin{enumerate}');
  241. end;
  242. procedure TLaTeXWriter.DescrEndOrderedList;
  243. begin
  244. WriteLn('\end{enumerate}');
  245. end;
  246. procedure TLaTeXWriter.DescrBeginUnorderedList;
  247. begin
  248. WriteLn('\begin{itemize}');
  249. end;
  250. procedure TLaTeXWriter.DescrEndUnorderedList;
  251. begin
  252. WriteLn('\end{itemize}');
  253. end;
  254. procedure TLaTeXWriter.DescrBeginDefinitionList;
  255. begin
  256. WriteLn('\begin{description}');
  257. end;
  258. procedure TLaTeXWriter.DescrEndDefinitionList;
  259. begin
  260. WriteLn('\end{description}');
  261. end;
  262. procedure TLaTeXWriter.DescrBeginListItem;
  263. begin
  264. Write('\item ');
  265. end;
  266. procedure TLaTeXWriter.DescrEndListItem;
  267. begin
  268. WriteLn('');
  269. end;
  270. procedure TLaTeXWriter.DescrBeginDefinitionTerm;
  271. begin
  272. Write('\item[');
  273. end;
  274. procedure TLaTeXWriter.DescrEndDefinitionTerm;
  275. begin
  276. WriteLn(']');
  277. end;
  278. procedure TLaTeXWriter.DescrBeginDefinitionEntry;
  279. begin
  280. // Do nothing
  281. end;
  282. procedure TLaTeXWriter.DescrEndDefinitionEntry;
  283. begin
  284. WriteLn('');
  285. end;
  286. procedure TLaTeXWriter.DescrBeginSectionTitle;
  287. begin
  288. Write('\subsection{');
  289. end;
  290. procedure TLaTeXWriter.DescrBeginSectionBody;
  291. begin
  292. WriteLn('}');
  293. end;
  294. procedure TLaTeXWriter.DescrEndSection;
  295. begin
  296. // Do noting
  297. end;
  298. procedure TLaTeXWriter.DescrBeginRemark;
  299. begin
  300. WriteLn('\begin{remark}');
  301. end;
  302. procedure TLaTeXWriter.DescrEndRemark;
  303. begin
  304. WriteLn('\end{remark}');
  305. end;
  306. procedure TLaTeXWriter.DescrBeginTable(ColCount: Integer; HasBorder: Boolean);
  307. var
  308. i: Integer;
  309. begin
  310. // !!!: How do we set the border?
  311. Write('\begin{FPCltable}{');
  312. for i := 1 to ColCount do
  313. Write('l');
  314. write('}{');
  315. TableCaptionWritten:=False;
  316. end;
  317. procedure TLaTeXWriter.DescrEndTable;
  318. begin
  319. WriteLn('\end{FPCltable}');
  320. end;
  321. procedure TLaTeXWriter.DescrBeginTableCaption;
  322. begin
  323. // Do nothing.
  324. end;
  325. procedure TLaTeXWriter.DescrEndTableCaption;
  326. begin
  327. Write('}{table');
  328. Inc(FTableCount);
  329. Write(IntToStr(FTableCount));
  330. Writeln('}');
  331. TableCaptionWritten := True;
  332. end;
  333. procedure TLaTeXWriter.DescrBeginTableHeadRow;
  334. begin
  335. if not TableCaptionWritten then
  336. DescrEndTableCaption;
  337. TableRowStartFlag := True;
  338. end;
  339. procedure TLaTeXWriter.DescrEndTableHeadRow;
  340. begin
  341. WriteLn('\\ \hline');
  342. end;
  343. procedure TLaTeXWriter.DescrBeginTableRow;
  344. begin
  345. if not TableCaptionWritten then
  346. DescrEndTableCaption;
  347. TableRowStartFlag := True;
  348. end;
  349. procedure TLaTeXWriter.DescrEndTableRow;
  350. begin
  351. WriteLn('\\');
  352. end;
  353. procedure TLaTeXWriter.DescrBeginTableCell;
  354. begin
  355. if TableRowStartFlag then
  356. TableRowStartFlag := False
  357. else
  358. Write(' & ');
  359. end;
  360. procedure TLaTeXWriter.DescrEndTableCell;
  361. begin
  362. // Do nothing
  363. end;
  364. procedure TLaTeXWriter.WriteLabel(const s: String);
  365. begin
  366. WriteLnF('\label{%s}', [LowerCase(StripText(s))]);
  367. end;
  368. procedure TLaTeXWriter.WriteIndex(const s : String);
  369. begin
  370. Write('\index{');
  371. Write(EscapeText(s));
  372. Writeln('}');
  373. end;
  374. procedure TLaTeXWriter.StartListing(Frames: Boolean; const name: String);
  375. begin
  376. FInVerbatim:=True;
  377. if Not LaTexHighLight then
  378. begin
  379. Writeln('');
  380. Writeln('\begin{verbatim}');
  381. end
  382. else
  383. if Frames then
  384. Writelnf('\begin{lstlisting}{%s}',[StripText(Name)])
  385. else
  386. Writelnf('\begin{lstlisting}[frame=]{%s}',[StripText(Name)]);
  387. end;
  388. procedure TLaTeXWriter.EndListing;
  389. begin
  390. FInVerbatim:=False;
  391. If LaTexHighLight then
  392. Writeln('\end{lstlisting}')
  393. else
  394. Writeln('\end{verbatim}')
  395. end;
  396. procedure TLatexWriter.WriteCommentLine;
  397. const
  398. CommentLine =
  399. '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%';
  400. begin
  401. Writeln(CommentLine);
  402. end;
  403. procedure TLatexWriter.WriteComment(Comment : String);
  404. begin
  405. Write('% ');
  406. Writeln(Comment);
  407. end;
  408. procedure TLatexWriter.StartChapter(ChapterName : String);
  409. begin
  410. WriteCommentLine;
  411. WriteComment(ChapterName);
  412. WriteCommentLine;
  413. Writeln('\chapter{'+EscapeText(ChapterName)+'}');
  414. end;
  415. procedure TLatexWriter.StartSection(SectionName : String);
  416. begin
  417. WriteCommentLine;
  418. WriteComment(SectionName);
  419. WriteComment('\section{'+EscapeText(SectionName)+'}');
  420. end;
  421. procedure TLatexWriter.StartSubSection(SubSectionName : String);
  422. begin
  423. WriteComment(SubSectionName);
  424. Write('\subsection{'+EscapeText(SubSectionName)+'}');
  425. end;
  426. procedure TLatexWriter.StartSubSubSection(SubSubSectionName : String);
  427. begin
  428. Write('\subsubsection{'+EscapeText(SubSubSectionName)+'}');
  429. end;
  430. procedure CreateLaTeXDocForPackage(APackage: TPasPackage; AEngine: TFPDocEngine);
  431. var
  432. Writer: TLaTeXWriter;
  433. begin
  434. Writer := TLaTeXWriter.Create(APackage, AEngine);
  435. try
  436. Writer.WriteDoc;
  437. finally
  438. Writer.Free;
  439. end;
  440. end;
  441. Procedure TLatexWriter.StartProcedure;
  442. begin
  443. Writeln('\begin{FPCList}');
  444. InList:=True;
  445. end;
  446. Procedure TLatexWriter.StartSynopsis;
  447. begin
  448. Writeln('\Synopsis');
  449. end;
  450. Procedure TLatexWriter.StartDeclaration;
  451. begin
  452. Writeln('\Declaration ');
  453. end;
  454. Procedure TLatexWriter.StartVisibility;
  455. begin
  456. Writeln('\Visibility');
  457. end;
  458. Procedure TLatexWriter.StartDescription;
  459. begin
  460. Writeln('\Description');
  461. end;
  462. Procedure TLatexWriter.StartErrors;
  463. begin
  464. Writeln('\Errors');
  465. end;
  466. Procedure TLatexWriter.StartAccess;
  467. begin
  468. Writeln('\Access')
  469. end;
  470. Procedure TLatexWriter.EndProcedure;
  471. begin
  472. InList:=False;
  473. Writeln('\end{FPCList}');
  474. end;
  475. Procedure TLatexWriter.StartProperty;
  476. begin
  477. Writeln('\begin{FPCList}');
  478. InList:=True;
  479. end;
  480. Procedure TLatexWriter.EndProperty;
  481. begin
  482. InList:=False;
  483. Writeln('\end{FPCList}');
  484. end;
  485. procedure TLateXWriter.WriteExampleFile(FN : String);
  486. begin
  487. If (FN<>'') then
  488. WritelnF('\FPCexample{%s}', [ChangeFileExt(FN,'')]);
  489. end;
  490. procedure TLatexWriter.StartOverview(WithAccess : Boolean);
  491. begin
  492. If WithAccess then
  493. begin
  494. WriteLn('\begin{tabularx}{\textwidth}{lllX}');
  495. WriteLnF('%s & %s & %s & %s \\ \hline',[EscapeText(SDocPage), EscapeText(SDocProperty), EscapeText(SDocAccess), EscapeText(SDocDescription)])
  496. end
  497. else
  498. begin
  499. WriteLn('\begin{tabularx}{\textwidth}{llX}');
  500. WriteLnF('%s & %s & %s \\ \hline',[EscapeText(SDocPage), EscapeText(SDocProperty), EscapeText(SDocDescription)])
  501. end;
  502. end;
  503. procedure TLatexWriter.EndOverview;
  504. begin
  505. WriteLn('\hline');
  506. WriteLn('\end{tabularx}');
  507. end;
  508. procedure TLatexWriter.WriteOverviewMember(ALabel,AName,Access,ADescr : String);
  509. begin
  510. WriteLnF('\pageref{%s} & %s & %s & %s \\',[ALabel,AName,Access,ADescr]);
  511. end;
  512. procedure TLatexWriter.WriteOverviewMember(ALabel,AName,ADescr : String);
  513. begin
  514. WriteLnF('\pageref{%s} & %s & %s \\',[ALabel,AName,ADescr]);
  515. end;
  516. function TLaTeXWriter.FileNameExtension: String;
  517. begin
  518. Result:=TexExtension;
  519. end;
  520. Procedure TLatexWriter.StartSeeAlso;
  521. begin
  522. If not InList then
  523. begin
  524. Writeln('');
  525. Writeln('\begin{FPCList}');
  526. end;
  527. Writeln('\SeeAlso');
  528. end;
  529. procedure TLaTeXWriter.EndSeealso;
  530. begin
  531. If Not InList then
  532. Writeln('\end{FPCList}');
  533. end;
  534. procedure TLatexWriter.StartUnitOverview(AModuleName,AModuleLabel : String);
  535. begin
  536. WriteLnF('\begin{FPCltable}{lr}{%s}{%s:0units}',
  537. [Format(SDocUsedUnitsByUnitXY, [AModuleName]), AModuleName]);
  538. WriteLn('Name & Page \\ \hline');
  539. end;
  540. procedure TLatexWriter.WriteUnitEntry(UnitRef : TPasType);
  541. begin
  542. WriteLnF('%s\index{unit!%s} & \pageref{%s} \\',
  543. [UnitRef.Name, UnitRef.Name, StripText(GetLabel(UnitRef))]);
  544. end;
  545. procedure TLatexWriter.EndUnitOverview;
  546. begin
  547. WriteLn('\end{FPCltable}');
  548. end;
  549. end.
  550. {
  551. $Log$
  552. Revision 1.8 2005-01-09 15:59:50 michael
  553. + Split out latex writer to linear and latex writer
  554. Revision 1.7 2004/11/15 18:01:16 michael
  555. + Example fixes, and more escape seqences
  556. Revision 1.6 2004/07/23 23:39:48 michael
  557. + Some fixes in verbatim writing
  558. Revision 1.5 2004/06/06 10:53:02 michael
  559. + Added Topic support
  560. Revision 1.4 2003/03/18 19:28:44 michael
  561. + Some changes to output handling, more suitable for tex output
  562. Revision 1.3 2003/03/18 19:12:29 michael
  563. + More EscapeText calls needed
  564. Revision 1.2 2003/03/18 01:11:51 michael
  565. + Some fixes to deal with illegal tex characters
  566. Revision 1.1 2003/03/17 23:03:20 michael
  567. + Initial import in CVS
  568. Revision 1.13 2003/03/13 22:02:13 sg
  569. * New version with many bugfixes and our own parser (now independent of the
  570. compiler source)
  571. Revision 1.12 2002/10/20 22:49:31 michael
  572. + Sorted all overviews. Added table with enumeration values for enumerated types.
  573. Revision 1.11 2002/05/24 00:13:22 sg
  574. * much improved new version, including many linking and output fixes
  575. Revision 1.10 2002/03/12 10:58:36 sg
  576. * reworked linking engine and internal structure
  577. Revision 1.9 2002/01/20 11:19:55 michael
  578. + Added link attribute and property to TFPElement
  579. Revision 1.8 2002/01/08 13:00:06 michael
  580. + Added correct array handling and syntax highlighting is now optional
  581. Revision 1.7 2002/01/08 08:22:40 michael
  582. + Implemented latex writer
  583. Revision 1.6 2001/12/17 14:41:42 michael
  584. + Split out of latex writer
  585. Revision 1.5 2001/12/17 13:41:18 jonas
  586. * OsPathSeparator -> PathDelim
  587. }