Add regression verification script
[ctsim.git] / doc / psbox.tex
1 %
2 %              %%%%%%%    %%%%%        %%%%%%    %%%%%   %     %
3 %              %      %  %             %     %  %     %   %   %
4 %              %      %  %             %     %  %     %    % %
5 %              %%%%%%%    %%%%%        %%%%%%   %     %     %
6 %              %               %       %     %  %     %    % %
7 %              %               %       %     %  %     %   %   %
8 %              %         %%%%%%        %%%%%%    %%%%%   %     %
9 %
10 %              By Jean Orloff %
11 %              Comments & suggestions by e-mail: ORLOFF@surya11.cern.ch
12 %              No modification of this file allowed if not e-sent to me.
13 %
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.
21 % History:
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
31 %
32 \def\temp{1.31}
33 \let\tempp=\relax
34 \expandafter\ifx\csname psboxversion\endcsname\relax
35   \message{version: \temp}
36 \else
37     \ifdim\temp cm>\psboxversion cm
38       \message{version: \temp}
39     \else
40       \message{psbox(\psboxversion) is already loaded: I won't load
41         psbox(\temp)!}
42       \let\temp=\psboxversion
43       \let\tempp=\endinput
44     \fi
45 \fi
46 \tempp
47 \let\psboxversion=\temp
48 \catcode`\@=11
49 % Every macro likes a little privacy...
50 %
51 % Some common defs
52 %
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}}
57 %
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)
62 %
63 \def\psfortextures{%     For TeXtures on the Macintosh
64 %-----------------
65 \def\PSspeci@l##1##2{%
66 \special{illustration ##1\space scaled ##2}%
67 }}
68 %
69 \def\psfordvitops{%      For the DVItoPS converter on IBM mainframes
70 %----------------
71 \def\PSspeci@l##1##2{%
72 \special{dvitops: import ##1\space \the\drawingwd \the\drawinght}%
73 }}
74 %
75 \def\psfordvips{%      For DVIPS converter on VAX, UNIX and PC's
76 %--------------
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}%
82 }}
83 %
84 \def\psforoztex{%        For the OzTeX shareware on the Macintosh
85 %--------------
86 \def\PSspeci@l##1##2{%
87 \special{##1 \space
88       ##2 1000 div dup scale
89       \putsp@ce{\number-\psllx} \putsp@ce{\number-\pslly} translate
90 }%
91 }}
92 \def\putsp@ce#1{#1 }
93 %
94 \def\psfordvitps{%       From the UNIX TeXPS package, vers.>3.12
95 %---------------
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"}
116 }}
117 \def\psforDVIALW{%   Try for dvialw, a UNIX public domain
118 %---------------
119 \def\PSspeci@l##1##2{
120 \special{language "PS"
121 literal "##2 1000 div dup scale"
122 include "##1"}}}
123 \def\psonlyboxes{%     Draft-like behaviour if none of the others works
124 %---------------
125 \def\PSspeci@l##1##2{%
126 \at(0cm;0cm){\boxit{\vbox to\drawinght
127   {\vss
128   \hbox to\drawingwd{\at(0cm;0cm){\hbox{(##1)}}\hss}
129   }}}
130 }%
131 }
132 %
133 \def\psloc@lerr#1{%
134 \let\savedPSspeci@l=\PSspeci@l%
135 \def\PSspeci@l##1##2{%
136 \at(0cm;0cm){\boxit{\vbox to\drawinght
137   {\vss
138   \hbox to\drawingwd{\at(0cm;0cm){\hbox{(##1) #1}}\hss}
139   }}}
140 \let\PSspeci@l=\savedPSspeci@l% restore normal output for other figs!
141 }%
142 }
143 %
144 %\def\psfor...  add your own!
145 %
146 %  \ReadPSize{PSfilename} reads the dimensions of a PostScript drawing
147 %      and stores it in \drawinght(wd)
148 \newread\pst@mpin
149 \newdimen\drawinght\newdimen\drawingwd
150 \newdimen\psxoffset\newdimen\psyoffset
151 \newbox\drawingBox
152 \newif\ifNotB@undingBox
153 \newhelp\PShelp{Proceed: you'll have a 5cm square blank box instead of
154 your graphics (Jean Orloff).}
155 \def\@mpty{}
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!
160   \else
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!
164   \fi
165   }
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
170 {\catcode`\%=12
171 \xdef\B@undingBox{%%BoundingBox}
172 }   %% is not a true comment in PostScript, even if % is!
173 \def\ReadPSize#1{
174  \edef\PSfilename{#1}
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
180    \closein\pst@mpin
181  \else
182    \immediate\write\psbj@inaux{#1,}
183    \loop
184      \executeinspecs{\catcode`\ =10\global\read\pst@mpin to\n@xtline}
185      \ifeof\pst@mpin
186        \errhelp=\PShelp
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}
191        \NotB@undingBoxfalse
192      \else
193        \expandafter\sc@nline\n@xtline:\@ndline
194        \ifx\p@rameter\B@undingBox\NotB@undingBoxfalse
195          \edef\t@mp{%
196            \expandafter\g@bblefirstblank\v@lue\space\space\space}
197          \expandafter\s@tsize\t@mp\@ndsize
198        \else\NotB@undingBoxtrue
199        \fi
200      \fi
201    \ifNotB@undingBox\repeat
202    \closein\pst@mpin
203  \fi
204 \message{#1}
205 }
206 %
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!).
212 %
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{
217    \ReadPSize{#3}
218    \divide\drawingwd by 1000
219    \divide\drawinght by 1000
220    \d@mx=#1
221    \ifdim\d@mx=0pt\xscale=1000
222          \else \xscale=\d@mx \divide \xscale by \drawingwd\fi
223    \d@my=#2
224    \ifdim\d@my=0pt\yscale=1000
225          \else \yscale=\d@my \divide \yscale by \drawinght\fi
226    \ifnum\yscale=1000
227          \else\ifnum\xscale=1000\xscale=\yscale
228                     \else\ifnum\yscale<\xscale\xscale=\yscale\fi
229               \fi
230    \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{
241       \kern-\psyoffset
242       \PSspeci@l{\PSfilename}{\the\xscale}
243       \vss}\hss\ps@nnotation}
244    \global\ht\drawingBox=\the\drawinght
245    \global\wd\drawingBox=\the\drawingwd
246    \baselineskip=0pt
247    \copy\drawingBox
248  \vss}\hss}
249   \global\psxoffset=0pt
250   \global\psyoffset=0pt% These are local to one figure
251   \global\pscm=1cm
252   \global\drawingwd=\drawingwd
253   \global\drawinght=\drawinght
254 }}
255 %
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
259 %   than 1/1000.
260 %
261 \def\psboxscaled#1#2{\vbox{
262   \ReadPSize{#2}
263   \xscale=#1
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{
272      \kern-\psyoffset
273      \PSspeci@l{\PSfilename}{\the\xscale}
274      \vss}\hss\ps@nnotation}
275   \global\ht\drawingBox=\the\drawinght
276   \global\wd\drawingBox=\the\drawingwd
277   \baselineskip=0pt
278   \copy\drawingBox
279   \global\psxoffset=0pt
280   \global\psyoffset=0pt% These are local to one figure
281   \global\pscm=1cm
282   \global\drawingwd=\drawingwd
283   \global\drawinght=\drawinght
284 }}
285 %
286 %  \psbox{PSfilename} makes a TeX box having the minimal size to
287 %      enclose the picture
288 \def\psbox#1{\psboxscaled{1000}{#1}}
289 %
290 %
291 %  \joinfiles file1, file2, ...n \into joinedfilename .
292 %     makes one file out of many
293 %  \splitfile joinedfilename
294 %     the opposite
295 %
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}}
300 %\newread\pst@mpin
301 \newif\ifn@teof\n@teoftrue
302 \newif\ifc@ntrolline
303 \newif\ifmatch
304 \newread\j@insplitin
305 \newwrite\j@insplitout
306 \newwrite\psbj@inaux
307 \immediate\openout\psbj@inaux=psbjoin.aux
308 \immediate\write\psbj@inaux{\string\joinfiles}
309 \immediate\write\psbj@inaux{\jobname,}
310 %
311 % We redefine input to keep track of the various files inputted
312 %
313 \immediate\let\oldinput=\input
314 \def\input#1 {
315  \immediate\write\psbj@inaux{#1,}
316  \oldinput #1 }
317 \def\empty{}
318 \def\setmatchif#1\contains#2{
319   \def\match##1#2##2\endmatch{
320     \def\tmp{##2}
321     \ifx\empty\tmp
322       \matchfalse
323     \else
324       \matchtrue
325     \fi}
326   \match#1#2\endmatch}
327 \def\warnopenout#1#2{
328  \setmatchif{TrashMe,psbjoin.aux,psbjoin.all}\contains{#2}
329  \ifmatch
330  \else
331    \immediate\openin\pst@mpin=#2
332    \ifeof\pst@mpin
333      \else
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}
337    \fi
338    \immediate\closein\pst@mpin
339  \fi
340  \message{#2}
341  \immediate\openout#1=#2}
342 %  No comments allowed below: % will have an unusual catcode
343 {
344 \catcode`\%=12
345 \gdef\splitfile#1 {
346  \immediate\openin\j@insplitin=#1
347  \message{Splitting file #1 into:}
348  \warnopenout\j@insplitout{TrashMe}
349  \loop
350    \ifeof
351      \j@insplitin\immediate\closein\j@insplitin\n@teoffalse
352    \else
353      \n@teoftrue
354      \executeinspecs{\global\read\j@insplitin to\spl@tinline\expandafter
355        \ch@ckbeginnewfile\spl@tinline%Beginning-Of-File-Named:%\endcheck}
356      \ifc@ntrolline
357      \else
358        \toks0=\expandafter{\spl@tinline}
359        \immediate\write\j@insplitout{\the\toks0}
360      \fi
361    \fi
362  \ifn@teof\repeat
363  \immediate\closeout\j@insplitout}
364 \gdef\ch@ckbeginnewfile#1%Beginning-Of-File-Named:#2%#3\endcheck{
365  \def\t@mp{#1}
366  \ifx\empty\t@mp
367    \def\t@mp{#3}
368    \ifx\empty\t@mp
369      \global\c@ntrollinefalse
370    \else
371      \immediate\closeout\j@insplitout
372      \warnopenout\j@insplitout{#2}
373      \global\c@ntrollinetrue
374    \fi
375  \else
376    \global\c@ntrollinefalse
377  \fi}
378 \gdef\joinfiles#1\into#2 {
379  \message{Joining following files into}
380  \warnopenout\j@insplitout{#2}
381  \message{:}
382  {
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}}
394  }
395  \tre@tfilelist#1, \endtre@t
396  \immediate\closeout\j@insplitout}
397 \gdef\tre@tfilelist#1, #2\endtre@t{
398  \def\t@mp{#1}
399  \ifx\empty\t@mp
400    \else
401    \llj@in{#1}
402    \tre@tfilelist#2, \endtre@t
403  \fi}
404 \gdef\llj@in#1{
405  \immediate\openin\j@insplitin=#1
406  \ifeof\j@insplitin
407    \errmessage{I couldn't find file #1.}
408    \else
409    \message{#1}
410    \toks0={%Beginning-Of-File-Named:#1}
411    \immediate\write\j@insplitout{\the\toks0}
412    \executeinspecs{\global\read\j@insplitin to\oldj@ininline}
413    \loop
414      \ifeof\j@insplitin\immediate\closein\j@insplitin\n@teoffalse
415        \else\n@teoftrue
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}
420      \fi
421    \ifn@teof
422    \repeat
423    \immediate\closein\j@insplitin
424  \fi}
425 }
426 % To be put at the end of a file, for making an tar-like file containing
427 %   everything it used.
428 \def\autojoin{
429  \immediate\write\psbj@inaux{\string\into\space psbjoin.all}
430  \immediate\closeout\psbj@inaux
431  \input psbjoin.aux
432 }
433 %
434 %  Annotations & Captions etc...
435 %
436 %
437 % \centinsert{anybox} is just a centered \midinsert, but is included as
438 %    people barely use the original inserts from TeX.
439 %
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
444    \copy\drawingBox
445    \vskip\baselineskip
446    \vbox{\hsize=\wd\drawingBox\setbox0=\hbox{#2}
447      \ifdim\wd0>\hsize
448        \noindent\unhbox0\tolerance=5000
449     \else\centerline{\box0}
450     \fi
451 }}}
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}}
455 %
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}}}
460 %
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}
467   \gridht=#1
468   \divide\gridht by \ht0
469   \multiply\gridht by \ht0
470   \gridwd=#2
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}}
475 %
476 % Useful to measure where to put annotations
477 \def\fillinggrid{\at(0cm;0cm){\vbox{
478   \gridfill(\drawinght;\drawingwd)}}}
479 %
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
485 %
486 \def\textleftof#1:{
487   \setbox1=#1
488   \setbox0=\vbox\bgroup
489     \advance\hsize by -\wd1 \advance\hsize by -2em}
490 \def\textrightof#1:{
491   \setbox0=#1
492   \setbox1=\vbox\bgroup
493     \advance\hsize by -\wd0 \advance\hsize by -2em}
494 \def\endtext{
495   \egroup
496   \hbox to \hsize{\valign{\vfil##\vfil\cr%
497 \box0\cr%
498 \noalign{\hss}\box1\cr}}}
499 %
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}}
508 %
509 %
510 \catcode`\@=12 % cs containing @ are unreachable
511 %
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).