%
% \iffalse
% psfrag.dtx Copyright (C) 1994 Michael C. Grant and Craig Barratt
%            All rights are reserved.
%
%            This system is distributed in the hope that it will be
%            useful, but WITHOUT ANY WARRANTY; without even the 
%            implied warranty of MERCHANTABILITY or FITNESS FOR A
%            PARTICULAR PURPOSE. Don't come complaining to us if you
%            modify this file and it doesn't work! If this file is
%            modified by anyone but the authors, those changes and
%            their authors must be explicitly stated HERE.
%
%<package|epsf>\NeedsTeXFormat{LaTeX2e}[1994/12/01]
%<package>\ProvidesPackage{psfrag}
%<epsf>\ProvidesPackage{epsf}
%<package|epsf>    [1995/04/04 v2.0 PSfrag (MCG)]
% \fi
% \ProvidesFile{psfrag.dtx}
%       
% \iffalse
%<*driver>
\documentclass{ltxdoc}
\usepackage{graphicx,psfrag}
\begin{document}
 \DocInput{psfrag.dtx}
\end{document}
%</driver>
% \fi
%
% \GetFileInfo{psfrag.dtx}
% \RecordChanges
%
% \newcommand{\pfg}{\textsf{PSfrag}}
% \newcommand{\bsl}{\protect\bslash}
% \newcommand{\ie}{\emph{i.e.}}
% \newcommand{\eg}{\emph{e.g.}}
% \newcommand{\etc}{\emph{etc.}}
% \newcommand{\netaddress}[1]{\texttt{#1}}
% \marginparsep 0pt
%
% \title{\texttt{psfrag.sty}, \texttt{epsf.sty}, and \texttt{ps2frag.ps}%
% \thanks{This file has version number \fileversion, last revised \filedate.}}
%
% \author{Craig Barratt \thanks{This author is no longer participating in
%         the development of \pfg.} \\ \netaddress{craig@arraycomm.com} \and
%         Michael C. Grant \\ \netaddress{mcgrant@isl.stanford.edu}}
% \date{\filedate}
% \maketitle
% \PrintChanges
%
% \changes{2.0}{1995/04/04}{Bug fixes}
% \changes{2.0}{1995/03/14}{Bug fixes. Better support for \LaTeX\ 2.09 \pfg\
%                           \pfg\ files, including both naming schemes. 
%                           Improved documentation and separated it from
%                           this file.}
% \changes{1.99}{1995/02/14}{Taken over from Craig, completely overhauled for
%                           \LaTeXe. Completely changed
%                           the placement code; baseline alignment added.
%                           Integrated \cs{psfrag} commands into the PostScript
%                           file. \textsf{graphics} package used for portability
%                           across multiple DVI-to-PostScript packages. Improved
%                           ps2frag.ps file provides improved (correct) support
%                           for ashow, widthshow, awidthshow, and kshow.}
% \changes{1.1}{1992/10/20}{Released version 1.1, adding support for ashow,
%                           widthshow, awidthshow, and kshow.}
% \changes{1.0}{1992/06/01}{Released version 1.0.}
% 
% \section{\texttt{psfrag.sty}}
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%
% \subsection{Intialization}
%
% We will need the \textsf{graphics} package, at least. In my
% opinion, \textsf{graphicx} should be used, but I can't force
% anyone...
%    \begin{macrocode}
\RequirePackage{graphics}
%    \end{macrocode}
%
% Here we allocate the dimension registers, file descriptors,
% and \cs{if} statements we will need. Because of the extremely
% local scope with which we use the dimension registers, we can
% safely re-use some of the registers from |graphics.sty| (which 
% are, in turn, re-used from \LaTeX).
%    \begin{macrocode}
\let\pfg@x\Gin@urx \let\pfg@mx\Gin@nat@width
\let\pfg@y\Gin@ury \let\pfg@my\Gin@nat@height
\newif\ifpfg@file \newif\ifpfg@found \newif\ifpfg@spec
\newif\ifpfg@compat \if@compatibility\pfg@compattrue\fi
\newread\pfg@file
\newtoks\pfg@proc \newtoks\pfg@str
%    \end{macrocode}
%
% \subsection{Package Options}
%
%    \begin{macrocode}
\DeclareOption{showall}{%
  \let\psfragshowfalse\relax
  \let\psfragshowdefault\relax
  \psfragshowtrue}
\if@compatibility
\DeclareOption{2emode}{\pfg@compatfalse}
\else
\DeclareOption{209mode}{\pfg@compattrue}
\fi
%    \end{macrocode}
%
% \subsection{Interface to the \textsf{graphics} package}
%
% \begin{macro}{\pfg@rawps}
% This macro is used, in the interim, until one is provided by
% the \textsf{graphics} package. It must send the contents of
% its argument straight to the PostScript file.
%    \begin{macrocode}
%<dvips|dvipsone|pubps>\def\pfg@rawps#1{\special{ps: #1}}
%<textures>\def\pfg@rawps#1{\special{rawpostscript #1}}
%<dvialw>\def\pfg@rawps#1{\special{language  "PS", literal "#1"}}
%<pctexps>\def\pfg@rawps#1{\special{ps::#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\Ginclude@eps}
% We need to redefine this macro from the \textsf{graphics} package
% so that it inserts the \pfg\ replacements. So we save the original
% definition of \cs{Ginclude@eps}, and wrap it with code that scans the
% EPS file for any frags that \pfg\ has been requested to replace,
% either through \cs{psfrag} commands or embedded \cs{tex} strings.
% If any are found, then the appropriate adjustments to the PostScript
% environment are made to filter them out; otherwise, the original
% \cs{Ginclude@eps} command is executed unchanged.
%    \begin{macrocode}
\let\pfg@include@eps\Ginclude@eps
\def\Ginclude@eps#1{%
   \pfg@scan{#1}\ifpfg@found
     \ifpsfragshow\else\pfg@hidestart\fi
     \pfg@include@eps{#1}%
     \ifpsfragshow\else\pfg@hideend\fi
     \the\pfg@proc\global\pfg@proc={}%
   \else\pfg@include@eps{#1}\fi}
%    \end{macrocode}
% \end{macro}
%
% \subsection{User interface macros}
%
% \begin{macro}{\ifpsfragshowall}
% \begin{macro}{\psfragshowtrue}
% \begin{macro}{\psfragshowfalse}
% \begin{macro}{\psfragshowall}
% \begin{macro}{\psfragshowdefault}
% Define the on-off switches for the replaced text, as described
% above.
%    \begin{macrocode}
\newif\ifpsfragshow \psfragshowfalse
\let\psfragshowall\psfragshowtrue
\let\psfragshowdefault\psfragshowfalse
\ProcessOptions
%    \end{macrocode}
% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}
%
% \begin{macro}{\psfrag}
% The main macro \cs{psfrag} must be defined specially in order
% to handle its odd combination of optional and required arguments.
%    \begin{macrocode}
\edef\pfg@dflt{\ifpfg@compat bl\else Bl\fi}
\def\psfrag#1{\@ifnextchar [{\@psfraga{#1}}%
                            {\@psfrag{#1}[\pfg@dflt][\pfg@dflt][1][0]}}
\def\@psfraga#1[#2]{\@ifnextchar [{\@psfragb{#1}[#2]}%
                                  {\@psfrag{#1}[#2][\pfg@dflt][1][0]}}
\def\@psfragb#1[#2][#3]{\@ifnextchar [{\@psfragc{#1}[#2][#3]}%
                                      {\@psfrag{#1}[#2][#3][1][0]}}
\def\@psfragc#1[#2][#3][#4]{\@ifnextchar [{\@psfrag{#1}[#2][#3][#4]}%
                                          {\@psfrag{#1}[#2][#3][#4][0]}}
\long\def\@psfrag#1[#2][#3][#4][#5]#6{%
  \@ifundefined{pfg@n@#1}{}{%
    \def\@tempa{#1}\ifx\@tempa\@empty\else
      \PackageWarning{PSfrag}%
        {Replacement for PostScript fragment `#1' on 
         page \thepage \space redefined.}\fi}%
%    \end{macrocode}
% For each fragment, two macros are defined based on its name.
% The macro \cs{pfg@m@\emph{name}} is defined so that, when executed,
% it fills temporary variables with the position, scale, and rotation
% information for the fragment. The macro \cs{pfg@n@\emph{name}} 
% contains the \LaTeX\ code to be typeset for a replacement.
%    \begin{macrocode}
    \@namedef{pfg@m@#1}{\edef\pfg@posn{#2}\edef\pfg@psposn{#3}%
                        \edef\pfg@scale{#4pt}\edef\pfg@rotn{#5pt}}%
    \@namedef{pfg@n@#1}{#6}\ignorespaces}
%    \end{macrocode}
% \end{macro}
%
% \begin{environment}{psfrags}
% This is a dummy environment whose sole purpose is to delimit the
% scope of \cs{psfrag} declarations. This environment will rarely
% be necessary, as any surrounding environment (such as a |figure|)
% will suffice.
%    \begin{macrocode}
\newenvironment{psfrags}{\ignorespaces}{\global\@ignoretrue}
%    \end{macrocode}
% \end{environment}
%
% \subsection{Fragment processing}
%
% \begin{macro}{\pfg@info}
% \marg{text}\parg{x,y}\parg{bbhx,bbhy}\ignorespaces%
% \parg{bbvx,bbvy}\marg{rotn}\marg{base}\\
% The following macro does the dirty work. It uses the information
% generated by the |ps2frag| script to determine a complete
% breakdown of the positioning of a piece of text in the PostScript file.
% \begin{description}
% \item[\marg{text}] is the argument of the PostScript text operator
%                    (|show|, |ashow|, |kshow|, |widthshow|, or |awidthshow|).
% \item[\parg{x,y}] is the absolute cooridinate, in points, of the
%    text's starting point (if the text is not rotated, the lower left
%    corner).
% \item[\parg{bbhx,bbhy}] is the vector from the lower left corner
%    to the lower right corner of the text's bounding box.
% \item[\parg{bbvx,bbvy}] is the vector from the lower left corner
%    to the upper left corner of the text's bounding box.
% \item[\marg{rotn}] is the rotation, in degrees, of the text's baseline.
% \item[\marg{base}] is the fraction of the vector \parg{bbvx,bbvy}\ which
%    would span the distance from the lower-left corner to the
%    left end of the baseline.
% \end{description}
% Note that these descriptions are technically accurate only for
% unrotated text; for rotated text, rotations are removed before
% the bounding box is calculated.
%    \begin{macrocode}
\def\pfg@excl{!}
\def\pfg@tfor#1\do{\@tfor\@tempa:=#1\do}
\def\pfg@info #1(#2,#3)(#4,#5)(#6,#7)#8#9{%
  \bgroup\@nameuse{pfg@m@#1}%
%    \end{macrocode}
% Determine the position of the anchor point on the PostScript text,
% and scale that position according to the scaling factor
% determined by the |graphics.sty| macros.
%    \begin{macrocode}
    \pfg@x=#2bp \advance\pfg@x by-\Gin@llx \pfg@mx=0.5bp%
    \pfg@y=#3bp \advance\pfg@y by-\Gin@lly \pfg@my=0.5bp%
    \expandafter\pfg@tfor\pfg@psposn\do{%
      \if l\@tempa\pfg@mx=0\else\if r\@tempa\pfg@mx=1\else
      \if b\@tempa\pfg@my=0\else\if t\@tempa\pfg@my=1\else
      \if B\@tempa\pfg@my=#9\fi\fi\fi\fi\fi bp}%
    \advance\pfg@x by#4\pfg@mx \advance\pfg@y by#5\pfg@mx
    \advance\pfg@x by#6\pfg@my \advance\pfg@y by#7\pfg@my
    \ifx\Gin@scalex\pfg@excl\let\Gin@scalex\Gin@scaley
    \else\ifx\Gin@scaley\pfg@excl\let\Gin@scaley\Gin@scalex\fi\fi
    \pfg@x=\Gin@scalex\pfg@x \pfg@y=\Gin@scaley\pfg@y
%    \end{macrocode}
% Create a zero-area box, with the desired \pfg\ replacement
% text typeset inside of it. Align the box with the alignment
% point of the replacement text.
% \changes{2.0}{1995/03/09}{Added the \cs{vbox} to protect any vertical
%                           space that might have been requested
%                           in the replacement text.}
%    \begin{macrocode}
    \setbox\z@\vbox{\hbox{\@nameuse{pfg@n@#1}}}%
    \dimen@=\ht\z@ \advance\dimen@ by\dp\z@
    \pfg@mx=0.5\wd\z@ \pfg@my=0.5\dimen@
    \expandafter\pfg@tfor\pfg@posn\do{%
      \if l\@tempa \pfg@mx=0bp\else\if r\@tempa \pfg@mx=\wd\z@\else
      \if b\@tempa \pfg@my=0bp\else\if B\@tempa \pfg@my=\dp\z@\else
      \if t\@tempa \pfg@my=\dimen@\fi\fi\fi\fi\fi}%
    \setbox\z@\hbox to\z@{\hskip-\pfg@mx
       \vbox to\z@{\vss\box\z@\vskip-\pfg@my}\hss}%
%    \end{macrocode}
% Place rotation and/or scaling constructs around the box. Rotation
% comes first. Using the \textsf{graphics} package's internal macros
% enhances portability. It is necessary to surround each construct
% with a zero-size box to insure that the coordinate system is indeed
% local when the transformations are performed.
%    \begin{macrocode}
    \pfg@mx=#8pt \advance\pfg@mx by\pfg@rotn \pfg@my=\pfg@scale
    \ifdim\pfg@mx=0pt\else
       \edef\Grot@angle{\strip@pt\pfg@mx}%
       \setbox\z@\hbox to\z@{\Grot@start\box\z@\Grot@end}\fi
    \ifdim\pfg@my=1pt\else
       \edef\Gscale@x{\strip@pt\pfg@my}\let\Gscale@y\Gscale@x
       \setbox\z@\hbox to\z@{\Gscale@start\box\z@\Gscale@end}\fi
%    \end{macrocode}
% Place the box.
%    \begin{macrocode}
    \@killglue\raise\pfg@y\hbox to\z@{\kern\pfg@x\box\z@\hss}%
  \egroup\ignorespaces}
%    \end{macrocode}
% \end{macro}
%
% \subsection{File handling}
%
% \begin{macro}{\pfg@scan}
% It is with this macro that the EPS file is scanned for 
% \pfg\ information. The replacement information is placed in two token
% registers: \cs{pfg@proc} holds the replacement macros, and 
% \cs{pfg@str} contains the strings to be replaced, in PostScript
% syntax, to be passed to the PostScript filtering \cs{special}.
%
% For compatibility mode, we just redefine those commands used
% in the |.frag| files to call the updated \LaTeXe\ versions.
%    \begin{macrocode}
\ifpfg@compat
  \typeout{PSfrag Compatibility Mode Enabled.}%
\else
\def\pfg@scan#1{%
  \edef\pfg@fname{#1}%
  \immediate\openin\pfg@file=#1\relax
  \pfg@foundfalse
  \ifeof\pfg@file\else
    \bgroup
%    \end{macrocode}
% Loop 1: We make rearrange the catcodes so that everything read in
% from the file remains unprocessed. Then we read in consecutive lines
% until the |%PSfragBegin| comment is encountered. If the header comments
% terminate first, then we know that \pfg\ has not touched this file...
%    \begin{macrocode}
      \let\do\@makeother\dospecials\catcode`\ 10 %
      \@makeother\^^D\catcode\endlinechar9 %
      \catcode`\{1\catcode`\}2 %
      \pfg@filetrue\loop\read\pfg@file to\pfg@line
         \ifeof\pfg@file\pfg@filefalse
         \else\ifx\pfg@line\@empty\pfg@filefalse
         \else\expandafter\pfg@find\pfg@line.....\\\fi\fi
      \ifpfg@file\repeat
    \egroup
    \ifpfg@found
      \global\pfg@foundfalse
      \bgroup
%    \end{macrocode}
% Loop 2: From now until the |%PSfragEnd| comment is found, we assume
% a very strict structure: one \pfg\ command per line, starting with
% the comment character (whose catcode is now changed to 0). So we can
% simply \emph{execute} each line to obtain the desired information.
%    \begin{macrocode}
        \catcode`\% 0 %
        \pfg@filetrue\loop
          \read\pfg@file to\pfg@line
          \ifeof\pfg@file\pfg@filefalse\else\pfg@line\\\fi
        \ifpfg@file\repeat
      \egroup
    \fi\immediate\closein\pfg@file\fi}
\fi
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\pfg@find}
% \begin{macro}{\pfg@@find}
% \begin{macro}{\pfg@gobble}
% These macros are used during the first loop in \cs{pfg@scan} to
% hunt for the first \pfg\ comment. Each line is tested by \cs{pfg@find}
% starting comment character; if one is not found, then we know
% that there must be no \pfg\ comments, and we may exit the loop
% early. Otherwise, we use \cs{pfg@@find} to determine if the
% current comment is in fact a \pfg\ comment, all of which start
% with |%PSfrag| (actually, only |%PSfra| is confirmed, because that
% is all the Adobe Document Structuring comments require for uniqueness.)
% \cs{pfg@gobble} simply eats the remaining text on the line.
%    \begin{macrocode}
{\catcode`\%=12\global\let\pfg@pcnt=%}
\def\pfg@find#1{%
  \ifx#1\pfg@pcnt\expandafter\pfg@@find\else
  \pfg@filefalse\expandafter\pfg@gobble\fi}
\def\pfg@pfx{PSfra}
\def\pfg@@find#1#2#3#4#5{%
  \def\pfg@{#1#2#3#4#5}\ifx\pfg@\pfg@pfx
    \global\pfg@foundtrue\global\pfg@filefalse\fi\pfg@gobble}
\def\pfg@gobble#1\\{}
%    \end{macrocode}
% \end{macro}\end{macro}\end{macro}
%
% \begin{macro}{\PSfragNext}
% \begin{macro}{\PSfragInfo}
% \begin{macro}{\PSfragEnd}
% \begin{macro}{\PSfragBegin}
% These macros are embedded in every \pfg-aware EPS file. The first
% two basically extract the information for their internal counterparts
% and place them in the \cs{pfg@proc} token register; the third
% signals the end the file search. \cs{PSfragBegin} actually isn't
% used; while it occurs in the file, it is discarded as text instead
% of executed. But I define it here for symmetry anyway, just in case
% I do decide to use it.
%    \begin{macrocode}
\def\PSfragNext#1\\{%
  \def\pfg@m@{}\global\pfg@proc=\expandafter{\the\pfg@proc\psfrag{}#1}}
\def\PSfragInfo#1#2\\{%
  \@ifundefined{pfg@m@#1}{}{%
    \global\pfg@foundtrue
    \global\pfg@proc=\expandafter{\the\pfg@proc\pfg@info{#1}#2}%
    \global\pfg@str=\expandafter{\the\pfg@str (#1)}}}
\def\PSfragEnd\\{\pfg@filefalse}
%    \end{macrocode}
% \end{macro}\end{macro}\end{macro}\end{macro}
%
% \subsection{\LaTeX\ 2.09 compatibility macros}
% The following macros---a different definition of \cs{pfg@scan}, and
% a few others---are here to maintain compatibility as best as possible
% with \LaTeX\ 2.09's version of \pfg.
%
% \begin{macro}{\psfragspecial}
% This macro is supported \emph{only} in back-compatabilty mode,
% and was used to call \cs{special} manually. I haven't implemented
% it yet; does anyone out there use it?
%    \begin{macrocode}
\ifpfg@compat
  \def\psfragspecial#1#2#3#4#5#6{%
    \PackageError{PSfrag}{\string\psfragspecial
                          not implemented yet.}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\pfg@scan}
% The \LaTeX\ 2.09 version of this macro simply \cs{input}s a |.frag|,
% |.epsfrag|, or |.psfrag| file (depending on the configuration). The
% commands within it are redefined to call the new versions.
%    \begin{macrocode}
\def\pfg@strip#1.#2\relax{#1}
\def\pfg@scan#1{%
  \pfg@foundfalse
%</package>
%<*package&longnames>
  \InputIfFileExists{#1frag}\relax{%
    \edef\@tempa{\pfg@strip#1..\relax.frag}
    \InputIfFileExists\@tempa\relax\relax}}
%</package&longnames>
%<*package&shortnames>
  \edef\@tempa{\pfg@strip#1..\relax.frag}
  \InputIfFileExists\@tempa\relax\relax}
%</package&shortnames>
%<*package>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\PsFragShowString}
% \begin{macro}{\PsFragInfo}
% \begin{macro}{\PsFrag}
% \begin{macro}{PSFragmentLocs}
% These macros lie inside every \LaTeX\ 2.09
% |.frag| file, and are redefined to process things
% the \LaTeXe\ way here. The grouping of the |PSFragmentLocs|
% environment is used to temporarily redefine \cs{put} and 
% \cs{psfrag} to direct them to the proper behavior. It also
% calls \cs{PSfragEnd} upon completion, which isn't necessary
% now, but may be in the future.
% \changes{2.0}{1995/03/09}{Fixed up the ignorespaces calls}
%    \begin{macrocode}
\def\PsFragShowString#1{\ignorespaces}
\def\PsFragInfo#1#2#3#4#5#6#7#8{%
  \PSfragInfo{#1}(#2,#3)(#4,#5)(#6,#7){#8}{0}\\\ignorespaces}
\def\PsFrag#1{\PSfragNext#1\\\ignorespaces}
\def\pfg@put(#1)#2{\ignorespaces}
\newenvironment{PSFragmentLocs}
  {\let\put\pfg@put\let\psfrag\PsFrag\ignorespaces}
  {\PSfragEnd\\\global\@ignoretrue}
\fi
%    \end{macrocode}
% \end{macro}\end{macro}\end{macro}\end{macro}
%
% \subsection{The PostScript interface}
%
% \begin{macro}{\pfg@hidestart}
% \begin{macro}{\pfg@hideend}
% These macros are called around any picture that requires \pfg
% processing in order to initialize the PostScript-based |show| 
% filter. It is assumed that the token register \cs{pfg@str}
% contains the list of strings, in PostScript syntax, to filter out.
%    \begin{macrocode}
\def\pfg@hidestart{%
  \ifpfg@specs\else\pfg@dospecs\pfg@specstrue\fi
  \pfg@rawps{PSfragShowDict begin PSfragDict begin
             /fragStrings [\the\pfg@str] def end}}
\def\pfg@hideend{\pfg@rawps{end}}
%    \end{macrocode}
% \end{macro}\end{macro}
%
% \begin{macro}{\ifpfg@specs}
% This \cs{if} is true if the \pfg\ PostScript dictionary has been
% inserted; false otherwise.
%    \begin{macrocode}
\newif\ifpfg@specs \pfg@specsfalse
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\pfg@dospecs}
% This macro is only called once, in order to insert the PostScript
% code necessary to perform the text-filtering operations. It is
% inserted \emph{only} if any text to replace is actually found.
% So, for example, if \cs{psfragshowtrue} is called, then this
% will never make it to the PostScript file.
% \changes{2.0}{1995/03/08}{Fixed some rather stupid bugs in here}
% \changes{2.0}{1995/03/08}{Rearranged so that PSfragShowDict is the
%                           only name polluting the global namespace.
%                           PSfragDict is still a ``reserved'' 
%                           word, though.}
%    \begin{macrocode}
\def\pfg@dospecs{\pfg@rawps{
  userdict begin /PSfragShowDict 6 dict def end
  PSfragShowDict begin /PSfragDict 30 dict def
    PSfragDict begin
      /BD { bind def } bind def /ED { exch def } BD 
      /LD { load def } BD /CHAR { /c ED ( ) dup 0 c put } BD
      /Oshow /show LD /Oashow /ashow LD /Okshow /kshow LD
      /Owidthshow /widthshow LD /Oawidthshow /awidthshow LD
      /Sshow { stringwidth rmoveto } BD
      /Sashow { dup Sshow length /m ED exch
                m mul exch m mul rmoveto } BD
      /Swshow { /by ED /bx ED /chr ED { chr eq
                { bx by rmoveto } forall } } BD
      /Swidthshow { dup 5 1 roll Sshow Swshow } BD
      /Sawidthshow { dup 7 1 roll Sashow Swshow } BD
      /Skshow { exch /kern exch BD { dup CHAR
                stringwidth rmoveto kern } forall } BD
      /condShow{ /pfrag ED /ptext ED /s ED
                 s s (\string\\tex) anchorsearch { pop pop pfrag }{ 
                   pop false fragStrings { 
                     s eq { pop true exit } if 
                   } forall { pfrag } { ptext } ifelse
                 } ifelse flush } BD
      /fragStrings [] def
    end
    /show { PSfragDict begin {Oshow} {Sshow} condShow end } bind def
    /ashow { PSfragDict begin {Oashow} {Sashow} condShow end } bind def
    /kshow { PSfragDict begin {Okshow} {Skshow} condShow end } bind def
    /widthshow { PSfragDict begin {Owidthshow} {Swidthshow} 
                 condShow end } bind def
    /awidthshow { PSfragDict begin {Oawidthshow} {Sawidthshow} 
                  condShow end } bind def
  end}}
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \section{\texttt{epsf.sty}}
%
% To insure seamless back-compatibility, an |epsf.sty| file has
% been created which simply uses the proper \cs{ProvidesPackage}
% command and loads |epsfig.sty|. 
%    \begin{macrocode}
%<*epsf>
\DeclareOption*{\PassOptionsToPackage{epsfig}{\CurrentOption}}
\ProcessOptions
\RequirePackage{epsfig}
%</epsf>
%    \end{macrocode}
%
% \section{\texttt{ps2frag.ps}}
%
% Thanks to the fact that PostScript shares the same comment
% characters with \TeX, I can maintain and document the 
% |ps2frag.ps| script in exactly the same fashion as I maintain
% the other \TeX\ files.
%
% |ps2frag.ps| redefines the text display operators in PostScript
% in order to generate and output information about each piece
% of text that is displayed. This information is collected by
% the |ps2frag| script and placed \emph{back} into the EPS fill
% as a set of Document Structuring comments. These comments affect
% the figure in no visible way, but provide information to 
% the \pfg\ \LaTeX\ macros that allow it to properly place the
% replacement text.
%
% Ghostscript calls this code in the following manner:
% \begin{quote}
% |gs -ddx=|\emph{dx}| -ddy=|\emph{dy}| -dNODISPLAY -dQUIET| \emph{file}
% \end{quote}
% \emph{dx} and \emph{dy} are the horizontal and vertical offsets,
% respectively, to add to the locations determined. They default
% to 0 if not supplied.
%
% The only changes made to the global namespace are to define /PSfragDict
% and to re-define the show commands to output bounding-box information.
% Therefore, virtually any picture should be processable; if you find
% a reasonable file that is not, let me know.
%
% \changes{2.0}{1995/03/01}{a few bug fixes, and the activation of 
%               \LaTeXe-specific behavior}
% \changes{1.99}{1994/11/12}{an interim version before 2.0 for \LaTeXe, 
%                containing  much of the 2.0 code, including
%                renovated bounding box calculations and improved
%                support for alternate show operators}
%
% \subsection{Intialization}
%
% Here we initialize the dictionary, grab |dx| and |dy| if they
% have been defined, and make some miscellaneous abbreviations.
%    \begin{macrocode}
%<*psdriver>
/PSfragDict 40 dict def PSfragDict begin
/DX /dx where { /dx get } { 0 } ifelse def
/DY /dy where { /dy get } { 0 } ifelse def
/BD { bind def } bind def /ED { exch def } BD 
/LD { load def } BD
/STR 16 string def /w /print LD
%    \end{macrocode}
%
% \subsection{Output commands}
%
% This section defines the commands that write out the 
% \pfg\ information, in the form of \cs{PSfragInfo} and
% \cs{PSfragNext} commands.
%
% We must be careful when writing out numbers that
% GhostScript not use scientific notation, because that
% breaks the \LaTeX\ interpreter.
% 
% \begin{macro}{wFrag}
% This macro expects the global variables |str|, |llx|, 
% |lly|, |dxx|, |dxy|, |dyx|, |dyy|, |rot|, and |base| to be
% filled with information about the current piece of text.
% This macro writes a single \cs{PSfragInfo} line to the
% output file. If the string begins with \cs{tex}, it is
% an embedded \pfg\ command, so a \cs{PSfragNext} command
% is also written out.
%
% The debugging version of the |wFrag| operator also draws
% bounding box information on the page to aid in debugging.
% To include this feature in your version of the file, 
% add the |debug| flag to the \textsf{docstrip} extraction 
% command. Normally, it should be omitted from |ps2frag.ps|,
% in part because it will not work with |kshow|.
%    \begin{macrocode}
/wa { ({) w w (}) w } BD
/wnum { 1e4 mul round 1e4 div dup dup cvi eq { cvi } if STR cvs w } BD
/wn { ({) w wnum (}) w } BD
/wc { (\() w wnum (,) w wnum (\)) w } BD 
/wFrag {
  str (\\tex) anchorsearch 
  { pop (%PSfragNext) w w (\n%PSfragInfo{}) w }
  { pop (%PSfragInfo) w str wa } ifelse
  lly DY add llx DX add wc dxy dxx wc dyy dyx wc 
  rot wn base wn (\n) w
%</psdriver>
%<*psdriver&debug>
  gsave str myCharPath fill grestore gsave
  initgraphics newpath
  llx lly moveto dxx dxy rlineto dyx dyy rlineto
  dxx neg dxy neg rlineto closepath stroke
  llx lly moveto dyx base mul dyy base mul rmoveto
  dxx dxy rlineto stroke
  llx lly 2 0 360 arc fill
  grestore
%</psdriver&debug>
%<*psdriver>
} BD
%    \end{macrocode}
% \end{macro}
%
% \subsection{Bounding-box determination}
%
% \begin{macro}{myCharPath}
% This command is called in replacement of the |show| operators and
% its kin. It needs to completely emulate the behavior of the original
% show operator; so |proc| is called after each character has been
% placed to effect any additional movements (kerns).
%
% \begin{macro}{aproc}
% \begin{macro}{wproc}
% \begin{macro}{awproc}
% These kerning commands emulate the behavior of |ashow|,
% |widthshow|, and |awidthshow|, respectively. |show| uses |pop|
% because it performs no kerning, and |kshow| uses its own 
% user-defined operator. See the PostScript manual for details.
%
% \changes{2.0}{1995/04/04}{Removed dictionary manipulation because
%                           it causes problems with Adobe Illustrator.}
%    \begin{macrocode}
/myCharPath { { ( ) dup 0 3 index put false charpath proc } forall } BD
/aproc { pop x y rmoveto } BD
/wproc { c eq { x y rmoveto } if } BD
/awproc { c eq { x y rmoveto } if x2 y2 rmoveto } BD
%    \end{macrocode}
% \end{macro}\end{macro}\end{macro}\end{macro}
%
% \begin{macro}{findbbox} usage: \emph{str} \emph{proc} |findbbox|\\
% This command accepts a string \emph{str} and a kerning procedure
% \emph{kern}, and determines the positioning and bounding box information
% that \pfg\ requires. Normal |pathbbox| calculations will not work
% for rotated text, so this procedure is somewhat complex. It proceeds
% as follows:
% \begin{enumerate}
% \item Determines the amount of rotation that the baseline of
%       the text will experience due to the current |FontMatrix| and
%       transformation matrix.
% \item Inserts a negative rotation between |defaultmatrix| and
%       |currentmatrix| so that the text will come out horizontal.
% \item Now that the bounding box will give tight bounds, uses 
%       |myCharPath| to trace out the text, and |pathbbox| to 
%       determine its bounding box.
% \item Transforms the box corners to default coordinates and 
%       determines the lower-left and upper-right corners.
% \item Determines the baseline height as a fraction of the total height.
% \item Rotates |(llx,lly)|, |(dxx,dxy)|, and |(dyx,dyy)| back to
%       the original coordinate system, and calls |wFrag|.
% \item Moves |currentpoint| to where it would be had the original
%       |show| command had been called.
% \end{enumerate}
%    \begin{macrocode}
/findbbox { 
  /proc ED /str ED
  str () ne {
    gsave currentpoint translate
    % Step 1.
    /CTM matrix currentmatrix matrix defaultmatrix
         matrix invertmatrix matrix concatmatrix def
    /rot 1 0 currentfont /FontMatrix get dtransform 
         CTM dtransform exch atan def
    % Step 2.
    rot 0 ne {
      /rm rot neg matrix rotate def
      CTM rm CTM concatmatrix initmatrix concat
    } if
    % Step 3.
    newpath 0 0 moveto str myCharPath flattenpath pathbbox
    currentpoint /nety ED /netx ED
    % Step 4.
    CTM transform 4 2 roll CTM transform
    /lly ED /llx ED /ury ED /urx ED
    lly ury gt { /ury lly /lly ury def def } if
    llx urx gt { /urx llx /llx urx def def } if
    % Step 5.
    /base ury lly eq { 0 } { CTM 5 get lly sub ury lly sub div 
                             dup abs add 0.5 mul } ifelse def
    % Step 6.
    rot 0 eq { 0 ury lly sub urx llx sub 0 llx lly }{
      0 ury lly sub rm idtransform
      urx llx sub 0 rm idtransform
      llx lly rm itransform 
    } ifelse [/lly /llx /dxy /dxx /dyy /dyx] {ED} forall
    grestore wFrag
    % Step 7.
    netx nety rmoveto
  } if
} BD
end
%    \end{macrocode}
% \end{macro}
%
% \subsection{Redefining the \texttt{show} operators}
% \begin{macro}{show}
% \begin{macro}{ashow}
% \begin{macro}{widthshow}
% \begin{macro}{awidthshow}
% \begin{macro}{kshow}
% The text display operators must be redefined so that they calculate
% bounding-box information instead of actually displaying text. These
% definitions, and the |PSfragDict| dictionary, are the only modifications
% made to PostScript's global namespace. Therefore, any Encapsulated 
% PostScript code that uses these standard operators should run though
% this processor without problems.
%    \begin{macrocode}
/show { PSfragDict begin 
  /pop load findbbox
end } bind def
/ashow { PSfragDict begin
  3 1 roll /y exch def /x exch def 
  /aproc load findbbox 
end } bind def
/widthshow { PSfragDict begin
  4 1 roll /c exch def /y exch def /x exch def 
  /wproc load findbbox
end } bind def
/awidthshow { PSfragDict begin
  6 1 roll /y2 exch def /x2 exch def /c exch def /y exch def 
  /x exch def /awproc load findbbox
} bind def
/kshow { PSfragDict begin
  exch findbbox
end } bind def
%</psdriver>
%    \end{macrocode}
% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}
%
% \Finale
%
