The MetaPost System

John D. Hobby

October 20, 1997

Abstract The MetaPost system implements a picture-drawing language very

much like Knuth’s except that it outputs PostScript commands instead of run-length-encoded bitmaps. MetaPost is a powerful language for producing figures for documents to be printed on PostScript printers. It provides easy access to all the features of PostScript and it includes facilities for integrating text and graphics.

This document describes the system and its implementation. It also includes basic user documentation to be used in conjunction with The book. Much of the source code was copied from the - sources by permission from the author.

1 Overview

The MetaPost system is based on Knuth’s ^{1} [3] and much of the source code is copied with permission from the sources. MetaPost is a graphics language like , but with new primitives for integrating text and graphics and for accessing special features of PostScript^{2} such as clipping, shading, and dashed lines. The language has the main features of including first-class objects for curves, pictures, affine transformations, and pen shapes. Another feature borrowed from is the ability to solve linear equations that are given implicitly, thus allowing many programs to be written in a largely declarative style.

While MetaPost could be used as a tool for generating PostScript fonts, the intended application is to generate figures for TEX^{3} and troff documents. The figures can be integrated into a TEX document via a freely available program called dvips as shown in Figure 1.^{4} A similar procedure works with troff: the dpost output processor includes PostScript figures when they are requested via troff’s \X command.

1 is a trademark of Addison Wesley Publishing company.

2PostScript is a trademark of Adobe Systems Inc.

3TEX is a trademark of the American Mathematical Society.

4The C source for dvips comes with the web2c TEX distribution. Similar programs are available from other sources.

Figures in MetaPost  TEX Document
↓  ↓

MetaPost  TEX
↓  ↓
Figures in PostScript  dvi file
↓  ↓

                              dvips

↓

PostScript

Fig. 1: A diagram of the processing for a TEX document with figures done in MetaPost

Other than the new commands for integrating text and accessing features of PostScript, the main difference between the and MetaPost languages is that the latter deals with continuous pictures rather than discrete ones. This affects the coordinate system and some of the subtler aspects of the language as outlined in the next two sections.

Sections 2 and 3 give a short summary of the language with numerous examples. Then Section 4 describes the implementation. A preliminary description of the language has already appeared [1].

2 Introduction to MetaPost

MetaPost is a lot like Knuth’s except that it outputs PostScript programs instead of bitmaps. Knuth describes the language in The book. [4]

This document introduces MetaPost via examples and references to key parts of The book. It is a good idea to start by reading chapters 2 and 3 in The book. The introductory material in these chapters applies to MetaPost except that coordinates are in units of PostScript points by default (72 units per inch).

To see MetaPost in action, consider a file containing the following text:

Then the command  produces an output file  that can be included in

a TEX document. After the TEX commands produce

The  line means that everything up to the next  is to be
used to create  . If there were more than one figure in  , there would
be additional  …  blocks.

The macro has been specially developed for MetaPost. There is also a command called that draws the following path with arrowheads on both ends. The line beginning with is a call to a standard macro for positioning text just above a given point. In this case, the point is the midpoint of the segment from to and the text is

generated by the TEX commands . In addition to  and  ,
there is also  ,  , and four other versions  for

upper-left etc. Just plain without any suffix centers the label on the given point.

The discussion of pens in Chapter 4 of The book applies to MetaPost as well, but simple figures often do not need to refer to pens explicitly because they can just use the default pen which is a circle 0.5bp in diameter.^{5} This produces lines of uniform thickness 0.5bp regardless of the direction of the line.

Chapter 5 of The book does not apply to MetaPost. In particular, there is no macro or “sharped units” and does not output files. MetaPost does have a set of preloaded macros but they are not the same as ’s plain base. If there were an analogous chapter about running MetaPost, it would probably mention that skips over … blocks and depends on a preprocessor to translate them into low level MetaPost commands. If the main file is , the translated TEX material is placed in a file named . This is normally done silently without any user intervention but it could fail if one of the … blocks contains an erroneous TEX command. If this happens, the erroneous TEX input is saved in the file and the error messages appear in .

5The letters “bp” stand for “big point” ( \frac{1}{72} inch). This is one of the standard units of measure in TEX and and it is the default unit for MetaPost. A complete listing of predefined units is given on page 92 of The book.

