diff options
Diffstat (limited to 'Master/texmf-dist/doc/metapost/base/source/mpintro.tex')
-rw-r--r-- | Master/texmf-dist/doc/metapost/base/source/mpintro.tex | 878 |
1 files changed, 878 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/metapost/base/source/mpintro.tex b/Master/texmf-dist/doc/metapost/base/source/mpintro.tex new file mode 100644 index 00000000000..99e487c46dd --- /dev/null +++ b/Master/texmf-dist/doc/metapost/base/source/mpintro.tex @@ -0,0 +1,878 @@ +\documentstyle{article} +\input epsf + +\author{John D. Hobby} +\title{The MetaPost System} + +\font\textt=cmtex10 + +\makeatletter +\def\logo{\global\font\logo=logo10 at1\@ptsize\p@ \logo} +\def\logosl{\global\font\logosl=logosl10 at1\@ptsize\p@ \logosl} +\def\MF{{\ifdim \fontdimen\@ne\font >\z@ \def\logo{\logosl}\fi + {\logo META}\-{\logo FONT}}} +\makeatother + +\def\descr#1{{\langle\hbox{#1}\rangle}} +\def\lit#1{{\hbox{\textt#1}}} +\def\okbreak{\vfil\penalty2000 \vfilneg} + +{\obeylines\obeyspaces\gdef\startverbatim{% +\vcenter\bgroup\textt\catcode`\$=12\catcode`\}=12\catcode`\{=12\catcode`\_=12% +\catcode`\\=12\catcode`\#=12\catcode`\^=12\catcode`\%=0% +\obeyspaces\let =\ \obeylines\let^^M=\cr\halign\bgroup##\hfil}} +\def\stopverbatim{\egroup\egroup} + +\begin{document} +\maketitle + +\begin{abstract} +The MetaPost system implements a picture-drawing language very much like Knuth's +\MF\ 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 {\it The \MF book}. +Much of the source code was copied from the \MF\ sources by permission from +the author. +\end{abstract} + + +\section{Overview} +The MetaPost system is based on Knuth's \MF\footnote{\MF\ is a trademark +of Addison Wesley Publishing company.}~\cite{kn:c} and much of the source +code is copied with permission from the \MF\ sources. MetaPost is a graphics +language like \MF, but with new primitives for integrating text and graphics and +for accessing special features of PostScript\footnote{PostScript is a +trademark of Adobe Systems Inc.} such as clipping, shading, and +dashed lines. The language has the main features of \MF\ including first-class +objects for curves, pictures, affine transformations, and pen shapes. +Another feature borrowed from \MF\ 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\footnote{\TeX\ is a +trademark of the American Mathematical Society.} and {\it troff\/} documents. +The figures can be integrated into a \TeX\ document via a freely available +program called {\tt dvips} as shown in Figure~1.\footnote{The C source for +{\tt dvips} comes with the web2c \TeX\ distribution. Similar programs are +available from other sources.} A similar procedure works with troff: the +{\tt dpost} output processor includes PostScript figures when they are +requested via troff's {\tt \char`\\X} command. + +\begin{figure}[htp] +$$ \def\fbox#1{\hbox{\vrule + \vbox{\hrule\kern5pt\hbox{\kern5pt\hbox{#1}\kern5pt}\kern5pt\hrule}% + \vrule}} + \vbox{ + \halign{$\hfil#\hfil$&\hskip1in$\hfil#\hfil$\cr + \hbox{Figures in MetaPost}& + \hbox{\TeX\ Document} + \cr + \bigg\downarrow& + \bigg\downarrow + \cr + \fbox{\vrule height.2in depth.133in width0pt + \kern .1in MetaPost\kern.1in} + & + \fbox{\vrule height.2in depth.133in width0pt + \kern .167in \TeX\kern.167in} + \cr + \bigg\downarrow& + \bigg\downarrow + \cr + \hbox{Figures in PostScript}& + \hbox{{\tt dvi} file} + \cr + \bigg\downarrow& + \bigg\downarrow + \cr + \fbox{\vrule height.2in depth.133in width0pt + \kern 1in {\tt dvips} \kern1in} + \span\omit\cr + \bigg\downarrow\span\omit\cr + \hbox{PostScript}\span\omit\cr}} + \atop + \vbox{\noindent Fig.~1: A diagram of the processing for a \TeX\ document with figures + done in Meta\-Post} +$$ +\end{figure} + +Other than the new commands for integrating text and accessing features of +PostScript, the main difference between the \MF\ 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 \ref{basic} and \ref{advanced} give a short summary of the language +with numerous examples. Then Section~\ref{impsec} describes the implementation. +A preliminary description of the language has already appeared~\cite{ho:mp1}. + +\section{Introduction to MetaPost} +\label{basic} +MetaPost is a lot like Knuth's \MF\ +except that it outputs PostScript programs instead +of bitmaps. Knuth describes the \MF\ language in {\sl The \MF book\/}.~\cite{kn:d} + +This document introduces MetaPost via examples and references to key parts of +{\sl The \MF book}. It is a good idea to start by reading chapters 2~and 3 +in {\sl The \MF 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 \lit{fig.mp} containing the +following text:\vadjust{\okbreak} +$$ \startverbatim +beginfig(1); +a=.7in; b=0.5in; +z0=(0,0); z1=(a,0); z2=(0,b); +z0=.5[z1,z3]=.5[z2,z4]; +draw z1..z2..z3..z4..cycle; +drawarrow z0..z1; +drawarrow z0..z2; +label.top(btex $a$ etex, .5[z0,z1]); +label.lft(btex $b$ etex, .5[z0,z2]); +endfig; +end +%stopverbatim$$ +Then the command \lit{mp} \lit{fig} produces an output file \lit{fig.1} +that can be included in a +\TeX\ document. After \lit{\string\input} \lit{epsf} the \TeX\ commands +\lit{\$\$\string\epsfbox\char`\{fig.1\char`\}\$\$} produce +$$ \epsfbox{examples.1} $$ +The \lit{beginfig(1)} line means that everything up to the next +\lit{endfig} is to be used to create \lit{fig.1}. If there +were more than one figure in \lit{fig.mp}, there would be additional +\lit{beginfig} $\ldots$ \lit{endfig} blocks. + +The \lit{drawarrow} macro has been specially developed for MetaPost. +There is also a command called \lit{drawdblarrow} that draws the +following path with arrowheads on both ends. The line beginning with +\lit{label.top} is a call to a standard macro for positioning text just +above a given point. In this case, the point \lit{.5[z0,z1]} is the +midpoint of the segment from \lit{z0} to \lit{z1} and the text is +generated by the \TeX\ commands \lit{\$a\$}. In addition to \lit{label.top} +and \lit{label.lft}, there is also \lit{label.bot}, \lit{label.rt}, +and four other versions \lit{label.ulft} for upper-left etc. Just +plain \lit{label} without any suffix centers the +label on the given point. + +The discussion of pens in Chapter~4 of {\sl The \MF 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.5{\it bp}$ in diameter.\footnote{The letters ``{\it bp}'' +stand for ``big point'' ($1\over72$ inch). This is one of the standard +units of measure in \TeX\ and \MF\ and it is the default unit for +MetaPost. A complete listing of predefined units is given on page~92 of +{\sl The \MF book}.} This produces lines of uniform thickness +$0.5{\it bp}$ regardless of the direction of the line. + +Chapter 5 of {\sl The \MF book\/} does not apply to MetaPost. +In particular, there is no \lit{mode\_setup} macro or ``sharped units'' +and \lit{mp} does not output \lit{gf} files. MetaPost does have +a set of preloaded macros but they are not the same as \MF's plain base. +If there were an +analogous chapter about running MetaPost, it would probably mention that +\lit{mp} skips over \lit{btex} $\ldots$ \lit{etex} blocks +and depends on a preprocessor to translate them into low level MetaPost +commands. If the main file is \lit{fig.mp}, the translated \TeX\ +material is placed in a file named \lit{fig.mpx}. This is normally +done silently without any user intervention but it could fail if one of +the \lit{btex} $\ldots$ \lit{etex} blocks contains an erroneous +\TeX\ command. If this happens, the erroneous \TeX\ input is saved in +the file \lit{mpxerr.tex} and the error messages appear in +\lit{mpxerr.log}. + +If there is a need for \TeX\ macro definitions or any other auxiliary +\TeX\ commands, they can be enclosed in a +\lit{verbatimtex} $\ldots$ \lit{etex} block. The difference between +\lit{btex} and \lit{verbatimtex} 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 +\lit{btex} $\ldots$ \lit{etex} and \lit{verbatimtex} $\ldots$ \lit{etex} +blocks are in {\it troff\/} instead of \TeX. When using this option, +it is a good idea to give the MetaPost command \lit{prologues:=1}. +This tells \lit{mp} to output structured PostScript and assume that +text comes from built-in PostScript fonts. + +Chapters 6--10 of {\sl The \MF book\/} cover important aspects of \MF\ +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 \lit{btex} and \lit{etex} except for leading +and trailing spaces. + +Chapters 7--10 discuss the types of variables and expressions that \MF\ +understands. MetaPost has an additional type ``\lit{color}'' that is +a lot like \lit{pair} 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 +\lit{.3[w,b]} is equivalent to \lit{w+.3(b-w)} which is allowed +even when \lit{w} and \lit{b} are colors. Colors can be specified +in terms of the predefined constants \lit{black}, \lit{white}, +\lit{red}, \lit{green}, \lit{blue}, or the red, green, and blue +components can be given explicitly. Black is \lit{(0,0,0)} and white +is \lit{(1,1,1)}. 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\vadjust{\okbreak} +$$ \startverbatim +beginfig(2); +h=2in; w=2.7in; +path p[], q[], pp; +for i=1.5,2,4: ii:=i**2; + p[i] = (w/ii,h){1/ii,-1}...(w/i,h/i)...(w,h/ii){1,-1/ii}; +endfor +for i=.5,1.5: q[i] = origin..(w,i*h) cutafter p1.5; endfor +pp = buildcycle(q0.5, p2, q1.5, p4); +fill pp withcolor .8white; +z0=center pp; +picture lab; lab=thelabel(btex $f>0$ etex, z0); +unfill bbox lab; draw lab; +draw q0.5; draw p2; draw q1.5; draw p4; +makelabel.top(btex $P$ etex, p2 intersectionpoint q0.5); +makelabel.rt(btex $Q$ etex, p2 intersectionpoint q1.5); +endfig; +%stopverbatim$$ +produces the following figure:\vadjust{\okbreak} +$$ \epsfbox{examples.2} $$ + +The third line declares arrays of paths \lit{p} and \lit{q} as explained +in Chapter~7. Note that \lit{q1.5} is the same as \lit{q[i]} when +$\lit{i}=1.5$. The \lit{for} loops make each \lit{p[i]} +an approximation to an arc of the hyperbola +$$xy={wh\over i^2} $$ +and each \lit{q[i]} a segment of slope $ih/w$. (Loops are discussed in +Chapter~19 of {\sl The \MF book\/}). + +The \lit{cutafter} operator is used to cut off the part of \lit{q[i]} after +the intersection with \lit{p1.5}. (There is no ``\lit{draw} \lit{p1.5}'' in +the input for the above figure so this hyperbola is invisible). There is also a +\lit{cutbefore} operator defined to make +$$ a \lit{ cutbefore } b $$ +what's left of path~$a$ when everything before its intersection with~$b$ is +removed. In case of multiple intersections \lit{cutbefore} and \lit{cutafter} +try to cut off as little as possible. + +The shaded region in the above figure is due to the line +$$ \lit{fill pp withcolor .8white} $$ +The boundary of this region is the path \lit{pp} that the \lit{buildcycle} +macro creates by piecing together the four paths given as arguments. In other +words, \lit{pp} is constructed by going along \lit{q0.5} until it +intersects \lit{p2}, then going along \lit{p2} until hitting +\lit{q1.5}, etc. It turns out that this requires going backwards along +\lit{p2} and \lit{q1.5}. The \lit{buildcycle} 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 \lit{fill} and \lit{unfill} macros in plain MetaPost are similar to +the corresponding macros discussed in Chapter~13 of {\sl The \MF book\/} +but MetaPost assigns colors to regions rather than assigning weights to pixels. +There is no \lit{cull} command or \lit{withweight} option in MetaPost. +The \lit{unfill} macro used to erase the rectangle containing the label +``$f>0$'' in the above figure works by specifying ``\lit{withcolor} +\lit{background}'' +where \lit{background}'' is usually equal to \lit{white}. The complete +syntax for primitive drawing commands in MetaPost is as follows: +$$\tabskip=0.0pt plus 1000.0pt minus 1000.0pt + \halign to\hsize{$#$\hfil\cr + \descr{picture command} \rightarrow + \descr{addto command} \mid \descr{clip command} \cr + \descr{addto command} \rightarrow {} \cr + \qquad \lit{addto }\descr{picture variable} \lit{ also } + \descr{picture expression} \descr{with list} \cr + \qquad {}\mid \lit{addto } \descr{picture variable} \lit{ contour } + \descr{path expression} \descr{with list} \cr + \qquad {}\mid \lit{addto } \descr{picture variable} \lit{ doublepath } + \descr{path expression} \descr{with list} \cr + \descr{with list} \rightarrow \descr{empty} \mid + \descr{with clause} \descr{with list} \cr + \descr{with clause} \rightarrow \lit{withcolor } \descr{color expression}\cr + \qquad {} \mid \lit{withpen } \descr{pen expression} + \mid \lit{dashed } \descr{picture expression}\cr + \descr{clip command} \rightarrow \lit{clip } + \descr{picture variable} \lit{ to } \descr{path expression} \cr} +$$ +If $P$ stands for \lit{currentpicture}, $q$ stands for +\lit{currentpen}, and $b$ stands for \lit{background}, the standard +drawing macros have roughly the following meanings: +$$ \tabskip=0.0pt plus 1000.0pt minus 1000.0pt + \halign to\hsize{$#$\hfil&\quad means\quad $#$\hfil\cr + \lit{draw }p& \lit{addto }P\lit{ doublepath }p\lit{ withpen }q\cr + \lit{fill }c& \lit{addto }P\lit{ contour }c\cr + \lit{filldraw }c& \lit{addto }P\lit{ contour }c\lit{ withpen }q\cr + \lit{undraw }p& \lit{addto }P\lit{ doublepath }p\lit{ withpen }q + \lit{ withcolor }b\cr + \lit{unfill }c& \lit{addto }P\lit{ contour }c\lit{ withcolor }b\cr + \lit{unfilldraw }c& \lit{addto }P\lit{ contour }c\lit{ withpen }q + \lit{ withcolor }b\cr} +$$ +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 \lit{draw} +and \lit{undraw} when the argument is a picture~$r$: +$$ \tabskip=0.0pt plus 1000.0pt minus 1000.0pt + \halign to\hsize{$#$\hfil&\quad means\quad $#$\hfil\cr + \lit{draw }r& \lit{addto }P\lit{ also }r\cr + \lit{undraw }r& \lit{addto }P\lit{ also }r\lit{ withcolor }b\cr} +$$ + +The argument to \lit{unfill} in the last example is \lit{bbox lab}. +This is a call to a standard macro that gives the bounding box of a picture +as a rectangular path. The \lit{center} macro used two lines previously +makes \lit{z0} the center of the bounding box for path \lit{pp}. (This +works for paths and pictures). The expression +$$ \lit{thelabel(btex \$f>0\$ etex, z0)} $$ +computes a picture containing the text ``$f>0$'' centered on the point +\lit{z0}. + +Here is the complete syntax for labeling commands: +$$\tabskip=0.0pt plus 1000.0pt minus 1000.0pt + \halign to\hsize{$#$\hfil\cr + \descr{label command} \rightarrow + \descr{command name} \descr{position suffix} + (\descr{label text},\ \descr{label loc}) \cr + \qquad {}\mid \lit{labels} \descr{position suffix} (\descr{suffix list}) \cr + \descr{command name} \rightarrow \lit{label} + \mid \lit{thelabel} \mid \lit{makelabel} \cr + \descr{position suffix} \rightarrow + \descr{empty} \mid \lit{.lft} \mid \lit{.rt} \mid \lit{.top} + \mid \lit{.bot} \cr + \qquad {}\mid \lit{.ulft} \mid \lit{.urt} \mid \lit{.llft} + \mid \lit{.lrt}\cr + \descr{label text} \rightarrow \descr{picture expression} + \mid \descr{string expression} \cr + \descr{label loc} \rightarrow \descr{pair expression} \cr + \descr{suffix list} \rightarrow \descr{suffix} + \mid \descr{suffix}, \descr{suffix list} \cr} +$$ +The \lit{label} command adds text to \lit{currentpicture} near the +position $\descr{label loc}$ as determined by the $\descr{position suffix}$. +An empty suffix centers the label and the other options offset it slightly so +that it does not overlap the $\descr{label loc}$. Using \lit{thelabel} just +creates a picture expression rather than actually adding it to +\lit{currentpicture}. Using \lit{makelabel} instead of \lit{label} adds a dot +at the location being labeled. Finally, the \lit{labels} +command does +$$ \lit{makelabel} \descr{position suffix} + (\lit{str}\,\descr{suffix},\,\lit{z}\descr{suffix}) +$$ +for each $\descr{suffix}$ in the $\descr{suffix list}$, using the \lit{str} +operator to convert the suffix to a string. Thus \lit{labels.top(1,2a)} places +labels ``\lit{1}'' and ``\lit{2a}'' just above \lit{z1} and \lit{z2a}. + +The examples given so far have all used $\descr{label text}$ of the form +$$ \lit{btex}\ \descr{\TeX\ commands}\ \lit{etex}. +$$ +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 \lit{defaultfont} at \lit{defaultscale} times its design size. +Normally, +$$ \lit{defaultfont="cmr10"} + \quad{\rm and}\quad \lit{defaultscale=1}, +$$ +but these can be reset if desired. Using \lit{cmtex10} instead of +\lit{cmr10} would allow the label to contain spaces and special characters. +If there is any doubt about what the design size is, use the \lit{fontsize} +operator to find it as follows: +$$ \lit{defaultfont:="Times";} + \qquad \lit{defaultscale:=10/fontsize "Times"} +$$ + +Notice that a $\descr{with clause}$ can be +``\lit{dashed} $\descr{picture expression}$.'' The picture +gives a template that tells how the line being drawn is to be dashed. There +is a standard template called \lit{evenly} 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 +$$ \lit{draw z1..z2 dashed evenly scaled 2} $$ +draws a line with dashes $6bp$ long with gaps of $6bp$. + +The following MetaPost input illustrates the use of dashed +lines:\vadjust{\okbreak} +$$ \startverbatim +beginfig(3); +3.2scf = 2.4in; +path fun; +# = .1; +fun = ((0,-1#)..(1,.5#){right}..(1.9,.2#){right} + ..{curl .1}(3.2,2#)) scaled scf yscaled(1/#); +vardef vertline primary x = (x,-infinity)..(x,infinity) enddef; +primarydef f atx x = (f intersectionpoint vertline x) enddef; +primarydef f whenx x = xpart(f intersectiontimes vertline x) + enddef; +z1a = (2.5scf,0); +z1 = fun atx x1a; +y2a=0; z1-z2a=whatever*direction fun whenx x1 of fun; +z2 = fun atx x2a; +y3a=0; z2-z3a=whatever*direction fun whenx x2 of fun; +draw fun withpen pencircle scaled 1pt; +drawarrow (0,0)..(3.2scf,0); +label.bot(btex $x_1$ etex, z1a); +draw z1a..z1 dashed evenly; +makelabel(nullpicture, z1); +draw z1..z2a withpen pencircle scaled .3; +label.bot(btex $x_2$ etex, z2a); +draw z2a..z2 dashed evenly; +makelabel(nullpicture, z2); +draw z2..z3a withpen pencircle scaled .3; +label.bot(btex $x_3$ etex, z3a); +endfig; +%stopverbatim$$ +This produces the following figure:\vadjust{\okbreak} +$$ \epsfbox{examples.3} $$ + +The above figure uses some of the more advanced properties of paths discussed +in Chapter~14 of {\sl The \MF book}. All of this material applies to +MetaPost as well as \MF\ 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 \lit{direction}, +\lit{intersectiontimes}, and \lit{intersectionpoint} operators. +In order to ensure that the path \lit{fun} makes $y$ a unique function +of~$x$, the path is first constructed with the $y$-coordinates compressed +by a factor of ten. The final ``\lit{yscaled(1/\char`\#)}'' restores +the original aspect ratio after MetaPost has chosen a cubic spline that +interpolates the given points. + +The \lit{yscaled} 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 +{\it currenttransform} and there is no restriction on the type of +transformations that can be applied to pictures. + +\section{More Advanced Topics} +\label{advanced} +MetaPost does have pens like those in \MF\ 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 +{\sl The \MF 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 \lit{cutoff} and +\lit{cutdraw} because the same effect can be achieved by setting the +internal parameter \lit{linecap:=butt}.\vadjust{\okbreak} +$$\startverbatim +beginfig(4); +for i=0 upto 2: + z[i]=(0,40i); z[i+3]-z[i]=(100,30); +endfor +pickup pencircle scaled 18; +def gray = withcolor .8white enddef; +draw z0..z3 gray; +linecap:=butt; draw z1..z4 gray; +linecap:=squared; draw z2..z5 gray; +labels.top(0,1,2,3,4,5); +endfig; linecap:=rounded; +%stopverbatim +\qquad +\vcenter{\epsfbox{examples.4}} +$$ + +There is also a \lit{linejoin} parameter as illustrated below. +The default values of \lit{linecap} and \lit{linejoin} are both +\lit{rounded}.\vadjust{\okbreak} +$$ \startverbatim +beginfig(5); +for i=0 upto 2: + z[i]=(0,50i); z[i+3]-z[i]=(60,40); + z[i+6]-z[i]=(120,0); +endfor +pickup pencircle scaled 24; +def gray = withcolor .8white enddef; +draw z0--z3--z6 gray; +linejoin:=mitered; draw z1..z4--z7 gray; +linejoin:=beveled; draw z2..z5--z8 gray; +labels.bot(0,1,2,3,4,5,6,7,8); +endfig; linejoin:=rounded; +%stopverbatim +\qquad +\vcenter{\epsfbox{examples.5}} +\mskip-54mu % allow it to hang into the margin +$$ + +Another way to adjust the behavior of drawing commands is by giving the +declaration +$$ \lit{drawoptions}(\descr{with list}) $$ +For instance, +$$ \lit{drawoptions(withcolor blue)} $$ +gives subsequent drawing commands the default color blue. This can still +be overridden by giving another \lit{withcolor} clause as in +$$ \lit{draw p withcolor red} $$ +The options apply only to relevant drawing commands: +$$ \lit{drawoptions(dashed dd)} $$ +will affect \lit{draw} commands but not fill commands. + +Chapters 17--20 of {\sl The \MF 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 \MF\ 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 \lit{beginfig} +and \lit{endfig} play the role of \MF's \lit{beginchar} and \lit{endchar}. +Look in the file \lit{plain.mp} 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 \lit{interim} statement makes temporary changes +to internal quantities. This works the same way in MetaPost except that +the example involving {\it autorounding} is inappropriate because MetaPost +doesn't have that particular quantity. Here is a complete list of the +internal quantities found in \MF\ but not MetaPost: +$$\vcenter{\hsize=.8\hsize \raggedright \multiply\rightskip by3 \textt\noindent + \lit{autorounding}, \lit{fillin}, \lit{granularity}, \lit{hppp}, + \lit{proofing}, \lit{smoothing}, \lit{tracingedges}, + \lit{tracingpens}, \lit{turningcheck}, \lit{vppp}, \lit{xoffset}, + \lit{yoffset}} +$$ +The following additional quantities are defined in plain \MF\ but not in +plain MetaPost: +$$\vcenter{\hsize=.8\hsize \raggedright \multiply\rightskip by3 \textt\noindent + \lit{pixels\_per\_inch}, \lit{blacker}, \lit{o\_correction}, + \lit{displaying}, \lit{screen\_rows}, \lit{screen\_cols}, + \lit{currentwindow}} +$$ + +There are also some internal quantities that are unique to MetaPost. +The \lit{linecap} and \lit{linejoin} parameters have already been mentioned. +There is also a \lit{miterlimit} parameter that behaves like the similarly +named parameter in PostScript. Another parameter, \lit{tracing\_lost\_chars} +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 \lit{btex} $\ldots$ \lit{etex} +blocks are not likely to use missing characters. + +The \lit{prologues} parameter was referred to earlier when we recommended +setting it to one when including MetaPost output in a {\it 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 \lit{cmr10}. 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 \lit{bboxmargin}, \lit{labeloffset} and \lit{ahangle} +as well as \lit{defaultscale} which controls the size of the default label +font as explained above. The \lit{bboxmargin} parameter is the amount of +extra space that the \lit{bbox} operator leaves; \lit{labeloffset} gives the +distance by which labels are offset from the point being labeled; +\lit{ahangle} is the angle of the pointed ends of arrowheads +($45^\circ$ by default). There is also a path \lit{ahcirc} that controls +the size of the arrowheads. The statement +$$ \lit{ahcirc := fullcircle scaled d} $$ +changes the arrowhead length to $\lit{d}/2$. + +The only relevant new material in {\sl The \MF 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 \lit{redpart}, \lit{bluepart}, and \lit{greenpart} operators for +colors and there is no \lit{totalweight} operator. The new primitive for +label text in pictures is +$$ \descr{picture secondary} \rightarrow + \descr{picture secondary} \lit{ infont } \descr{string primary} +$$ +Bounding box information can be obtained via the operators +\begin{eqnarray*} + \descr{pair primary} &\rightarrow& \descr{corner selector} + \descr{picture primary}\\ + \descr{corner selector} &\rightarrow& \lit{llcorner} \mid \lit{urcorner} + \mid \lit{lrcorner} \mid \lit{urcorner} +\end{eqnarray*} +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 +$$ \lit{special }\descr{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 \lit{Times-Roman}. +$$ \startverbatim +special "/Times-Roman /Times-Roman def"; +special "/fshow {exch findfont exch scalefont setfont show}"; +special " bind def"; +%stopverbatim +$$ +A similar definition is generated automatically when you set \lit{prologues:=1}. +With \lit{prologues=0}, it is assumed that the program that translates \TeX\ +output and includes PostScript figures will add the necessary definition.% +\footnote{A full description of how to avoid including your +output in a \TeX\ document is beyond the scope of this documentation. +MetaPost output generated with \lit{prologues:=1} can be sent directly to a +PostScript printer if it uses only built-in fonts like \lit{Helvetica}.} + +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 \lit{evenly} 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~\lit{dd}: +$$\startverbatim +draw (1,0)..(3.0); draw (5,0)..(6,0); +picture dd; dd=currentpicture; clearit; +%stopverbatim +$$ +Lining up an infinite number of copies of \lit{dd} produces a set of line +segments +$$ \{\,(5i,0)\ldots(5i+3,0) \mid \hbox{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 \lit{dd} are offset by $5bp$ because +the range of $x$ coordinates covered by the line segments in \lit{dd} is +$6-1$ or $5bp$. The offset can be increased by shifting the dash pattern +vertically so that it lies at a $y$-coordinate 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. + +\bigbreak +\centerline{\bf Making Boxes} +\nobreak\medskip +There are auxiliary macros not included in plain MetaPost that make it +convenient to do things that {\it pic} is good at. What follows +is a description of how to use the macros contained in the file \lit{boxes.mp}. +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 +$$ \lit{boxit} \descr{suffix}(\descr{picture expression}) $$ +in order to create pair variables $\descr{suffix}\lit{.c}$, +$\descr{suffix}\lit{.n}$, $\descr{suffix}\lit{.e}$, etc. These can then be +used for positioning the picture before drawing it with a separate command such +as +$$ \lit{drawboxed}(\descr{suffix}) $$ +The command \lit{boxit.bb(pic)} makes \lit{bb.c} the position where the center +of picture \lit{pic} is to be placed and defines \lit{bb.sw}, \lit{bb.se}, +\lit{bb.ne}, and \lit{bb.nw} to be the corners of a rectangular path that will +surround the resulting picture. Variables \lit{bb.dx} and \lit{bb.dy} give +the spacing between the shifted version of \lit{pic} and the surrounding +rectangle and \lit{bb.off} is the amount by which \lit{pic} has to be shifted +to achieve all this. + +The \lit{boxit} macro gives linear equations that force \lit{bb.sw}, +\lit{bb.se}, $\ldots$ to be the corners of a rectangle aligned on the $x$ and +$y$ axes with the picture \lit{pic} centered inside. The values of \lit{bb.dx}, +\lit{bb.dy}, and \lit{bb.c} are left unspecified so that the user can give +equations for positioning the boxes. If no such equations are given, macros +such as \lit{drawbox} can detect this and give default values.\vadjust{\okbreak} +$$ \epsfbox{examples.6} $$ + +\okbreak + +The following example shows how this works in practice. +$$ \startverbatim +input boxes +beginfig(7); boxjoin(a.se=b.sw; a.ne=b.nw); +boxit.a(btex $\cdots$ etex); boxit.ni(btex $n_i$ etex); +boxit.di(btex $d_i$ etex); boxit.nii(btex $n_{i+1}$ etex); +boxit.dii(btex $d_{i+1}$ etex); boxit.aa(pic_.a); +boxit.nk(btex $n_k$ etex); boxit.dk(btex $d_k$ etex); +di.dy = 2; +drawboxed(a,ni,di,nii,dii,aa,nk,dk); label.lft("ndtable:", a.w); +boxjoin(a.sw=b.nw; a.se=b.ne); +interim defaultdy:=7; +boxit.ba(); boxit.bb(); boxit.bc(); +boxit.bd(btex $\vdots$ etex); boxit.be(); boxit.bf(); +bd.dx=8; ba.ne=a.sw-(15,10); +drawboxed(ba,bb,bc,bd,be,bf); label.lft("hashtab:",ba.w); +def ndblock suffix $ = + boxjoin(a.sw=b.nw; a.se=b.ne); + forsuffixes $$=$a,$b,$c: boxit$$(); ($$dx,$$dy)=(5.5,4); + endfor; enddef; +ndblock nda; ndblock ndb; ndblock ndc; +nda.a.c-bb.c = ndb.a.c-nda.c.c = (whatever,0); +xpart ndb.c.se = xpart ndc.a.ne = xpart di.c; +ndc.a.c - be.c = (whatever,0); +drawboxes(nda.a,nda.b,nda.c,ndb.a,ndb.b,ndb.c,ndc.a,ndc.b,ndc.c); +drawarrow bb.c .. nda.a.w; +drawarrow be.c .. ndc.a.w; +drawarrow nda.c.c .. ndb.a.w; +drawarrow nda.a.c{right}..{curl0}ni.c cutafter bpath ni; +drawarrow nda.b.c{right}..{curl0}di.c cutafter bpath di; +drawarrow ndc.a.c{right}..{curl0}nii.c cutafter bpath nii; +drawarrow ndc.b.c{right}..{curl0}dii.c cutafter bpath dii; +drawarrow ndb.a.c{right}..nk.c cutafter bpath nk; +drawarrow ndb.b.c{right}..dk.c cutafter bpath dk; +x.ptr=xpart aa.c; y.ptr=ypart ndc.a.ne; +drawarrow subpath (0,.7) of (z.ptr..{left}ndc.c.c); +label.rt(btex ndblock etex, z.ptr); endfig; +%stopverbatim +$$ +It is instructive to compare the MetaPost output below with the similar figure +in the {\it pic} manual \cite{ke:pic}.\vadjust{\okbreak} +$$ \epsfbox{examples.7} $$ + +The second line of input for the above figure contains +$$ \lit{boxjoin(a.se=b.sw; a.ne=b.nw)} $$ +This causes boxes to line up horizontally by giving additional equations that +are invoked each time some box \lit{a} is followed by some other box~\lit{b}. +These equations are first invoked on the next line when box~\lit{a} is followed +by box~\lit{ni}. This yields +$$ \lit{a.se=ni.sw; a.ne=ni.nw} $$ +The next pair of boxes is box~\lit{ni} and box~\lit{di}. This time the +implicitly generated equations are +$$ \lit{ni.se=di.sw; ni.ne=di.nw} $$ +This process continues until a new \lit{boxjoin} is given. In this case the +new declaration is +$$ \lit{boxjoin(a.sw=b.nw; a.se=b.ne)} $$ +which causes boxes to be stacked below each other. + +After calling \lit{boxit} for the first eight boxes \lit{a} through \lit{dk}, +the example gives the single equation $\lit{di.dy}=2$ followed by a call to +\lit{drawboxed} 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~\lit{di} (the label ``$d_i$''). Since this doesn't fully specify the +sizes and positions of the boxes, the \lit{drawboxed} macro starts by +selecting default values, setting \lit{a.dx} through \lit{dk.dx} equal to +the default value of $3bp$. + +The argument to boxit can be omitted as in \lit{boxit.ba()} +or \lit{boxit.bb()}. This is like calling \lit{boxit} 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 \lit{a.sw}, \lit{a.se}, $\ldots$, a command +like \lit{boxit.a} defines points \lit{a.w}, \lit{a.s}, \lit{a.e} and +\lit{a.n} at the midpoints of the outer rectangle. +If this bounding rectangle is needed for something other than just being drawn +by the \lit{drawboxed} macro, it can be referred to as \lit{bpath.a} or in +general +$$ \lit{bpath} \descr{box name} $$ + +The \lit{bpath} macro is used in the arguments to \lit{drawarrow} in the +previous example. For instance +$$ \lit{nda.a.c\char`\{right\char`\}..\char`\{curl0\char`\}ni.c} $$ +is a path from the center of box \lit{nda.a} to the center of box \lit{ni}. +Following this with ``\lit{cutafter} \lit{bpath.ni}'' 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 +\lit{circleit} in place of \lit{boxit}. Saying \lit{circleit.a(pic)} +defines points \lit{a.c}, \lit{a.s}, \lit{a.e}, \lit{a.n}, \lit{a.w} +and distances \lit{a.dx} and \lit{a.dy}. These variables describe how the +picture is centered in an oval as can be seen from the following +diagram:\vadjust{\okbreak} +$$ \epsfbox{examples.8} $$ + +\okbreak + +Here is the input for the figure that uses \lit{circleit}: +$$\startverbatim +beginfig(9); +vardef cuta(suffix a,b) expr p = + drawarrow p cutbefore bpath.a cutafter bpath.b; + point .5*length p of p +enddef; +vardef self@# expr p = + cuta(@#,@#) @#.c{curl0}..@#.c+p..{curl0}@#.c enddef; +verbatimtex + \def\stk#1#2{$\displaystyle{\matrix{#1\cr#2\cr}}$} etex +circleit.aa("Start"); aa.dx=aa.dy; +circleit.bb(btex \stk B{(a|b)^*a} etex); +circleit.cc(btex \stk C{b^*} etex); +circleit.dd(btex \stk D{(a|b)^*ab} etex); +circleit.ee("Stop"); ee.dx=ee.dy; +numeric hsep; +bb.c-aa.c = dd.c-bb.c = ee.c-dd.c = (hsep,0); +cc.c-bb.c = (0,.8hsep); +xpart(ee.e - aa.w) = 3.8in; +drawboxed(aa,bb,cc,dd,ee); +label.ulft(btex$b$etex, cuta(aa,cc) aa.c{dir50}..cc.c); +label.top(btex$b$etex, self.cc(0,30pt)); +label.rt(btex$a$etex, cuta(cc,bb) cc.c..bb.c); +label.top(btex$a$etex, cuta(aa,bb) aa.c..bb.c); +label.llft(btex$a$etex, self.bb(-20pt,-35pt)); +label.top(btex$b$etex, cuta(bb,dd) bb.c..dd.c); +label.top(btex$b$etex, cuta(dd,ee) dd.c..ee.c); +label.lrt(btex$a$etex, cuta(dd,bb) dd.c..{dir140}bb.c); +label.bot(btex$a$etex, + cuta(ee,bb) ee.c..tension1.3 ..{dir115}bb.c); +label.urt(btex$b$etex, + cuta(ee,cc) ee.c{(cc.c-ee.c)rotated-15}..cc.c); +endfig; +%stopverbatim +$$ +The ``boxes'' produced when using \lit{circleit} come out circular unless +something forces a different aspect ratio.\vadjust{\okbreak} +$$ \epsfbox{examples.9} $$ + +In the above figure, the equations \lit{aa.dx=aa.dy} and \lit{ee.dx=ee.dy} after +$$ \lit{circleit.aa("Start")} + \quad{\rm and}\quad \lit{circleit.ee("Stop")} +$$ +make the start and stop nodes non-circular. + +The general rule is that $\lit{bpath.}c$ comes out circular if +$c\lit{.dx}$, $c\lit{.dy}$, and $c\lit{.dx}-c\lit{.dy}$ 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 +\lit{circmargin}). + +There is also a \lit{pic} macro that makes $\lit{pic.}c$ the picture that +goes inside $\lit{bpath.}c$ In addition to the \lit{drawboxed} macro +that draws the picture and the surrounding rectangle or oval, there are +\lit{drawunboxed} and \lit{drawboxes} macros that draw the pictures and +the surrounding paths separately. + +\section{Implementation} +\label{impsec} + +The MetaPost interpreter is written in Knuth's {\tt WEB} language which +can be thought of as PASCAL with macros. This choice allows the +sharing of code with the \MF\ interpreter.~\cite{kn:d} Indeed, about +three fourths of the code in the main source file {\tt mp.web} is copied +from this source by permission from the author. + +In accordance with the standard methodology for {\tt WEB} programs, +parts of the program that are specific to the UNIX\footnote{UNIX is a +registered trademark of UNIX System Laboratories.} system are given in a +separate file {\tt mp.ch} that +the {\tt tangle} processor merges with {\tt 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 {\tt mpext.c} and a small include file +{\tt mp.h} to tie it all together. + +In addition to the main interpreter, there are some programs that control +the translation of typesetting commands in \lit{btex} $\ldots$ \lit{etex} +blocks. When the interpreter encounters \lit{btex} in some input file +\lit{foo.mp}, it needs to start reading from an auxiliary file \lit{foo.mpx}. +This file should contain translations of the \lit{btex} $\ldots$ \lit{etex} +blocks in \lit{foo.mp} into low-level MetaPost commands. If \lit{foo.mpx} 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 \lit{foo.mpx} from an input file +\lit{foo.mp} is a three step process: a C~program called \lit{mptotex} +strips out the \TeX\ commands; then \TeX\ produces a binary file that +gives low-level typesetting instructions; and finally, a {\tt WEB} program +\lit{dvitomp} writes equivalent MetaPost commands in the \lit{foo.mpx} +file. When using troff, C~programs \lit{mptotr} and \lit{dmp} replace +\lit{mptotex} and \lit{dvitomp}. + + + +\bibliographystyle{plain} +\bibliography{mpintro} + + +\end{document} |