(*******************************************************************
This file was generated automatically by the Mathematica front end.
It contains Initialization cells from a Notebook file, which
typically will have the same name as this file except ending in
".nb" instead of ".m".

This file is intended to be loaded into the Mathematica kernel using
the package loading commands Get or Needs.  Doing so is equivalent
to using the Evaluate Initialization Cells menu command in the front
end.

DO NOT EDIT THIS FILE.  This entire file is regenerated
automatically each time the parent Notebook file is saved in the
Mathematica front end.  Any changes you make to this file will be
overwritten.
***********************************************************************)







MathPSfragLicense::usage="
Copyright (c) 2003-2007 Johannes Grosse
This software is distributed under the terms of the
``CPC non-profit use licence''.
A copy of this licence should have been distributed 
together with this program. If not, you may obtain the 
licence from http://cpc.cs.qub.ac.uk/licence/licence.html.
";

MathPSfragVersion::usage="MathPSfrag Version 2.0-rev55 2008-01-16";





BeginPackage["MathPSfrag`",{"Utilities`FilterOptions`"}]

Unprotect["MathPSfrag`*"];
Unprotect["$MathPSfragGlobal`*"];

MathPSfrag::usage="MathPSfrag is a package for the production of high-quality LaTeX labels in Mathematica plots. The three main functions are PSfragExport, UnPSfrag and PSfrag. In addition PSfragManualExport can be used to avoid automatic treatment of text that is generated by plot options. While UnPSfrag is not strictly needed, it is very convenient. It does however require three external programs (latex, dvips and Ghostscript) and has to be configured accordingly. It is recommended to read and evaluate MathPSfrag-Test.nb, which has step-by-step instructions for a proper configuration.";

$MathPSfragGlobal`SaneSystemID=
    Switch[$SystemID,"MacOSX-x86","Darwin",_,$SystemID];
MathPSfragDebug=Null;





PSfrag::usage="PSfrag[expr, opts] can be used to achieve a higher lever of control of the output of PSfragExport by attaching individual typesetting information to expr. Use PSfrag[expr] whereever you want to display StandardForm[expr] on the _screen_, while a corresponding TeX command will be prepared for use within LaTeX. A typical use is Plot[..., PlotLabel->PSfrag[expr,opts]]. The most important option to PSfrag is TeXComand, which allows to define how expr is typeset when exported to an EPS file. \n\n\tUse PSfragExport[filename, graphicsobj] to write an EPS file in the current working directory (see ?SetDirectory[]). PSfragExport will append a suffix (default: '-psfrag.eps') to filename. This file will contain a substitute alphanumeric tag for every PSfrag command which in turn is replaced by a TeX command (by default guessed by a stupid algorithm) using the \\psfrag command (see documentation of psfrag.sty). The replacement tex rules are by default written to 'filename-psfrag.tex'. You may independently generate and display these \\psfrag commands by CreatePSfragRules[graphicsobj]. \n\n\tPSfrag is automatically threaded over a List when the argument of TeXCommand is a List of same length. \n\n\tThe available options are TeXCommand, TeXPosition, PSPosition, PSRotation, PSScaling, PSfragTag. Each has a separate help text. You might also want to study the documentation shipped with psfrag.sty.\n\n\tFor a usage example, see ?PSfragExample\n";

PSfragExample::usage=
    "PSfrag Example\n--------------\n"<>
      "In Mathematica: \n\t"<>
      
      "Needs[\"MathPSfrag`\"];\n\t"<>
      "(* set output directory to what ever you like *)\n\t"<>

            "SetDirectory[\"/tmp\"];\n\n\t"<>
      "pl=Plot[Sin[x^2], {x, 0, 2 Pi[]}, \n\t"<>

            "\tAxesLabel->PSfrag[{x,Sin[x^2]}], \n\t"<>
      "\tPlotLabel->PSfrag[\"A wonderful PSfrag test.\"]];\n\n\t"<>

            "(* This shows the rules to be inserted as TeX commands\n\t"<>
   
         "   (It's a good idea to check them for a badly guessed TeXCommand) *)\n\t"<>

            "CreatePSfragRules[pl]\n\n\t"<>
      "(* actually carry out export *)\n\t"<>

            "PSfragExport[\"wonderful-test\",pl];\n\n"<>
      "In LaTeX:\n\t"<>

            "\\usepackage{psfrag,graphicx,amsmath} % in the preamble \n\t"<>
 
           "... \n\t"<>
      "\\begin{psfrag} % in the document\n\t"<>
      
      "\\include{filename-psfrag.tex}\n\t"<>
      "\\includegraphics{filename-psfrag.eps}\n\t"<>

            "\\end{psfrag}\n";



Options[PSfrag]={TeXCommand\[Rule]Automatic,TeXPosition\[Rule]Automatic,
      PSPosition\[Rule]CopyTeXPosition,PSRotation\[Rule]Automatic,
      PSScaling\[Rule]Automatic,PSfragTag\[Rule]Automatic,TeXShiftX\[Rule]0,
      TeXShiftY\[Rule]0,FallBack\[Rule]Automatic};

TeXCommand::usage="TeXCommand is an option of PSfrag[]. The default PSfrag[expression, TeXCommand->Automatic] deduces the TeX command from the given expression. For complicated expressions, this may not give satisfactory results and you may have to set them by hand using TeXCommand->\"TeX command string\". (Note, that the TeXForm output of Mathematica is version dependent.) If the argument is not a string, it is assumed to be a function that returns a suitable TeX string when applied to the Mathematica expression.";\


TeXPosition::usage="TeXPosition is an option of PSfrag[] defining the alignment of the TeX text replacing the PSfrag[] command in an EPS output. Possible values are any two-character combination of (\"B\", \"t\", \"c\", \"b\") and (\"l\", \"c\", \"r\"). The default is Automatic. For the x label in AxesLabel you should use \"Bl\".";\


PSPosition::usage="PSPosition is an option of PSfrag[] defining the alignment of the postscript text output by Export. Its default CopyTeXPosition takes over value of the Position option, while the value Automatic is replaced by the alignment of the first surrounding Text graphics directive. Explicit values can be the same as those of Position.";\


TeXShift::usage = \
"TeXShift->{\"x\",\"y\"} is an option of PSfrag shifting the position of the TeX box by the specified amount. x and y are TeX dimensions; e.g., 3cm or 4pt. When a numeric value is given, the unit 'pt' is assumed.";\


TeXShiftX::usage = \
"Option for PSfrag. TeXShiftX->value is equivalent to TeXShift->{value,0}.";
TeXShiftY::usage = \
"Option for PSfrag. TeXShiftY->value is equivalent to TeXShift->{0,value}.";

CopyTeXPosition::usage="Default value of PSfrag's option PSPosition.";

PSRotation::usage="PSRotation is an option of PSfrag[]. Its range is 0 to 360 degree. It may be used to turn the text counterclockwise in the final postscipt output.";\


PSScaling::usage="PSScaling is an option of PSfrag[]. It is a positive number which is used to increase the size of any TeX command's output in the final postscript. The default value Automatic inserts predefined tex macros depending on the type of expression. (See Options[CreatePSfragRules, PSfragPrologue].) A factor of 1 corresponds to no scaling.";\


PSfragTag::usage=
    "PSfragTag is an option of PSfrag[] which may be used to manually set the tag which is used by the TeX command \\"<>\
"psfrag to replace TeX output into an eps file. Usually the default setting (PSfragTag->Automatic) gives good results an should be left unchanged. If you have problems with the bounding box, you might also try to use RenumberTags->True as an option for PSfragExport, which yields shorter tags.";\


FallBack::usage="Fallback is an option of PSfrag that may be used to specify which value the alignment parameters TeXPosition and PSPosition should take if the automatic determination fails for some reason. (This is used for tick marks to assign a default alignment depending on whether the tick marks are vertical or horizontal, because for some Mathemtica versions AbsoluteOptions sometimes skips a few ticks such that the default algorithm fails.)";





PSfragTicks::usage="PSfragTicks[tickspec,opts] maps PSfrag[#,opts]& at each label in a tick mark specification (see the Ticks option of Plot). Note that tickspec is for one axis only, so PSfragTicks has to be applied to each axis. PSfragExport applied to two-dimensional graphics, will automatically wrap PSfrag at the correct positions. This is only needed, when you want to have additional control over the output or for three-dimensional plots. A typical usage example: \n