If there is a need for TEX macro definitions or any other auxiliary TEX com-

mands, they can be enclosed in a  …  block. The difference
between  and  is that the former generates a picture expression

while the latter does not.

On Unix systems, an environment variable can be used to specify that … and … blocks are in troff instead of TEX. When using this option, it is a good idea to give the MetaPost command . This tells to output structured PostScript and assume that text comes from built-in PostScript fonts.

Chapters 6–10 of The book cover important aspects of - that are almost identical in MetaPost. The only change to the tokenization process described in Chapter 6 is that TEX material can contain percent signs and unmatched double quote characters so these are treated like spaces when skipping TEX material. The preprocessor gives TEX everything between and except for leading and trailing spaces.

Chapters 7–10 discuss the types of variables and expressions that understands. MetaPost has an additional type “ ” that is a lot like except that it has three components instead of two. The operations allowed on colors are addition, subtraction, scalar multiplication, and scalar division. MetaPost also understands mediation expressions involving colors since is equivalent to which is allowed even when and are colors. Colors can be specified in terms of the predefined constants , , , , , or the red, green, and blue components can be given explicitly. Black is and white is . There is no restriction against colors “blacker than black” or “whiter than white” except all components are snapped back to the [0, 1] range when a color is given in an output file. MetaPost solves linear equations involving colors the same way it does so for pairs. (This is explained in Chapter 9).

Let’s consider another example that uses some of the ideas discussed above. The MetaPost program produces the following figure:

The third line declares arrays of paths and as explained in Chapter 7. Note that is the same as when = 1.5. The loops make each an approximation to an arc of the hyperbola

xy = \frac{wh}{i^{2}}

and each a segment of slope ih/w. (Loops are discussed in Chapter 19 of The book).

The  operator is used to cut off the part of  after the inter-
section with  . (There is no “  ” in the input for the above figure

so this hyperbola is invisible). There is also a operator defined to make

a b

what’s left of path a when everything before its intersection with b is removed. In case of multiple intersections and try to cut off as little as possible.

The shaded region in the above figure is due to the line

The boundary of this region is the path that the macro creates by piecing together the four paths given as arguments. In other words, is constructed by going along until it intersects , then going along until hitting , etc. It turns out that this requires going backwards along and . The macro tries to avoid going backwards if it has a choice as to which intersection points to choose, but in this example each pair of consecutive path arguments has a unique intersection point. It is generally a good idea to avoid multiple intersections because they can lead to unpleasant surprises.

The and macros in plain MetaPost are similar to the corresponding macros discussed in Chapter 13 of The book but MetaPost assigns colors to regions rather than assigning weights to pixels. There is no command or option in MetaPost. The macro used to erase the rectangle containing the label “f > 0” in the above figure works by specifying “ ” where ” is usually equal to . The complete syntax for primitive drawing commands in MetaPost is as follows:

⟨picture command⟩ → ⟨addto command⟩ | ⟨clip command⟩ ⟨addto command⟩ →

⟨picture variable⟩  ⟨picture expression⟩⟨with list⟩
|  ⟨picture variable⟩  ⟨path expression⟩⟨with list⟩
|  ⟨picture variable⟩  ⟨path expression⟩⟨with list⟩

⟨with list⟩ → ⟨empty⟩ | ⟨with clause⟩⟨with list⟩

⟨with clause⟩ → ⟨color expression⟩

|  ⟨pen expression⟩ |  ⟨picture expression⟩
⟨clip command⟩ →  ⟨picture variable⟩  ⟨path expression⟩
If P stands for  , q stands for  , and b stands for

, the standard drawing macros have roughly the following meanings:

p  means  P  p  q
c  means  P  c
c  means  P  c  q
p  means  P  p  q  b
c  means  P  c  b
c means  P  c  q  b

The expressions denoted by c in the table must be cyclic paths, while path expressions p need not be cyclic. It is also possible to use and when the argument is a picture r:

r  means  P  r
r  means  P  r  b
The argument to  in the last example is  . This is a call

to a standard macro that gives the bounding box of a picture as a rectangular path. The macro used two lines previously makes the center of the bounding box for path . (This works for paths and pictures). The expression

computes a picture containing the text “f > 0” centered on the point . Here is the complete syntax for labeling commands:

⟨label command⟩ → ⟨command name⟩⟨position suffix⟩(⟨label text⟩, ⟨label loc⟩)

| ⟨position suffix⟩(⟨suffix list⟩)

⟨command name⟩ →  |  |
⟨position suffix⟩ → ⟨empty⟩ |  |  |  |
|  |  |  |

⟨label text⟩ → ⟨picture expression⟩ | ⟨string expression⟩ ⟨label loc⟩ → ⟨pair expression⟩ ⟨suffix list⟩ → ⟨suffix⟩ | ⟨suffix⟩, ⟨suffix list⟩

The  command adds text to  near the position ⟨label loc⟩

as determined by the ⟨position suffix⟩. An empty suffix centers the label and the other options offset it slightly so that it does not overlap the ⟨label loc⟩. Using just creates a picture expression rather than actually adding it to . Using instead of adds a dot at the location being labeled. Finally, the command does

⟨position suffix⟩( ⟨suffix⟩, ⟨suffix⟩)

for each ⟨suffix⟩ in the ⟨suffix list⟩, using the operator to convert the suffix to a string. Thus places labels “ ” and “ ” just above and .

The examples given so far have all used ⟨label text⟩ of the form

⟨TEX commands⟩ .

This gets converted into a picture expression. If the label is simple enough, it can be given directly as a string expression in which case it is typeset in at times its design size. Normally,

and ,

but these can be reset if desired. Using  instead of  would allow

the label to contain spaces and special characters. If there is any doubt about what the design size is, use the operator to find it as follows:

Notice that a ⟨with clause⟩ can be “ ⟨picture expression⟩.” The picture gives a template that tells how the line being drawn is to be dashed. There is a standard template called that makes dashes 3bp long separated by gaps of length 3bp. It is possible to scale the template in order to get a finer or coarser pattern. Thus

draws a line with dashes 6bp long with gaps of 6bp.

The following MetaPost input illustrates the use of dashed lines:

This produces the following figure:

The above figure uses some of the more advanced properties of paths discussed in Chapter 14 of The book. All of this material applies to MetaPost as well as except for the explanation of “strange paths” which fortunately cannot occur in MetaPost. The parts most relevant to this figure are the explanation of “curl” specifications and the , , and operators. In order to ensure that the path makes y a unique function of x, the path is first constructed with the y-coordinates compressed by a factor of ten. The final “ ” restores the original aspect ratio after MetaPost has chosen a cubic spline that interpolates the given points.

The operator is an example of a very important class of operators that apply affine transformations to pairs, paths, pens, pictures, and other transforms. The discussion in Chapter 15 is relevant and important. The only differences are that MetaPost has no currenttransform and there is no restriction on the type of transformations that can be applied to pictures.

3 More Advanced Topics

MetaPost does have pens like those in but they aren’t very important to the casual user except occasionally to specify changes in line widths as in the preceding figure. Anyone reading the description in Chapter 16 of The book should beware that there is no such thing as a “future pen” in MetaPost and elliptical pens are never converted into polygons. Furthermore, there is no need for and because the same effect can be achieved by setting the internal parameter .

There is also a parameter as illustrated below. The default values

of  and  are both  .

Another way to adjust the behavior of drawing commands is by giving the declaration

(⟨with list⟩)

For instance,

gives subsequent drawing commands the default color blue. This can still be overridden by giving another clause as in

The options apply only to relevant drawing commands:

will affect commands but not fill commands.

Chapters 17–20 of The book describe the programming constructs necessary to customize the language to a particular problem. These features work the same way in MetaPost but a few additional comments are needed. These chapters mention certain macros from plain that are not in the plain macro package for MetaPost. Generally if it sounds as though it’s for making fonts, MetaPost doesn’t have it. Remember that and play the role of ’s and . Look in the file in the standard macro area if there is any doubt about what macros are predefined. This file is also a good source of examples.

Chapter 17 explains how the statement makes temporary changes to internal quantities. This works the same way in MetaPost except that the example involving autorounding is inappropriate because MetaPost doesn’t have that particular quantity. Here is a complete list of the internal quantities found in but not MetaPost:

The following additional quantities are defined in plain but not in plain MetaPost:

{ \atop }

