2 % %%%%%%% %%%%% %%%%%% %%%%% % %
5 % %%%%%%% %%%%% %%%%%% % % %
8 % % %%%%%% %%%%%% %%%%% % %
11 % Comments & suggestions by e-mail: ORLOFF@surya11.cern.ch
12 % No modification of this file allowed if not e-sent to me.
14 % A simple way to measure the size of encapsulated postscript figures
15 % from inside TeX, and to use it for automatically formatting texts
16 % with inserted figures. Works both under Plain TeX-based macros
17 % (Phyzzx, Harvmac, Psizzl, ...) and LaTeX environment.
18 % Provides exactly the same result on any PostScript printer provided
19 % the single instruction \psfor... is changed to fit the needs of the
20 % particular dvi->ps translator used.
22 % 1.31: adds \psforDVIALW(?)
23 % 1.30: adds \splitfile & \joinfiles for multi-file management
24 % 1.24: fix error handling & add \psonlyboxes
25 % 1.23: adds \putsp@ce for OzTeX fix
26 % 1.22: makes \drawingBox \global for use in Phyzzx
27 % 1.21: accepts %%BoundingBox: (atend)
28 % 1.20: tries to add \psfordvitps for the TeXPS package.
29 % 1.10: adds \psforoztex, error handling...
30 %2345678 1 2345678 2 2345678 3 2345678 4 2345678 5 2345678 6 2345678 7 23456789
34 \expandafter\ifx\csname psboxversion
\endcsname\relax
35 \message{version:
\temp}
37 \ifdim\temp cm>
\psboxversion cm
38 \message{version:
\temp}
40 \message{psbox(
\psboxversion) is already loaded: I won't load
42 \let\temp=
\psboxversion
47 \let\psboxversion=
\temp
49 % Every macro likes a little privacy...
53 \def\execute#1{#1}% NOT stupid: cs in #1 are then identified BEFORE execution
54 \def\psm@keother
#1{\catcode`
#112\relax}% borrowed from latex
55 \def\executeinspecs#1{%
56 \execute{\begingroup\let\do\psm@keother
\dospecials\catcode`\^^M=
9#1\endgroup}}
58 %Trying to tame the variety of \special commands for Postscript: the
59 % universal internal command \PSspeci@l##1##2 takes ##1 to be the
60 % filename and ##2 to be the integer scale factor*1000 (as for usual
61 % TeX \scale commands)
63 \def\psfortextures{% For TeXtures on the Macintosh
65 \def\PSspeci@l#
#1#
#2{%
66 \special{illustration #
#1\space scaled #
#2}%
69 \def\psfordvitops{% For the DVItoPS converter on IBM mainframes
71 \def\PSspeci@l#
#1#
#2{%
72 \special{dvitops: import #
#1\space \the\drawingwd \the\drawinght}%
75 \def\psfordvips{% For DVIPS converter on VAX, UNIX and PC's
77 \def\PSspeci@l#
#1#
#2{%
78 % \special{/@scaleunit 1000 def}% never read dox without trying!
79 \d@my=
0.1bp
\d@mx=
\drawingwd \divide\d@mx by
\d@my
%
80 \special{PSfile=#
#1\space llx=
\psllx\space lly=
\pslly\space%
81 urx=
\psurx\space ury=
\psury\space rwi=
\number\d@mx
}%
84 \def\psforoztex{% For the OzTeX shareware on the Macintosh
86 \def\PSspeci@l#
#1#
#2{%
88 #
#2 1000 div dup scale
89 \putsp@ce
{\number-
\psllx} \putsp@ce
{\number-
\pslly} translate
94 \def\psfordvitps{% From the UNIX TeXPS package, vers.>3.12
96 % Convert a dimension into the number \psn@sp (in scaled points)
97 \def\psdimt@n@sp#
#1{\d@mx=#
#1\relax\edef\psn@sp
{\number\d@mx
}}
98 \def\PSspeci@l#
#1#
#2{%
99 % psfig.psr contains the def of "startTexFig": if you can locate it
100 % and include the correct pathname, it should work
101 \special{dvitps: Include0 "psfig.psr"
}% contains def of "startTexFig"
102 \psdimt@n@sp
{\drawingwd}
103 \special{dvitps: Literal "
\psn@sp
\space"
}
104 \psdimt@n@sp
{\drawinght}
105 \special{dvitps: Literal "
\psn@sp
\space"
}
106 \psdimt@n@sp
{\psllx bp
}
107 \special{dvitps: Literal "
\psn@sp
\space"
}
108 \psdimt@n@sp
{\pslly bp
}
109 \special{dvitps: Literal "
\psn@sp
\space"
}
110 \psdimt@n@sp
{\psurx bp
}
111 \special{dvitps: Literal "
\psn@sp
\space"
}
112 \psdimt@n@sp
{\psury bp
}
113 \special{dvitps: Literal "
\psn@sp
\space startTexFig
\space"
}
114 \special{dvitps: Include1 "#
#1"
}
115 \special{dvitps: Literal "endTexFig
\space"
}
117 \def\psforDVIALW{% Try for dvialw, a UNIX public domain
119 \def\PSspeci@l#
#1#
#2{
120 \special{language "PS"
121 literal "#
#2 1000 div dup scale"
123 \def\psonlyboxes{% Draft-like behaviour if none of the others works
125 \def\PSspeci@l#
#1#
#2{%
126 \at(
0cm;
0cm)
{\boxit{\vbox to
\drawinght
128 \hbox to
\drawingwd{\at(
0cm;
0cm)
{\hbox{(#
#1)
}}\hss}
134 \let\savedPSspeci@l=
\PSspeci@l
%
135 \def\PSspeci@l#
#1#
#2{%
136 \at(
0cm;
0cm)
{\boxit{\vbox to
\drawinght
138 \hbox to
\drawingwd{\at(
0cm;
0cm)
{\hbox{(#
#1)
#1}}\hss}
140 \let\PSspeci@l=
\savedPSspeci@l
% restore normal output for other figs!
144 %\def\psfor... add your own!
146 % \ReadPSize{PSfilename} reads the dimensions of a PostScript drawing
147 % and stores it in \drawinght(wd)
149 \newdimen\drawinght\newdimen\drawingwd
150 \newdimen\psxoffset\newdimen\psyoffset
152 \newif\ifNotB@undingBox
153 \newhelp\PShelp{Proceed: you'll have a
5cm square blank box instead of
154 your graphics (Jean Orloff).
}
156 \def\s@tsize
#1 #2 #3 #4\@ndsize
{
157 \def\psllx{#1}\def\pslly{#2}%
158 \def\psurx{#3}\def\psury{#4}% needed by a crazyness of dvips!
159 \ifx\psurx\@mpty
\NotB@undingBoxtrue
% this is not a valid one!
161 \drawinght=
#4bp
\advance\drawinght by-
#2bp
162 \drawingwd=
#3bp
\advance\drawingwd by-
#1bp
163 % !Units related by crazy factors as bp/pt=72.27/72 should be BANNED!
166 \def\sc@nline
#1:
#2\@ndline
{\edef\p@rameter
{#1}\edef\v@lue
{#2}}
167 \def\g@bblefirstblank
#1#2:
{\ifx#1 \else#1\fi#2}
168 \def\psm@keother
#1{\catcode`
#112\relax}% borrowed from latex
169 \def\execute#1{#1}% Seems stupid, but cs are identified BEFORE execution
171 \xdef\B@undingBox
{%%BoundingBox}
172 } %% is not a true comment in PostScript, even if % is!
175 \openin\pst@mpin=
#1\relax
176 \ifeof\pst@mpin
\errhelp=
\PShelp
177 \errmessage{I haven't found your postscript file (
\PSfilename)
}
178 \psloc@lerr
{was not found
}
179 \s@tsize
0 0 142 142\@ndsize
182 \immediate\write\psbj@inaux
{#1,
}
184 \executeinspecs{\catcode`\ =
10\global\read\pst@mpin to
\n@xtline
}
187 \errmessage{(
\PSfilename) is not an Encapsulated PostScript File:
188 I could not find any
\B@undingBox: line.
}
189 \edef\v@lue
{0 0 142 142:
}
190 \psloc@lerr
{is not an EPSFile
}
193 \expandafter\sc@nline
\n@xtline:\@ndline
194 \ifx\p@rameter
\B@undingBox
\NotB@undingBoxfalse
196 \expandafter\g@bblefirstblank
\v@lue
\space\space\space}
197 \expandafter\s@tsize
\t@mp\@ndsize
198 \else\NotB@undingBoxtrue
201 \ifNotB@undingBox
\repeat
207 % \psboxto(xdim;ydim){psfilename}: you specify the dimensions and
208 % TeX uniformly scales to fit the largest one. If xdim=0pt, the
209 % scale is fully determined by ydim and vice versa.
210 % Notice: psboxes are a real vboxes; couldn't take hbox otherwise all
211 % indentation and all cr's would be interpreted as spaces (hugh!).
213 \newcount\xscale \newcount\yscale \newdimen\pscm\pscm=
1cm
214 \newdimen\d@mx
\newdimen\d@my
215 \let\ps@nnotation=
\relax
216 \def\psboxto(
#1;
#2)
#3{\vbox{
218 \divide\drawingwd by
1000
219 \divide\drawinght by
1000
221 \ifdim\d@mx=
0pt
\xscale=
1000
222 \else \xscale=
\d@mx
\divide \xscale by
\drawingwd\fi
224 \ifdim\d@my=
0pt
\yscale=
1000
225 \else \yscale=
\d@my
\divide \yscale by
\drawinght\fi
227 \else\ifnum\xscale=
1000\xscale=
\yscale
228 \else\ifnum\yscale<
\xscale\xscale=
\yscale\fi
231 \divide \psxoffset by
1000\multiply\psxoffset by
\xscale
232 \divide \psyoffset by
1000\multiply\psyoffset by
\xscale
233 \global\divide\pscm by
1000
234 \global\multiply\pscm by
\xscale
235 \multiply\drawingwd by
\xscale \multiply\drawinght by
\xscale
236 \ifdim\d@mx=
0pt
\d@mx=
\drawingwd\fi
237 \ifdim\d@my=
0pt
\d@my=
\drawinght\fi
238 \message{scaled
\the\xscale}
239 \hbox to
\d@mx
{\hss\vbox to
\d@my
{\vss
240 \global\setbox\drawingBox=
\hbox to
0pt
{\kern\psxoffset\vbox to
0pt
{
242 \PSspeci@l
{\PSfilename}{\the\xscale}
243 \vss}\hss\ps@nnotation
}
244 \global\ht\drawingBox=
\the\drawinght
245 \global\wd\drawingBox=
\the\drawingwd
249 \global\psxoffset=
0pt
250 \global\psyoffset=
0pt
% These are local to one figure
252 \global\drawingwd=
\drawingwd
253 \global\drawinght=
\drawinght
256 % \psboxscaled{scalefactor*1000}{PSfilename} allows to bypass the
257 % rounding errors of TeX integer divisions for situations where the
258 % TeX box should fit the original BoundingBox with a precision better
261 \def\psboxscaled#1#2{\vbox{
264 \message{scaled
\the\xscale}
265 \divide\drawingwd by
1000\multiply\drawingwd by
\xscale
266 \divide\drawinght by
1000\multiply\drawinght by
\xscale
267 \divide \psxoffset by
1000\multiply\psxoffset by
\xscale
268 \divide \psyoffset by
1000\multiply\psyoffset by
\xscale
269 \global\divide\pscm by
1000
270 \global\multiply\pscm by
\xscale
271 \global\setbox\drawingBox=
\hbox to
0pt
{\kern\psxoffset\vbox to
0pt
{
273 \PSspeci@l
{\PSfilename}{\the\xscale}
274 \vss}\hss\ps@nnotation
}
275 \global\ht\drawingBox=
\the\drawinght
276 \global\wd\drawingBox=
\the\drawingwd
279 \global\psxoffset=
0pt
280 \global\psyoffset=
0pt
% These are local to one figure
282 \global\drawingwd=
\drawingwd
283 \global\drawinght=
\drawinght
286 % \psbox{PSfilename} makes a TeX box having the minimal size to
287 % enclose the picture
288 \def\psbox#1{\psboxscaled{1000}{#1}}
291 % \joinfiles file1, file2, ...n \into joinedfilename .
292 % makes one file out of many
293 % \splitfile joinedfilename
296 %\def\execute#1{#1}% NOT stupid: cs in #1 are then identified BEFORE execution
297 %\def\psm@keother#1{\catcode`#112\relax}% borrowed from latex
298 %\def\executeinspecs#1{%
299 %\execute{\begingroup\let\do\psm@keother\dospecials\catcode`\^^M=9#1\endgroup}}
301 \newif\ifn@teof
\n@teoftrue
305 \newwrite\j@insplitout
307 \immediate\openout\psbj@inaux=psbjoin.aux
308 \immediate\write\psbj@inaux
{\string\joinfiles}
309 \immediate\write\psbj@inaux
{\jobname,
}
311 % We redefine input to keep track of the various files inputted
313 \immediate\let\oldinput=
\input
315 \immediate\write\psbj@inaux
{#1,
}
318 \def\setmatchif#1\contains#2{
319 \def\match#
#1#2#
#2\endmatch{
327 \def\warnopenout#1#2{
328 \setmatchif{TrashMe,psbjoin.aux,psbjoin.all
}\contains{#2}
331 \immediate\openin\pst@mpin=
#2
334 \errhelp{If the content of this file is so precious to you, abort (ie
335 press x or e) and rename it before retrying.
}
336 \errmessage{I'm just about to replace your file named
#2}
338 \immediate\closein\pst@mpin
341 \immediate\openout#1=
#2}
342 % No comments allowed below: % will have an unusual catcode
346 \immediate\openin\j@insplitin=
#1
347 \message{Splitting file
#1 into:
}
348 \warnopenout\j@insplitout
{TrashMe
}
351 \j@insplitin
\immediate\closein\j@insplitin
\n@teoffalse
354 \executeinspecs{\global\read\j@insplitin to
\spl@tinline
\expandafter
355 \ch@ckbeginnewfile
\spl@tinline
%Beginning-Of-File-Named:%\endcheck}
358 \toks0=
\expandafter{\spl@tinline
}
359 \immediate\write\j@insplitout
{\the\toks0}
363 \immediate\closeout\j@insplitout
}
364 \gdef\ch@ckbeginnewfile
#1%Beginning-Of-File-Named:#2%#3\endcheck{
369 \global\c@ntrollinefalse
371 \immediate\closeout\j@insplitout
372 \warnopenout\j@insplitout
{#2}
373 \global\c@ntrollinetrue
376 \global\c@ntrollinefalse
378 \gdef\joinfiles#1\into#2 {
379 \message{Joining following files into
}
380 \warnopenout\j@insplitout
{#2}
383 \edef\w@#
#1{\immediate\write\j@insplitout
{#
#1}}
384 \w@
{% This text was produced with psbox's \string\joinfiles.}
385 \w@
{% To decompose and tex it:}
386 \w@
{%-save this with a filename CONTAINING ONLY LETTERS, and no extensions}
387 \w@
{% (say, JOINTFIL), in some uncrowded directory;}
388 \w@
{%-make sure you can \string\input\space psbox.tex (version>=1.3);}
389 \w@
{%-tex JOINTFIL using Plain, or LaTeX, or whatever is needed by}
390 \w@
{% the first part in the joining (after splitting JOINTFIL into}
391 \w@
{% it's constituents, TeX will try to process it as it stands).}
392 \w@
{\string\input\space psbox.tex
}
393 \w@
{\string\splitfile{\string\jobname}}
395 \tre@tfilelist
#1,
\endtre@t
396 \immediate\closeout\j@insplitout
}
397 \gdef\tre@tfilelist
#1,
#2\endtre@t
{
402 \tre@tfilelist
#2,
\endtre@t
405 \immediate\openin\j@insplitin=
#1
407 \errmessage{I couldn't find file
#1.
}
410 \toks0=
{%Beginning-Of-File-Named:#1}
411 \immediate\write\j@insplitout
{\the\toks0}
412 \executeinspecs{\global\read\j@insplitin to
\oldj@ininline
}
414 \ifeof\j@insplitin
\immediate\closein\j@insplitin
\n@teoffalse
416 \executeinspecs{\global\read\j@insplitin to
\j@ininline
}
417 \toks0=
\expandafter{\oldj@ininline
}
418 \let\oldj@ininline=
\j@ininline
419 \immediate\write\j@insplitout
{\the\toks0}
423 \immediate\closein\j@insplitin
426 % To be put at the end of a file, for making an tar-like file containing
427 % everything it used.
429 \immediate\write\psbj@inaux
{\string\into\space psbjoin.all
}
430 \immediate\closeout\psbj@inaux
434 % Annotations & Captions etc...
437 % \centinsert{anybox} is just a centered \midinsert, but is included as
438 % people barely use the original inserts from TeX.
440 \def\centinsert#1{\midinsert\line{\hss#1\hss}\endinsert}
441 \def\psannotate#1#2{\def\ps@nnotation
{#2\global\let\ps@nnotation=
\relax}#1}
442 \def\pscaption#1#2{\vbox{
443 \setbox\drawingBox=
#1
446 \vbox{\hsize=
\wd\drawingBox\setbox0=
\hbox{#2}
448 \noindent\unhbox0\tolerance=
5000
449 \else\centerline{\box0}
452 % for compatibility with older versions
453 \def\psfig#1#2#3{\pscaption{\psannotate{#1}{#2}}{#3}}
454 \def\psfigurebox#1#2#3{\pscaption{\psannotate{\psbox{#1}}{#2}}{#3}}
456 % \at(#1;#2)#3 puts #3 at #1-higher and #2-right of the current
457 % position without moving it (to be used in annotations).
458 \def\at(
#1;
#2)
#3{\setbox0=
\hbox{#3}\ht0=
0pt
\dp0=
0pt
459 \rlap{\kern#1\vbox to0pt
{\kern-
#2\box0\vss}}}
461 % \gridfill(ht;wd) makes a 1cm*1cm grid of ht by wd whose lower-left
462 % corner is the current point
463 \newdimen\gridht \newdimen\gridwd
464 \def\gridfill(
#1;
#2)
{
465 \setbox0=
\hbox to
1\pscm
466 {\vrule height1
\pscm width
.4pt
\leaders\hrule\hfill}
468 \divide\gridht by
\ht0
469 \multiply\gridht by
\ht0
471 \divide\gridwd by
\wd0
472 \multiply\gridwd by
\wd0
473 \advance \gridwd by
\wd0
474 \vbox to
\gridht{\leaders\hbox to
\gridwd{\leaders\box0\hfill}\vfill}}
476 % Useful to measure where to put annotations
477 \def\fillinggrid{\at(
0cm;
0cm)
{\vbox{
478 \gridfill(
\drawinght;
\drawingwd)
}}}
480 % \textleftof\anybox: Sample text\endtext
481 % inserts "Sample text" on the left of \anybox ie \vbox, \psbox.
482 % \textrightof is the symmetric (not documented, too uggly)
483 % Welcome any suggestion about clean wraparound macros from
484 % TeXhackers reading this
488 \setbox0=
\vbox\bgroup
489 \advance\hsize by -
\wd1 \advance\hsize by -
2em
}
492 \setbox1=
\vbox\bgroup
493 \advance\hsize by -
\wd0 \advance\hsize by -
2em
}
496 \hbox to
\hsize{\valign{\vfil##
\vfil\cr%
498 \noalign{\hss}\box1\cr}}}
500 % \frameit{\thick}{\skip}{\anybox}
501 % draws with thickness \thick a box around \anybox, leaving \skip of
502 % blank around it. eg \frameit{0.5pt}{1pt}{\hbox{hello}}
503 % \boxit{\anybox} is a shortcut.
504 \def\frameit#1#2#3{\hbox{\vrule width
#1\vbox{
505 \hrule height
#1\vskip#2\hbox{\hskip#2\vbox{#3}\hskip#2}%
506 \vskip#2\hrule height
#1}\vrule width
#1}}
507 \def\boxit#1{\frameit{0.4pt
}{0pt
}{#1}}
510 \catcode`\@=
12 % cs containing @ are unreachable
512 % CUSTOMIZE YOUR DEFAULT DRIVER:
513 % Uncomment the line corresponding to your TeX system:
514 %\psfortextures% For TeXtures on the Macintosh
515 %\psforoztex % For OzTeX shareware on the Macintosh
516 %\psfordvitops % For the DVItoPS converter for TeX on IBM mainframes
517 \psfordvips % For DVIPS converter on VAX and UNIX
518 %\psfordvitps % For dvitps from TeXPS package under UNIX
519 %\psforDVIALW % For DVIALW, UNIX public domain
520 %\psonlyboxes % Blank Boxes (when all else fails).