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% 81urx=\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" 121literal "##2 1000 div dup scale" 122include "##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 154your 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 335press 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). 521