There are also some internal quantities that are unique to MetaPost. The and parameters have already been mentioned. There is also a parameter that behaves like the similarly named parameter in PostScript. Another parameter, suppresses error messages about attempts to typeset missing characters. This is probably only relevant when using string parameters in the labeling macros since expressions generated by … blocks are not likely to use missing characters.

The parameter was referred to earlier when we recommended setting it to one when including MetaPost output in a troff document. Any positivie value causes the output files to be “conforming PostScript” that assumes only standard Adobe fonts are used. This makes the output more portable but on most implementations, it precludes the use of the use of TEX fonts such as . Software for sending TEX output to PostScript printers generally downloads such fonts one character at a time and does not make them available in included PostScript figures.

Plain MetaPost also has internals , and as well as which controls the size of the default label font as explained above. The parameter is the amount of extra space that the operator leaves; gives the distance by which labels are offset from the point being labeled; is the angle of the pointed ends of arrowheads (45^{∘} by default). There is also a path that controls the size of the arrowheads. The statement

changes the arrowhead length to /2.

The only relevant new material in The book not mentioned so far is in Chapters 21–22 and Appendix D. Chapters 23 and 24 do not apply to MetaPost at all. The grammar given in Chapters 25 and 26 isn’t exactly a grammar of MetaPost, but most of the differences have been mentioned above. There are , , and operators for colors and there is no operator. The new primitive for label text in pictures is

⟨picture secondary⟩ → ⟨picture secondary⟩ ⟨string primary⟩

Bounding box information can be obtained via the operators

⟨pair primary⟩ → ⟨corner selector⟩⟨picture primary⟩
⟨corner selector⟩ →  |  |  |

The main reason for having these in the MetaPost language is for measuring text but they work for pictures containing any mixture of text and graphics.

The command

⟨string expression⟩

adds a line of text at the beginning of the next output file. For instance, the following commands add PostScript definitions that allow MetaPost output to use the built-in font .

A similar definition is generated automatically when you set . With , it is assumed that the program that translates TEX output and includes PostScript figures will add the necessary definition.^{6}

Another new feature of MetaPost that needs further explanation is the idea of a dash pattern. It is easiest if you can just get by with the dash pattern called that is defined in plain MetaPost, but it seems necessary to give the exact rules just in case they are needed.

A dash pattern is a picture containing one or more horizontal line segments. It doesn’t matter what pen is used to draw the line segments. MetaPost behaves as though the dash pattern is replicated to form an infinitely long horizontal dashed line to be used as a template for dashed lines. For example, the following commands create a dash pattern :

6A full description of how to avoid including your output in a TEX document is beyond the scope of this documentation. MetaPost output generated with can be sent directly to a PostScript printer if it uses only built-in fonts like .

{ \atop }

Lining up an infinite number of copies of produces a set of line segments

{ (5i, 0) … (5i + 3, 0) | for all integer i }.

This template is used by starting from the y-axis and going to the right, producing dashes 3bp long separated by gaps of length 2bp.

In this example, successive copies of are offset by 5bp because the range of x coordinates covered by the line segments in is 6 − 1 or 5bp. The offset can be increased by shifting the dash pattern vertically so that it lies at a ycoordinate greater that 5bp in absolute value. The rule is that the horizontal offset between copies of the dash pattern is the maximum of |y| and the range of x-coordinates.

Making Boxes

There are auxiliary macros not included in plain MetaPost that make it convenient to do things that pic is good at. What follows is a description of how to use the macros contained in the file . This may be of some interest to users who don’t need these macros but want to see additional examples of what can be done in MetaPost.

The main idea is that one should say

⟨suffix⟩(⟨picture expression⟩)

in order to create pair variables ⟨suffix⟩ , ⟨suffix⟩ , ⟨suffix⟩ , etc. These can then be used for positioning the picture before drawing it with a separate command such as

(⟨suffix⟩)
The command  makes  the position where the center of
picture  is to be placed and defines  ,  ,  , and  to

be the corners of a rectangular path that will surround the resulting picture.

Variables  and  give the spacing between the shifted version of
and the surrounding rectangle and  is the amount by which  has to

be shifted to achieve all this.

