5

How does I include an image (e.g. an eps) in plain TeX without using a package that does so for me? All other questions (like this one) don't actually answer the question how you include an image in plain TeX. They instead tell you to \input a huge macro package that mysteriously does that for you. I would like to understand what these packages actually do.

  • Related: TeX FAQ: \special commands -- "TeX provides the means to express things that device drivers can do, but about which TeX itself knows nothing. For example, TeX itself knows nothing about how to include PostScript figures into documents, or how to set the colour of printed text; but some device drivers do." – Mike Renfro May 7 '16 at 13:08
  • 1
    I've set this as tex-core as the same fundamentals apply to all formats. – Joseph Wright May 7 '16 at 13:08
  • Related tex.stackexchange.com/q/63789/21930 – Manuel May 7 '16 at 13:29
  • since the \specials provided by different drivers differ significantly, there's no practical way to answer this question compactly. if you can identify the driver you intend to use, that would make an answer more feasible, but it's still not simple. – barbara beeton May 7 '16 at 15:42
13

Inserting a graphic into a TeX document has two parts:

  • Making sure that from the TeX 'point of view' the space is allowed for correctly
  • Telling the driver (via the appropriate \special or related engine-dependent primitive) to actually place the image in the output

Some parts of this process are independent of the driver whilst of course the lowest-level stuff is driver-dependent.

To 'allow for space' you first need to pick up how big the image is, either at natural size or from any user settings. The latter of course is easy as it does not need access to the image file, but the former is more common. The route required depends on the driver/graphic type. For example, for an .eps file one arranges to parse the file line-by-line in TeX and to pick up the BoundingBox line. For binary formats such as .png, engine support is needed. Such images can be measured for example by using the appropriate primitive to include them in a box then measuring the box.

Once the dimensions of the image are known (which may include scaling, etc., again handled in a driver-dependent way), image can be inserted using the appropriate primitive. The 'current' position from a TeX point-of-view must then be adjusted such that it matches up with the appearance of the image. Remember here that images can extend outside of the bounding box of the image, so it can still overlap the text (if not clipped).

Note that it's usually most convenient to insert the image in a arbitrary sized box then to adjust the 'TeX view' around it to make space as required, rather than to include the image with whatever size the driver supplies for it. (This is more important with some drivers than others, but in the usual set up in graphics the aim is to share code paths so all drivers are treated in the same way.)


Taking the specific example of including an .eps file using the dvips driver, the \special line in dvips.def reads

\special{PSfile="#1"\space
      llx=\Gin@llx\space
      lly=\Gin@lly\space
      urx=\Gin@urx\space
      ury=\Gin@ury\space
      \ifx\Gin@scalex\@tempa\else rwi=\number\dimen@\space\fi
      \ifx\Gin@scaley\@tempa\else rhi=\number\@tempdima\space\fi
      \ifGin@clip clip\fi}%

What you can see here (covered by texdoc dvips) is that the command to actually include the graphic is PSfile="<name>". The other settings then include the lower/upper left/right co-ordinates to use (which will normally surround the image entirely but may not do if a viewport is in use), scale factors in x and y (or not if the scale is 1), and a clip keyword if appropriate.

Each driver requires a check on its syntax here: for example, dvipdfmx can use the same syntax here (though it has an alternative syntax for PDF inclusion), while direct PDF output requires \pdfimage with pdfTeX (though of course can't use .eps files, which are handled by doing a conversion to PDF).


The core part of the inclusion code from the TeX point of view (again taking it from graphics) is

\def\Gin@setfile#1#2#3{%
  \ifx\\#2\\\Gread@false\fi
  \ifGin@bbox\else
    \ifGread@
      \csname Gread@%
         \expandafter\ifx\csname Gread@#1\endcsname\relax
           eps%
         \else
           #1%
         \fi
      \endcsname{\Gin@base#2}%
    \else
      \Gin@nosize{#3}%
    \fi
  \fi
  \Gin@viewport@code
  \Gin@nat@height\Gin@ury bp%
  \advance\Gin@nat@height-\Gin@lly bp%
  \Gin@nat@width\Gin@urx bp%
  \advance\Gin@nat@width-\Gin@llx bp%
  \Gin@req@sizes
  \expandafter\ifx\csname Ginclude@#1\endcsname\relax
    \Gin@drafttrue
    \expandafter\ifx\csname Gread@#1\endcsname\relax
      \@latex@error{Can not include graphics of type: #1}\@ehc
      \global\expandafter\let\csname Gread@#1\endcsname\@empty
    \fi
  \fi
  \leavevmode
  \ifGin@draft
      \hb@xt@\Gin@req@width{%
        \vrule\hss
        \vbox to \Gin@req@height{%
           \hrule \@width \Gin@req@width
           \vss
           \edef\@tempa{#3}%
           \rlap{ \ttfamily\expandafter\strip@prefix\meaning\@tempa}%
           \vss
           \hrule}%
        \hss\vrule}%
  \else
    \@addtofilelist{#3}%
    \ProvidesFile{#3}[Graphic file (type #1)]%
    \setbox\z@\hbox{\csname Ginclude@#1\endcsname{#3}}%
    \dp\z@\z@
    \ht\z@\Gin@req@height
    \wd\z@\Gin@req@width
  \box\z@
  \fi}

where you'll see that the basic flow is 'look for a size', 'set some dimensions', (some code for skipping inclusion in draft mode), setting a box with the image, including that box at the required size. Earlier code picks up the file type so that the correct reading/inclusion method is used.


All of this can of course be written out 'by hand' but the measurements are somewhat tedious. At the same time, having to track the driver type is normally not that convenient. For this reason it's normally easier to use graphics.tex with plain TeX/the graphics package with LaTeX to do the image insertion rather than writing out ones own code for the same. Of course, that code can be read over to get the details of the algorithms required.

  • What are the appropriate \special calls? Your answer is interesting, but it lacks too many details to really answer my question. Perhaps a concrete example could be useful. – FUZxxl May 7 '16 at 13:16
  • 1
    @FUZxxl A full answer in that sense would require all of the graphics bundle. I can add an example of the \special line if you like but that's actually a small part of the whole. – Joseph Wright May 7 '16 at 13:17
  • I cannot imagine that it's so complicated to include an image that it can't be done in the scope of an answer. – FUZxxl May 7 '16 at 13:18
  • 1
    @FUZxxl The line itself is easy enough for one driver/image type, but covering all image types/drivers and all of the calculations is rathter longer! – Joseph Wright May 7 '16 at 13:24
  • 3
    @FUZxxl: Your question is too vage. "TeX" can be a lot of different things: pdftex, tex+dvips, tex+dvipdfmx, xetex, luatex ... writing an answer which covers all is difficult. Perhaps you should concentrate on one compilation method. – Ulrike Fischer May 7 '16 at 13:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.