(* :Title: AddTeX2Eps *)
(* :Context: Graphics`AddTeX2Eps` *)
(* :Author: Janko Slavic (janko.slavic@fs.uni-lj.si) *)
(* :Summary: 
    Package for using native LaTeX syntax on eps figures directly from Mathematica. 
    AddTeX2Eps calls latex.exe and dvips.exe and makes use of psfrag package (needs to be installed).

    default.tex is the LaTeX template where you can add packages and define your own LaTeX commands.
    Copy default.tex and AddTeX2Eps.m to ..\AddOns\StandardPackages\Graphics\  or to search path.

*)
(* :Package Version: 1.12 *)
(* :Mathematica Version: 5.2 *)
(* :History:
	1.12 by Janko Slavic, april, 2006 (default.tex located in searh path or ..\AddOns\StandardPackages\Graphics\).
	1.11 by Janko Slavic, april, 2006 (directory problem resolved).
	1.1 by Janko Slavic, april, 2006.
	1.0 by Janko Slavic, 2003.
*)
(* :Keywords: eps, tex, latex, psfrag.  
*)


BeginPackage["Graphics`AddTeX2Eps`"]

EpsExport::usage="EpsExport[fileName,graphics,PSFrag]
EpsExport is used to export graphics to eps files
and then use psfrag LaTeX package with latex.exe and dvips.exe. \n
fileName is a string with full path (long names and spaces can cause troubles)\n
graphics is a graphical object to export\n
PSFrag is List of strings with psfrag syntax\n
\n
Example:\n\n
Needs[\"Graphics`AddTeX2Eps`\"];\n
fig = Plot[Sin[x^2], {x, 0, 4}, AxesLabel -> {\"a\",\"b\"},PlotLabel -> \"c\"];\n
EpsExport[\"d:/test.eps\",fig,\n
{\n
\"\\psfrag{a}[c]{$x$}\",\n
\"\\psfrag{b}[c]{$\\sin(x^2)$}\",\n
\"\\psfrag{c}[c]{Native \\LaTeX via psfrag package}\"\n
}]
";

CorrectBB::usage="Use to manually correct bounding box dimensions: {llx, lly, urx, ury}.\n
For example: {-10, 0, 0, 0} moves the lower left bounding box point for 10 points to the left.";

IncludeGraphicsOptions ::usage="Native LaTeX includegraphics options (scale, trim,...)";

DeleteTempFiles::usage="If you are having problems with compiling, it may help to look at the temporary files.
 Try to compile temp.tex with latex.exe."

Options[EpsExport]={
	CorrectBB -> {0, 0, 0, 0}, 
	IncludeGraphicsOptions -> "[scale=1.0]",
	DeleteTempFiles -> True};

Begin["`Private`"]

EpsExport[fileName_String, graphics_Graphics, PSFrag_List, opts___] := 
    Module[{stream},
      Export[fileName, graphics, "EPS"];
      stream = OpenAppend[fileName];
      (*Save PSFrag syntax in file - if needed later*)
      WriteString[stream, 
        "%%PSFragBegin\n" <> StringJoin[StringInsert[PSFrag,"\n%%",1]] <> 
          "\n%%PSFragEnd"];
      Close[stream];
      
      (*run latex and ps*)
      RunLaTeX[fileName, PSFrag, opts];
      ];


RunLaTeX[fileName_String, PSFrag_List, opts___] := 
    Module[{texDat, bbText, bb, stream, w, h, workD, llx, lly, urx, ury, 
        epsFile, tmp, deleteTempFiles},
      {{cllx, clly, curx, cury}, incGrapOpts, 
          deleteTempFiles} = {CorrectBB, IncludeGraphicsOptions, 
              DeleteTempFiles} /. Flatten[{opts}] /. Options[EpsExport];
      
      (*Default.tex needs to be in Graphics dir*)
      (*if needed, add packages/new commands to Default.tex*)
      texDat := Module[{out},
	out=Import["Default.tex", "Text"]; (*searchable path*)
	If[out==$Failed,out=Import["Graphics//Default.tex", "Text"];]; (*compatibility issue with ver 1.1*)
	out
	];
 
      (*Read bounding box*)
      stream = OpenRead[fileName];
      bbText = Find[stream, "%%BoundingBox:"];
      bb = ToExpression[Drop[StringSplit[bbText], 1]];
      Close[stream];
      {w, h} = IntegerPart[{bb[[3]] - bb[[1]], bb[[4]] - bb[[2]]}];



      (*Prepare TeX dat*)
      texDat = StringReplace[texDat,
          {"psfragSyntax" -> StringJoin[StringInsert[PSFrag,"\n",1]],
            "[scaleSyntax]" -> incGrapOpts,
            "figureName" -> StringReplace[StringReplace[fileName, "/" -> $PathnameSeparator], __ ~~$PathnameSeparator~~ name_ -> name],
            "{width}" -> "{" <> ToString[w] <> "pt}",
            "{height}" -> "{" <> ToString[h] <> "pt}"
            }];
      
      
      (*set working dir*)
      workDir = Directory[];
      SetDirectory[DirectoryName[StringReplace[fileName, "/" -> $PathnameSeparator]]];

      (*Export tex*)
      Export["EpsExport.tex", texDat, "Text"];
      
      (*Run Latex*)
      Run["latex EpsExport"];
      
      (*Run dvi to ps*)
      Run["dvips -E EpsExport"];
      

      (*read bounding box*)
      stream = OpenRead["EpsExport.ps"];
      bbText = Find[stream, "%%BoundingBox:"];
      {llx, lly, urx, ury} = ToExpression[Drop[StringSplit[bbText], 1]];
      Close[stream];




      (*correct bounding box*)
      {llx, ury, lly, urx} = {urx - w + cllx, lly + h + cury, lly + clly, 
          urx + curx};
      bbText = 
        ToString[llx] <> " " <> ToString[lly] <> " " <> ToString[urx] <> " " <>
           ToString[ury];
      epsFile = Import["EpsExport.ps", "Lines"];
      epsFile = Join[
          
          StringReplace[Take[epsFile, 20], 
            StartOfLine ~~ "%%BoundingBox:" ~~ tmp__ -> 
              "%%BoundingBox: " ~~ bbText],
          Drop[epsFile, 20]
          ];
      Export[fileName, epsFile, "Lines"];

      (*delete files*)
      If[deleteTempFiles,
        DeleteFile[{"EpsExport.ps", "EpsExport.aux", "EpsExport.dvi", "EpsExport.log",
               "EpsExport.tex"}];
        ];

      
      
      
      (*reset working dir*)
      SetDirectory[workDir];
      
      ];


End[]

Protect[EpsExport]

EndPackage[]