dw_latex.pp 15 KB

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