%%%% pinlabel.sty v1.2 %%%% %%%% Written by Colin Rourke %%%% %%%% Based on geompsfi.sty by Silvio Levy %%%% Based on psfig.sty by Trevor Darrell %%%% %%%% Copyright 2006-11 Mathematical Sciences Publishers (MSP) %%%% %%%% NOTICE %%%% %%%% This package may be distributed and/or modified under the %%%% conditions of the LaTeX Project Public License, either version %%%% 1.3 of this license or (at your option) any later version. %%%% The latest version of this license is in %%%% %%%% http://www.latex-project.org/lppl.txt %%%% %%%% and version 1.3 or later is part of all distributions of LaTeX %%%% version 2005/12/01 or later. %%%% %%%% This package has the LPPL maintenance status `maintained' and is %%%% currently maintained by MSP: contact@mathscipub.org %%%% %%%% It comprises the files: pinlabel.sty (this file) and the manual %%%% pinlabdoc.pdf where full documentation may be found, togther %%%% with the source files for the documentation. %%%% %%%% %%%% pinlabel.sty is designed for inserting perfectly formatted TeX %%%% labels in eps or pdf files for inclusion in documents. %%%% It uses the coordinates provided by ghostview (or gv) to %%%% position the label and reads the relevant bounding box %%%% information from the eps file (or alternatively ps or pdf %%%% file). You must supply one of these three. To label a jpg %%%% for example, you need to convert it first to eps or pdf. %%%% Several features are provided which facilitate perfect %%%% first-time label positioning, of which the most important %%%% is auto-spacing, which sets the label a predetermined gap %%%% away from the figure object which is being labelled. The %%%% gap is \hair (a TeX dimension, preset to 3pt, but settable %%%% on the fly) and the direction of the spacing is chosen %%%% automatically. The result is consistent and eye-pleasing %%%% spacing. %%%% In use, read the position of the object that you wish to %%%% label and do not guess the position of the actual label. %%%% Then choose the orientation of the label (eg [tr] which %%%% means top-right) and the label will automatically be set %%%% so that top-right of the label bounding box is set one %%%% \hair away from the object being labelled. %%%% %%%% %%%% pinlabel.sty was written specifically for the use of editors and %%%% authors of MSP papers and is the recommended package for %%%% use for labelling diagrams for MSP. %%%% %%%% pinlabel.sty is a revised version of geomsfig.sty with improved %%%% functionality and simpler syntax. The old syntax remains %%%% available for backwards compatibility, see below. %%%% %%%% new syntax: \pinlabel {label} by x-pin y-pin at x-location y-location %%%% and \pinlabel* {label} by x-pin y-pin at x-location y-location %%%% %%%% where "x-pin y-pin" is the point in intrinsic coords in label %%%% space where we are placing the pin and "x-location y-location" %%%% is the point in diagram space (in PS points as read in gv) where %%%% the label is pinned. \pinlabel uses \hair autospacing \pinlabel* %%%% does not. See the manual for full details. %%%% \mathsurround is set to 0pt for parsing the label %%%% %%%% options: "by x-pin y-pin" may be omitted the default is 0 0 %%%% orientation commands [r], [l] etc may replace "by x-pin y-pin" %%%% [r] is right-centre (same as "by 0 1") etc %%%% a manual adjustment "" may be added before "at" %%%% or directly after the label %%%% %%%% Examples \pinlabel $a^b$ [l] <-2pt,1pt> at 231 47 %%%% Same as \pinlabel $a^b$ by -1 0 <-2pt,1pt> at 231 47 %%%% Same as \pinlabel $a^b$ <-2pt,1pt> [l] at 231 47 %%%% Same as \pinlabel $a^b$ <-2pt,1pt> by -1 0 at 231 47 %%%% %%%% which pins "$a^b$" by centre-left at 231 47 with two %%%% adjustments: \hair (autospacing) and then (-2pt,1pt) manual %%%% %%%% \pinlabel* {A nice figure} [Bl] <-5pt,0pt> at 231 47 %%%% %%%% which pins "A nice figure" by baseline-left at 231 47 %%%% with one adjustment: (-5pt,0pt) %%%% %%%% Full list of orientation commands: r=right, l=left, t=top, b=bottom %%%% and B=baseline, default is centre and any sensible combination %%%% of two commands may be give (in either order) eg %%%% [tl]=[lt]=top-left of label bounding box %%%% %%%% NB the commands are syntax sensitive and use spaces as separators so %%%% they DON'T work with \obeyspaces set. Braces must be placed %%%% around labels containing spaces but may be omitted if there are %%%% no spaces in the label code (see the examples above and below). %%%% %%%% Label instructions go either in the file inside \labellist %%%% ... \endlabellist or in a separate .lab file (ie if fig %%%% is fig4-1.eps or .ps, then labels go in \figdir/fig4-1.lab %%%% where \figdir/ is the directory containing fig4-1.eps). %%%% The \labellist overrides a .lab file. %%%% \labellist ... \endlabellist can be given at any time before %%%% the next figure, but typically will be included in the figure %%%% code, as in the following example. %%%% %%%% Here is a complete example of a relabelled figure: %%%% %%%% \begin{figure}[ht!] %%%% \labellist\small\hair 2.5pt %%%% \pinlabel {$\partial _1 X$} by 1 0 at 156 426 %%%% \pinlabel {$\partial _2 X$} by -1 1 at 334 429 %%%% \pinlabel $X_1$ at 431 513 %%%% \pinlabel $X_2$ at 428 460 %%%% \pinlabel $H_X$ [lb] at 311 622 %%%% \pinlabel* $H_X'$ [tr] <-1.5pt,-2pt> at 178 370 %%%% \endlabellist %%%% \centerline{\psfig{file=\figdir/decomp,width=3in}} %%%% \caption{Labelling the boundary components of $X$} %%%% \label{Fig:decomp} %%%% \end{figure} %%%% %%%% The actual figure can be included by using either psfig or %%%% graphicx. psfig is used by the code, but graphicx %%%% commands are translated automatically, so in the above %%%% example the alternative code: %%%% %%%% \centerline{\includegraphics[width=3in]{\figdir/decomp}} %%%% %%%% would produce identical results. Automatic translation ONLY %%%% takes place is a labellist is present, so if you use a .lab %%%% file then you MUST use the psfig syntax. %%%% %%%% %%%% VERY IMPORTANT %%%% ============== %%%% %%%% The file extension MUST NOT be given. The program will find %%%% the correct file (\figdir/decomp.eps or .ps or .pdf). %%%% %%%% READ THE BUGS below before using \includegraphics with pinlabel. %%%% %%%% %%%% old syntax: \setlabel is unchanged (but \mathsurround is set to 0pt) %%%% \setlabel* is a new variant which sets \hair to 0pt (no %%%% autospacing) and an optional manual adjustment may be added %%%% eg: %%%% %%%% \setlabel<-2pt,-1pt>{a^b}{321}{33}{1}{1} %%%% \setlabel*<-2pt,-1pt>{a^b}{321}{33}{1}{1} %%%% \setlabel{a^b}{321}{33}{1}{1} %%%% \setlabel*{a^b}{321}{33}{1}{1} %%%% %%%% the first uses autospacing and adds a (-2pt,-1pt) manual %%%% adjustment; the second uses just the manual adjustment, %%%% the third just autospacing and the fourth nothing. %%%% %%%% old and new syntax may be mixed in a label list and given %%%% either in a .lab file or inside \labellist ... \endlabellist %%%% %%%% ***Users of geomsfig note the change to \mathsurround. If you %%%% do not use it, there will be no change in label positioning. %%%% If you do, labels may move a small amount horizontally.*** %%%% %%%% %%%% !!!NBNB label is in horizontal mode in new syntax and math mode in old!!! %%%% %%%% %%%% BUGS: NO spaces are permitted in the file argument of \psfig %%%% Autotranslation of \includegraphics[]{} means that no %%%% spaces are permitted in the file argument to \includegraphics %%%% Eg \includegraphics[width=4in]{ foo } will produce errors, %%%% use \includegraphics[width=4in]{foo}. Spaces are permitted %%%% with other arguments. %%%% %%%% Many of the options in graphicx are not supported. The %%%% supported ones are: width, height, scale, bbllx, bblly %%%% bburx, bbury and clip. The syntax for clip is "clip=". %%%% Replace "keepaspectratio=true" by "proportional=". %%%% %%%% The command \reallyincludegraphics will force the use of %%%% graphicx (ie cancel autotranslation). Since code will use %%%% graphicx automatically if there is no labellist present, %%%% \reallyincludegraphics will only be needed if a labellist %%%% has already been given for a later figure. %%%% %%%% \graphicspath{} is not supported. Use \figdir instead. %%%% %%%% %%%% Automatic configuration for dvips and pdflatex is included %%%% in this file. No support is provided for other drivers. %%%% %%%% NB \psfig ouputs a vbox, which is not centred in latex' {center} %%%% environment. Either use \centerline{} or type \leavevmode %%%% before \psfig{..}. The translator adds \leavevmode for %%%% \includegraphics, which therefore centres correctly as usual %%%% in the {center} environment. %%%% %%%% PLAIN TeX compatibility: uses miniltx.tex and works with dvips %%%% but NOT with pdftex. For pdf output from plain TeX use dvips %%%% followed by ps2pdf. %%%% %%%% NEW FOR VERSION 1.2: Thanks to Mark Petelier, you no longer %%%% need to convert a pdf figure to eps. pinlabel now reads the %%%% BB from a pdf file if no ps or eps file is supplied. \edef\atcatcode{\the\catcode`\@} \catcode`@=11 \def\@message#1{\immediate\write16{#1}} \newif\ifoldlabels \oldlabelsfalse \expandafter\ifx\csname @ifundefined\endcsname\relax \long\def\@ifundefined#1#2#3{\expandafter\ifx\csname #1\endcsname\relax#2\else#3\fi} \def\@iden#1{#1} %\newdimen\@tempdima \alloc@1\dimen\dimendef\insc@unt\@tempdima \def\@warning#1{\@message{Warning: #1.}} \fi %%% if not latex \input miniltx (for plain tex compatibility) \@ifundefined{RequirePackage}{\input miniltx}{\relax} %%% make sure graphicx is loaded \RequirePackage{graphicx} \let\@includegraphics@\includegraphics %%% for auto translation of graphicx \let\reallyincludegraphics\@includegraphics@ %%% to override translation \@ifundefined{ps@init}{}{\endinput} \@ifundefined{hyperactivelabels}{\let\hyperactivelabels\relax}{} %%% in-line label list handling %%% \long\def\labellist#1\endlabellist{\gdef\thelabellist{#1}} \let\thelabellist\relax %%%% initialise \newif\if@topspecials %false for Rokicki's dvips: \special is at bottom of box % true for dvitps, dvi2ps \newif\ifdvi\dvitrue \@ifundefined{pdfoutput}{}{\ifnum\pdfoutput>0 \dvifalse\fi} \ifdvi %%% start of driver.chg {\catcode`\p=12 \catcode`\t=12 \gdef\read@PT#1pt{#1}} \def\sp@topt#1#2{\psfig@dimen=#2sp \if\psfig@dimen=0pt \psfig@dimen=1sp\fi \edef#1{\expandafter\read@PT \the\psfig@dimen}} \def\sp@tobp#1#2{\psfig@dimen=#2sp \if\psfig@dimen=0pt \psfig@dimen=1sp\fi \expandafter\@tempdima\expandafter\read@PT \the\psfig@dimen bp \advance\psfig@dimen-.5 \@tempdima \multiply\psfig@dimen 2 \edef#1{\expandafter\read@PT \the\psfig@dimen}} \def\ps@init{} \def\ps@begin{\sp@tobp\@tempa\@p@sbbllx \sp@tobp\@tempb\@p@sbblly \sp@tobp\@tempc\@p@sbburx \sp@tobp\@tempd\@p@sbbury \sp@tobp\@tempe{\@p@swidth0} \sp@tobp\@tempf{\@p@sheight0} \special{PSfile=\@p@sfile\space llx=\@tempa\space lly=\@tempb\space urx=\@tempc\space ury=\@tempd\space rwi=\@tempe\space rhi=\@tempf}} % rwi is the total width, in tenths of the units used for the % other dimensions (this is dvips's brain damage) \def\ps@prolog{} \def\ps@clip{} % \def\ps@include{} % \def\ps@postlog{} % \def\ps@end{} % %%% end of driver.chg \else \@ifundefined{usepackage}{\@message{} \@message {!!! pinlabel.sty cannot be used for direct pdf output except with latex !!!} \@message {For pdf output from plain tex use dvips and ps2pdf} \@message{}}{} %%% start of gpdftex.chg {\catcode`\p=12 \catcode`\t=12 \gdef\read@PT#1pt{#1}} \def\sp@topt#1#2{\psfig@dimen=#2sp \if\psfig@dimen=0pt \psfig@dimen=1sp\fi \edef#1{\expandafter\read@PT \the\psfig@dimen}} \def\sp@tobp#1#2{\psfig@dimen=#2sp \if\psfig@dimen=0pt \psfig@dimen=1sp\fi \expandafter\@tempdima\expandafter\read@PT \the\psfig@dimen bp \advance\psfig@dimen-.5 \@tempdima \multiply\psfig@dimen 2 \edef#1{\expandafter\read@PT \the\psfig@dimen}} \def\ps@init{} \def\ps@begin{\sp@tobp\@tempa\@p@sbbllx \sp@tobp\@tempb\@p@sbblly \sp@tobp\@tempc\@p@sbburx \sp@tobp\@tempd\@p@sbbury \sp@tobp\@tempe\@p@swidth \sp@tobp\@tempf\@p@sheight% \edef\foobar{[width=\@p@swidth sp,height=\@p@sheight sp]{\@p@dffile}}% %,viewport=\@tempa\space\@tempb\space\@tempc\space\@tempd \@message{\string\@includegraphics@\foobar}% \rlap{\smash{\expandafter\@includegraphics@\foobar}}% } % rwi is the total width, in tenths of the units used for the % other dimensions (this is dvips's brain damage) \def\ps@prolog{} \def\ps@clip{} % \def\ps@include{} % \def\ps@postlog{} % \def\ps@end{} % %%%% end of gpdftex.chg \fi %%%% graphicx translation %%%% first set a flag to detect use of graphicx and initialise %%%% the default is \relax (graphicx not used) any other value %%%% means graphicx is used \let\inc@graph@flag\relax %%%% redefine \includegraphics to mimic \psfig ONLY IF a labellist is present \def\includegraphics{\ifx\thelabellist\relax\let\next\@includegraphicsnolist@% \else\let\next\@includegraphics@list@\fi\next} \let\@includegraphicsnolist@\reallyincludegraphics \def\@includegraphics@list@{\def\inc@graph@flag{1}% \@ifnextchar[{\includegraphicswithoptions}{\includegraphicsplain}} \def\includegraphicswithoptions[#1]#2{\leavevmode\psfig{file=#2,#1}} \def\includegraphicsplain#1{\leavevmode\psfig{file=#1}} \newcount\psfc@a \newcount\psfc@b \newcount\psfc@c \newcount\psfc@d \newcount\psfc@e \newcount\psfc@f \newcount\psfc@g \newcount\psfc@h \newcount\psfc@i \newcount\psfc@j \newcount\psscale@count \newtoks\psfigtoks@ % A dimension register for temporarily storing a dimension in % \@pDimenToSpNumber. \newdimen\psfig@dimen % %\newwrite\@unused %\def\typeout#1{{\let\protect\string\immediate\write\@unused{#1}}} % Identifying message is here. % \typeout{psfig/tex 1.4.gcg / TeXPS}\fi % % @psdo control structure -- similar to Latex @for. % I redefined these with different names so that psfig can % be used with TeX as well as LaTeX, and so that it will not % be vunerable to future changes in LaTeX's internal % control structure. \def\@nnil{\@nil} \def\@empty{} \def\@psdonoop#1\@@#2#3{} \def\@psdo#1:=#2\do#3{\edef\@psdotmp{#2}\ifx\@psdotmp\@empty \else \expandafter\@psdoloop#2,\@nil,\@nil\@@#1{#3}\fi} \def\@psdoloop#1,#2,#3\@@#4#5{\def#4{#1}\ifx #4\@nnil \else #5\def#4{#2}\ifx #4\@nnil \else#5\@ipsdoloop #3\@@#4{#5}\fi\fi} \def\@ipsdoloop#1,#2\@@#3#4{\def#3{#1}\ifx #3\@nnil \let\@nextwhile=\@psdonoop \else #4\relax\let\@nextwhile=\@ipsdoloop\fi\@nextwhile#2\@@#3{#4}} \def\@tpsdo#1:=#2\do#3{\xdef\@psdotmp{#2}\ifx\@psdotmp\@empty \else \@tpsdoloop#2\@nil\@nil\@@#1{#3}\fi} \def\@tpsdoloop#1#2\@@#3#4{\def#3{#1}\ifx #3\@nnil \let\@nextwhile=\@psdonoop \else #4\relax\let\@nextwhile=\@tpsdoloop\fi\@nextwhile#2\@@#3{#4}} % \def\psdraft{% \def\@psdraft{0} %\typeout{draft level now is \@psdraft \space.} } \def\psfull{% \def\@psdraft{100} %\typeout{draft level now is \@psdraft \space.} } \psfull \newif\if@prologfile \newif\if@postlogfile \newif\if@noisy \def\pssilent{% \@noisyfalse } \def\psnoisy{% \@noisytrue } %\psnoisy \pssilent % These are for the option list: % a specification of the form a = b maps to calling \@p@@sa{b}. \newif\if@bbllx \newif\if@bblly \newif\if@bburx \newif\if@bbury \newif\if@height \newif\if@width \newif\if@rheight \newif\if@rwidth \newif\if@clip \newif\if@proportional \newif\if@scale \newif\if@verbose \def\@p@@sclip#1{\@cliptrue} \def\@p@@sproportional#1{\@proportionaltrue} \def\@p@@sfile#1{% %\typeout{file is #1} \def\@filestem{#1}% \def\@p@dffile{#1.pdf}% \def\@labfile{#1.lab}% } \let\@p@@sfigure\@p@@sfile % \@pDimenToSpNumber % ================== % Convert a dimension into scaled points. % #1: the name of macro which will expand to the dimension in % scaled points, without the unit 'sp' though, i.e. as a pure % integer. % #2: the dimension (not a dimension register, use % \the if dimension is stored in a dimension register). \def\@pDimenToSpNumber #1#2{% \psfig@dimen = #2\relax \edef#1{\number\psfig@dimen}% } \def\@p@@sbbllx#1{% %\typeout{bbllx is #1} \@bbllxtrue \@pDimenToSpNumber{\@p@sbbllx}{#1}% } \def\@p@@sbblly#1{% %\typeout{bblly is #1} \@bbllytrue \@pDimenToSpNumber{\@p@sbblly}{#1}% } \def\@p@@sbburx#1{% %\typeout{bburx is #1} \@bburxtrue \@pDimenToSpNumber{\@p@sbburx}{#1}% } \def\@p@@sbbury#1{% %\typeout{bbury is #1} \@bburytrue \@pDimenToSpNumber{\@p@sbbury}{#1}% } \def\@p@@sheight#1{% \@heighttrue \@pDimenToSpNumber{\@p@sheight}{#1}% %\typeout{Height is \@p@sheight} } \def\@p@@swidth#1{% %\typeout{Width is #1} \@widthtrue \@pDimenToSpNumber{\@p@swidth}{#1}% } \def\@p@@srheight#1{% %\typeout{Reserved height is #1} \@rheighttrue \@pDimenToSpNumber{\@p@srheight}{#1}% } \def\@p@@srwidth#1{% %\typeout{Reserved width is #1} \@rwidthtrue \@pDimenToSpNumber{\@p@srwidth}{#1}% } \def\@p@@ssilent#1{% \@verbosefalse } \def\@p@@sscale #1{% \def\@p@scale{#1}% \@scaletrue } \def\@p@@sprolog#1{\@prologfiletrue\def\@prologfileval{#1}} \def\@p@@spostlog#1{\@postlogfiletrue\def\@postlogfileval{#1}} \def\@cs@name#1{\csname #1\endcsname} \def\@setparms#1=#2,{\def\@tempa{#2}\ifx\@tempa\@empty \@warning{bad syntax (missing = or extra comma) in argument of \string\psfig}% \else\@@setparms#1=#2,\fi} \def\@@setparms#1=#2=,{\@cs@name{@p@@s#1}{#2}} % % Initialize the defaults. % \def\ps@init@parms{% \@bbllxfalse \@bbllyfalse \@bburxfalse \@bburyfalse \@heightfalse \@widthfalse \@rheightfalse \@rwidthfalse \@scalefalse \def\@p@sbbllx{}\def\@p@sbblly{}% \def\@p@sbburx{}\def\@p@sbbury{}% \def\@p@sheight{}\def\@p@swidth{}% \def\@p@srheight{}\def\@p@srwidth{}% \def\@p@sfile{}% \def\@labfile{}% \def\@p@scost{10}% \def\@sc{}% \@prologfiletrue \@postlogfilefalse \@clipfalse \@proportionalfalse \if@noisy \@verbosetrue \else \@verbosefalse \fi } %%%% space bug fixes \expandafter\let\csname @p@@s scale \endcsname\@p@@sscale \expandafter\let\csname @p@@sscale \endcsname\@p@@sscale \expandafter\let\csname @p@@s scale\endcsname\@p@@sscale \expandafter\let\csname @p@@s file \endcsname\@p@@sfile \expandafter\let\csname @p@@sfile \endcsname\@p@@sfile \expandafter\let\csname @p@@s file\endcsname\@p@@sfile \expandafter\let\csname @p@@s width \endcsname\@p@@swidth \expandafter\let\csname @p@@swidth \endcsname\@p@@swidth \expandafter\let\csname @p@@s width\endcsname\@p@@swidth \expandafter\let\csname @p@@s rwidth \endcsname\@p@@srwidth \expandafter\let\csname @p@@srwidth \endcsname\@p@@srwidth \expandafter\let\csname @p@@s rwidth\endcsname\@p@@srwidth \expandafter\let\csname @p@@s height \endcsname\@p@@sheight \expandafter\let\csname @p@@sheight \endcsname\@p@@sheight \expandafter\let\csname @p@@s height\endcsname\@p@@sheight \expandafter\let\csname @p@@s rheight \endcsname\@p@@srheight \expandafter\let\csname @p@@srheight \endcsname\@p@@srheight \expandafter\let\csname @p@@s rheight\endcsname\@p@@srheight \expandafter\let\csname @p@@s bbllx \endcsname\@p@@sbbllx \expandafter\let\csname @p@@sbbllx \endcsname\@p@@sbbllx \expandafter\let\csname @p@@s bbllx\endcsname\@p@@sbbllx \expandafter\let\csname @p@@s bblly \endcsname\@p@@sbblly \expandafter\let\csname @p@@sbblly \endcsname\@p@@sbblly \expandafter\let\csname @p@@s bblly\endcsname\@p@@sbblly \expandafter\let\csname @p@@s bburx \endcsname\@p@@sbburx \expandafter\let\csname @p@@sbburx \endcsname\@p@@sbburx \expandafter\let\csname @p@@s bburx\endcsname\@p@@sbburx \expandafter\let\csname @p@@s clip \endcsname\@p@@sclip \expandafter\let\csname @p@@sclip \endcsname\@p@@sclip \expandafter\let\csname @p@@s clip\endcsname\@p@@sclip \expandafter\let\csname @p@@s proportional \endcsname\@p@@sproportional \expandafter\let\csname @p@@sproportional \endcsname\@p@@sproportional \expandafter\let\csname @p@@s proportional\endcsname\@p@@sproportional % % Go through the options setting things up. % \def\parse@ps@parms#1{% \@psdo\@psfiga:=#1\do {\expandafter\@setparms\@psfiga=,}% } \newif\ifno@file \newif\ifno@psfile \newif\ifno@bb \newif\ifnot@eof \newif\if@bbmatch \newread\ps@stream \newread\lab@stream \newcount\@linecount \newcount\maxheaderlines \maxheaderlines=100 % % Scan header of file, looking for ``BoundingBox'' line % \def\scan@header{% \openin\lab@stream=\@labfile \openin\ps@stream=\@filestem.ps \ifeof\ps@stream \relax\closein\ps@stream \openin\ps@stream=\@filestem.eps \ifeof\ps@stream \relax\closein\ps@stream\no@psfiletrue \openin\ps@stream=\@filestem.pdf \ifeof\ps@stream \relax %needed here so the \@warning won't cause trouble \@warning{cannot open \@filestem.ps or .eps or .pdf} \closein\ps@stream \no@filetrue \else \edef\@p@sfile{\@filestem.pdf} \relax\closein\ps@stream \ifno@bb % % Next five lines of code supplied by Mark Petelier % % Read BB from pdf file: % \pdfximage cropbox {\@filestem.pdf} \@p@@sbbllx{\pdfximagebbox\pdflastximage 1} \@p@@sbblly{\pdfximagebbox\pdflastximage 2} \@p@@sbburx{\pdfximagebbox\pdflastximage 3} \@p@@sbbury{\pdfximagebbox\pdflastximage 4} \no@bbfalse \if@bbllx \else \no@bbtrue \fi \if@bblly \else \no@bbtrue \fi \if@bburx \else \no@bbtrue \fi \if@bbury \else \no@bbtrue \fi \fi\fi \else \relax \edef\@p@sfile{\@filestem.eps} \fi \else \relax \edef\@p@sfile{\@filestem.ps} \fi \ifno@psfile\else \not@eoftrue \ifno@bb \@bbmatchfalse \else \@bbmatchtrue \fi \catcode`\%=12 \catcode`\:=12 % in case punctuation is active (e.g., under french.sty) \@linecount=\maxheaderlines \loop \read\ps@stream to \line@in \global\psfigtoks@=\expandafter{\line@in} \ifeof\ps@stream \not@eoffalse \fi %\typeout{ looking at :: \the\psfigtoks@ } \if@bbmatch \else \@bbtest{\psfigtoks@} \fi \if@bbmatch \not@eoffalse \fi \advance\@linecount-1 \ifnum\@linecount=0 \not@eoffalse \fi \ifnot@eof \repeat \fi \catcode`\%=14 } % '% ' becomes a regular character for a very short time. { \catcode`\%=12 \catcode`\:=12 \gdef\@bbtest#1{\expandafter\@bb@\the#1%%BoundingBox:\@bbtest\@bb@} \global\long\def\@bb@#1%%BoundingBox:#2#3\@bb@{\ifx\@bbtest#2 \else\@bbmatchtrue\expandafter\bb@cull\the\psfigtoks@\fi} } \def\bb@cull#1:{\expandafter\bb@@cull\@iden} \long\def\bb@@cull#1 #2 #3 #4 {% \@pDimenToSpNumber{\@p@sbbllx}{#1bp}% \@pDimenToSpNumber{\@p@sbblly}{#2bp}% \@pDimenToSpNumber{\@p@sbburx}{#3bp}% \@pDimenToSpNumber{\@p@sbbury}{#4bp}% \no@bbfalse } % Compute \@bbw and \@bbh, the width and height of the % bounding box. \def\compute@bb{% \no@bbfalse \if@bbllx \else \no@bbtrue \fi \if@bblly \else \no@bbtrue \fi \if@bburx \else \no@bbtrue \fi \if@bbury \else \no@bbtrue \fi \scan@header \ifno@file \else \ifno@bb \@warning{no bounding box found in \@p@sfile} \no@filetrue \else % Now compute the size of the bounding box. \psfc@c=\@p@sbburx \psfc@b=\@p@sbbury \advance\psfc@c by -\@p@sbbllx \advance\psfc@b by -\@p@sbblly \edef\@bbw{\number\psfc@c} \edef\@bbh{\number\psfc@b} %\typeout{\string\compute@bb: bbh = \@bbh, bbw = \@bbw} \fi \fi } % % \in@hundreds performs #1 * (#2 / #3) correct to the hundreds, % then leaves the result in \@result. % % note: #3 should be a big number, or a multiple of 10. % \def\in@hundreds #1#2#3{% \psfc@g=#2 \psfc@d=#3 \divide\psfc@d 10 \psfc@a=\psfc@g % First two digits #2/#3. \divide\psfc@a by \psfc@d \psfc@f=\psfc@a \multiply\psfc@f by \psfc@d \advance\psfc@g by -\psfc@f \multiply\psfc@g by 10 \psfc@f=\psfc@g % Third digit of #2/#3. \divide\psfc@f by \psfc@d \psfc@j=\psfc@f \multiply\psfc@j by \psfc@d \advance\psfc@g by -\psfc@j \multiply\psfc@g by 10 \psfc@j=\psfc@g % Third digit. \divide\psfc@j by \psfc@d \psfc@h=#1\psfc@i=0 \psfc@e=\psfc@h \multiply\psfc@e by \psfc@a \advance\psfc@i by \psfc@e \psfc@e=\psfc@h \divide\psfc@e by 10 \multiply\psfc@e by \psfc@f \advance\psfc@i by \psfc@e % \psfc@e=\psfc@h \divide\psfc@e by 100 \multiply\psfc@e by \psfc@j \advance\psfc@i by \psfc@e \divide\psfc@i 10 % \edef\@result{\number\psfc@i} } % Scale a value #1 by the current scaling factor and reassign the new % scaled value. \def\@ScaleInHundreds #1{% \in@hundreds{#1}{\@p@scale}{100}% \edef#1{\@result}% } % % % Compute width from height. \def\compute@wfromh{% % computing : width = height * (bbw / bbh) \in@hundreds{\@p@sheight}{\@bbw}{\@bbh}% %\typeout{ \@p@sheight * \@bbw / \@bbh, = \@result } \edef\@p@swidth{\@result}% %\typeout{w from h: width is \@p@swidth}% } % % Compute height from width. % \def\compute@hfromw{% % computing : height = width * (bbh / bbw) \in@hundreds{\@p@swidth}{\@bbh}{\@bbw}% %\typeout{ \@p@swidth * \@bbh / \@bbw = \@result } \edef\@p@sheight{\@result}% %\typeout{h from w : height is \@p@sheight}% } % % Compute height and width when both are given and proportionality % must be preserved. % \def\compute@minhw{% \in@hundreds{\@p@swidth}{\@bbh}{\@bbw}% \ifnum\@p@sheight<\@result \in@hundreds{\@p@sheight}{\@bbw}{\@bbh}% \edef\@p@swidth{\@result}% \else \edef\@p@sheight{\@result}% \fi } % % Compute height and width, i.e. \@p@sheight and \@p@swidth. % \def\compute@handw{% % If height is given. \if@height % If width is given \if@width \if@proportional \compute@minhw \fi \else % Height, no width: compute width. \compute@wfromh \fi \else % No height. \if@width % Width is given, no height though: compute it. \compute@hfromw \else % Neither width no height is give. \edef\@p@sheight{\@bbh} \edef\@p@swidth{\@bbw} \fi \fi } % Compute the amount of space to reserve. Unless defined % using rheight and rwidth when \psfig is called, these values % default to \@p@sheight and \@p@swidth. \def\compute@resv{% \if@rheight \else \edef\@p@srheight{\@p@sheight} \fi \if@rwidth \else \edef\@p@srwidth{\@p@swidth} \fi } % % % \psfig % ====== % usage: \psfig{file=, height=, width=, bbllx=, bblly=, bburx=, bbury=, % rheight=, rwidth=, clip=, scale=, proportional=} % % "clip=" and "proportional=" are switches and take no value, % but the `=' must be present. % \def\partest{\par} \def\psfig#1{% \vbox {% \offinterlineskip \ps@init@parms \parse@ps@parms{#1}% % Compute any missing sizes. \compute@bb \ifno@file\vbox{\hbox{\footnotesize{\tt\@filestem.\{ps,eps,pdf\}} not found (or no BBox)}}% \else \compute@handw \compute@resv \if@scale \ifx\inc@graph@flag\relax\else %% \graphicx syntax used so \psfig@dimen=100sp %% multiply scale by 100 \psfig@dimen=\@p@scale\psfig@dimen \def\@p@scale{\number\psfig@dimen} \let\inc@graph@flag\relax %% reset \fi %\if@verbose \typeout{psfig: scaling by \@p@scale}\fi %\if@verbose \typeout{psfig: scaling by \@p@scale}\fi % We now scale the width and height as reported to the PS printer. \@ScaleInHundreds{\@p@swidth}% \@ScaleInHundreds{\@p@sheight}% \@ScaleInHundreds{\@p@srwidth}% \@ScaleInHundreds{\@p@srheight}% \fi % \ifnum\@p@scost<\@psdraft %\if@verbose \typeout{psfig: including \@p@sfile \space}\fi \if@topspecials\do@specials\fi % Create a vbox to reserve the proper amount of space for the figure. \vbox to \@p@srheight sp{% \hbox to \@p@srwidth sp{}% \vss }% \if@topspecials\else\do@specials\fi \ifx\thelabellist\relax %%% no labellist so look for .lab file \ifeof\lab@stream \else{% \hyperactivelabels \not@eoftrue \loop \read\lab@stream to \line@in \ifx\line@in\partest\else\line@in\fi \ifeof\lab@stream \not@eoffalse \fi \ifnot@eof \repeat }\fi \else \hyperactivelabels\thelabellist %%% use labellist and \global\let\thelabellist\relax %%% reset for next figure \ifeof\lab@stream \else{ \@message{} \@message{I have found both a labellist AND a .lab file for \@p@sfile.} \@message{I am using the labellist.} \@message{If this is not what you want, then edit out the labellist.} \@message{} }\fi \fi \else % Draft mode: reserve the space for the figure and print the path name. \vbox to \@p@srheight sp{% \hbox to \@p@srwidth sp{% \if@verbose \@p@sfile \fi }% \vss }% \fi \fi }% } \def\do@specials{\ps@init\ps@begin \if@clip %\if@verbose \typeout{(clip)} \fi \ps@clip \fi \if@prologfile \ps@prolog \fi \ps@include \if@postlogfile \ps@postlog \fi \ps@end} \newbox\label@box \newdimen\x@lab \newdimen\y@lab \newdimen\x@aux \newdimen\y@aux \newdimen\hair\hair=3pt %%%%% version without math mode, with \mathsurround set to 0pt %%%%% and final manual adjustment <#6,#7> \def\@setlabel@#1#2#3#4#5#6#7{% \setbox\label@box\hbox{\mathsurround 0pt\ignorespaces#1}% \x@lab.5\wd\label@box \x@lab#4\x@lab \y@lab.5\ht\label@box\advance\y@lab.5\dp\label@box \y@lab#5\y@lab % rotate lab clockwise by 22.5 degrees to get aux \x@aux.92388\x@lab \advance\x@aux.38268\y@lab \y@aux-.38268\x@lab \advance\y@aux.92388\y@lab % choose \ifdim\x@aux>0pt \ifdim\y@aux>0pt \ifdim\x@aux>\y@aux\advance\x@lab.7071\hair\advance\y@lab.7071\hair \else\advance\y@lab\hair\fi \else \ifdim\x@aux>-\y@aux\advance\x@lab\hair \else\advance\x@lab.7071\hair\advance\y@lab-.7071\hair\fi \fi \else \ifdim\y@aux>0pt \ifdim\x@aux>-\y@aux\advance\x@lab-.7071\hair\advance\y@lab.7071\hair \else\advance\x@lab-\hair\fi \else \ifdim\x@aux>\y@aux\advance\y@lab-\hair \else \ifdim\x@aux<0pt \advance\x@lab-.7071\hair\advance\y@lab-.7071\hair\fi \fi \fi \fi \advance\x@lab.5\wd\label@box \advance\y@lab.5\ht\label@box\advance\y@lab.5\dp\label@box \x@aux=#2bp \ifoldlabels \else \advance\x@aux by -\@p@sbbllx sp \fi \y@aux=#3bp \ifoldlabels \else \advance\y@aux by -\@p@sbblly sp \fi \in@hundreds{\x@aux}{\@p@swidth}{\@bbw} \edef\@xpos{\@result} \in@hundreds{\y@aux}{\@p@sheight}{\@bbh} \edef\@ypos{\@result} \vbox to 0pt{% \vss\hbox to\@p@srwidth sp{\hskip \@xpos sp \hskip-\x@lab \hskip #6 \box\label@box\hss}\vskip \@ypos sp \vskip-\y@lab \vskip #7}} %%%% old syntax: \setlabel and variant \setlabel* (\hair set 0pt) %%%% both start in math mode for back-compatibility: \def\setlabel{\@ifnextchar*{\setlabel@nohair}{\setlabel@hair}} %%%% manual adjustment added? \def\setlabel@nohair*% {\@ifnextchar<{\setlabel@nohair@adj}{\setlabel@nohair@noadj}} \def\setlabel@hair% {\@ifnextchar<{\setlabel@hair@adj}{\setlabel@hair@noadj}} \def\setlabel@nohair@noadj#1#2#3#4#5% {{\hair 0pt\@setlabel@{$#1$}{#2}{#3}{#4}{#5}{0pt}{0pt}}} \def\setlabel@nohair@adj<#1,#2>#3#4#5#6#7% {{\hair 0pt\@setlabel@{$#3$}{#4}{#5}{#6}{#7}{#1}{#2}}} \def\setlabel@hair@noadj#1#2#3#4#5% {\@setlabel@{$#1$}{#2}{#3}{#4}{#5}{0pt}{0pt}} \def\setlabel@hair@adj<#1,#2>#3#4#5#6#7% {\@setlabel@{$#3$}{#4}{#5}{#6}{#7}{#1}{#2}} %%% \pinlabel macro starts here %%% set up two flags for killing autospacing and using baseline %%% and initialise: %%% \relax is default ie \hair used but baseline not used %%% any other value means \hair not used but baseline used \let\hair@flag\relax\let\baseline@flag\relax %%% define four control sequences to carry the auxiliary information %%% and set to default values \def\@labxpos@{0}\def\@labypos@{0}% \def\@xadj@{0pt}\def\@yadj@{0pt} %%%% endgame \def\finally@pinlabel #1 {\@ifnextchar a% {\finally@pinlabel@ {#1} }{\@message{}% \@message{There is something wrong with your syntax for label #1;} \@message{you must finish with " at XXX YYY " : the "at" and spaces are important!} \@message{I'm going to try to ignore this label: don't blame me if there are some} \@message{funny numbers in your diagram and later labels are out-of-position.} \@message{}}} \def\finally@pinlabel@ #1 at #2 #3 {% \ifx\hair@flag\relax% \@setlabel@{\ifx\baseline@flag\relax\the@label\else\smash{\the@label}\fi}% {#2}{#3}{\@labxpos@}{\@labypos@}{\@xadj@}{\@yadj@}% \else {\hair 0pt \@setlabel@{\ifx\baseline@flag\relax\the@label\else\smash{\the@label}\fi}% {#2}{#3}{\@labxpos@}{\@labypos@}{\@xadj@}{\@yadj@}} \fi %%%% don't forget to reset the flags etc to default values \let\hair@flag\relax\let\baseline@flag\relax% \def\@labxpos@{0}\def\@labypos@{0}% \def\@xadj@{0pt}\def\@yadj@{0pt}} %%%% start to parse the argument %%%% is this a starred form or not? \def\pinlabel{\@ifnextchar*% {\pin@nohair}{\@pinlabel@}} \def\pin@nohair* #1 {\def\hair@flag{0}\@pinlabel@ {#1} } %%%% store the label for safety then %%%% is there any label position information? \def\@pinlabel@ #1 {\def\the@label{#1}\@ifnextchar a% {\finally@pinlabel {#1} }{\@pinlabel@@ {#1} }} %%%% are we using "by" or [ or going directly to <..,..> \def\@pinlabel@@ #1 {\@ifnextchar [% {\pin@by@letters {#1} }{\@@pinlabel@@ {#1} }} \def\@@pinlabel@@ #1 {\@ifnextchar b {\pin@by@numbers {#1} }{\@@pinlabel@@@ {#1} }} \def\@@pinlabel@@@ #1 {\@ifnextchar <% {\pin@with@adj {#1} }{\@message{}% \@message{I don't understand your positioning information for label #1 and shall} \@message{ignore it; or perhaps your label has a space and needs braces.} \finally@pinlabel {#1} }} %%%% pin@with@adj recycles from the top (to allow to come first) \def\pin@with@adj #1 <#2,#3> {% \def\@xadj@{#2}\def\@yadj@{#3} \@pinlabel@ {#1} } %%%% we are using letters, is there adjustment? \def\pin@by@letters #1 [#2] {\@ifnextchar <% {\pin@by@letters@with@adj {#1} [#2] }{\pin@by@letters@no@adj {#1} [#2] }} %%%% we are using numbers, is there adjustment? \def\pin@by@numbers #1 by #2 #3 {\@ifnextchar <% {\pin@by@numbers@with@adj {#1} by #2 #3 }{\pin@by@numbers@no@adj {#1} by #2 #3 }} \def\pin@by@numbers@with@adj #1 by #2 #3 <#4,#5> at #6 #7{% \def\@labxpos@{#2}\def\@labypos@{#3}% \def\@xadj@{#4}\def\@yadj@{#5} \finally@pinlabel {#1} at #6 #7} \def\pin@by@numbers@no@adj #1 by #2 #3 at #4 #5{% \def\@labxpos@{#2}\def\@labypos@{#3}% \def\@xadj@{0pt}\def\@yadj@{0pt} \finally@pinlabel {#1} at #4 #5} %%% read the letter pin positions to a control sequence \def\pin@by@letters@no@adj #1 [#2] {% \expandafter\ifx\csname position@#2\endcsname\relax \@message{} \@message{Unknown position code [#2]; I shall ignore it.} \@message{}\else \csname position@#2\endcsname\fi \finally@pinlabel {#1} } \def\pin@by@letters@with@adj #1 [#2] <#3,#4> {% \expandafter\ifx\csname position@#2\endcsname\relax \@message{} \@message{Unknown position code [#2]; I shall ignore it.} \@message{}\else \csname position@#2\endcsname\fi \def\@xadj@{#3}\def\@yadj@{#4} \finally@pinlabel {#1} } %%%% final task: parse the letter pin positions \def\position@t{\def\@labxpos@{0}\def\@labypos@{1}} \def\position@b{\def\@labxpos@{0}\def\@labypos@{-1}} \def\position@l{\square@left\def\@labxpos@{-1}\def\@labypos@{0}} \def\position@r{\square@right\def\@labxpos@{1}\def\@labypos@{0}} \def\position@B{\def\baseline@flag{1}\def\@labxpos@{0}\def\@labypos@{0}} \def\position@rt{\square@right\def\@labxpos@{1}\def\@labypos@{1}} \def\position@tr{\square@right\def\@labxpos@{1}\def\@labypos@{1}} \def\position@br{\square@right\def\@labxpos@{1}\def\@labypos@{-1}} \def\position@rb{\square@right\def\@labxpos@{1}\def\@labypos@{-1}} \def\position@lt{\square@left\def\@labxpos@{-1}\def\@labypos@{1}} \def\position@tl{\square@left\def\@labxpos@{-1}\def\@labypos@{1}} \def\position@bl{\square@left\def\@labxpos@{-1}\def\@labypos@{-1}} \def\position@lb{\square@left\def\@labxpos@{-1}\def\@labypos@{-1}} \def\position@lB{\square@left\def\baseline@flag{1}% \def\@labxpos@{-1}\def\@labypos@{0}} \def\position@Bl{\square@left\def\baseline@flag{1}% \def\@labxpos@{-1}\def\@labypos@{0}} \def\position@rB{\square@right\def\baseline@flag{1}% \def\@labxpos@{1}\def\@labypos@{0}} \def\position@Br{\square@right\def\baseline@flag{1}% \def\@labxpos@{1}\def\@labypos@{0}} %%%% \square@left and \square@right are hacks to force diagonal %%%% autospacing for the corner letter pin positions \def\square@left{% \setbox\label@box\hbox{\mathsurround 0pt\ignorespaces\the@label}% \y@lab\ht\label@box\advance\y@lab\dp\label@box\let\old@label\the@label \def\the@label{\hbox to \y@lab{\old@label\hss}}} \def\square@right{% \setbox\label@box\hbox{\mathsurround 0pt\ignorespaces\the@label}% \y@lab\ht\label@box\advance\y@lab\dp\label@box\let\old@label\the@label \def\the@label{\hbox to \y@lab{\hss \old@label}}} %%%% end of \pinlabel macro \catcode`@=\atcatcode \endinput %%%%% History: Version 1.1 released 25 March 2006 %%%%% 28/Mar/06: bugfixes and code to detect mathematica/illustrator deleted %%%%% 5/Apr/06: bugfix and extra utility: can come first %%%%% 20/Apr/06: \includegraphics uses graphicx if no labellist (Naom) %%%%% 1/May/06: bugfix to \includegraphics code %%%%% 23/Oct/06: LPPL license added (for CTAN) %%%%% 4/Nov/11: Version 1.2: Mark Petelier's code added to read BB from pdf file