\tNeeds[\"CustomTicks`\"];\n
\tPlot3D[..., Ticks->{\n
\t\tPSfragTicks[LinTicks[xmin,xmax], TeXPosition->\"Bc\"],\n
\t\tPSfragTicks[LinTicks[ymin,ymax], TeXPosition->\"Bl\"],\n
\t\tPSfragTicks[LinTicks[zmin,zmax], TeXPosition->\"Br\"] }];";





PSfragManualExport::usage="PSfragManualExport[filename,graphics] converts all PSfrag entries in a Graphics object into alphanumerical tags using CreatePSfragRules. The result is exported into an ordinary EPS file, while the generated \\psfrag TeX commands are written into a TeX file. The respective filenames are determined from the parameter 'filename' and the suffix given in the PSfragExport option EpsSuffix and TeXSuffix. PSfragManualExport returns a list of the form {filename, epsfilename, texfilename}, which is suitable as input to UnPSfrag. PSfragManualExport is internally called by PSfragExport after constructing automatic PSfrag commands for all textual elements in a graphic by calling HandleAutomaticPSfrag.";



HandleAutomaticPSfrag::usage="By default HandleAutomaticPSfrag[graphics,opts] wraps PSfrag commands around all textual elements generated by the graphics options AxesLabel, Ticks, PlotLabel, FrameLabel and FrameTicks. It accepts a number of options, all starting with 'Format', that allow to fine-tune this behaviour. For example FormatTicksX has the default value 'PSfrag'. Setting FormatTicksX->(PSfrag[#,TeXCommand->myFormatter[#]]&) would allow to write a function that gives better TeX output for all entries on X axis. See also ?NumberToTeX.";

Options[HandleAutomaticPSfrag]:={
      OptionsToHandle\[Rule]{AxesLabel,Ticks,PlotLabel,FrameLabel,
          FrameTicks},
      OptionHandlers\[Rule]{
          {AxesLabel,HandleAxesLabel},
          {Ticks,HandleTicks},
          {PlotLabel,HandlePlotLabel},
          {FrameLabel,HandleFrameLabel},
          {FrameTicks,HandleFrameTicks}
          },
      
      FormatFrameTicksNorth\[Rule](PSfrag[#,PSfragTag\[Rule] Automatic["N"],
              FallBack\[Rule]"bc"]&),
      FormatFrameTicksWest\[Rule](PSfrag[#,PSfragTag\[Rule] Automatic["W"],
              FallBack\[Rule] "cr"]&),
      FormatFrameTicksSouth\[Rule](PSfrag[#,PSfragTag\[Rule] Automatic["S"],
              FallBack\[Rule] "tc"]&),
      FormatFrameTicksEast\[Rule](PSfrag[#,PSfragTag\[Rule] Automatic["E"],
              FallBack\[Rule] "cl"]&),
      
      FormatTicksX\[Rule](PSfrag[#,PSfragTag\[Rule] Automatic["x"],
              FallBack\[Rule] "tc"]&),
      FormatTicksY\[Rule](PSfrag[#,PSfragTag\[Rule] Automatic["y"],
              FallBack\[Rule] "cr"]&),
      
      FormatAxesLabelX\[Rule]PSfrag,FormatAxesLabelY\[Rule]PSfrag,
      
      FormatPlotLabel\[Rule]PSfrag,
      
      FormatFrameLabelNorth\[Rule]PSfrag,
      FormatFrameLabelWest\[Rule]PSfrag,
      FormatFrameLabelWestRotated\[Rule](PSfrag[#,TeXPosition\[Rule]"bc",
              PSPosition\[Rule]"bc"]&),
      FormatFrameLabelSouth\[Rule]PSfrag,
      FormatFrameLabelEast\[Rule]PSfrag,
      FormatFrameLabelEastRotated\[Rule](PSfrag[#,TeXPosition\[Rule]"bc",
              PSPosition\[Rule]"bc"]&)
      
      (*ApplyLinTicks\[Rule]False*)
      };

OptionHandlers::usage="Option for HandleAutomaticPSFrag and PSfragExport that assigns to Plot options different default handlers that actually carry out the formatting. Usually do not touch this option but instead use the corresponding ?MathPSfrag`Format* options to change the behaviour or switch automatic handling off by setting OptionsToHandle accordingly.";\


HandleAxesLabel::usage=HandleTicks::usage=HandlePlotLabel::usage=
        HandleFrameLabel::usage=
          HandleFrameTicks::usage="Default handler that takes care of auto-wrapping PSfrag commands around the Text elements generated by the associated Plot option. Use OptionsToHandle to decide if this handler is called and the corresponding ?MathPSfrag`Format* options to fine-tune the formatting.";\


OptionsToHandle::usage="Option for HandleAutomaticPSfrag and PSfragExport that contains a list of all options that are taken care off by the automatics. Currently automatics are implemented for {AxesLabel,Ticks,PlotLabel,FrameLabel,FrameTicks}, which is the default value of OptionsToHandle. You can switch off the automatics entirely by setting this option to {}. The formatting of a Plot's elements can be changed by setting the corresponding ?MathPSfrag`Format* options.";\


(*ApplyLinTicks::usage=
      "Option for HandleAutomaticPSfrag and PSfragExport that will apply LinTickify to the graphics. ApplyLinTicks->True will replace all tick mark contents by the output of LinTicks, which is often what the user will want. You can have a preview of this effect by using Show[LinTickify[plot],DisplayFunction->$DisplayFunction]";\
*)

FormatFrameTicksNorth::usage="Option for HandleAutomaticPSfrag and PSfragExport. All ?MathPSfrag`Format* options can be used to fine-tune the output of the current automatic handling of axes labels and the like. Their respective default values are usually just PSfrag, which is wrapped around each Text element that is produced by Plot options like AxesLabel or Ticks. Since the default behaviour of PSfrag is to call GuessTeX, you obtain the TeX code that is generated by this rather imperfect function. You can include you own TeX generating function by setting Format...->PSfrag[#,TeXCommand->mytexguesser[#]]&, where you obviously would have to implement mytexguesser to convert an arbitrary expression that could show up into a TeX command. For Tick marks these are usually just numbers, so you might want to use the FormatTicksX and ...Y options to apply a function that sets exactly the number format you want. See also NumberToTeX, a function that could be used for this job.";\


FormatFrameTicksWest::usage=
    FormatFrameTicksSouth::usage=FormatFrameTicksEast::usage=
        FormatTicksX::usage=
          FormatTicksY::usage=
            FormatAxesLabelX::usage=FormatAxesLabelY::usage=
                
                FormatPlotLabel::usage=
                  FormatFrameLabelNorth::usage=FormatFrameLabelWest::usage=
                      
                      FormatFrameLabelEastRotated::usage=
                        FormatFrameLabelSouth::usage=
                          FormatFrameLabelEast::usage=
                            FormatFrameLabelEastRotated::usage=
                              "Option for HandleAutomaticPSfrag and PSfragExport. See FormatFrameTicksNorth for details.";



NumberToTeX::usage="NumberToTeX[number,opts] returns a string containing TeX code that represents number. There are several options that influence the appearance of number: IntegerPartDigits determines the number of digits before the decimal point in a floating point number, FractionalPartDigits sets the number of digits after the decimal point. When ChopExponent is True, exponents of the form 10^0 are suppressed. ChopImaginaryPart->True turns complex numbers with almost vanishing imaginary part into real numbers. In a similar manner Integerize->True will turn floating point numbers like '1.' into integers. ExponentSymbol->\"\\cdot 10^\" will format floats in the form 1.23 \\cdot 10^{4}. This is the default behaviour.

Example: NumberToTeX[Exp[10.]]"

Options[NumberToTeX]:={
    IntegerPartDigits\[Rule] 1,
    FractionalPartDigits\[Rule]2,
    ChopExponent\[Rule]True,
    ChopImaginaryPart\[Rule]True,
    ChopFractionalPart\[Rule]False,
    RationalToReal\[Rule]False,
    IntegerToReal\[Rule]False,
    Integerize\[Rule]True,
    ExponentSymbol\[Rule]
      "\\cdot 10^"
    (*ForceExponent\[Rule] False*)
    }

IntegerPartDigits::usage="Option for ?NumberToTeX, see there.";
FractionalPartDigits::usage="Option for ?NumberToTeX, see there.";
ChopExponent::usage="Option for ?NumberToTeX, see there.";
ChopImaginaryPart::usage="Option for ?NumberToTeX, see there.";
ChopFractionalPart::usage="Option for ?NumberToTeX, see there.";
RationalToReal::usage="Option for ?NumberToTeX, see there.";
IntegerToReal::usage="Option for ?NumberToTeX, see there.";
Integerize::usage="Option for ?NumberToTeX, see there.";
ExponentSymbol::usage="Option for ?NumberToTeX, see there.";





PSfragExport::usage="PSfragExport[filename, graphics, opts] writes an Enscapulated PostScript (EPS) version of graphics into a file. Filename may contain a directory, otherwise the eps file is written into the current working directory. This EPS file is meant to be read by \\includegraphics and processed by the psfrag LaTeX package. The TeX commands required by psfrag are also writen into a file. Note that PSfragExport automatically appends suffices defined by EpsSuffix->... and TeXSuffix->... to create the actual filenames. PSfragExport first generates automatic PSfrag commands for all textual elements of a graphic (including numbers and formulae) by calling HandleAutomaticPSfrag. All options opts are passed through. This means that in particular special formatting instructions of HandleAutomaticPSfrag can be given directly to PSfragExport. The second step is to call PSfragManualExport, which does the actual job of creating the EPS and TeX file. A list containing 'filename' and the names of the generated files is returned. This list is suitable as input for UnPSfrag, such that typical usage looks like this:

PSfragExport[\"mydemo\",myplot]//UnPSfrag";



Options[PSfragExport]={EpsSuffix\[Rule]"-psfrag.eps",
      TeXSuffix\[Rule]"-psfrag.tex"};

EpsSuffix::usage="Option for PSfragExport, see there.";
TeXSuffix::usage="Option for PSfragExport, see there.";

$MathPSfragGlobal`PSfragExportResult={"For debugging purpose this variable contains the results of the last call to PSfragExport."}\
;

$MathPSfragGlobal`SurroundTags:="a";





GuessTeX::usage="GuessTeX[expr] creates a string containing the TeX form of expr. It is used by PSfrag (see there) when TeXCommand->Automatic is set (default).";

GuessTag::usage="GuessTag[expr] tries to create a unique string describing expr and entirely consisting of alpha-numerical characters. (This is called a `tag`.) It is used by PSfrag when PSfragTag->Automatic is set (default).";





Options[GuessTeX]={
      ReplacementHookExclusive\[RuleDelayed]$MathPSfragGlobal`$\
ReplacementHookExclusive,
      ReplacementHookCooperative\[RuleDelayed]$MathPSfragGlobal`$\
ReplacementHookCooperative
      };

ReplacementHookExclusive::usage="Option for GuessTeX which contains a list of shape {{priority, test, command},...} that can be used to customize the behaviour of GuessTeX. Starting with the lowest value of `priority`, each `test` is called with the Mathematica expression that is to be transformed to a LaTeX expression. The first test returning True -- if any -- will stop the default generation of LaTeX code. Instead the associated `command` is called and its return value is used as TeX code.";\


ReplacementHookCooperative::usage=
    "Option for GuessTex which contains a list of shape {{priority, test, applybefore, applyafter},...} that can be used to customize the behaviour of GuessTeX. Starting with the lowest value of `priority`, each `test` is called with the Mathematica expression that GuessTeX is supposed to transform into a LaTeX expression. Each `test` that returns True will cause the respective `applybefore` command to be applied to the Mathematica expression. In addition after the default generation of LaTeX code that is preformed in any case, the associated `applyafter` command is applied to the string containing the LaTeX code.";\



Options[GuessTag]={
      MinimumTagLength\[Rule]1,
      MaximumTagLength\[Rule]10
      };

MinimumTagLength::usage="Option for GuessTag. This sets the minimum length of a tag produced by GuessTag.";\

MaximumTagLength::usage="Option for GuessTag. This sets the maximum length of a tag produced by GuessTag.";



(* Format of this list is 
    {priority, test, applybefore, applyafter} 
  *)

$MathPSfragGlobal`$ReplacementHookCooperative={
      If[$VersionNumber>=5.1,
        {10000,True&,Identity,StringJoin["$",#,"$"]&},
        (* Mma 4/Mma 5.0: 
            strings do not require $ signs since they are not typeset in math \
mode *)
        {10000,(Head[#]=!=String)&,Identity,StringJoin["$",#,"$"]&}]
      };

 (* 
  Format of this list is
    {priority, test, command} 
  *)

$MathPSfragGlobal`$ReplacementHookExclusive=Join[
      {
        (* Mma5: 
            undo AbsoluteOption bug that converts integers to reals *)
       \
 {900,Chop[#-Round[#]]===0&,"$"<>ToString[Round[#]]<>"$"&},
        
        (* Mma5: TeXForm is no good for numbers, 
          so check if ToString alone does the job *)
        \
{1000,(NumberQ[#]&&(StringPosition[ToString[#],"\n"]==={}))&,
          "$"<>ToString[#]<>"$"&},
        
        (* Mma5: 
            The only numbers that should reach this point are of the form 1.0 \
* 10^-6 *)
        {1100,NumberQ,"$"<>NumberToTeX[#]<>"$"&}
        },
      If[$VersionNumber<5.1,
        {
          (* Mma4: TeXForm[PaddedForm[...]] does not do what expected, 
            but ToString[
                PaddedForm[...]] works *)
          {5000,(Head[#]===
                  PaddedForm)&,ToString[" "<>ToString[#],TeXForm]&}
          },
        {}]
      ];



TextToPSfrag::usage="TextToPSfrag[graphics] simply wraps PSfrag around all Text directives. It is used by HandleAutomaticPSfrag which in turn is called by PSfragExport. ";





CreatePSfragRules::usage="CreatePSfragRule[expr] generates the TeX commands corresponding to any PSfrag[] used in expr. This is an auxilliary function for PSfragExport[] and may be directly used for debugging or educational purposes. You may want to apply it to a Graphics object whose labels contain PSfrag[] commands. The usual application is CreatePSfragRules[FullGraphics[anyplot]].";



Options[CreatePSfragRules]={RenumberTags\[Rule]False, 
      PSfragPrologue\[RuleDelayed]$MathPSfragGlobal`$PSfragPrologue};

PSfragPrologue::usage="Option for CreatePSfragRules that can also be used for PSfragExport (see there).";\

RenumberTags::usage="Option for CreatePSfragRules that can also be used for PSfragExport (see there).";





If[$VersionNumber<5.1,
    $MathPSfragGlobal`Mma4TeX="mma4tex";
    
    $MathPSfragGlobal`Mma4TeXFound="Mma4TeX loaded.";
    $MathPSfragGlobal`Mma4TeXMissing=
      "Could NOT find Mma4TeX. Only a subset of TeX code generated by Mathematica will be handled correctly.";\

    ];

$MathPSfragGlobal`$PSfragPrologue:=
    
    "%auto-ignore (makes arXiv.org ignore this file)\n"<>
      "% This file replaces labels in an EPS graphic by LaTeX macros,\n"<>

            "% i.e. it should be accompanied by an EPS file (%%%EPSFILENAME%%%). \n"<>

            "\\def\\PFGstripminus-#1{#1}%\n"<>
      "\\def\\PFGshift(#1,#2)#3{\\raisebox{#2}[\\height][\\depth]{\\hbox{%\n"<>

            "  \\ifdim#1<0pt\\kern#1 #3\\kern\\PFGstripminus#1\\else\\kern#1 #3\\kern-#1\\fi}}}%\n"<>

            "\\providecommand{\\PFGstyle}{}%\n"<>
      
      If[$VersionNumber\[GreaterEqual]5.1,"",
        "\\InputIfFileExists{"<>$MathPSfragGlobal`Mma4TeX<>".tex}%\n"<>
      
              "  {\\typeout{"<>$MathPSfragGlobal`Mma4TeXFound<>"}}%\n"<> 
          "  {\\typeout{"<>$MathPSfragGlobal`Mma4TeXMissing<>"}}%\n"];






LatinQ::usage="LatinQ[string] returns True if string consists entirely of letters A to Z or a to z.";\

LatinNumQ::usage="LatinQ[string] returns True if string constists entirely of alphanumerical characters (A-Z,a-z,0-9).";\

LatinCharacterSet::usage="Characters which LatinQ assumes to be latin.";
LatinNumCharacterSet::usage="Characters which LatinQ assumes to be alphanumeric.";\

NumToBase52::usage="NumToBase52[integer] converts a non-negative integer into an alphabetic string.";





NextLaTeXError::usage="Typical usage is NextLaTeXError[] after an unsuccesful UnPSfrag. By default it shows the first error message, though NextLaTeXError[2] gives the second error and so forth.";





$MathPSfragGlobal`GsDeviceBBOX={"bbox",".bbox",""};
$MathPSfragGlobal`GsDeviceBBOXpnm={"pnm",".pnm","-r72x72"};
$MathPSfragGlobal`GsDeviceEPS={"EPS",".eps",""};
$MathPSfragGlobal`GsDevicePDF={"pdfwrite",".pdf",""};
$MathPSfragGlobal`GsDevicePNM={"pnm",".pnm",
      "-r120x120 -dTextAlphaBits=4 -dGraphicsAlphaBits=4"};
$MathPSfragGlobal`GsDevicePNG={"png",".png",
      "-r120x120 -dTextAlphaBits=4 -dGraphicsAlphaBits=4"};
$MathPSfragGlobal`GsDeviceJPEG={"jpeg",".jpeg",
      "-r120x120 -dTextAlphaBits=4 -dGraphicsAlphaBits=4"};

Options[UnPSfrag]={
      TemporaryDirectory\[RuleDelayed]GenerateTemporaryName["unpsfrag"],
      TeXPreamble\[Rule]"",
      IncludeGraphicsOptions\[Rule]"",
      ForceOverwrite\[Rule]True,
      RemoveTemporaries\[Rule]True,
      SuppressOutput\[Rule]" >nullstdout.txt 2>nullstderr.txt",
      PreviewDevice\[Rule]
        If[$MathPSfragGlobal`SaneSystemID=="Darwin"&&$VersionNumber<5,
          NoneAndComplain,$MathPSfragGlobal`GsDevicePNM],
      BoundingBoxDevice\[Rule]
        If[$MathPSfragGlobal`SaneSystemID=="Darwin"&&$VersionNumber<
              5,$MathPSfragGlobal`GsDeviceBBOX,$MathPSfragGlobal`\
GsDeviceBBOXpnm],
      UnPSfragOutputFormats\[Rule]{$MathPSfragGlobal`GsDeviceEPS,$\
MathPSfragGlobal`GsDevicePDF},
      ExtraMargin\[Rule]1,
      MasterTeXFile\[RuleDelayed]$MathPSfragGlobal`$MasterTeXFile,
      
      (* set defaults for the following options based on operating system *)
 
           LaTeXExecutable\[Rule]
        Switch[$MathPSfragGlobal`SaneSystemID,"Darwin","/usr/texbin/latex",_,
          "latex"],
      LaTeXOptions\[Rule]"",
      DvipsExecutable\[Rule]
        Switch[$MathPSfragGlobal`SaneSystemID,"Darwin","/usr/texbin/dvips",_,
          "dvips"],
      DvipsOptions\[Rule]" -Ppdf",
      GhostscriptExecutable\[Rule]
        Switch[$MathPSfragGlobal`SaneSystemID,"Darwin","/usr/local/bin/gs","Windows",
          "gswin32c",_,"gs"]
      };

TemporaryDirectory::usage="Option for UnPSfrag that gives the name of a subdirectory where the LaTeX run in performed. All intermediate files are stored there. The temporary directory is removed after succesful execution unless RemoveTemporaries has been set to False.";\

TeXPreamble::usage="Option for UnPSfrag that in particular can be used to change the fonts used in the image. UnPSfrag needs a TeX file to convert a psfrag-EPS file, as produced by PSfragExport, to an EPS file independent of any psfrag commands. TeXPreamble is a string that is included in the TeXPreamble of that file and can be used to include additional LaTeX packages. For example: TeXPreamble->\"\\usepackage{euler}\" to change the math fonts.";\

IncludeGraphicsOptions::usage="Options for UnPSfrag that can be used to change the size of the generated image. For example IncludeGraphicsOption->\"width=3in\"  will change the size of the plot. However the size is only approximate since LaTeX does not include the size of the labels.";\

ForceOverwrite::usage="Option for UnPSfrag and for MathPSfragConfigurationTest (see there, respectively). ";\

RemoveTemporaries::usage="Option for UnPSfrag that can be set to False for debugging.";\

SuppressOutput::usage="Option for UnPSfrag that contains instructions to discard output of external programs.";\

PreviewDevice::usage=
    "Option for UnPSfrag. Unless there are severe problems, the only value you might choose instead of the default is 'None' to suppress generation of preview images. Allowed values are 'None' or a device triplet, i.e. a list {gsdevice, suffix, options}, where gsdevice is the name of a Ghostscript device, suffix is a string that is a suitable suffix for the generated file, e.g. \".eps\" for an EPS file, and options are additional command line options to Ghostscript that can be used to change anti-aliasing settings or the like. Typically a preview device should be a raster device, like pnm or png. Further information can be found in the documentation of the Ghostscript program.";\

BoundingBoxDevice::usage="Option for UnPSfrag that defaults to Ghostscript's bbox device. Do not change this option unless you have good reason to do so. The format is a device triplet as described for the PreviewDevice option. You may choose a raster device like png or pnm here in which case Mathematica will determine the bounding box from the bitmap graphic by counting non-empty rows and columns. This is not quite as precise as the bounding box generated from Ghostscript's bbox device and takes more memory and time. It has the advantage of correctly dealing with invisible elements, which are not cut off by Ghostscript's bbox.";\

UnPSfragOutputFormats::usage="Option for UnPSfrag that contains a list of devices triplets, i.e. {{gsdev1, suffix1, opts1},...,{gsdevN, suffixN, optsN}}. gsdev is a string containing the Ghostscript device like png, pdf and so forth. The suffix is for the filename and should contain a leading dot, i.e. '.png', '.pdf'. The options are passed to the respective Ghostscript call and allow to set additional options. In particular the resolution and the anti-aliasing settings. ";\

ExtraMargin::usage="Option for UnPSfrag that is an Integer by which the bounding box is extended in all directions. This defaults to 1 and is a safety measure agains rounding errors.";\

MasterTeXFile::usage="Option for UnPSfrag that contains the full TeX file that is used to convert the psfrag-EPS into a final PostScript version. Then Ghostscript is used to convert this pure PostScript file into other formats.";\

LaTeXExecutable::usage=
    "Option for UnPSfrag that is a string containing an absolute or relative name of the 'latex' command. On unices this will usually be in the system path, so no change will be required in most cases. On Windows systems 'latex' neither has a standard location nor is it necessarily in one of the folders given in the system's PATH environment variable. In that case, you will have to manually search the 'latex' program and set the absolute path explicitly, e.g. LaTeXExecutable->\"C:\\Programs\\texmf\\bin\\latex\". Also make sure to set the correct values of DvipsExecutable and GhostscriptExecutable. You can check your configuration with MathPSfragConfigurationTest. The MathPSfrag-Test.nb notebook gives a step-by-step guide for the correct configuration of UnPSfrag. Also have a look at PersonalMathPSfragConfiguration.";\

DvipsExecutable::usage="Option for UnPSfrag that is a string containing an absolute or relative name of the 'dvips' command. On unices this will usually be in the system path, so no change will be required in most cases. On Windows systems 'dvips' neither has a standard location nor is it necessarily in one of the folders given in the system's PATH environment variable. In that case, you will have to manually search the 'dvips' program and set the absolute path explicitly, e.g. DvipsExecutable->\"C:\\Programs\\texmf\\bin\\dvips\". Also make sure to set the correct values of LaTeXExecutable and GhostscriptExecutable. You can check your configuration with MathPSfragConfigurationTest. The MathPSfrag-Test.nb notebook gives a step-by-step guide for the correct configuration of UnPSfrag. Also have a look at PersonalMathPSfragConfiguration.";
GhostscriptExecutable::usage=
  "Option for UnPSfrag that is a string containing an absolute or relative name of the Ghostscript command. On unices this defaults to 'gs' and will usually be in the system path, so no change will be required in most cases. Sometimes you have to change this to 'gs-gpl'. On Windows systems, this option defaults to 'gswin32c', but the program neither has a standard location nor is it necessarily in one of the folders given in the system's PATH environment variable. In that case, you will have to manually search the 'gswin32c' program and set the absolute path explicitly, e.g. GhostscriptExecutable->\"C:\\Programs\\texmf\\bin\\latex\". Also make sure to set the correct values of LaTeXExecutable and DvipsExecutable. You can check your configuration with MathPSfragConfigurationTest. The MathPSfrag-Test.nb notebook gives a step-by-step guide for the correct configuration of UnPSfrag. Also have a look at PersonalMathPSfragConfiguration.";\


Global`$PostMathPSfrag::usage="This variable can be used to permanently configure your MathPSfrag by setting personal default values any options. It is meant for the UnPSfrag options LaTeXExecutable, DvipsExecutable, GhostscriptExecutable. This (by default undefined) variable can and should be set *before* loading MathPSfrag as one might want to in an 'init.m' file. (See your help browser.) Always use the delayed assignment operator \":=\" to set the value of $PostMathPSfrag. A typical usage reads as follows:
    
    $PostMathPSfrag := SetOptions[UnPSfrag, LaTeXExecutable->\"C:\\\\mypaththo\\\\latex\", DvipsExecutable->\"C:\\\\mypathto\\\\dvips\", GhostscriptExecutable->\"C:\\\\mypathto\\\\gswin32c\"]. Of course you have to fill in the apropriate pathes and file names for your operating system. See also the help text of those three options and have a look at the MathPSfrag-Test.nb notebook.";



$MathPSfragGlobal`$MasterTeXFile:=
    
    "\\documentclass{article}\n"<>
      "\\usepackage{graphicx}\n"<>
      "\\usepackage{psfrag}\n"<>

            "\\usepackage{amsmath}\n"<>
      "%%%TeXPreamble%%% %\n"<>
      
      "\\pagestyle{empty}\n"<>
      If[$VersionNumber\[GreaterEqual]5.1,"",
        "\\IfFileExists{"<>$MathPSfragGlobal`Mma4TeX<>".sty}%\n"<>
          
          "  {\\usepackage{mma4tex}\\typeout{Style "<>$MathPSfragGlobal`\
Mma4TeXFound<>"}}%\n"<>
          
          "  {\\typeout{Style file: "<>$MathPSfragGlobal`Mma4TeXMissing<>
          "}}%\n"
        ]<>
      "\\begin{document}\n"<>
      "\\begin{psfrags}\n"<>

            "%%%PSfragCommands%%% %\n"<>
      "\\includegraphics[%%%IncludeGraphicsOptions%%%]{input.eps}\n"<>

            "\\end{psfrags}\n"<>
      "\\end{document}";

$MathPSfragGlobal`LaTeXLog="This variable contains the whole log file of the last LaTeX run performed by UnPSfrag. It may be quite long and you may consider using NextLaTeXError[] to see the first error message only.";



UnPSfrag::usage="UnPSfrag[{outputprefix,epsinput,texinput},opts] transforms EPS graphics relying on \\psfrag commands into a standalone graphics. outputprefix should give a valid filename when a suffix like '.eps' or '.pdf' is appended. 

Example:
\tUnPSfrag[PSfragExport[\"example\",myplot]];
or
\tPSfragExport[\"example\",myplot]//UnPSfrag;";



GenerateTemporaryName::usage="GenerateTemporaryName[\"prepend\"] creates a string that can be used as a unique file name and starts with a given string \"prepend\".";



BoundingBoxFromRaster::usage=
  "BoundingBoxFromRaster[rastergraphics,extramargin] returns the smallest rectangle around the non empty region of rastergraphics. This rectangle is enlarged by extramargin in all directions."



PatchType1FontIntoEps::usage="PatchType1FontIntoEps['infile','outfile'] copies missing fonts into an EPS file. This is a hack that will result in possibly usable but not standard conformant eps files. The upshot: DO NOT USE THIS. You will not need this when you replace all expressions with MathPSfrag, which is a clean solution.";



FetchGhostscriptDevices::usage="FetchGhostscriptDevices[tempfilename] calls Ghostscript to find out which devices listed in $MathPSfragGlobal`PredefGsDevices are supported by the particular version of Ghostscript on this system.";

$MathPSfragGlobal`PredefGsDevices={
      "RumpelStilzchen",(* RumpelStilzchen will never be available, 
        it is just a test for the test *)
      "alc1900", "alc2000", 
      "alc4000", "alc4100", "alc8500", "alc8600", "alc9100", "ap3250", 
      "appledmp", "atx23", "atx24", "atx38", "bbox", "bit", "bitcmyk", 
      "bitrgb", "bitrgbtags", "bj10e", "bj10v", "bj10vh", "bj200", "bjc600", 
      "bjc800", "bjc880j", "bjccmyk", "bjccolor", "bjcgray", "bjcmono", 
      "bmp16", "bmp16m", "bmp256", "bmp32b", "bmpgray", "bmpmono", "bmpsep1", 
      "bmpsep8", "ccr", "cdeskjet", "cdj1600", "cdj500", "cdj550", "cdj670", 
      "cdj850", "cdj880", "cdj890", "cdj970", "cdjcolor", "cdjmono", "cfax", 
      "cgm24", "cgm8", "cgmmono", "chp2200", "cif", "cljet5", "cljet5c", 
      "cljet5pr", "coslw2p", "coslwxl", "cp50", "cups", "declj250", 
      "deskjet", "devicen", "dfaxhigh", "dfaxlow", "display", "dj505j", 
      "djet500", "djet500c", "dl2100", "dnj650c", "epl2050", "epl2050p", 
      "epl2120", "epl2500", "epl2750", "epl5800", "epl5900", "epl6100", 
      "epl6200", "eps9high", "eps9mid", "epson", "epsonc", "epswrite", 
      "escp", "escpage", "faxg3", "faxg32d", "faxg4", "fmlbp", "fmpr", 
      "fs600", "gdi", "hl1240", "hl1250", "hl7x0", "hpdj1120c", "hpdj310", 
      "hpdj320", "hpdj340", "hpdj400", "hpdj500", "hpdj500c", "hpdj510", 
      "hpdj520", "hpdj540", "hpdj550c", "hpdj560c", "hpdj600", "hpdj660c", 
      "hpdj670c", "hpdj680c", "hpdj690c", "hpdj850c", "hpdj855c", "hpdj870c", 
      "hpdj890c", "hpdjplus", "hpdjportable", "ibmpro", "ijs", "imagen", 
      "imdi", "inferno", "iwhi", "iwlo", "iwlq", "jetp3852", "jj100", "jpeg", 
      "jpegcmyk", "jpeggray", "la50", "la70", "la75", "la75plus", "laserjet", 
      "lbp310", "lbp320", "lbp8", "lex2050", "lex3200", "lex5700", "lex7000", 
      "lips2p", "lips3", "lips4", "lips4v", "lj250", "lj3100sw", "lj4dith", 
      "lj4dithp", "lj5gray", "lj5mono", "ljet2p", "ljet3", "ljet3d", "ljet4", 
      "ljet4d", "ljet4pjl", "ljetplus", "ln03", "lp1800", "lp1900", "lp2000", 
      "lp2200", "lp2400", "lp2500", "lp2563", "lp3000c", "lp7500", "lp7700", 
      "lp7900", "lp8000", "lp8000c", "lp8100", "lp8200c", "lp8300c", 
      "lp8300f", "lp8400f", "lp8500c", "lp8600", "lp8600f", "lp8700", 
      "lp8800c", "lp8900", "lp9000b", "lp9000c", "lp9100", "lp9200b", 
      "lp9200c", "lp9300", "lp9400", "lp9500c", "lp9600", "lp9600s", 
      "lp9800c", "lps4500", "lps6500", "lq850", "lx5000", "lxm3200", 
      "lxm5700m", "m8510", "mag16", "mag256", "md1xMono", "md2k", "md50Eco", 
      "md50Mono", "md5k", "mgr4", "mgr8", "mgrgray2", "mgrgray4", "mgrgray8", 
      "mgrmono", "miff24", "mj500c", "mj6000c", "mj700v2c", "mj8000c", 
      "ml600", "necp6", "npdl", "nullpage", "oce9050", "oki182", "oki4w", 
      "okiibm", "omni", "oprp", "opvp", "paintjet", "pam", "pbm", "pbmraw", 
      "pcl3", "pcx16", "pcx24b", "pcx256", "pcx2up", "pcxcmyk", "pcxgray", 
      "pcxmono", "pdfwrite", "pgm", "pgmraw", "pgnm", "pgnmraw", "photoex", 
      "picty180", "pj", "pjetxl", "pjxl", "pjxl300", "pkm", "pkmraw", "pksm", 
      "pksmraw", "plan9bm", "png16", "png16m", "png256", "png48", "pngalpha", 
      "pnggray", "pngmono", "pnm", "pnmraw", "ppm", "ppmraw", "pr1000", 
      "pr1000_4", "pr150", "pr201", "ps2write", "psdcmyk", "psdrgb", 
      "psgray", "psmono", "psrgb", "pswrite", "pxlcolor", "pxlmono", "r4081", 
      "rpdl", "samsunggdi", "sgirgb", "sj48", "spotcmyk", "st800", "stcolor", 
      "sunhmono", "t4693d2", "t4693d4", "t4693d8", "tek4696", "tiff12nc", 
      "tiff24nc", "tiff32nc", "tiffcrle", "tiffg3", "tiffg32d", "tiffg4", 
      "tiffgray", "tifflzw", "tiffpack", "tiffsep", "uniprint", "wtscmyk", 
      "wtsimdi", "x11", "x11alpha", "x11cmyk", "x11cmyk2", "x11cmyk4", 
      "x11cmyk8", "x11gray2", "x11gray4", "x11mono", "xcf", "xes"
      };
(*{"pbm","pnm","pnggray","pngmono","png16m","pdfwrite","epswrite","bbox"}*)



MathPSfragConfigurationTest::usage="MathPSfragConfigurationTest[tempfile,opts] checks the configuration of UnPSfrag (see there). tempfile is by default a (hopefully) unique name generated from $SessionId. It is written to the current directory. By default the test is not carried out if tempfile already exists, though you can set ForceOverwrite->True as an option to change that. Be careful. It may be better to simply provide a different name for tempfile.";



(*LinTickify::usage=
      "LinTickify[gr] tries to automatically create beautiful tick marks by using LinTicks of CustomTicks. This only works when the CustomTicks package is installed and loaded. See also the ApplyLinTicks option of HandleAutomaticPSfrag. Typical usage: PSfragExport[LinTickify[plot]]//UnPSfrag;";\
*)



RawTeX::usage="Wrap around any expression to make PSfrag leave it alone.";





Begin["`Private`"]





Format[RawTeX[expr_],StandardForm]:=StandardForm[expr];
Format[RawTeX[expr_],OutputForm]:=OutputForm[expr];
Format[RawTeX[expr_],TraditionalForm]:=TraditionalForm[expr];


Format[PSfragEntry[_,Visible\[Rule]"Expression",x___],StandardForm]:=
    StandardForm[Expression/.{x}];
Format[PSfragEntry[_,Visible\[Rule]"Expression",x___],OutputForm]:=
    OutputForm[Expression/.{x}];
Format[PSfragEntry[_,Visible\[Rule]"Expression",x___],TraditionalForm]:=
    TraditionalForm[Expression/.{x}];

Format[PSfragEntry[_,Visible\[Rule]"Tag",x__],StandardForm]:=
    OutputForm[(*$MathPSfragGlobal`SurroundTags<>*)(PSfragTag/.{x})(*<>$\
MathPSfragGlobal`SurroundTags*)];
Format[PSfragEntry[_,Visible\[Rule]"Tag",x__],OutputForm]:=
    OutputForm[(*$MathPSfragGlobal`SurroundTags<>*)
        PSfragTag/.{x}(*<>$MathPSfragGlobal`SurroundTags*)];
Format[PSfragEntry[_,Visible\[Rule]"Tag",x__],TraditionalForm]:=
    OutputForm[(*$MathPSfragGlobal`SurroundTags<>*)
        PSfragTag/.{x}(*<>$MathPSfragGlobal`SurroundTags*)];



PSfragTicks[None,opts___Rule]:=None;
PSfragTicks[Automatic,opts___Rule]:=Automatic;
PSfragTicks[pos_?VectorQ,opts___Rule]:=PSfrag[#,opts]&/@pos;
PSfragTicks[pos_List,opts___Rule]/;Depth[pos]\[GreaterEqual]3:=
    MapAt[Function[{label},PSfrag[label,opts]],#,{2}]&/@pos;



myprivatecounter=0;
GenerateTemporaryName[prepend_String]:=
    prepend<>ToString[$SessionID]<>ToString[myprivatecounter++];



NumberToTeX[nb_Complex,opts___Rule]:=
    
    If[(ChopImaginaryPart/.{opts}/.Options[NumberToTeX])===True&&
        Chop[Im[nb]]===0,
      NumberToTeX[Re[nb],opts],
      NumberToTeX[Re[nb],opts]<>"+"<>NumberToTeX[Im[nb],opts]<>"i"];

NumberToTeX[nb_Integer,opts___Rule]:=
    
    If[(IntegerToReal/.{opts}/.Options[NumberToTeX])===True,
      If[nb===0,NumberToTeX[0.0],NumberToTeX[1.0*nb,opts]],
      ToString[nb]];

NumberToTeX[nb_Rational,opts___Rule]:=
    
    If[(RationalToReal/.{opts}/.Options[NumberToTeX])===True,
      NumberToTeX[nb*1.,opts],
      "\\frac{"<>ToString[Numerator[nb]]<>"}{"<>ToString[Denominator[nb]]<>
        "}"];

NumberToTeX[nb_Real,opts___Rule]:=
  
  Module[{ipartdigits,fpartdigits,mantis,expo,fractionstr},
    If[(Integerize/.{opts}/.Options[NumberToTeX])===True&&
        Chop[nb-IntegerPart[nb]]===0,
      NumberToTeX[IntegerPart[nb],IntegerToReal\[Rule]False,opts],
      (* else *)
      {ipartdigits,
          fpartdigits}={IntegerPartDigits,
              FractionalPartDigits}/.{opts}/.Options[NumberToTeX];
      {mantis,expo}=MantissaExponent[nb];
      mantis=Round[mantis*10^(ipartdigits+fpartdigits)]*10^(-fpartdigits);
      expo=expo-ipartdigits;
      If[Chop[nb]===0,mantis=0;expo=0];
      
      fractionstr=ToString[FractionalPart[mantis]*10^fpartdigits];
      If[(ChopFractionPart/.{opts}/.Options[NumberToTeX])===True&&
          fractionstr==="0",fpartdigits=0];
      fractionstr=
        StringJoin[Table["0",{fpartdigits-StringLength[fractionstr]}],
          fractionstr];
      
      StringJoin[
        ToString[IntegerPart[mantis]],
        If[fpartdigits>0,"."<>fractionstr,""],
        If[(ChopExponent/.{opts}/.Options[NumberToTeX])===True&&expo===0,"",
          {ExponentSymbol/.{opts}/.Options[NumberToTeX],
            " {"<>ToString[expo]<>"}"}]
        ]
      ](*endif*)
    ]





allowedPosition=
    Flatten[{Automatic,Outer[StringJoin,{"B","t","c","b"},{"l","c","r"}]}];

ToTagForm[gr_]:=
    gr/.PSfragEntry[a_,Visible\[Rule]"Expression",z__]\[Rule]
        PSfragEntry[a,Visible\[Rule]"Tag",z];
(*ToExprForm[gr_Graphics]:=
      gr/.PSfragEntry["Tag",z__]\[Rule]PSfragEntry["Expression",z];*)



TextOffsetToTeXOffset[Automatic]=TextOffsetToTeXOffset[Center];
TextOffsetToTeXOffset[a:(Center|Left|Right)]:=
    TextOffsetToTeXOffset[{a,Center}];
TextOffsetToTeXOffset[a:(Top|Bottom)]:=TextOffsetToTeXOffset[{Center,a}];
TextOffsetToTeXOffset[{a:(Left|Right|Center),b_}]:=
    TextOffsetToTeXOffset[{a/.{Left\[Rule]-1,Center\[Rule]0,Right\[Rule]1},
        b}];
TextOffsetToTeXOffset[{a_,b:(Top|Bottom|Center)}]:=
    TextOffsetToTeXOffset[{a,
        b/.{Top\[Rule]-1,Center\[Rule]0,Bottom\[Rule]1}}];

TextOffsetToTeXOffset[{x_?NumericQ,y_?NumericQ}]:=
    Sort[MapThread[
          List,{Tr[(#-{y,x})^2]&/@
              Flatten[Outer[List,{-1/3,1,0,-1},{-1,0,1}],1],
            Flatten[Outer[StringJoin,{"B","t","c","b"},{"l","c","r"}]]}],
        Less[First[#1],First[#2]]&][[1,2]];



TextOrientationToTeXOrientation[{x_,y_}]:=
    Module[{ang=Round[N[180/Pi Arg[x+I*y]]]},If[ang<0,ang+360,ang]];



PSfrag::badpos="Option `1` has bad value `2`. Use ?`1` to see allowed values.";\

PSfrag::nonum="Option `1` has value `2`, which is neither numeric nor Automatic.";\

PSfrag::badtag="Option PSfragTag->`1` contained non-alphanumeric characters. `2` will be used instead.";\

PSfrag::notex="Option TeXCommand->`1` did not yield a string, but `2`."









(*PSfrag[x_List]:=PSfrag/@x;*)

PSfrag[x_List,TeXCommand\[Rule]y_List]/;(Length[x]===Length[y]):=
    MapThread[PSfrag[#1,TeXCommand\[Rule]#2]&,{x,y}];
(*PSfrag[x_List,opts:({_\[Rule]y_/;Head[y]=!=List}..)]:=PSfrag[#,opts]&/@x;*)



PSfrag[expr_,opts___Rule]:=
  Module[{teXCommand,position,pSPosition,rotation,scaling,pSfragTag,teXShiftX,
      teXShiftY,x,y,dummy,fallback},
    {teXCommand,position,pSPosition,rotation,scaling,pSfragTag,teXShiftX,
        teXShiftY,
        fallback}={TeXCommand,TeXPosition,PSPosition,PSRotation,PSScaling,
          PSfragTag,TeXShiftX,TeXShiftY,
          FallBack}/.(Join[{opts},
              Options[PSfrag]]/.(TeXShift\[Rule]{x_,y_})\[Rule]
              Unevaluated[Sequence[TeXShiftX\[Rule]x,TeXShiftY\[Rule]y]]);
    
    MathPSfragDebug["PSfrag",expr,opts];
    
    If[expr==="",Return[""]];
    
    (* if teXCommand is a string, 
      no work is to be done. For Automatic postpone. *)
    (* 
      but if teXCommand is neither, 
      its assumed to be a function that should return a string or Automatic. *)

        If[teXCommand=!=Automatic&&Head[teXCommand]=!=String,
      dummy=teXCommand[expr];
      If[dummy=!=Automatic&&Head[dummy]=!=String,
        Message[PSfrag::notex,teXCommand,dummy];teXCommand=Automatic,
        teXCommand=dummy;
        ]];
    (* By now, 
      teXCommand is either a string or Automatic. 
          Automatic means we use GuessTeX, 
      RawTeX always overrides any TeXCommand *)
    
    If[Head[expr]===RawTeX,teXCommand=expr[[1]],
      If[teXCommand===Automatic,
        teXCommand=GuessTeX[expr]; 
        If[Head[teXCommand]=!=String,
          Message[PSfrag::notex,Automatic,teXCommand];
          teXCommand="Automatic failed"]
        ]];
    
    If[!MemberQ[allowedPosition,position],
      Message[PSfrag::badpos,"TeXPosition",position]; position="Bc"];
    
    If[pSPosition===CopyTeXPosition,pSPosition=position];
    If[!MemberQ[allowedPosition,pSPosition],
      Message[PSfrag::badpos,"PSPosition",pSPosition]; pSPosition="Bc"];
    (*If[pSPosition===Automatic,pSPosition=position];*)
    
    If[!MemberQ[allowedPosition,fallback],
      Message[PSfrag::badpos,"FallBack",fallback]; fallback="Bc"];
    If[fallback===Automatic,fallback="Bc"];
    
    If[pSfragTag===Automatic,pSfragTag=GuessTag[expr]];
    If[Head[pSfragTag]===Automatic,
      pSfragTag=GuessTag[expr,ToString[pSfragTag[[1]]]]];
    If[!LatinNumQ[pSfragTag],
      Message[PSfrag::badtag,pSfragTag,pSfragTag=GuessTag[expr]] ];
    
    If[!NumericQ[scaling]&&(scaling=!=Automatic),
      Message[PSfrag::nonum,"PSScaling",scaling];scaling=Automatic];
    If[scaling===Automatic,scaling=1];
    If[!NumericQ[rotation]&&(rotation=!=Automatic),
      Message[PSfrag::nonum,"PSRotation",rotation];rotation=Automatic];
    If[rotation===Automatic,rotation=0];
    
    If[1.0*ToExpression[teXShiftX]==0.,teXShiftX="0pt"];
    If[NumericQ[teXShiftX],
      teXShiftX=ToString[AccountingForm[Re[teXShiftX]]]<>"pt"];
    If[1.0*ToExpression[teXShiftY]==0.,teXShiftY="0pt"];
    If[NumericQ[teXShiftY],
      teXShiftY=ToString[AccountingForm[Re[teXShiftY]]]<>"pt"];
    
    PSfragEntry[Status\[Rule]"WaitForTextWrapping",Visible\[Rule]"Expression",
      Expression\[Rule]expr,TeXCommand\[Rule]teXCommand,
      TeXPosition\[Rule]position,PSPosition\[Rule]pSPosition,
      PSScaling\[Rule]scaling,PSRotation\[Rule]rotation,
      TeXShiftX\[Rule]teXShiftX,TeXShiftY\[Rule]teXShiftY,
      PSfragTag\[Rule]pSfragTag,FallBack\[Rule]fallback]
    ]







(* old code:
        Text[
          HoldPattern[
            PSfragEntry[Status\[Rule]"WaitForTextWrapping",furtheropts___]],
          pos_,offset_:{0,0},dir_:{1,0},opts___]^:=
    Text[PSfragEntry[Status\[Rule]"WaitForTextWrapping",
        Sequence@@({furtheropts}/.((psarg:(TeXPosition|PSPosition))\[Rule]
                    Automatic)\[Rule](psarg\[Rule]
                    TextOffsetToTeXOffset[offset]))],pos,offset,dir,opts]
  *)

(Text[HoldPattern[
                PSfragEntry[Status\[Rule]"WaitForTextWrapping",
                  furtheropts___]],pos_,offset_,dir_,opts___]/;Head[pos]=!=
          Rule&&Head[offset]=!=Rule&&Head[dir]=!=Rule&&
        SameQ[Rule,Sequence@@(Head/@{opts})])^:=
    finalText[{furtheropts},pos,offset,dir,opts];
(Text[HoldPattern[
            PSfragEntry[Status\[Rule]"WaitForTextWrapping",furtheropts___]],
          pos_,offset_,opts___]/;
        Head[pos]=!=Rule&&Head[offset]=!=Rule&&
          SameQ[Rule,Sequence@@(Head/@{opts})])^:=
    finalText[{furtheropts},pos,offset,{1,0},opts];
(Text[HoldPattern[
            PSfragEntry[Status\[Rule]"WaitForTextWrapping",furtheropts___]],
          pos_,opts___]/;
        Head[pos]=!=Rule&&SameQ[Rule,Sequence@@(Head/@{opts})])^:=
    finalText[{furtheropts},pos,{0,0},{1,0},opts];

finalText[{furtheropts___},pos_,offset_,dir_,opts___Rule]:=
  
  Text[PSfragEntry[Status\[Rule]"WaitForTextWrapping",
      Sequence@@({furtheropts}/.
            ((psarg:(TeXPosition|
                          PSPosition))\[Rule]Automatic)\[Rule](psarg\[Rule]
                  TextOffsetToTeXOffset[offset]))],pos,offset,dir,opts]



PSfragEntry[Status\[Rule]"WaitForTextWrapping",
      rest__/;FreeQ[{TeXPosition,PSPosition}/.{rest},Automatic]]=
    PSfragEntry[Status\[Rule]"Final",rest];





GuessTeX[expression_]:=Module[{prerules,postrules,exclusiverules},
    exclusiverules=
      Sort[Select[
          ReplacementHookExclusive/.Options[
                GuessTeX]/.ReplacementHookExclusive\[Rule]{},
          (#[[2]])[expression]&],OrderedQ[{First[#2],First[#1]}]];
    If[exclusiverules=!={},
      Return[(exclusiverules[[1,3]])[expression]]];
    
    {prerules,postrules}=Transpose[Join[{{Null,Null,Identity,Identity}},Sort[
              
              Select[ReplacementHookCooperative/.Options[
                      GuessTeX]/.ReplacementHookCooperative\[Rule]{},((#[[2]])\
[expression])&],
              OrderedQ[{First[#2],First[#1]}]&
              ]][[All,{3,4}]]];
    (Composition@@postrules)[
      ToString[TeXForm[(Composition@@prerules)[expression]]]]
    ]

GuessTag[expr_,prepend_:""]:=Module[{guessed,x,expression},
    expression=
      If[Head[expr]===Real,
        If[Chop[expr]===0,"0",
          StringJoin[
            ToString/@({10*#1,#2/.(0->"")}&@@MantissaExponent[expr])]],expr];
    If[Head[expression]===PaddedForm,expression=ToString[expression]];
    guessed=
      StringReplace[
        StringJoin[prepend,
          Flatten[ReplaceAll[
              Map[Characters,
                ReplaceAll[
                  Characters[
                    StringReplace[
                      ToString[InputForm[expression]],{"-"->"m",
                        "Subscript"\[Rule]"","PaddedForm"\[Rule]"",
                        "HoldForm"->""}]],
                  (x_/;!LatinNumQ[x])\[RuleDelayed]
                    ToString[FullForm[x]]]],(x_/;!LatinNumQ[x])\[Rule]{}]]],
        "Capital"\[Rule]"C"];
    
    If[StringLength[guessed]<(MinimumTagLength/.Options[GuessTag]),
      guessed=StringJoin[guessed,
          Table["psfrag",{Ceiling[(MinimumTagLength/.Options[GuessTag])/
                  6]}]]];
    (*If[!LatinQ[StringTake[guessed,1]],guessed="a"<>guessed];*)
    
    If[StringLength[guessed]>(MaximumTagLength/.Options[GuessTag]),
      StringTake[guessed,(MaximumTagLength/.Options[GuessTag])],guessed]
    ] (*GuessTag*)







UniquePSfragTagQ[psfragentrycontent:{__Rule}]:=Module[{tag},
    tag=(PSfragTag/.psfragentrycontent);
    If[Head[PSfragStore[tag]]===PSfragStore,
      (* nothing stored yet, so we are unique *)
      
      PSfragStore[tag]=Sort[psfragentrycontent]; True,
      (*else, 
        see if we stored exactly the same content *)
      (PSfragStore[tag]===
          Sort[psfragentrycontent])
      ]
    ]



UniquePSfragTag[psfragentrycontent:{__Rule}]:=
  
  Module[{tag=ToString[(PSfragTag/.psfragentrycontent)],newtag,i=0},
    If[!LatinQ[StringTake[tag,1]],tag=$MathPSfragGlobal`SurroundTags<>tag];
    newtag=tag;
    While[!UniquePSfragTagQ[
          psfragentrycontent/.(PSfragTag\[Rule]_)\[Rule](PSfragTag\[Rule]
                  newtag)],newtag=tag<>NumToBase52[i++]];
    newtag
    ]



ClearPSfrag:=Clear[PSfragStore];



TeXifyPSfrag[psfragentrycontent:{__Rule}]:= 
  Module[{expr,TeX,posn,psposn,scaling,rot,shiftx,shifty,tag},
    {expr,TeX,posn,psposn,scaling,rot,shiftx,shifty,tag}=
      ToString/@({Expression,TeXCommand,TeXPosition,PSPosition,PSScaling,
              PSRotation,TeXShiftX,TeXShiftY,PSfragTag}/.psfragentrycontent);
    tag=StringJoin[
        "{",(*$MathPSfragGlobal`SurroundTags,*)
          tag,(*$MathPSfragGlobal`SurroundTags,*)"}"];
    psposn=If[psposn=="Bl","",StringJoin["[",psposn,"]"]];
    posn=If[posn==="Bl","",StringJoin["[",posn,"]"]];
    scaling=If[scaling==="1","",StringJoin["[",scaling,"]"]];
    rot=If[rot==="0","",StringJoin["[",rot,"]"]];
    TeX="\\PFGstyle "<>TeX;
    TeX=If[shiftx\[Equal]shifty\[Equal]"0pt",
        StringJoin["{",TeX,"}"],
        StringJoin["{\\PFGshift(",shiftx,",",shifty,"){",TeX,"}"]
        ];
    
    StringJoin["\\psfrag",tag,posn,psposn,scaling,rot,TeX,"%\n"]
    ]



FallBackToStatic[opts___]:=Module[{newopts},
      newopts={opts}/.{(TeXPosition\[Rule]Automatic)\[Rule](TeXPosition\[Rule]
                  "Bc"),(PSPosition\[Rule]Automatic)\[Rule](PSPosition\[Rule]
                  "Bc")};
      Sequence@@newopts
      ];

CreatePSfragRules::incomplete="Ran into incompletely processed PSfrag entry. This should never happen. Please contact the author. (Content: `1`).";

CreatePSfragRules[expr_,opts___]:=
    Module[{psfragcoms={},newtag,newcontent,PSfragTagNb=1,
        reNb=RenumberTags/.{opts}/.Options[CreatePSfragRules]},
      ClearPSfrag;
      Reverse[{Short[
            expr/.PSfragEntry[
                  content__]:>
                (newcontent={content};
                  If[(Status/.newcontent)=!="Final",
                    Message[CreatePSfragRules::incomplete,newcontent];
                    newcontent={FallBackToStatic[content]}];
                  
                  newtag=If[reNb===True,NumToBase52[PSfragTagNb++],
                      UniquePSfragTag[newcontent]];
                  
                  newcontent=
                    newcontent/.(PSfragTag\[Rule]_)\[Rule](PSfragTag\[Rule]
                            newtag);
                  psfragcoms={psfragcoms,TeXifyPSfrag[newcontent]};
                  PSfragEntry@@newcontent)],
          "% -- content from the PSfragPrologue option --\n"<>  
            StringReplace[PSfragPrologue/.{opts}/.Options[CreatePSfragRules],
              
              "%%%EPSFILENAME%%%"\[Rule]ToString[
                  EPSFILENAME/.{opts}/.EPSFILENAME\[Rule]""]]<>
            "% -- end of PSfragPrologue option --\n%\n% psfrag replacement commands\n"<>
            Apply[StringJoin,Union[Flatten[psfragcoms]]]<>"%"}
        ]];





TextToPSfrag[x_]:=
    x/.{Text[fst_/;Head[fst]=!=PSfragEntry,rest__]\[RuleDelayed]
          Text[PSfrag[fst],rest]};





ComplementFilterOptions[commands__,opts___Rule]:=
    Sequence@@Complement[{opts},FilterOptions[#,opts]&/@{commands}];



PSfragManualExport[filename_String,gr:(_Graphics|_Graphics3D),opts___Rule]:=
    Module[
      {sanefilename=filename,
        checksuffix=ToLowerCase[StringTake[filename,-4]],
        epsname,texname},
      
      If[checksuffix===".eps"||checksuffix===".pdf",
        sanefilename=StringDrop[filename,-4]];
      
      epsname=sanefilename<>(EpsSuffix/.{opts}/.Options[PSfragExport]);
      texname=sanefilename<>(TeXSuffix/.{opts}/.Options[PSfragExport]);
      
      If[sanefilename=!=filename,
        Message[PSfragExport::suffix,epsname,texname]];
      psfragmanualexport[sanefilename,epsname,texname,gr,opts]
      ];

psfragmanualexport[filename_String,epsname_String,texname_String,
      gr:(_Graphics|_Graphics3D),opts___Rule]:=Module[{
        ostream,graphicWithUniqueTags,
        exportoptions=FilterOptions[Export,opts],
        createoptions=FilterOptions[CreatePSfragRules,opts],
        showoptions
        },
      MathPSfragDebug["psfragmanualexport",filename,epsname,texname,gr,opts];
      
      showoptions=
        Sequence@@
          Complement[{opts},{exportoptions},{FilterOptions[PSfragExport,
                opts]},{createoptions}];
      
      (* Complain about any PSfragEntry that requires Automatic to be \
handled. *)
      graphicWithUniqueTags=CreatePSfragRules[
          
          gr/.HoldPattern[
                PSfragEntry[a___,b:((TeXPosition|PSPosition)\[Rule]Automatic),
                  c___]]\[RuleDelayed](Message[
                  PSfragExport::staticdef,{a,b,c}];
                PSfragEntry[FallBackToStatic[a,b,c]]),
          EPSFILENAME\[Rule]epsname,createoptions];
      
      (* For error diagnosis, store main result in global variable *)
      
      Unprotect[$MathPSfragGlobal`PSfragExportResult];
      $MathPSfragGlobal`PSfragExportResult={graphicWithUniqueTags[[1]],
          ToTagForm[
            Show[graphicWithUniqueTags[[2,1]],showoptions,
              DisplayFunction\[Rule]Identity]]};
      Protect[$MathPSfragGlobal`PSfragExportResult];
      
      ostream=OpenWrite[texname];
      WriteString[ostream,$MathPSfragGlobal`PSfragExportResult[[1]]];
      Close[ostream];
      
      (* Return filename, epsname, texname *)
      {filename,
        Export[epsname,$MathPSfragGlobal`PSfragExportResult[[2]],"EPS"],
        texname}
      ];





PSfragExport::staticdef="Warning: Found 'Automatic' in Alignment argument (`1`). Fallback values are being used.";\

PSfragExport::suffix="Warning: Your filename has a .pdf or .eps suffix, which I stripped. Output files will be `1` and `2`.";



applyPSfragWrapper[arg_,wrapper_]:=
    If[arg=!=None&&Head[arg]=!=PSfragEntry,wrapper[arg],arg];

HandleTickAxis[None,_]:=None;
HandleTickAxis[arg_List/;!MemberQ[Head/@arg,List],
      psfragwrapper_]:={#,applyPSfragWrapper[#,psfragwrapper]}&/@arg;
HandleTickAxis[arg:{{__}..},psfragwrapper_]:=
    Replace[arg,({a_,b_/;(b=!=""),c___}\[RuleDelayed]{a,
            applyPSfragWrapper[b,psfragwrapper],c}),{1}];

HandleAxesLabel[{x_,y_},_List]:={applyPSfragWrapper[x,FormatAxesLabelX],
      applyPSfragWrapper[y,FormatAxesLabelY]};
HandleAxesLabel[arg_/;(Head[arg]=!=List),_List]:=
    applyPSfragWrapper[arg,FormatAxesLabelY];

HandlePlotLabel[arg_,_List]:=applyPSfragWrapper[arg,FormatPlotLabel];

HandleFrameLabel[None,_List]:=None;
HandleFrameLabel[arg_/;(Head[arg]=!=List),_List]:=
    applyPSfragWrapper[arg,FormatFrameLabelSouth];
HandleFrameLabel[{x_,y_}/;!(Head[x]===Head[y]===List),otheropts_List]:={
      applyPSfragWrapper[x,FormatFrameLabelSouth],
      If[True===(RotateLabel/.otheropts),
        applyPSfragWrapper[y,FormatFrameLabelEastRotated],
        applyPSfragWrapper[y,FormatFrameLabelEast]
        ]
      };
HandleFrameLabel[{{w_,e_},{s_,n_}},otheropts_List]:=
    HandleFrameLabel[{s,w,n,e},otheropts];
HandleFrameLabel[{s_,w_,n_,e_},otheropts_List]:=Module[{ns,nw,nn,ne},
      {ns,nw,nn,ne}={
          applyPSfragWrapper[s,FormatFrameLabelSouth],
          (*Print["Rotated:",otheropts];*)
          
          If[True===(RotateLabel/.otheropts),
            applyPSfragWrapper[w,FormatFrameLabelWestRotated],
            applyPSfragWrapper[w,FormatFrameLabelWest]
            ],
          applyPSfragWrapper[n,FormatFrameLabelNorth],
          If[True===(RotateLabel/.otheropts),
            applyPSfragWrapper[e,FormatFrameLabelEastRotated],
            applyPSfragWrapper[e,FormatFrameLabelEast]
            ]
          };
      If[TrueQ[$VersionNumber<6.0],{ns,nw,nn,ne},{{nw,ne},{ns,nn}}]
      ];

nolistQ[x_]:=Head[x]=!=List;
tickmarkspec=(None|Automatic|All|
        _?VectorQ|
        {{_?nolistQ,_?nolistQ}..}|
        {{_?nolistQ,_?nolistQ,_?nolistQ}..}|
        {{_?nolistQ,_?nolistQ,_?nolistQ,_}..}|
        {{_?nolistQ,_?nolistQ,{_?nolistQ,_?nolistQ}}..}|
        {{_?nolistQ,_?nolistQ,{_?nolistQ,_?nolistQ},_}..}
      );

HandleFrameTicks[None,_List]:=None;
HandleFrameTicks[{a:tickmarkspec,b:tickmarkspec,c:tickmarkspec,
        d:tickmarkspec},_List]:={
      HandleTickAxis[a,FormatFrameTicksSouth],
      HandleTickAxis[b,FormatFrameTicksWest],
      HandleTickAxis[c,FormatFrameTicksNorth],
      HandleTickAxis[d,FormatFrameTicksEast]
      };
HandleFrameTicks[{{a:tickmarkspec,b:tickmarkspec},{c:tickmarkspec,
          d:tickmarkspec}},_List]:={
      {HandleTickAxis[a,FormatFrameTicksWest],
        HandleTickAxis[b,FormatFrameTicksEast]},
      {HandleTickAxis[c,FormatFrameTicksSouth],
        HandleTickAxis[d,FormatFrameTicksNord]}
      };
HandleFrameTicks[{a:tickmarkspec,b:tickmarkspec},_List]:={
      HandleTickAxis[a,FormatFrameTicksSouth],
      HandleTickAxis[b,FormatFrameTicksEast]
      };

(*HandleFrameTicks[None,_List]:=None;
  HandleFrameTicks[{a_,b_,c_,d_},_List]:={
      HandleTickAxis[a,FormatFrameTicksSouth],
      HandleTickAxis[b,FormatFrameTicksWest],
      HandleTickAxis[c,FormatFrameTicksNorth],
      HandleTickAxis[d,FormatFrameTicksEast]
      };
  HandleFrameTicks[{a_,b_},_List]:={
      HandleTickAxis[a,FormatFrameTicksSouth],
      HandleTickAxis[b,FormatFrameTicksEast]
      };*)

HandleTicks[None,_List]:=None;
HandleTicks[x_/;(Head[x]=!=List),_List]:=HandleTickAxis[x,FormatTicksX];
HandleTicks[{x_,y_},_List]:={HandleTickAxis[x,FormatTicksX],
      HandleTickAxis[y,FormatTicksY]};

$MathPSfragGlobal`UniqueString="QMX";



HandleAutomaticPSfrag::unable="Expressions `1` could not be treated automatically. Fallback values used, position may be inacurate.";\

Off[HandleAutomaticPSfrag::unable];

HandleAutomaticPSfrag[gr_Graphics,opts___Rule]:=
    Module[{activeOptions,allopts,absopts,origopts,optsToHandle,handlers,
        listOfWaitingPSfrag={},nr=0,optsWithoutPSfrag,sig,
        listofpsfragentries={},optsToHandlePos,a,b,c,d,e,f,p,
        automaticsFilledIn,uniqstr=$MathPSfragGlobal`UniqueString,
        extendedplotrange,(*applylintickify=(ApplyLinTicks/.{opts}/.Options[
                  HandleAutomaticPSfrag])*)dummy,
        filopts=Join[{FilterOptions[HandleAutomaticPSfrag,opts]},
            Options[HandleAutomaticPSfrag]]},
      
      (*gr=
            If[applylintickify===True,lintickify[gra],
              If[applylintickify=!=Automatic,gra,
                
                dummy=Select[
                      Options[
                        gra,{Ticks,FrameTicks}],#[[2]]===Automatic&][[All,1]];
                Show[gra,DisplayFunction\[Rule]Identity,
                  Sequence@@
                    Select[lintickifiedOptions[gra],MemberQ[dummy,#[[1]]]&]]
                ]];*)
      
      MathPSfragDebug["HandleAutomaticPSfrag",0,InputForm[Options[gr]],opts];
      
      (* all options that can be set for the graphics object. 
            we clean up some of the mess, 
        AbsoluteOptions creates by using the function MyAbsoluteOptions *) 
      allopts=Sort[MyAbsoluteOptions[gr]];
      
      MathPSfragDebug["HandleAutomaticPSfrag",1,
        "MyAbsoluteOptions[gr]"\[Rule]InputForm[allopts]];
      (*MathPSfragDebug["HandleAutomaticPSfrag",1.5,
            "AbsoluteOptions (diff)"\[Rule] 
              Complement[AbsoluteOptions[gr],
                Intersection[AbsoluteOptions[gr],allopts]]];*)
      
      (* List of options that will be processed *)
      
      activeOptions=Sort[OptionsToHandle/.filopts];
      
      MathPSfragDebug["HandleAutomaticPSfrag",2,
        "activeOptions"\[Rule] InputForm[activeOptions]];
      
      (* List of Rules: options that will be processed, 
        Automatic replaced by explicit values.*)
      
      absopts=(Rule@@#)&/@Transpose[{activeOptions,activeOptions/.allopts}];
      
      MathPSfragDebug["HandleAutomaticPSfrag",3,"absopts"\[Rule] absopts];
      
      (* List of Rules: options that will be processed, 
        original values *)
      (* 
        We also convert FrameTicks to version 5 format because FullGraphics \
will choke otherwise -- we did the same in MyAbsoluteOptions *)
      
      origopts=Replace[(Rule@@#)&/@
            Transpose[{activeOptions,
                activeOptions/.Options[gr]/.Options[
                    Graphics]}],(FrameTicks\[Rule]{{a_,b_},{c_,
                    d_}})\[Rule] (FrameTicks\[Rule]{c,a,d,b}),{1}];
      
      MathPSfragDebug["HandleAutomaticPSfrag",4,"origopts"\[Rule] origopts];
      
      (* List of options to be processed, 
        where Automatic has been replaced with explicit values, 
        but all other options have not been passed through AbsoluteOptions *)
\
      (* new for version 6: All *)
      (* 
        we take special caution here to allow Ticks and FrameTicks to be \
assigned a function that generates tick marks *)
      optsToHandlePos=Join[
          Position[origopts,Automatic],
          Position[origopts,All],
          (* 
            extract position of symbols in Ticks and FrameTicks that are not \
Automatic and not All to avoid doubling *)
          
          Position[Replace[#,(a_\[Rule]_)/;a=!=Ticks\[Rule]{}]&/@origopts,
            b_Symbol/;b=!=Automatic&&b=!=All&&b=!=Ticks,3,Heads\[Rule]False],
          
          Position[
            Replace[#,(a_\[Rule]_)/;a=!=FrameTicks\[Rule]{}]&/@origopts,
            b_Symbol/;b=!=Automatic&&b=!=All&&b=!=FrameTicks,3,
            Heads\[Rule]False]
          ];
      
      (*
        
        optsToHandlePos=
          Join[Position[origopts,Automatic],Position[origopts,All]];
        If[
          Head[Ticks/.origopts]===Symbol&&(Ticks/.origopts)=!=
              Automatic&&(Ticks/.origopts)=!=All,
          
          AppendTo[optsToHandlePos,
            Join[Drop[First[Position[origopts,Ticks]],-1],{2}]]];
        If[
          Head[FrameTicks/.origopts]===Symbol&&(FrameTicks/.origopts)=!=
              Automatic&&(FrameTicks/.origopts)=!=All,
          
          AppendTo[optsToHandlePos,
            Join[Drop[First[Position[origopts,FrameTicks]],-1],{2}]]];
        *)
      
      optsToHandle=
        Fold[ReplacePart[#1,#2[[2]],#2[[1]]]&,
          origopts,{#,absopts[[Sequence@@#]]}&/@optsToHandlePos];
      (*Print["FrameTicks - allopts"\[Rule]FrameTicks/.allopts];
        Print[
          " FrameTicks - origopts"\[Rule]
              FrameTicks/.origopts];*)
      (*Print[
            "plotrange - allopts"\[Rule]PlotRange/.allopts,
            "origopts"\[Rule]origopts,
            "opttohandle"\[Rule]optsToHandle];*)
      (*Print[
          "FrameTicks -allopts"\[Rule]Shallow[(FrameTicks/.allopts)]];
        Print[
          " FrameTicks - optsToHandle"\[Rule]FrameTicks/.optsToHandle];*)
    \
  
      MathPSfragDebug["HandleAutomaticPSfrag",5,
        "optsToHandlePos"\[Rule]optsToHandle,
        "optsToHandle"\[Rule] optsToHandle];
      
      (* create a list of rules that can be used to turn options like \
PlotLabel\[Rule]{x,y} into *)
      (* 
        PlotLabel\[Rule]specifiedhandler[{x,y},otheropts], 
        where otheropts are all other graphic *)
      (* 
        options in case they affect how the handler does its job. 
            This is needed to take *)
      (* 
        care of options like RotateLabel. *)
      
      handlers=Replace[
            Select[OptionHandlers/.filopts,
              MemberQ[activeOptions,First[#]]&],{a_,
                b_}\[Rule]((a\[Rule]c_)\[RuleDelayed]((*Print[(a\[Rule]\
Shallow[c,4])\[Rule](a\[Rule]Shallow[b[c,allopts],7])];*)
                      a\[Rule]b[c,allopts])),2]/.filopts;
      
      MathPSfragDebug["HandleAutomaticPSfrag",6,"handlers"\[Rule]handlers];
      
      (* first apply PSfrag to all options by calling their specific \
automatic handlers*)
      (* second extract all PSfrag commands *)
      (* 
        third mark their location by putting little text strings where PSfrag \
commands have been*)
      (* store that list in "optWithoutPSfrag", 
        story original PSfrag commands in "listOfWaitingPSfrag" *)
      
      optsWithoutPSfrag=
        ((optsToHandle/.handlers)/.{FilterOptions[HandleAutomaticPSfrag,
                    opts]}/.Options[HandleAutomaticPSfrag])/.HoldPattern[
              Pattern[p,
                PSfragEntry[
                  Status->"WaitForTextWrapping",___]]]\[RuleDelayed](sig=
                uniqstr<>ToString[++nr];
              AppendTo[listOfWaitingPSfrag,sig\[Rule]p];sig);
      
      MathPSfragDebug["HandleAutomaticPSfrag",7,
        "optsWithoutPSfrag"\[Rule]optsWithoutPSfrag];
      
      (* Run all options through FullGraphics to create real Text[] \
directives, *)
      (* 
        which contain position and alignment information. *)
      (* 
        Extract this information and store in "listofpsfragentries". *)
      
      extendedplotrange=(Abs[#[[1]]-#[[2]]]*{-0.05,
                    0.05}+#)&/@(PlotRange/.allopts);
      
      MathPSfragDebug["HandleAutomaticPSfrag",8];
      (*Global`storetheseoptions=optsWithoutPSfrag;*)
      
      TextToPSfrag[
          FullGraphics[
            Show[gr,DisplayFunction\[Rule]Identity,
              PlotRange\[Rule]extendedplotrange,
              optsWithoutPSfrag]]]/.HoldPattern[
            Pattern[p,
              PSfragEntry[Status\[Rule]"Final",___,
                Expression\[Rule]e_String/;(StringTake[e,
                          Min[StringLength[e],StringLength[uniqstr]]]===
                        uniqstr),___]]]\[RuleDelayed](AppendTo[
                listofpsfragentries,e\[Rule]p];);
      
      MathPSfragDebug["HandleAutomaticPSfrag",9];
      
      (* merge extracted position information into old list of psfrag \
commands *)
      
      automaticsFilledIn=((listOfWaitingPSfrag/.listofpsfragentries)//.\
HoldPattern[(PSfragEntry[c___,a_\[Rule]b_,d___]\[Rule]PSfragEntry[e___,
                        a_\[Rule]Automatic,f___])]:>(PSfragEntry[c,a\[Rule]b,
                      d]\[Rule]PSfragEntry[e,a\[Rule]b,f]))/.HoldPattern[
              PSfragEntry[___,
                  Expression\[Rule]e_,___]\[Rule]b_]\[Rule](e\[Rule]b);
      
      MathPSfragDebug["HandleAutomaticPSfrag",10,
        "automaticsFilledIn"\[Rule]InputForm[automaticsFilledIn]];
      (*Print["optsWithoutPSfrag"\[Rule]optsWithoutPSfrag,
            "automaticsFilledIn"\[Rule]automaticsFilledIn];*)
      
      (* apply freshly produced PSfrag commands containing absolute \
orientation, position and TeX command to graphics *)
      (*
        
        Show[TextToPSfrag[gr],DisplayFunction\[Rule]Identity,
            Sequence@@(optsWithoutPSfrag/.automaticsFilledIn)]/.HoldPattern[
              p:PSfragEntry[Status->"WaitForTextWrapping",___,
                  Expression\[Rule]e_,___]]\[RuleDelayed](Message[
                HandleAutomaticPSfrag::unable,HoldForm[e]];
              
              MathPSfragDebug["HandleAutomaticPSfrag",11,
                "automatics not dealt with in", 
                Expression\[Rule]
                  InputForm[
                    e]];(p/.{(TeXPosition\[Rule]
                          Automatic)\[Rule](TeXPosition\[Rule]
                          "bc"),(PSPosition\[Rule] 
                          Automatic)\[Rule](PSPosition\[Rule] "bc")}))
        *)
      
      Show[TextToPSfrag[gr],DisplayFunction\[Rule]Identity,
          Sequence@@(optsWithoutPSfrag/.automaticsFilledIn)]/.HoldPattern[
            p:PSfragEntry[Status->"WaitForTextWrapping",___,
                Expression\[Rule]e_,___]]\[RuleDelayed](Message[
              HandleAutomaticPSfrag::unable,HoldForm[e]];
            
            MathPSfragDebug["HandleAutomaticPSfrag",11,
              "automatics not dealt with in", 
              Expression\[Rule]InputForm[
                  e]];(p/.{(TeXPosition\[Rule]Automatic)\[Rule](TeXPosition\
\[Rule](FallBack/.(List@@p))),(PSPosition\[Rule] 
                        Automatic)\[Rule](PSPosition\[Rule](FallBack/.(List@@
                                p)))}))
      ];



PSfragExport[filename_String,gr_Graphics3D,opts___Rule]:=
    
    PSfragManualExport[filename,gr,opts];

(*PSfragExport[filename_String,gr_Graphics,opts___Rule]:=
    
    PSfragManualExport[filename,
      HandleAutomaticPSfrag[gr,FilterOptions[HandleAutomaticPSfrag,opts]],
      ComplementFilterOptions[HandleAutomaticPSfrag,opts]
      ]*)

(* new version for Inset graphics *)

PSfragExport[filename_String,gr_Graphics,opts___Rule]:=
  
  PSfragManualExport[filename,
    MapAt[HandleAutomaticPSfrag[#,FilterOptions[HandleAutomaticPSfrag,opts]]&,
      gr,Drop[#,-1]&/@Position[gr,Graphics]],
    ComplementFilterOptions[HandleAutomaticPSfrag,opts]
    ]









MyAbsoluteOptions[gr_Graphics]:=
    Module[{frameticks,frameticksH,frameticksV,frameticksHempty,
        frameticksVempty,a,b,c,d,Empty,finaloptions},
      If[$VersionNumber<6.0,
        finaloptions=AbsoluteOptions[gr],
        (* else *)
        
        frameticks=FrameTicks/.Options[gr,FrameTicks];
        If[frameticks\[Equal]True,frameticks=Automatic];
        
        If[
          Head[frametick]===Symbol||
            Position[frameticks,_Symbol,2,Heads\[Rule]False]=!={},
          (*If[
              Intersection[
                  Flatten[{frameticks}],{All,Automatic,
                    None}]=!={},*)
          {frameticksH,frameticksV,
              frameticksHempty,frameticksVempty}=
            FrameTicks/.AbsoluteOptions[Show[gr,FrameTicks\[Rule]Automatic],
                FrameTicks];
          
          
          If[Length[frameticks]\[Equal]4,
            frameticks={{frameticks[[2]],frameticks[[4]]},{frameticks[[1]],
                  frameticks[[3]]}}];
          
          If[VectorQ[frameticks]&&Length[frameticks]\[Equal]2,
            frameticks={frameticks[[2]],frameticks[[1]]}];
          (*frameticks=
              Replace[frameticks,(a:(All|None|Automatic))\[Rule]{a,a}];
            
            frameticks=
              Replace[#,(a:(All|None|Automatic))\[Rule]{a,a}]&/@frameticks;*)

                    frameticks=Replace[frameticks,a_Symbol\[Rule]{a,a}];
          frameticks=Replace[#,a_Symbol\[Rule]{a,a}]&/@frameticks;
          frameticks=Replace[#,{a_,Automatic}\[Rule]{a,Empty}]&/@frameticks;
          frameticks={
              
              Replace[#,
                    a_Symbol\[RuleDelayed]
                      a@@(PlotRange/.AbsoluteOptions[
                                gr])[[2]]]&/@(frameticks[[1]]/.{(All|
                            Automatic)\[Rule]frameticksV,
                      Empty\[Rule]frameticksVempty,None\[Rule]{}}),
              
              Replace[#,
                    a_Symbol\[RuleDelayed]
                      a@@(PlotRange/.AbsoluteOptions[
                                gr])[[1]]]&/@(frameticks[[2]]/.{(All|
                            Automatic)\[Rule]frameticksH,
                      Empty\[Rule]frameticksHempty,None\[Rule]{}})
              }
          ];
        
        (* 
          We need Version 5 FrameTicks format because version 6 FullGraphics \
still does not understand Version 6 FrameTicks format: *)
        
        frameticks=Replace[frameticks,{{a_,b_},{c_,d_}}\[Rule]{c,a,d,b}];
        
        (* 
          glue the new frameticks into the other options and patch PaddedForm \
while we are at it *)
        
        finaloptions=
          Join[Select[AbsoluteOptions[Show[gr,FrameTicks\[Rule]Automatic]],
              First[#]=!=FrameTicks&],{FrameTicks\[Rule]frameticks}];
        ];
      (*Print[AbsoluteOptions[gr],finaloptions];*)
      
      Return[finaloptions/.HoldPattern[
              PaddedForm[a_,b_,c___]]\[RuleDelayed]PaddedForm[a,Round[b],
              Evaluate[Sequence@@({c}/.d_Real\[RuleDelayed]Round[d])]]];
      ];





(*applylinticks[a:{{_,_,_,_}..}]:=(CustomTicks`LinTicks[First[#],Last[#]]&)[
      Sort[First/@a]];
applylinticks[a_/;Head[a]=!=List]=a;
  applylinticks[{}]={};
  applylinticks[a_List/;(!SameQ[4,Sequence@@(Length/@a)])]=a;*)

(*lintickifiedOptions[
        gr_Graphics]:=
      {Ticks\[Rule]
          applylinticks/@(Ticks/.MyAbsoluteOptions[gr]),
        FrameTicks\[Rule]applylinticks/@(FrameTicks/.MyAbsoluteOptions[gr])};*)



(*lintickify[gr_Graphics]:=
      Show[gr,DisplayFunction\[Rule]Identity,
        Sequence@@lintickifiedOptions[gr]];*)

(*LinTickify[gr_Graphics]:=
      MapAt[lintickify,gr,Drop[#,-1]&/@Position[gr,Graphics]];*)





LatinCharacterSet=Join[CharacterRange["A","Z"],CharacterRange["a","z"]];

LatinNumCharacterSet=Join[LatinCharacterSet,CharacterRange["0","9"]];

LatinQ[expr_String]:=Complement[Characters[expr],LatinCharacterSet]==={};

LatinNumQ[expr_String]:=
    Complement[Characters[expr],LatinNumCharacterSet]==={};

numtobase[0,_List]:="";
numtobase[num_Integer,baseset_List]:=
    numtobase[Quotient[num,Length[baseset]],baseset]<>
      LatinCharacterSet[[1+Mod[num,Length[baseset]]]];
NumToBase[0,baseset_List]:=baseset[[1]];
NumToBase[num_Integer,baseset_List]:=numtobase[Abs[num],baseset];
NumToBase52[num_Integer]:=NumToBase[num,LatinCharacterSet];





countlines[data_List,bgcolor_]:=
  Module[{emptyline=Table[bgcolor,{Evaluate[Dimensions[data]][[2]]}],
      i=1},
    While[data[[i]]===emptyline,i++];
    i-1
    ]



BoundingBoxFromRaster[gr:Graphics[Raster[___],___],extramargin_Integer]:=
  Module[
    {bgcolor=gr[[1,1,1,1]],
      wholedim=Dimensions[gr[[1,1]]][[{1,2}]]},
    {{countlines[Transpose[gr[[1,1]]],bgcolor],countlines[gr[[1,1]],bgcolor]}-
        extramargin,
      {wholedim[[2]]-countlines[Reverse[Transpose[gr[[1,1]]]],bgcolor],
          wholedim[[1]]-countlines[Reverse[gr[[1,1]]],bgcolor]}+extramargin
      }
    ]





MathPSfragConfigurationTest::moreinfo= "See ?UnPSfrag for more information on correct configuration.";



testrun[check_,goal_String]:=
    If[check===True,Print[" + ",goal,"...passed"];True,
      Print[" + ",goal,"... FAILED"];
      Message[MathPSfragConfigurationTest::moreinfo];False];

defaulttestfile="unpsfragtest-"<>ToString[$SessionID]<>".txt";



MathPSfragConfigurationTest[testfile_String:defaulttestfile,opts___Rule]:=
  
  Module[{overwrite=(ForceOverwrite/.{opts}/.ForceOverwrite\[Rule]False)===
          True,
      gs,latex,dvips,output},
    CheckAbort[
      (* ensure that we do not overwrite an foreign file *)
      
      If[FileType[testfile]=!=None,If[!overwrite,
          
          Print["This test needs to write into a file. The chosen filename ("<>
              testfile<>" in "<>Directory[]<>") already exists. Use MathPSfragConfigurationTest[\"anotherfilename\"] "<>
              "or MathPSfragConfigurationTest[ForceOverwrite->True] or remove the file manually."]\
;
          Abort[],
          (* else *)
          DeleteFile[testfile]]
        ];
      Export[testfile,"Write Test","Text"];
      If[FileType[testfile]===None,
        Print["Could not write to testfile "<>testfile<> ". Check write permissions! The current working directory is "<>
            Directory[]];
        Abort[]];
      
      (* start Test *)
      
      Print[
        "The current setting is: ",{"GhostscriptExecutable"\[Rule]
              GhostscriptExecutable,"LaTeXExecutable"\[Rule]LaTeXExecutable,
            "DvipsExecutable"\[Rule]DvipsExecutable,
            "UnPSfragOutputFormats"\[Rule]UnPSfragOutputFormats,
            "BoundingBoxDevice"\[Rule]BoundingBoxDevice,
            "PreviewDevice"\[Rule]PreviewDevice}/.Options[UnPSfrag]];
      
      {gs,latex,dvips,output}={GhostscriptExecutable,LaTeXExecutable,
            DvipsExecutable,UnPSfragOutputFormats}/.Options[UnPSfrag];
      
      Print[
        "This test checks if the above options have been set to reasonable values. "]\
;
      Print["First try to find the executables"];
      
      If[!testrun[Run[latex<> " --help >"<>testfile];
            FindList[testfile,"TeX"]=!={},"Find LaTeX"],Abort[]];
      DeleteFile[testfile];
      
      If[!testrun[Run[dvips<>" 2>"<>testfile];
            FindList[testfile,"This is dvips"]=!={},"Find dvips (windows)"],
        Abort[]];
      DeleteFile[testfile];
      
      (* check devices *)
      
      If[!testrun[Run[gs<>" --help >"<>testfile];
            FindList[testfile,"Ghostscript"]=!={},"Find Ghostscript"],
        Abort[]];
      
      availabledevices=FetchGhostscriptDevices[testfile];
      Print["List of (some) available Ghostscript devices: ",Short[
          availabledevices,4]];
      Print["Testing now, if all options only use available devices."];
      
      testrun[
        MemberQ[availabledevices,First[BoundingBoxDevice/.Options[UnPSfrag]]],
        "BoundingBoxDevice available"];
      If[MemberQ[{None,NoneAndComplain},PreviewDevice/.Options[UnPSfrag]],
        testrun[True,"PreviewDevice deactivated (test skipped)"],
        testrun[
          MemberQ[Join[availabledevices,{"EPS"}],
            First[PreviewDevice/.Options[UnPSfrag]]],
          "PreviewDevice available"]
        ];
      
      If[!testrun[
            Complement[(UnPSfragOutputFormats/.Options[UnPSfrag])[[All,1]],
                Join[{"EPS"},availabledevices]]==={},
            "Devices in UnPSfragOutputFormats available"],Abort[]];
      DeleteFile[testfile];
      True,
      (* Aborted *)
      DeleteFile[testfile];
      False]
    ]

(*MathPSfragConfigurationTest[testfile_String:defaulttestfile,opts___Rule]:=
 
       Module[{overwrite=(ForceOverwrite/.{opts}/.ForceOverwrite\[Rule]False)===
            True,
        gs,latex,dvips,output},
      
      (* ensure that we do not overwrite an foreign file *)
      
      If[FileType[testfile]=!=None,If[!overwrite,
          
          Print["This test needs to write into a file. The chosen filename ("<>
              testfile<>") already exists. Use MathPSfragConfigurationTest[\"anotherfilename\"] "<>
              "or MathPSfragConfigurationTest[ForceOverwrite->True] or remove the file manually."]\
;
          Abort[],
          (* else *)
          DeleteFile[testfile]]
        ];
      Export[testfile,"Write Test","Text"];
      If[FileType[testfile]===None,
        Print["Could not write to testfile "<>testfile<> ". Check write permissions! The current working directory is "<>
            Directory[]];
        Abort[]];
      
      (* start Test *)
      
      Print[
        "The current setting is: ",{"GhostscriptExecutable"\[Rule]
              GhostscriptExecutable,"LaTeXExecutable"\[Rule]LaTeXExecutable,
            "DvipsExecutable"\[Rule]DvipsExecutable,
            "UnPSfragOutputFormats"\[Rule]UnPSfragOutputFormats,
            "BoundingBoxDevice"\[Rule]BoundingBoxDevice,
            "PreviewDevice"\[Rule]PreviewDevice}/.Options[UnPSfrag]];
      
      {gs,latex,dvips,output}={GhostscriptExecutable,LaTeXExecutable,
            DvipsExecutable,UnPSfragOutputFormats}/.Options[UnPSfrag];
      
      Print[
        "This test checks if the above options have been set to reasonable values. "]\
;
      Print["First try to find the executables"];
      
      (* redirect into testfile to avoid use of $SuppressOut which may have \
been set to empty string *)
      
      If[!testrun[exitcodeok[Run[latex<> " --help >"<>testfile]],
            "Find LaTeX"],Abort[]];
      If[$MathPSfragGlobal`SaneSystemID\[Equal]"Windows",
        If[!testrun[Run[dvips<>" 2>"<>testfile];
              FindList[testfile,"This is dvips"]=!={},"Find dvips (windows)"],
          Abort[]],
        If[!testrun[exitcodeok[Run[dvips<>" --help >"<>testfile]],
              "Find dvips"],Abort[]]
        ];
      
      (* check devices *)
      
      If[!testrun[exitcodeok[Run[gs<>" --help >"<>testfile]],
            "Find Ghostscript"],Abort[]];
      
      availabledevices=FetchGhostscriptDevices[testfile];
      Print["List of (some) available Ghostscript devices: ",
        availabledevices];
      Print["Testing now, if all options only use available devices."];
      
      If[!testrun[
            MemberQ[availabledevices,
              First[BoundingBoxDevice/.Options[UnPSfrag]]],
            "BoundingBoxDevice available"],ABORTLATER[]];
      If[!testrun[
            MemberQ[availabledevices,First[PreviewDevice/.Options[UnPSfrag]]],
            "PreviewDevice available"],ABORTLATER[]];
      
      If[!testrun[
            Complement[(UnPSfragOutputFormats/.Options[UnPSfrag])[[All,1]],
                Join[{"EPS"},availabledevices]]==={},
            "Devices in UnPSfragOutputFormats available"],Abort[]];
      DeleteFile[testfile];
      ]*)





(* check if word is surrounded by non-alphanumeric characters *)

checkword[
    haystack_String,{posL_,posR_}]:=(If[
      posL===1||!LatinNumQ[StringTake[haystack,{posL-1}]],
      If[posR===
            StringLength[haystack]||!LatinNumQ[
              StringTake[haystack,{posR+1}]],
        Return[True]]];
    False)

(* check if needle is contained in haystack and is a single "word" *)

dumbgrep[haystack_String,needle_String]:=
    Or@@(checkword[haystack,#]&/@StringPosition[haystack,needle]);



FetchGhostscriptDevices[tempfile_String]:=Module[{helpcontent},
    Run[(GhostscriptExecutable/.Options[UnPSfrag])<>" --help >"<>tempfile];
    helpcontent=Import[tempfile,"Text"];
    Select[$MathPSfragGlobal`PredefGsDevices,dumbgrep[helpcontent,#]&]
    ]





clip[x_,{a_,b_}]:=Max[Min[x,Max[a,b]],Min[a,b]];



NextLaTeXError[nb_Integer:0]:=NextLaTeXError[$MathPSfragGlobal`LaTeXLog,nb];

NextLaTeXError[logcontent_String,nb_Integer:0]:=
  Module[{errorposes=(Last/@StringPosition[logcontent,"\n!"]),errorpos},
    If[Length[errorposes]<=nb,False,
      errorpos=errorposes[[nb+1]];
      "[...snip...]\n\n"<>StringTake[logcontent,
          clip[#,{1,StringLength[logcontent]}]&/@{errorpos-300,errorpos+400}]<>
        "\n\n[...snip...]"
      ]]





UnPSfrag::fileexists="Output EPS (`1`) already exists, use ForceOverwrite->True to proceed or choose different name.";\


UnPSfrag::direxists="Temporary working directory (`1`) already exists. As you requested to remove the temporary directory after job is done, I refuse to go on. Choose better value for TemporaryDirectory option or rename existing directory.";\


UnPSfrag::failed="`1` could not produce `2` file in directory `3`. I intentionally did not clean up temporary files, which will have to be removed manually.";\


UnPSfrag::texhint=
    "A typical cause is bad autogenerated TeX code. "<>
      "Check the contents of $MathPSfragGlobal`PSfragExportResult for "<>

            "bad code and $MathPSfragGlobal`LaTeXLog for error messages. "<>
 \
     "To do so evaluate First[$MathPSfragGlobal`PSfragExportResult] and NextLaTeXError[].";\


UnPSfrag::texbadlog=
    "Log file contains errors. Have a close look at the "<>"graphics and evaluate NextLaTeXError[].";\


If[$VersionNumber<5.1,
    UnPSfrag::mma4tex=
        "LaTeX could not find MMA4TeX, which provides additional "<>
         
           "support for most of Mathematica's special symbols. "<>
          
          "This may cause LaTeX errors in some cases.";
    ];

UnPSfrag::bboxfailed="`Could not determine bounding box from file `1` in directory `2`. I intentionally did not clean up temporary files, which will have to be removed manually.";\


UnPSfrag::badbbox="Hardly usable unPSfrag'ed EPS file created with bad bounding box. You should get Ghostscript version 8 or later (the GPL version suffices) or use the psfrag version of the graphic. Alternatively you might try to correct the bounding box with 'ps2eps' by Roland Bless.";\


UnPSfrag::unavail="Your version of Ghostscript does not support output format(s) `1`. Available are `2`.";\
 
UnPSfrag::nopre=
  "Previews are off by default. Set PreviewDevice->None to suppress this note. Use ?MathPSfrag`GsDevice* to obtain a list of valid preview devices. Note that bitmap graphics are recommended but may crash the kernel on your particular system."



replacebbox[line_String,bbox_]:=
    Module[{firstchars=StringTake[line,Min[15,StringLength[line]]]},
      If[firstchars==="%%BoundingBox: ",bbox,
        If[firstchars==="%%HiResBounding"||firstchars==="%%ExactBounding",{},
          line]]
      ];

callghostscript[gs_,device_,ineps_,outfile_,furtheropts_]:=(
    (* ensure that there is a showpage command *)
    
    command=gs<>" "<>furtheropts<>" -dNOPAUSE -dBATCH -sQUIET -sDEVICE="<>
        device<>" -sOutputFile="<>outfile<>" "<>
        ineps;(*<>If[device==="pdfwrite",""," -c showpage"];*)
    
    MathPSfragDebug["callghostscript",1,"command"\[Rule]command];
    Run[command];
    If[FileType[outfile]===None,
      Message[UnPSfrag::failed,gs,outfile,Directory[]];
      False,True]
    )

RunLaTeX[masterfile_,latex_,dvips_,suppressoutput_]:=Module[{},
      (* Run latex on master file to produce DVI and read log file*)
      
      Run[latex<>" --interaction batchmode \""<>masterfile<>".tex\" "<>
          suppressoutput];
      Unprotect[$MathPSfragGlobal`LaTeXLog];
      $MathPSfragGlobal`LaTeXLog=Import[masterfile<>".log","Text"];
      Protect[$MathPSfragGlobal`LaTeXLog];
      
      (* did we produce a DVI ? *)
      
      If[FileType[masterfile<>".dvi"]===None,
        Message[UnPSfrag::failed,"latex",masterfile<>".dvi",Directory[]];
        Message[UnPSfrag::texhint];
        If[VersionNumber<5.1,
          
          If[StringPosition[$MathPSfragGlobal`LaTeXLog,
                  StringTake[$MathPSfragGlobal`Mma4TeXMissing,70]]=!={},
              Message[UnPSfrag::mma4tex];
              ];
          ];
        Abort[]];
      
      (* check if there are minor errors *)
      
      If[NextLaTeXError[]=!=False,
        Message[UnPSfrag::texbadlog]];
      
      (* Convert DVI to EPS with bad bounding box *)
      
      Run[dvips<>" -q -E -o \""<>masterfile<>".eps\" \""<>masterfile<>".dvi\" "<>
          suppressoutput];
      If[FileType[masterfile<>".eps"]===None,
        Message[UnPSfrag::failed,"dvips",masterfile<>".eps",Directory[]];
        Abort[]];
      True
      ];

MeasureBoundingBox[mastereps_,gs_,bboxgsdevice_,bboxfile_,bboxopts_,
      extramargin_]:=Module[{bboxstring,bbox},
      CheckAbort[
        If[bboxgsdevice=!="bbox",
          (* 
            create a coarse preview bitmap file to determine the bounding box \
*)
          
          If[!callghostscript[gs,bboxgsdevice,mastereps,bboxfile,bboxopts],
            Message[UnPSfrag::failed,gs,bboxfile,Directory[]];Abort[]];
          
          (* read in the bitmap and measure bounding box *)
          
          bbox=BoundingBoxFromRaster[Import[bboxfile],extramargin];
          
          If[Head[bbox]=!=List,
            Message[UnPSfrag::bboxfailed,bboxfile,Directory[]];Abort[]],
          
          (* else (bboxgsdevice=!="bbox") *)
          
          Run[gs<>" "<>bboxopts<>" -dNOPAUSE -dBATCH -sQUIET -sDEVICE="<>
              bboxgsdevice<>" \""<>mastereps<>"\" 2>"<>bboxfile];
          bboxstring=First[Import[bboxfile,"Lines"]];
          If[StringTake[bboxstring,15]=!="%%BoundingBox: ",
            Message[UnPSfrag::bboxfailed,bboxfile,Directory[]];Abort[]];
          bboxstring=StringDrop[bboxstring,15];
          
          
          bbox=Partition[
                ToExpression/@(StringTake[bboxstring,#+{1,-1}]&/@
                      Partition[
                        Flatten[{0,First/@StringPosition[bboxstring," "],
                            StringLength[bboxstring]+1}],2,1]),2]+
              extramargin*{{-1,-1},{1,1}};
          ];
        MathPSfragDebug["MeasureBoundingBox",0,"mastereps"\[Rule]mastereps,
          "bbox"\[Rule]bbox];
        bbox,
        $Aborted]
      ];

CorrectBoundingBox[mastereps_,outputeps_,shiftedeps_,bbox_,tempdir_]:=
  Module[{masterepscontent,shiftedbbox,bboxstring,bboxcommands},
    (* correct the bounding box *)
    
    masterepscontent=Import[mastereps,"Lines"];
    
    (* create beautiful eps file for latex by hand*)
    If[outputeps=!={},
      ResetDirectory[];
      bboxstring=StringJoin[ToString/@Flatten[Transpose[{
                  {"%%BoundingBox: "," "," "," "},
                  Flatten[bbox]}
                ]]];
      Export[outputeps[[1,2]],
        Join[
          Flatten[replacebbox[#,bboxstring]&/@Take[masterepscontent,30]],
          Drop[masterepscontent,30]
          ],"Lines"];
      SetDirectory[tempdir]
      ];
    
    (* create eps with corrected origin for further ghostscript processing *)

        shiftedbbox={{0,0},bbox[[2]]-bbox[[1]]};
    bboxcommands={
        StringJoin[ToString/@Flatten[Transpose[{
                  {"%%BoundingBox: "," "," "," "},
                  Flatten[shiftedbbox]}
                ]]],
        "<< /PageSize["<>ToString[shiftedbbox[[2,1]]]<>
          " "<>
          ToString[shiftedbbox[[2,2]]]<>"] >> setpagedevice",
        "gsave "<>ToString[-bbox[[1,1]]]<>" "<>ToString[-bbox[[1,2]]]<>
          " translate"
        };
    Export[shiftedeps,
      Join[
        Flatten[replacebbox[#,bboxcommands]&/@Take[masterepscontent,30]],
        Drop[masterepscontent,30]
        ],"Lines"];
    ]



UnPSfrag[opts___Rule]=UnPSfrag[#,opts]&;

UnPSfrag[{outputfileprefix_String,epsfile_String,texfile_String},opts___Rule]:=
  Module[{availabledevices,outputfiles,outputeps,
      bboxfile,bboxdevice,
      previewfile,previewdevice,previewtype,
      tempdir,forceoverwrite,
      removetemp,masterfile,extramargin,
      outputformats,gs,latex,latexopt,dvips,dvipsopt,suppressoutput},
    {tempdir,forceoverwrite,
        removetemp,masterfile,extramargin,
        bboxdevice,previewdevice,
        outputformats,gs,latex,latexopt,dvips,dvipsopt,suppressoutput}
      ={TemporaryDirectory,ForceOverwrite,
            RemoveTemporaries,MasterTeXFile,ExtraMargin,
            BoundingBoxDevice,PreviewDevice,
            UnPSfragOutputFormats,
            GhostscriptExecutable,
            LaTeXExecutable,LaTeXOptions,
            DvipsExecutable,DvipsOptions,
            SuppressOutput}/.{opts}/.Options[UnPSfrag];
    
    MathPSfragDebug["UnPSfrag",outputfileprefix,epsfile,texfile,opts];
    
    (* refuse to work if tempdir already exists. 
          This avoids removing an existing directory by accident *)
    
    If[(FileType[tempdir]=!=None)(*&&(removetemp=!=False)*),
      Message[UnPSfrag::direxists,tempdir];Abort[]]; 
    
    (* create tempdir *)
    CreateDirectory[tempdir];
    
    (* get available image formats *)
    If[gs=!="",
      SetDirectory[tempdir];
      availabledevices=FetchGhostscriptDevices["gshelp.txt"];
      If[availabledevices==={},Message[UnPSfrag::nodevices];Abort[]];
      ResetDirectory[],
      availabledevices={}];
    AppendTo[availabledevices,"EPS"];
    
    (* see if all selected output formats are available: *)
    
    If[Complement[outputformats[[All,1]],availabledevices]=!={},
      Message[UnPSfrag::unavail,
        Complement[outputformats[[All,1]],availabledevices],availabledevices];
      Abort[]];
    
    outputfiles={#[[1]],outputfileprefix<>#[[2]],#[[3]]}&/@outputformats;
    outputeps=Select[outputfiles,First[#]==="EPS"&];
    outputfiles=Select[outputfiles,First[#]=!="EPS"&];
    
    bboxfile="master"<>bboxdevice[[2]];
    bboxgsdevice=bboxdevice[[1]];
    bboxopts=bboxdevice[[3]];
    If[!MemberQ[availabledevices,bboxgsdevice],
      Message[UnPSfrag::unavail,bboxgsdevice,availabledevices];Abort[]];
    
    If[previewdevice=!=None&&previewdevice=!=NoneAndComplain,
      previewgsdevice=previewdevice[[1]];
      If[!MemberQ[availabledevices,previewgsdevice],
        Message[UnPSfrag::unavail,previewgsdevice,availabledevices];
        previewdevice=None,
        (* else *)
        
        previewfile=ToFileName[tempdir,"master"<>previewdevice[[2]]];
        If[!MemberQ[outputfiles[[All,2]],previewfile],
          
          outputfiles=
            Append[outputfiles,{previewgsdevice,previewfile,
                previewdevice[[3]]}]];
        ];
      ];
    outputfiles=Union[outputfiles]; (* 
      eliminate duplicates -- we could use a better test *)
    
    (* check if files already exist *)
    If[(FileType[#]=!=None),
          
          If[forceoverwrite,DeleteFile[#],
            Message[UnPSfrag::fileexists,output];Abort[]]
          ]&/@outputfiles[[All,2]];
    
    (* produce LaTeX master file *)
    
    Export[ToFileName[tempdir,"master.tex"],
      StringReplace[
        masterfile,{"%%%PSfragCommands%%%"\[Rule]Import[texfile,"Text"],
              "%%%TeXPreamble%%%"\[Rule]TeXPreamble,
              "%%%IncludeGraphicsOptions%%%"\[Rule]IncludeGraphicsOptions}/.{\
opts}/.Options[UnPSfrag]],
      "Text"
      ];
    
    (* bring input eps graphic into place *)
    
    CopyFile[epsfile,ToFileName[tempdir,"input.eps"]];
    
    (* go to working directory *)
    SetDirectory[tempdir];
    
    (* Run latex on master file to produce DVI and read log file*)
    
    CheckAbort[
      RunLaTeX["master",latex<>" "<>latexopt,dvips<>" "<>dvipsopt,
        suppressoutput],
      ResetDirectory[];Abort[]];
    
    If[gs==="",
      (* no ghostscript, so produce an eps file with bad bounding box *)
     
       ResetDirectory[];
      RenameFile[ToFileName[tempdir,"master.eps"],outputeps];
      Message[UnPSfrag::badbbox],
      
      (* else (If gs==="") *)
      (* yippie, we have ghostscript *)
      
      bbox=
        MeasureBoundingBox["master.eps",gs,bboxgsdevice,bboxfile,bboxopts,
          extramargin];
      If[bbox===$Aborted,ResetDirectory[];Abort[]];
      CorrectBoundingBox["master.eps",outputeps,"mastershifted.eps",bbox,
        tempdir];
      
      (* create outputfiles in desired formats *)
      ResetDirectory[];
      If[!callghostscript[gs,#[[1]],
                ToFileName[tempdir,"mastershifted.eps"],#[[2]],#[[3]]],
            Abort[]]&/@outputfiles;
      
      (* if asked for preview, load now *)
      Switch[previewdevice,
        None,Null,
        NoneAndComplain,Message[UnPSfrag::nopre],
        _, (*default *)
        
        Print["Low resolution preview of UnPSfrag'ed image:"];
        If[$VersionNumber<6.0,Show,Print]@@{Import[previewfile]};
        ];
      
      ];(* if gs===""*)
    
    (* clean up if requested *)
    
    If[removetemp===True,DeleteDirectory[tempdir,DeleteContents\[Rule]True]];
    ]



PatchType1FontIntoEps[infile_String]:=PatchType1FontIntoEps[infile,infile];

PatchType1FontIntoEps[infile_String,outfile_String]:=Module[
      {fontdir,availablefonts,epscontent,endcommentpos,epsheader,epsrest,
        resourcepos,nextcomment,neededResources,neededfonts,fonts2include,
        includefontcmd},
      
      (* find Mathematica Fonts *)
      
      fontdir=ToFileName[{$TopDirectory,"SystemFiles","Fonts","Type1"}];
      SetDirectory[fontdir];
      availablefonts=StringDrop[#,-4]&/@FileNames["*.pfa"];
      ResetDirectory[];
      
      (* Read infile and split into header and rest *)
      
      epscontent=Import[infile,"Text"];
      endcommentpos=
        First[First[StringPosition[epscontent,"%%EndComments"]]]-1;
      epsheader=StringTake[epscontent,endcommentpos];
      epsrest=StringDrop[epscontent,endcommentpos];
      Clear[epscontent];
      
      (* extract needed fonts from %%DocumentNeededResources *)
      
      resourcepos=
        Last[Last[StringPosition[epsheader,"%%DocumentNeededResources"]]];
      nextcomment=
        First[Select[
            Join[First/@
                StringPosition[epsheader,"%%Document"],{StringLength[
                  epsheader]}],#>resourcepos&]];
      neededResources=StringTake[epsheader,{resourcepos,nextcomment}];
      neededfonts=
        StringTake[neededResources,#+{1,-1}]&/@
          Partition[Last/@StringPosition[neededResources,{" font ","\n"}],2,
            1];
      
      (* but only include those which we really have *)
      
      fonts2include=Intersection[neededfonts,availablefonts];
      
      (* patch fonts into the header and export *)
      
      includefontcmd:=("%%BeginResource: font "<>#<>"\n"<>
              
              "%%BeginFont: "<>#<>"\n"<>
              
              Import[ToFileName[fontdir,#<>".pfa"],"Text"]<>
              
              "\n%%EndFont\n%%EndFont\n%%EndResource\n"&);
      
      Export[outfile,
        epsheader<>(includefontcmd/@fonts2include)<>epsrest,
        "Text"]
      ];





End[]



Global`$PostMathPSfrag;



Protect["MathPSfrag`*"];
Protect["$MathPSfragGlobal`*"];
(*Unprotect["MathPSfrag`$PSfragCounter"];*)
(*Unprotect[
      "MathPSfrag`$PSfragExportResult"];*)



EndPackage[]