The macro gives linear equations that force , , … to be the corners of a rectangle aligned on the x and y axes with the picture centered inside. The values of , , and are left unspecified so that the user can give equations for positioning the boxes. If no such equations are given, macros such as can detect this and give default values.

14

The following example shows how this works in practice. It is instructive to compare the MetaPost output below with the similar figure in the pic manual [2].

The second line of input for the above figure contains

This causes boxes to line up horizontally by giving additional equations that are invoked each time some box is followed by some other box . These equations are first invoked on the next line when box is followed by box . This yields

The next pair of boxes is box and box . This time the implicitly generated equations are

This process continues until a new is given. In this case the new declaration is

which causes boxes to be stacked below each other.

After calling for the first eight boxes through , the example gives the single equation = 2 followed by a call to that draws the eight boxes with the given text inside of them. The equation forces there to be 2bp of space above and below the contents of box (the label “d_{i}”). Since this doesn’t fully specify the sizes and positions of the boxes, the macro starts by selecting default values, setting through equal to the default value of 3bp.

The argument to boxit can be omitted as in or . This is like calling with an empty picture. Alternatively the argument can be a string expression instead of a picture expression in which case the string is typeset in the default font.

In addition to the corner points  ,  , …, a command like
defines points , ,  and  at the midpoints of the outer rectangle.

If this bounding rectangle is needed for something other than just being drawn

by the  macro, it can be referred to as  or in general
⟨box name⟩

The  macro is used in the arguments to  in the previous

example. For instance

is a path from the center of box to the center of box . Following this with “ ” makes the arrow go towards the center of the box but stop when it hits the outer rectangle.

The next example also uses this technique of cutting connecting arrows when they hit a bounding path, but in this case the bounding paths are circles and ovals instead of rectangles. The circles and ovals are created by using

in place of  . Saying  defines points , , , ,
and distances  and  . These variables describe how the picture is

centered in an oval as can be seen from the following diagram:

Here is the input for the figure that uses : The “boxes” produced when using come out circular unless something forces a different aspect ratio.

In the above figure, the equations  and  after
and

make the start and stop nodes non-circular.

The general rule is that c comes out circular if c , c , and c − c are all unspecified. Otherwise the macros select an oval just big enough to contain the given picture. (The margin of safety is given by the internal parameter ).

There is also a macro that makes c the picture that goes inside c In addition to the macro that draws the picture and the surrounding rectangle or oval, there are and macros that draw the pictures and the surrounding paths separately.

4 Implementation

The MetaPost interpreter is written in Knuth’s WEB language which can be thought of as PASCAL with macros. This choice allows the sharing of code with the interpreter. [4] Indeed, about three fourths of the code in the main source file mp.web is copied from this source by permission from the author.

In accordance with the standard methodology for WEB programs, parts of the program that are specific to the UNIX^{7} system are given in a separate file mp.ch that the tangle processor merges with mp.web to form a PASCAL program. (It is then automatically translated into C using a special-purpose translator that is included with the UNIX version of TEX.) The only other code required by the MetaPost interpreter is a short external C program mpext.c and a small include file mp.h to tie it all together.

7UNIX is a registered trademark of UNIX System Laboratories.

In addition to the main interpreter, there are some programs that control

the translation of typesetting commands in  …  blocks. When the
interpreter encounters  in some input file  , it needs to start reading

from an auxiliary file . This file should contain translations of the … blocks in into low-level MetaPost commands. If is out of date or does not exist, the MetaPost interpreter invokes a shell script that generates the file.

The generation of an auxiliary file from an input file is a three step process: a C program called strips out the TEX commands; then TEX produces a binary file that gives low-level typesetting instructions; and finally, a WEB program writes equivalent MetaPost commands in the file. When using troff, C programs and replace and .

References

[1] J. D. Hobby. A -like system with PostScript output. Tugboat, the TEX User’s Group Newsletter, 10(4):505–512, December 1989.

[2] Brian W. Kernighan. Pic—a graphics language for typesetting. In Unix Research System Papers, Tenth Edition, pages 53–77. AT&T Bell Laboratories, 1990.

[3] D. E. Knuth. Computers and Typesetting, volume C. Addison Wesley, Reading, Massachusetts, 1986.

[4] D. E. Knuth. Computers and Typesetting, volume D. Addison Wesley, Reading, Massachusetts, 1986.