dw_latex.pp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  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. FImageDir: 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 DescrWriteImageEl(const AFileName, ACaption, ALinkName : DOMString); override;
  77. procedure DescrWriteFileEl(const AText: DOMString); override;
  78. procedure DescrWriteKeywordEl(const AText: DOMString); override;
  79. procedure DescrWriteVarEl(const AText: DOMString); override;
  80. procedure DescrBeginLink(const AId: DOMString); override;
  81. procedure DescrEndLink; override;
  82. procedure DescrWriteLinebreak; override;
  83. procedure DescrBeginParagraph; override;
  84. procedure DescrBeginCode(HasBorder: Boolean; const AHighlighterName: String); override;
  85. procedure DescrWriteCodeLine(const ALine: String); override;
  86. procedure DescrEndCode; override;
  87. procedure DescrEndParagraph; override;
  88. procedure DescrBeginOrderedList; override;
  89. procedure DescrEndOrderedList; override;
  90. procedure DescrBeginUnorderedList; override;
  91. procedure DescrEndUnorderedList; override;
  92. procedure DescrBeginDefinitionList; override;
  93. procedure DescrEndDefinitionList; override;
  94. procedure DescrBeginListItem; override;
  95. procedure DescrEndListItem; override;
  96. procedure DescrBeginDefinitionTerm; override;
  97. procedure DescrEndDefinitionTerm; override;
  98. procedure DescrBeginDefinitionEntry; override;
  99. procedure DescrEndDefinitionEntry; override;
  100. procedure DescrBeginSectionTitle; override;
  101. procedure DescrBeginSectionBody; override;
  102. procedure DescrEndSection; override;
  103. procedure DescrBeginRemark; override;
  104. procedure DescrEndRemark; override;
  105. procedure DescrBeginTable(ColCount: Integer; HasBorder: Boolean); override;
  106. procedure DescrEndTable; override;
  107. procedure DescrBeginTableCaption; override;
  108. procedure DescrEndTableCaption; override;
  109. procedure DescrBeginTableHeadRow; override;
  110. procedure DescrEndTableHeadRow; override;
  111. procedure DescrBeginTableRow; override;
  112. procedure DescrEndTableRow; override;
  113. procedure DescrBeginTableCell; override;
  114. procedure DescrEndTableCell; override;
  115. // TFPDocWriter class methods
  116. Function InterPretOption(Const Cmd,Arg : String) : boolean; override;
  117. Property ImageDir : String Read FImageDir Write FImageDir;
  118. end;
  119. function TLaTeXWriter.GetLabel(AElement: TPasElement): String;
  120. var
  121. i: Integer;
  122. begin
  123. if AElement.ClassType = TPasUnresolvedTypeRef then
  124. Result := Engine.ResolveLink(Module, AElement.Name)
  125. else
  126. begin
  127. Result := AElement.PathName;
  128. Result := LowerCase(Copy(Result, 2, Length(Result) - 1));
  129. end;
  130. for i := 1 to Length(Result) do
  131. if Result[i] = '.' then
  132. Result[i] := ':';
  133. end;
  134. Function TLatexWriter.EscapeText(S : String) : String;
  135. var
  136. i: Integer;
  137. begin
  138. if FInVerBatim=True then
  139. Result:=S
  140. else
  141. begin
  142. SetLength(Result, 0);
  143. for i := 1 to Length(S) do
  144. case S[i] of
  145. '&','{','}','#','_','$','%': // Escape these characters
  146. Result := Result + '\' + S[i];
  147. '~','^':
  148. Result := Result + '\'+S[i]+' ';
  149. '\':
  150. Result:=Result+'$\backslash$'
  151. else
  152. Result := Result + S[i];
  153. end;
  154. end;
  155. end;
  156. Function TLatexWriter.StripText(S : String) : String;
  157. var
  158. I: Integer;
  159. begin
  160. SetLength(Result, 0);
  161. for i := 1 to Length(S) do
  162. If not (S[i] in ['&','{','}','#','_','$','%','''','~','^', '\']) then
  163. Result := Result + S[i];
  164. end;
  165. procedure TLaTeXWriter.DescrBeginBold;
  166. begin
  167. Write('\textbf{');
  168. end;
  169. procedure TLaTeXWriter.DescrEndBold;
  170. begin
  171. Write('}');
  172. end;
  173. procedure TLaTeXWriter.DescrBeginItalic;
  174. begin
  175. Write('\textit{');
  176. end;
  177. procedure TLaTeXWriter.DescrEndItalic;
  178. begin
  179. Write('}');
  180. end;
  181. procedure TLaTeXWriter.DescrBeginEmph;
  182. begin
  183. Write('\emph{');
  184. end;
  185. procedure TLaTeXWriter.DescrEndEmph;
  186. begin
  187. Write('}');
  188. end;
  189. procedure TLaTeXWriter.DescrWriteImageEl(const AFileName, ACaption, ALinkName : DOMString);
  190. Var
  191. FN : String;
  192. L : Integer;
  193. begin
  194. Writeln('\begin{figure}[ht]%');
  195. Writeln('\begin{center}');
  196. If (ACaption<>ACaption) then
  197. Writeln(Format('\caption{%s}',[EscapeText(ACaption)]));
  198. If (ALinkName<>'') then
  199. WriteLabel('fig:'+ALinkName);
  200. FN:=ImageDir;
  201. L:=Length(FN);
  202. If (L>0) and (FN[l]<>'/') then
  203. FN:=FN+'/';
  204. FN:=FN+AFileName;
  205. Writeln('\epsfig{file='+FN+'}');
  206. Writeln('\end{center}');
  207. Writeln('\end{figure}');
  208. end;
  209. procedure TLaTeXWriter.DescrWriteFileEl(const AText: DOMString);
  210. begin
  211. Write('\file{');
  212. DescrWriteText(AText);
  213. Write('}');
  214. end;
  215. procedure TLaTeXWriter.DescrWriteKeywordEl(const AText: DOMString);
  216. begin
  217. Write('\textbf{\\ttfamily ');
  218. DescrWriteText(AText);
  219. Write('}');
  220. end;
  221. procedure TLaTeXWriter.DescrWriteVarEl(const AText: DOMString);
  222. begin
  223. Write('\var{');
  224. DescrWriteText(AText);
  225. Write('}');
  226. end;
  227. procedure TLaTeXWriter.DescrBeginLink(const AId: DOMString);
  228. begin
  229. FLink := Engine.ResolveLink(Module, AId);
  230. // System.WriteLn('Link "', AId, '" => ', FLink);
  231. end;
  232. procedure TLaTeXWriter.DescrEndLink;
  233. begin
  234. WriteF(' (\pageref{%s})',[StripText(Flink)]);
  235. end;
  236. procedure TLaTeXWriter.DescrWriteLinebreak;
  237. begin
  238. WriteLn('\\');
  239. end;
  240. procedure TLaTeXWriter.DescrBeginParagraph;
  241. begin
  242. // Do nothing
  243. end;
  244. procedure TLaTeXWriter.DescrEndParagraph;
  245. begin
  246. WriteLn('');
  247. WriteLn('');
  248. end;
  249. procedure TLaTeXWriter.DescrBeginCode(HasBorder: Boolean;
  250. const AHighlighterName: String);
  251. begin
  252. StartListing(HasBorder,'');
  253. end;
  254. procedure TLaTeXWriter.DescrWriteCodeLine(const ALine: String);
  255. begin
  256. WriteLn(ALine);
  257. end;
  258. procedure TLaTeXWriter.DescrEndCode;
  259. begin
  260. EndListing
  261. end;
  262. procedure TLaTeXWriter.DescrBeginOrderedList;
  263. begin
  264. WriteLn('\begin{enumerate}');
  265. end;
  266. procedure TLaTeXWriter.DescrEndOrderedList;
  267. begin
  268. WriteLn('\end{enumerate}');
  269. end;
  270. procedure TLaTeXWriter.DescrBeginUnorderedList;
  271. begin
  272. WriteLn('\begin{itemize}');
  273. end;
  274. procedure TLaTeXWriter.DescrEndUnorderedList;
  275. begin
  276. WriteLn('\end{itemize}');
  277. end;
  278. procedure TLaTeXWriter.DescrBeginDefinitionList;
  279. begin
  280. WriteLn('\begin{description}');
  281. end;
  282. procedure TLaTeXWriter.DescrEndDefinitionList;
  283. begin
  284. WriteLn('\end{description}');
  285. end;
  286. procedure TLaTeXWriter.DescrBeginListItem;
  287. begin
  288. Write('\item ');
  289. end;
  290. procedure TLaTeXWriter.DescrEndListItem;
  291. begin
  292. WriteLn('');
  293. end;
  294. procedure TLaTeXWriter.DescrBeginDefinitionTerm;
  295. begin
  296. Write('\item[');
  297. end;
  298. procedure TLaTeXWriter.DescrEndDefinitionTerm;
  299. begin
  300. WriteLn(']');
  301. end;
  302. procedure TLaTeXWriter.DescrBeginDefinitionEntry;
  303. begin
  304. // Do nothing
  305. end;
  306. procedure TLaTeXWriter.DescrEndDefinitionEntry;
  307. begin
  308. WriteLn('');
  309. end;
  310. procedure TLaTeXWriter.DescrBeginSectionTitle;
  311. begin
  312. Write('\subsection{');
  313. end;
  314. procedure TLaTeXWriter.DescrBeginSectionBody;
  315. begin
  316. WriteLn('}');
  317. end;
  318. procedure TLaTeXWriter.DescrEndSection;
  319. begin
  320. // Do noting
  321. end;
  322. procedure TLaTeXWriter.DescrBeginRemark;
  323. begin
  324. WriteLn('\begin{remark}');
  325. end;
  326. procedure TLaTeXWriter.DescrEndRemark;
  327. begin
  328. WriteLn('\end{remark}');
  329. end;
  330. procedure TLaTeXWriter.DescrBeginTable(ColCount: Integer; HasBorder: Boolean);
  331. var
  332. i: Integer;
  333. begin
  334. // !!!: How do we set the border?
  335. Write('\begin{FPCltable}{');
  336. for i := 1 to ColCount do
  337. Write('l');
  338. write('}{');
  339. TableCaptionWritten:=False;
  340. end;
  341. procedure TLaTeXWriter.DescrEndTable;
  342. begin
  343. WriteLn('\end{FPCltable}');
  344. end;
  345. procedure TLaTeXWriter.DescrBeginTableCaption;
  346. begin
  347. // Do nothing.
  348. end;
  349. procedure TLaTeXWriter.DescrEndTableCaption;
  350. begin
  351. Write('}{table');
  352. Inc(FTableCount);
  353. Write(IntToStr(FTableCount));
  354. Writeln('}');
  355. TableCaptionWritten := True;
  356. end;
  357. procedure TLaTeXWriter.DescrBeginTableHeadRow;
  358. begin
  359. if not TableCaptionWritten then
  360. DescrEndTableCaption;
  361. TableRowStartFlag := True;
  362. end;
  363. procedure TLaTeXWriter.DescrEndTableHeadRow;
  364. begin
  365. WriteLn('\\ \hline');
  366. end;
  367. procedure TLaTeXWriter.DescrBeginTableRow;
  368. begin
  369. if not TableCaptionWritten then
  370. DescrEndTableCaption;
  371. TableRowStartFlag := True;
  372. end;
  373. procedure TLaTeXWriter.DescrEndTableRow;
  374. begin
  375. WriteLn('\\');
  376. end;
  377. procedure TLaTeXWriter.DescrBeginTableCell;
  378. begin
  379. if TableRowStartFlag then
  380. TableRowStartFlag := False
  381. else
  382. Write(' & ');
  383. end;
  384. procedure TLaTeXWriter.DescrEndTableCell;
  385. begin
  386. // Do nothing
  387. end;
  388. procedure TLaTeXWriter.WriteLabel(const s: String);
  389. begin
  390. WriteLnF('\label{%s}', [LowerCase(StripText(s))]);
  391. end;
  392. procedure TLaTeXWriter.WriteIndex(const s : String);
  393. begin
  394. Write('\index{');
  395. Write(EscapeText(s));
  396. Writeln('}');
  397. end;
  398. procedure TLaTeXWriter.StartListing(Frames: Boolean; const name: String);
  399. begin
  400. FInVerbatim:=True;
  401. if Not LaTexHighLight then
  402. begin
  403. Writeln('');
  404. Writeln('\begin{verbatim}');
  405. end
  406. else
  407. if Frames then
  408. Writelnf('\begin{lstlisting}{%s}',[StripText(Name)])
  409. else
  410. Writelnf('\begin{lstlisting}[frame=]{%s}',[StripText(Name)]);
  411. end;
  412. procedure TLaTeXWriter.EndListing;
  413. begin
  414. FInVerbatim:=False;
  415. If LaTexHighLight then
  416. Writeln('\end{lstlisting}')
  417. else
  418. Writeln('\end{verbatim}')
  419. end;
  420. procedure TLatexWriter.WriteCommentLine;
  421. const
  422. CommentLine =
  423. '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%';
  424. begin
  425. Writeln(CommentLine);
  426. end;
  427. procedure TLatexWriter.WriteComment(Comment : String);
  428. begin
  429. Write('% ');
  430. Writeln(Comment);
  431. end;
  432. procedure TLatexWriter.StartChapter(ChapterName : String);
  433. begin
  434. WriteCommentLine;
  435. WriteComment(ChapterName);
  436. WriteCommentLine;
  437. Writeln('\chapter{'+EscapeText(ChapterName)+'}');
  438. end;
  439. procedure TLatexWriter.StartSection(SectionName : String);
  440. begin
  441. WriteCommentLine;
  442. WriteComment(SectionName);
  443. Writeln('\section{'+EscapeText(SectionName)+'}');
  444. end;
  445. procedure TLatexWriter.StartSubSection(SubSectionName : String);
  446. begin
  447. WriteComment(SubSectionName);
  448. Writeln('\subsection{'+EscapeText(SubSectionName)+'}');
  449. end;
  450. procedure TLatexWriter.StartSubSubSection(SubSubSectionName : String);
  451. begin
  452. Writeln('\subsubsection{'+EscapeText(SubSubSectionName)+'}');
  453. end;
  454. procedure CreateLaTeXDocForPackage(APackage: TPasPackage; AEngine: TFPDocEngine);
  455. var
  456. Writer: TLaTeXWriter;
  457. begin
  458. Writer := TLaTeXWriter.Create(APackage, AEngine);
  459. try
  460. Writer.WriteDoc;
  461. finally
  462. Writer.Free;
  463. end;
  464. end;
  465. Procedure TLatexWriter.StartProcedure;
  466. begin
  467. Writeln('\begin{FPCList}');
  468. InList:=True;
  469. end;
  470. Procedure TLatexWriter.StartSynopsis;
  471. begin
  472. Writeln('\Synopsis');
  473. end;
  474. Procedure TLatexWriter.StartDeclaration;
  475. begin
  476. Writeln('\Declaration ');
  477. end;
  478. Procedure TLatexWriter.StartVisibility;
  479. begin
  480. Writeln('\Visibility');
  481. end;
  482. Procedure TLatexWriter.StartDescription;
  483. begin
  484. Writeln('\Description');
  485. end;
  486. Procedure TLatexWriter.StartErrors;
  487. begin
  488. Writeln('\Errors');
  489. end;
  490. Procedure TLatexWriter.StartAccess;
  491. begin
  492. Writeln('\Access')
  493. end;
  494. Procedure TLatexWriter.EndProcedure;
  495. begin
  496. InList:=False;
  497. Writeln('\end{FPCList}');
  498. end;
  499. Procedure TLatexWriter.StartProperty;
  500. begin
  501. Writeln('\begin{FPCList}');
  502. InList:=True;
  503. end;
  504. Procedure TLatexWriter.EndProperty;
  505. begin
  506. InList:=False;
  507. Writeln('\end{FPCList}');
  508. end;
  509. procedure TLateXWriter.WriteExampleFile(FN : String);
  510. begin
  511. If (FN<>'') then
  512. WritelnF('\FPCexample{%s}', [ChangeFileExt(FN,'')]);
  513. end;
  514. procedure TLatexWriter.StartOverview(WithAccess : Boolean);
  515. begin
  516. If WithAccess then
  517. begin
  518. WriteLn('\begin{tabularx}{\textwidth}{lllX}');
  519. WriteLnF('%s & %s & %s & %s \\ \hline',[EscapeText(SDocPage), EscapeText(SDocProperty), EscapeText(SDocAccess), EscapeText(SDocDescription)])
  520. end
  521. else
  522. begin
  523. WriteLn('\begin{tabularx}{\textwidth}{llX}');
  524. WriteLnF('%s & %s & %s \\ \hline',[EscapeText(SDocPage), EscapeText(SDocProperty), EscapeText(SDocDescription)])
  525. end;
  526. end;
  527. procedure TLatexWriter.EndOverview;
  528. begin
  529. WriteLn('\hline');
  530. WriteLn('\end{tabularx}');
  531. end;
  532. procedure TLatexWriter.WriteOverviewMember(ALabel,AName,Access,ADescr : String);
  533. begin
  534. WriteLnF('\pageref{%s} & %s & %s & %s \\',[ALabel,EscapeText(AName),Access,ADescr]);
  535. end;
  536. procedure TLatexWriter.WriteOverviewMember(ALabel,AName,ADescr : String);
  537. begin
  538. WriteLnF('\pageref{%s} & %s & %s \\',[ALabel,EscapeText(AName),ADescr]);
  539. end;
  540. class function TLaTeXWriter.FileNameExtension: String;
  541. begin
  542. Result:=TexExtension;
  543. end;
  544. Procedure TLatexWriter.StartSeeAlso;
  545. begin
  546. If not InList then
  547. begin
  548. Writeln('');
  549. Writeln('\begin{FPCList}');
  550. end;
  551. Writeln('\SeeAlso');
  552. end;
  553. procedure TLaTeXWriter.EndSeealso;
  554. begin
  555. If Not InList then
  556. Writeln('\end{FPCList}');
  557. end;
  558. procedure TLatexWriter.StartUnitOverview(AModuleName,AModuleLabel : String);
  559. begin
  560. WriteLnF('\begin{FPCltable}{lr}{%s}{%s:0units}',
  561. [Format(SDocUsedUnitsByUnitXY, [EscapeText(AModuleName)]), StripText(AModuleName)]);
  562. WriteLn('Name & Page \\ \hline');
  563. end;
  564. procedure TLatexWriter.WriteUnitEntry(UnitRef : TPasType);
  565. begin
  566. WriteLnF('%s\index{unit!%s} & \pageref{%s} \\',
  567. [EscapeText(UnitRef.Name), EscapeText(UnitRef.Name), StripText(GetLabel(UnitRef))]);
  568. end;
  569. procedure TLatexWriter.EndUnitOverview;
  570. begin
  571. WriteLn('\end{FPCltable}');
  572. end;
  573. Function TLatexWriter.InterPretOption(Const Cmd,Arg : String) : boolean;
  574. begin
  575. Result:=True;
  576. if (cmd= '--latex-highlight') then
  577. LatexHighLight:=True
  578. else if Cmd = '--latex-extension' then
  579. TexExtension:=Arg
  580. else if Cmd = '--image-dir' then
  581. ImageDir:=Arg
  582. else
  583. Result:=False;
  584. end;
  585. initialization
  586. // Do not localize.
  587. RegisterWriter(TLaTeXWriter,'latex','Latex output using fpc.sty class.');
  588. finalization
  589. UnRegisterWriter('latex');
  590. end.