[Tex/LaTex] How to write a bounding box information in PostScript to an external file and read it in TeX at the second compilation

auxiliary-filespostscriptprogrammingpstricks

Scenario

  • I want to create a new environment, e.g., pscanvas that does not need any size specification but just a unique filename. It can contain any graphic objects that pspicture can contain.

    Thus

    \begin{pscanvas}{<filename>}% no size specification needed
    % any graphic objects go here
    \end{pscanvas}
    

    will simplify

    \begin{pspicture}(<width>,<height>)% size specification needed as usual
    % any graphic objects go here
    \end{pspicture}
    

    or

    \begin{pspicture}(<x1>,<y1>)(<x2>,<y2>)% size specification needed as usual
    % any graphic objects go here
    \end{pspicture}
    
  • Because the canvas size is not specified in the TeX input file, the TeX input file needs to be compiled at least twice.

    The first compilation with latex->dvips->gs must produce a temporary file, for example, <filename>.bbi (bbi stands for bounding box info). This temporary file is generated on the fly by GhostScript when invoking PostScript code embedded in pscanvas.

The first compilation does not need to produce PDF output because the canvas size has not been properly prepared by TeX. However, if we produce PDF output, the PDF should render a notification box saying "Graphics is premature, please compile once more.".

The second compilation with latex, TeX engine reads the <filename>.bbi to make the exact space for the graphics filename. Compilation with dvips->ps2pdf then produces a final PDF output.

Question

How to write bounding box information of the canvas in PostScript to an external file <filename>.bbi and read it from TeX world for preparing the canvas size?

Best Answer

I'm not sure of the requirements for reading the info back into TeX, but you can get the bounding box information from ghostscript formatted as a DSC comment.

gs -sDEVICE=bbox file.ps

This will print 2 lines to stderr in response to each showpage event.

%%BoundingBox: 51 93 511 731
%%HiResBoundingBox: 51.335998 93.131997 510.209984 730.061978

%%BoundingBox: 23 83 587 765
%%HiResBoundingBox: 23.147999 83.087997 586.331982 764.801977

(The extra blank line was when I hit enter for the invisible showpage prompt. Invisible because I redirected stdout to get a nice picture of stderr.)

To capture it in a file, we need to wrangle the stderr handle.

gs -sDEVICE=bbox file.ps 2>file.bbi

Some other useful options are -dBATCH: exit after the file (otherwise it goes to a PS> prompt), and -dNOPAUSE: do not wait for enter at showpage.

If we can control how the shell-out to gs is handled, it might be possible to pipe the postscript fragment without an additional intermediate file.

??? | gs -q -sDEVICE=bbox -dNOPAUSE -dBATCH - 2>&1 | ???

This assumes the postscript program makes no interfering text output of its own.