fptexexport.pp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. unit fptexexport;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, DB, fpdbexport;
  6. Type
  7. TTeXExportOption = (teHeaderRow,teTableEnvironment,teHeaderLine,teTopLine,teBottomLine,teUseWidths,teCreateDocument);
  8. TTeXExportOptions = Set of TTeXExportOption;
  9. TTexTabularEnvironment = (ttTabular,ttTabularX,ttLongtable,ttSuperTabular);
  10. TTexUnits = (tuEm,tuMM);
  11. { TTeXExportFormatSettings }
  12. TTeXExportFormatSettings = Class(TExportFormatSettings)
  13. Private
  14. FOptions : TTeXExportOptions;
  15. FUnits : TTexUnits;
  16. FTabular : TTexTabularEnvironment;
  17. Public
  18. Constructor Create(DoInitSettings : Boolean); override;
  19. Procedure Assign(Source : TPersistent); override;
  20. Published
  21. // Properties
  22. Property Options : TTeXExportOptions Read FOptions Write FOptions;
  23. Property Units : TTexUnits Read FUnits Write FUnits;
  24. Property Tabular : TTexTabularEnvironment Read FTabular Write FTabular;
  25. end;
  26. { TTeXExportFieldItem }
  27. TTeXExportFieldItem = Class(TExportFieldItem)
  28. private
  29. FLineAfter: Boolean;
  30. FLineBefore: Boolean;
  31. FWidth: Integer;
  32. FAlign: TAlignment;
  33. Public
  34. Procedure Assign(Source : TPersistent); override;
  35. Published
  36. Property Width : Integer Read FWidth Write FWidth;
  37. Property Align: TAlignment Read FAlign write FAlign;
  38. Property LineBefore : Boolean Read FLineBefore Write FLineBefore;
  39. Property LineAfter : Boolean Read FLineAfter Write FLineAfter;
  40. end;
  41. { TCustomTeXExporter }
  42. TCustomTeXExporter = Class(TCustomFileExporter)
  43. Private
  44. FCurrentRow : String;
  45. FEO : TTeXExportOptions;
  46. FTD : String; // Tabular(X) Table definition string
  47. FTH : String; // Table header row
  48. FTN : String; // Tabular environment name (for closing)
  49. function GetTeXFormatsettings: TTexExportFormatSettings;
  50. procedure SetTeXFormatSettings(const AValue: TTexExportFormatSettings);
  51. Protected
  52. function EscapeLaTeX(S: String): String;
  53. procedure OutputRow(const ARow: String); virtual;
  54. procedure OutputTableEnd; virtual;
  55. procedure OutputTableStart; virtual;
  56. procedure CloseDocument; virtual;
  57. procedure OpenDocument; virtual;
  58. Function CreateFormatSettings : TCustomExportFormatSettings; override;
  59. Procedure BuildDefaultFieldMap(AMap : TExportFields); override;
  60. Function CreateExportFields : TExportFields; override;
  61. Procedure DoDataHeader; override;
  62. Procedure DoDataFooter; override;
  63. Procedure DoBeforeExecute; override;
  64. Procedure DoAfterExecute; override;
  65. Procedure DoDataRowStart; override;
  66. Procedure ExportField(EF : TExportFieldItem); override;
  67. Procedure DoDataRowEnd; override;
  68. Public
  69. Property FormatSettings : TTexExportFormatSettings Read GetTeXFormatsettings Write SetTeXFormatSettings;
  70. end;
  71. TTeXExporter = Class(TCustomTeXExporter)
  72. Published
  73. Property FileName;
  74. Property Dataset;
  75. Property ExportFields;
  76. Property FromCurrent;
  77. Property RestorePosition;
  78. Property FormatSettings;
  79. Property OnExportRow;
  80. end;
  81. Procedure RegisterTexExportFormat;
  82. Procedure UnRegisterTexExportFormat;
  83. Const
  84. STeXExport = 'TeX export';
  85. STeXExportExt = '.tex';
  86. TabularPackageNames : Array[TTexTabularEnvironment] of string
  87. = ('array','tabularx','longtable','supertabular');
  88. TabularNames : Array[TTexTabularEnvironment] of string
  89. = ('tabular','tabularx','longtable','supertabular');
  90. TeXUnitNames : array[TTexUnits] of string = ('em','cm');
  91. Resourcestring
  92. STeXExportDescr = 'Export to LaTeX table';
  93. implementation
  94. procedure RegisterTexExportFormat;
  95. begin
  96. ExportFormats.RegisterExportFormat(STeXExport,STeXExportDescr,STexExportExt,TTexExporter);
  97. end;
  98. procedure UnRegisterTexExportFormat;
  99. begin
  100. ExportFormats.UnRegisterExportFormat(STeXExport);
  101. end;
  102. { TCustomTeXExporter }
  103. function TCustomTexExporter.EscapeLaTeX(S: String): String;
  104. Var
  105. I,J,L : Integer;
  106. P : Pchar;
  107. begin
  108. I:=1;
  109. J:=1;
  110. Result:='';
  111. L:=Length(S);
  112. P:=PChar(S);
  113. While I<=L do
  114. begin
  115. if (P^ in ['&','{','}','#','_','$','%']) then
  116. begin
  117. Result:=Result+Copy(S,J,I-J)+'\'+P^;
  118. J:=I+1;
  119. end
  120. else if (P^ in ['~','^']) then
  121. begin
  122. Result:=Result+Copy(S,J,I-J)+'\'+P^+' ';
  123. J:=I+1;
  124. end
  125. else if (P^='\') then
  126. begin
  127. Result:=Result+Copy(S,J,I-J)+'$\backslash$';
  128. J:=I+1;
  129. end;
  130. Inc(I);
  131. Inc(P);
  132. end;
  133. Result:=Result+Copy(S,J,I-1);
  134. end;
  135. function TCustomTeXExporter.GetTeXFormatsettings: TTexExportFormatSettings;
  136. begin
  137. Result:=TTexExportFormatSettings(Inherited FormatSettings)
  138. end;
  139. procedure TCustomTeXExporter.OutputRow(const ARow: String);
  140. begin
  141. Writeln(TextFile,ARow);
  142. end;
  143. procedure TCustomTeXExporter.BuildDefaultFieldMap(AMap: TExportFields);
  144. Const
  145. FieldWidths : Array[TFieldType] of integer
  146. = (-1,0,3,10,5,
  147. 1,20,20,20,10,8,20,
  148. 0,0,10,0,0,0,0,
  149. 0,0,0,0,0,
  150. 0,0,0,0,0,
  151. 0,0,0,0,0,
  152. 0,0,0,0,0,0,
  153. 0,0,10,4,1,20);
  154. Var
  155. I : Integer;
  156. FL : TTexExportFieldItem;
  157. F : TField;
  158. W : Integer;
  159. begin
  160. inherited BuildDefaultFieldMap(AMap);
  161. For I:=0 to AMap.Count-1 do
  162. begin
  163. FL:=TTexExportFieldItem(AMAP[i]);
  164. F:=Dataset.Fields[i];
  165. W:= FieldWidths[F.DataType];
  166. If (W>0) then
  167. FL.Width:=W
  168. else if (W=0) then
  169. begin
  170. if (F.DataType in StringFieldTypes) then
  171. FL.Width:=F.Size;
  172. end;
  173. If (F.DataType in IntFieldTypes) then
  174. Fl.Align:=taRightJustify;
  175. end;
  176. end;
  177. function TCustomTeXExporter.CreateExportFields: TExportFields;
  178. begin
  179. Result:=TExportFields.Create(TTexExportFieldItem);
  180. end;
  181. procedure TCustomTeXExporter.DoDataHeader;
  182. Const
  183. AlChars : Array[TAlignment] of char = 'lcr';
  184. Var
  185. I,TW : Integer;
  186. B1,B2 : Boolean;
  187. EF : TTeXExportFieldItem;
  188. UN,S,FTW : String;
  189. begin
  190. B1:=teUseWidths in FEO;
  191. B2:=teHeaderRow in FEO;
  192. UN:=TexUnitnames[FormatSettings.Units];
  193. S:='';
  194. TW:=0;
  195. For I:=0 to ExportFields.Count-1 do
  196. begin
  197. EF:=TTexExportFieldItem(ExportFields[i]);
  198. If EF.Enabled then
  199. begin
  200. If EF.LineBefore then
  201. S:=S+'|';
  202. if B1 then
  203. begin
  204. TW:=TW+EF.Width;
  205. S:=S+'p{'+IntToStr(EF.Width)+'}'+UN;
  206. end
  207. else
  208. S:=S+ALChars[EF.Align];
  209. If EF.LineAfter then
  210. S:=S+'|';
  211. If B2 THEN
  212. begin
  213. If (FTH<>'') then
  214. FTH:=FTH+' & ';
  215. FTH:=FTH+EscapeLaTeX(EF.ExportedName);
  216. end;
  217. end;
  218. end;
  219. If FormatSettings.Tabular=ttTabularx then
  220. if Not B1 then
  221. FTW:='{\textwidth}'
  222. else
  223. FTW:=Format('{\%d%s}',[TW,UN]);
  224. FTD:=Format('\begin{%s}%s{%s}',[FTN,FTW,S]);
  225. If B2 then
  226. FTH:=FTH+'\\';
  227. OutPutTableStart;
  228. inherited DoDataHeader;
  229. end;
  230. procedure TCustomTeXExporter.DoDataFooter;
  231. begin
  232. OutPutTableEnd;
  233. Inherited DoDataFooter;
  234. end;
  235. procedure TCustomTeXExporter.OutputTableEnd;
  236. begin
  237. If teBottomLine in FEO then
  238. OutputRow('\hline');
  239. OutputRow(Format('\end{%s}',[FTN]));
  240. if (teTableEnvironment in FEO) then
  241. OutputRow('\end{table}');
  242. end;
  243. procedure TCustomTeXExporter.OutputTableStart;
  244. Var
  245. S : String;
  246. I : Integer;
  247. begin
  248. S:='';
  249. if (teTableEnvironment in FEO) then
  250. OutputRow('\begin{table}');
  251. OutputRow(FTD);
  252. If teHeaderRow in FEO then
  253. begin
  254. if (TeHeaderLine in FEO) then
  255. OutputRow('\hline');
  256. OutputRow(FTH);
  257. end;
  258. if (TeTopLine in FEO) then
  259. OutputRow('\hline');
  260. end;
  261. procedure TCustomTeXExporter.SetTeXFormatSettings(
  262. const AValue: TTexExportFormatSettings);
  263. begin
  264. Inherited FormatSettings:=AValue
  265. end;
  266. function TCustomTeXExporter.CreateFormatSettings: TCustomExportFormatSettings;
  267. begin
  268. Result:=TTexExportFormatSettings.Create(False);
  269. end;
  270. procedure TCustomTeXExporter.DoBeforeExecute;
  271. begin
  272. inherited DoBeforeExecute;
  273. OpenTextFile;
  274. FEO:=FormatSettings.Options;
  275. FTD:='';
  276. FTH:='';
  277. FTN:=TabularNames[FormatSettings.Tabular];
  278. If teCreateDocument in FEO then
  279. OpenDocument;
  280. end;
  281. procedure TCustomTeXExporter.OpenDocument;
  282. Var
  283. S : string;
  284. begin
  285. OutputRow(Format('\documentclass%s{%s}',['','article']));
  286. S:=TabularPackageNames[FormatSettings.Tabular];
  287. If (S<>'') then
  288. OutputRow(Format('\usepackage{%s}',[s]));
  289. OutputRow('\begin{document}');
  290. end;
  291. procedure TCustomTeXExporter.CloseDocument;
  292. begin
  293. OutputRow('\end{document}');
  294. end;
  295. procedure TCustomTeXExporter.DoAfterExecute;
  296. begin
  297. If teCreateDocument in FEO then
  298. CloseDocument;
  299. CloseTextFile;
  300. inherited DoAfterExecute;
  301. end;
  302. procedure TCustomTeXExporter.DoDataRowStart;
  303. begin
  304. FCurrentRow:='';
  305. inherited DoDataRowStart;
  306. end;
  307. procedure TCustomTeXExporter.ExportField(EF: TExportFieldItem);
  308. Var
  309. S : String;
  310. begin
  311. S:=FormatField(EF.Field);
  312. If (FCurrentRow<>'') then
  313. FCurrentRow:=FCurrentRow+' & ';
  314. FCurrentRow:=FCurrentRow+EscapeLaTex(S);
  315. end;
  316. procedure TCustomTeXExporter.DoDataRowEnd;
  317. begin
  318. FCurrentRow:=FCurrentRow+' \\';
  319. OutputRow(FCurrentRow);
  320. end;
  321. { TTeXExportFormatSettings }
  322. constructor TTeXExportFormatSettings.Create(DoInitSettings: Boolean);
  323. begin
  324. inherited Create(DoInitSettings);
  325. FOptions:=[teHeaderRow,teTableEnvironment,teTopLine,teBottomLine]
  326. end;
  327. procedure TTeXExportFormatSettings.Assign(Source: TPersistent);
  328. Var
  329. FS : TTeXExportFormatSettings;
  330. begin
  331. If (Source is TTeXExportFormatSettings) then
  332. begin
  333. FS:=Source as TTeXExportFormatSettings;
  334. Options:=FS.OPtions;
  335. Units:=FS.Units;
  336. Tabular:=FS.Tabular;
  337. end;
  338. inherited Assign(Source);
  339. end;
  340. { TTeXExportFieldItem }
  341. procedure TTeXExportFieldItem.Assign(Source: TPersistent);
  342. Var
  343. Fi : TTeXExportFieldItem;
  344. begin
  345. If (Source is TTeXExportFieldItem) then
  346. begin
  347. FI:=Source as TTeXExportFieldItem;
  348. Width:=FI.Width;
  349. Align:=FI.Align;
  350. LineBefore:=FI.LineBefore;
  351. LineAfter:=FI.LineAfter;
  352. end;
  353. inherited Assign(Source);
  354. end;
  355. end.