summaryrefslogtreecommitdiff
path: root/doc/context/sources/general/manuals/metafun/metafun-text.tex
diff options
context:
space:
mode:
Diffstat (limited to 'doc/context/sources/general/manuals/metafun/metafun-text.tex')
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-text.tex1784
1 files changed, 1784 insertions, 0 deletions
diff --git a/doc/context/sources/general/manuals/metafun/metafun-text.tex b/doc/context/sources/general/manuals/metafun/metafun-text.tex
new file mode 100644
index 000000000..f70f53ac3
--- /dev/null
+++ b/doc/context/sources/general/manuals/metafun/metafun-text.tex
@@ -0,0 +1,1784 @@
+% language=uk
+%
+% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa
+
+\startcomponent metafun-text
+
+\environment metafun-environment
+
+\startchapter[reference=sec:typesetting,title={Typesetting in \METAPOST}]
+
+\startintro
+
+It is said that a picture tells more than a thousand words. So you might expect
+that text in graphics becomes superfluous. Out of experience we can tell you that
+this is not the case. In this chapter we explore the ways to add text to
+\METAPOST\ graphics, and let you choose whether or not to have it typeset by
+\TEX.
+
+\stopintro
+
+\startsection[title={The process}]
+
+\index{text}
+
+You can let \METAPOST\ process text that is typeset by \TEX. Such text is first
+embedded in the \METAPOST\ file in the following way:
+
+\starttyping
+btex Some text to be typeset by \TEX etex
+\stoptyping
+
+This returns a picture, but only after \METAPOST\ has made sure that \TEX\ has
+converted it into something useful. This process of conversion is slightly system
+dependent and even a bit obscure. Traditional \METAPOST\ calls a program that
+filters the \type {btex}|\unknown|\type {etex} commands, next it calls \TEX\ by
+passing the output routine, in order to make sure that each piece of text ends up
+on its own page, and afterwards it again calls a program that converts the \DVI\
+pages into \METAPOST\ pictures. In \LUATEX's \MPLIB\ a different route is
+followed.
+
+In \CONTEXT\ \MKII, when using \WEBC, you can generate the graphics at run||time.
+This takes more time than processing the graphics afterwards, but has the
+advantage that \TEX\ knows immediately what graphic it is dealing with. When
+enabled, \CONTEXT\ will call either \METAPOST, or, when the graphic contains
+\type {btex}||\type {etex} commands, call \TEXEXEC, which in turn makes sure that
+the right auxiliary programs are executed.
+
+In \CONTEXT\ \MKIV\ you won't notice this at all because everything is tightly
+integrated with \LUATEX's \MPLIB. This has an enormous speed gain: when this
+manual had about 425 pages, on my laptop with mobile 3840QM processor, one run of
+this document takes 18 seconds (14.5 with \LUAJITTEX) and that includes loadint a
+bunch of (outline) fonts and processing some 2200 \METAPOST\ images. While
+writing the first version of this manual runtime was upto 50 times slower for
+half the number of pages so compared to \MKII\ we have gained a lot.
+
+\startFLOWchart[metatex]
+ \startFLOWcell
+ \name {script 1}
+ \location {1,1}
+ \shape {action}
+ \text {\type{context}}
+ \connection [rl] {context 1}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {context 1}
+ \location {2,1}
+ \shape {action}
+ \text {\CONTEXT}
+ \connection [bt] {metapost 1}
+ \connection [rl] {script 2}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {metapost 1}
+ \location {2,2}
+ \shape {action}
+ \text {\METAPOST}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {script 2}
+ \location {3,1}
+ \shape {action}
+ \text {\type{context}}
+ \connection [rl] {context 2}
+ \connection [bt] {metapost 2}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {context 2}
+ \location {4,1}
+ \shape {action}
+ \text {\CONTEXT}
+ \stopFLOWcell
+ \startFLOWcell
+ \name {metapost 2}
+ \location {3,2}
+ \shape {action}
+ \text {\METAPOST}
+ \stopFLOWcell
+\stopFLOWchart
+
+\startplacefigure[title={How \TEX\ and \METAPOST\ work together.}]
+ \FLOWchart[metatex]
+\stopplacefigure
+
+\stopsection
+
+\startsection[title={Environments}]
+
+\index{environments}
+
+In case you want to pass code that is shared by all \type {btex}||\type {etex}
+pictures, \METAPOST\ provides:
+
+\starttyping
+verbatimtex \DefineSomeCommands etex ;
+\stoptyping
+
+However, in \CONTEXT\ one has a better mechanism available. In \CONTEXT\ \MKII\
+the advised method is passing environments. The best way to pass them is the
+following. As an example we switch to the 15 basic \POSTSCRIPT\ fonts.
+
+\startbuffer[pos]
+\startMPenvironment
+ \usetypescript[palatino][texnansi] % mkii has encodings
+ \setupbodyfont[palatino]
+\stopMPenvironment
+\stopbuffer
+
+\typebuffer[pos]
+
+This means that in code like the following, a Palatino font will be used.
+
+\starttyping
+\startMPcode
+draw btex Meta is a female lion! etex
+ xysized (\the\textwidth,\the\textheight) ;
+\stopMPcode
+\stoptyping
+
+However, in \CONTEXT\ \MKIV\ this method is no longer recomended as all
+processing happens in the same run anyway.
+
+% beware: extensive scaling can make acrobat crash and okular drop the !
+
+\startbuffer[lioncode]
+\startMPcode
+numeric w, h ; w := \the\textwidth ; h := w/2 ;
+
+picture p ; p := btex \colored[r=.375,g=.375]{Meta is a female lion!} etex
+ xysized (w,h) ;
+picture q ; q := btex \colored[r=.625] {Meta is a female lion!} etex
+ xysized (w,h) ;
+
+path b ; b := boundingbox p ; draw p ;
+
+for i=(.28w,.90h),(.85w,.90h),(w,.05h) :
+ picture r ; r := q ;
+ path s ; s := (fullsquare xscaled .05w yscaled .4h) shifted i ;
+ clip r to s ; draw r ; % draw s ;
+endfor ;
+
+setbounds currentpicture to b ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[lioncode]
+
+\in {Figure} [lionclip] shows the previous sentence in a slightly different look.
+You may consider coloring the dots to be an exercise in clipping.
+
+\getbuffer[pos]
+
+\placefigure
+ [here][lionclip]
+ {An example of clipping.}
+ {\getbuffer[lioncode]}
+
+\resetMPenvironment
+
+An environment can be reset with \typ {\resetMPenvironment} or by passing \type
+{reset} to \typ {\startMPenvironment}.
+
+\starttyping
+\startMPenvironment[reset]
+ \usetypescript[postscript][texnansi] % mkii
+ \setupbodyfont[postscript]
+\stopMPenvironment
+\stoptyping
+
+So, to summarize: if you're using \CONTEXT\ \MKIV\ you might as well forgot what
+you just read.
+
+\stopsection
+
+\startsection[title={Labels}]
+
+\index{labels}
+
+In \METAPOST\ you can use the \type {label} macro to position text at certain
+points.
+
+\starttyping
+label("x", origin) ;
+\stoptyping
+
+The font and scale are determined by two variables, \type {defaultfont} and \type
+{defaultscale}, the former expecting the name of a font in the form of a string,
+the latter expecting a numeric to be used in the scaling of the font. Should you
+choose not to set these yourself, they default to \type {"Mono"} and \type
+{1.0}, respectively. However, you can change the defaults as follows:
+
+\starttyping
+defaultfont := "texgyrepagella-regular*default" ;
+defaultscale := 1.2 ;
+\stoptyping
+
+These settings selects Pagella at about 12pt. You can also set these variables
+to \CONTEXT\ related values. For \CONTEXT\ graphics they are set to:
+
+\starttyping
+defaultfont := "\truefontname{Regular}*default" ;
+defaultscale := \the\bodyfontsize/10 ;
+\stoptyping
+
+This means that they will adapt themselves to the current body font (in this
+document we get \truefontname{Regular}) and the current size of the bodyfont
+(here \the\bodyfontsize/10).
+
+\stopsection
+
+\startsection[title={\TeX\ text}]
+
+\index{text}
+
+In the next example we will use a special mechanism for building graphics step by
+step. The advantage of this method is that we can do intermediate calculations in
+\TEX. Our objective is to write a macro that draws text along a circular path.
+While doing so we want to achieve the following:
+
+\startitemize[packed]
+\item the text should be properly kerned, i.e.\ the
+ spacing between characters should be optimal,
+\item the position on the circle should vary, and
+\item the radius of the circle should vary.
+\stopitemize
+
+This implementation is not the most straightforward one, but by doing it step by
+step, at least we see what is involved. Later, we will see a better method. If
+you run these examples yourself, you must make sure that the \TEX\ environment of
+your document matches the one used by \METAPOST.
+
+We let the bodyfont match the font used in this document, and define \type
+{RotFont} to be the regular typeface, the one you are reading right now, but
+bold.
+
+\startbuffer
+\definefont[RotFont][RegularBold*default]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Since \METAPOST\ is unaware of kerning, we have to use \TEX\ to keep track of the
+positions. We will split the text into tokens (often characters) and store the
+result in an array of pictures (\type {pic}). We will also store the accumulated
+width in an array (\type {len}). The number of characters is stored in~\type {n}.
+In a few paragraphs we will see why the other arrays are needed.
+
+While defining the graphic, we need \TEX\ to do some calculations. Therefore, we
+will use \type {\startMPdrawing} to stepwise construct the definition. The basic
+pattern we will follow is:
+
+\starttyping
+\resetMPdrawing
+\startMPdrawing
+ metapost code
+\stopMPdrawing
+tex code
+\startMPdrawing
+ metapost code
+\stopMPdrawing
+\MPdrawingdonetrue
+\getMPdrawing
+\stoptyping
+
+In the process, we will use a few variables. We will store the individual
+characters of the text in the variable \type {pic}, its width in \type {wid} and
+the length of the string so far in \type {len}. Later we will use the \type {pos}
+array to store the position where a character ends up. The variable \type {n}
+holds the number of tokens.
+
+\startbuffer[init]
+\resetMPdrawing
+\startMPdrawing
+ picture pic[] ;
+ numeric wid[], len[], pos[], n ;
+ wid[0] := len[0] := pos[0] := n := 0 ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[init]
+
+We also started fresh by resetting the drawing. From now on, each start command
+will add some more to this graphic. The next macro is responsible for collecting
+the data. Each element is passed on to \TEX, using the \type {btex} construct.
+So, \METAPOST\ itself will call \TEX !
+
+\startbuffer[toks]
+\def\whatever#1%
+ {\appendtoks#1\to\MPtoks
+ \setbox\MPbox=\hbox{\bfd\the\MPtoks}%
+ \startMPdrawing
+ n := n + 1 ; len[n] := \the\wd\MPbox ;
+ \stopMPdrawing
+ \startMPdrawing[-]
+ pic[n] := textext("\bfd\setstrut\strut#1") ;
+ pic[n] := pic[n] shifted - llcorner pic[n] ;
+ \stopMPdrawing}
+
+\handletokens MetaPost is Fun!\with\whatever
+\stopbuffer
+
+\typebuffer[toks]
+
+We use the low level \CONTEXT\ macro \type {\appendtoks} to extend the token list
+\type {\MPtoks}. The \type {\handletokens} macro passes each token (character) of
+\typ {MetaPost is Fun!} to the macro \type {\whatever}. The tokens are appended
+to the token register \type {\MPtoks} (already defined). Then we typeset the
+content of \type {\MPtoks} in \type {\MPbox} (also already defined). The width of
+the box is passed to \METAPOST\ and stored in \type {len}.
+
+By default the content of the drawing is expanded, which means that the macro is
+replaced by its current meaning, so the current width ends up in the \METAPOST\
+file. The next part of the drawing, starting with \type {btex}, puts the token in
+a picture. This time we don't expand the drawing, since we want to pass font
+information. Here, the \type {[-]} suppresses expansion of \typ {btex \bfd #1
+etex}. The process is iterated by \type {\handletokens} for each character of the
+text \typ {MetaPost is Fun!}.
+
+Before we typeset the text, now available in pieces in \type {pic}, in a circle,
+we will first demonstrate what they look like. You may like to take a look at the
+file \type {mpgraph.mp} to see what is passed to \METAPOST.
+
+\startbuffer[test]
+\startMPdrawing
+ pair len ; len := origin ;
+ for i=1 upto n :
+ draw pic[i] shifted len ;
+ draw boundingbox pic[i] shifted len
+ withpen pencircle scaled .25pt withcolor red ;
+ len := len+(xpart urcorner pic[i]-xpart llcorner pic[i],0) ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[test]
+
+\startbuffer[show]
+\MPdrawingdonetrue\getMPdrawing
+\stopbuffer
+
+We can call up this drawing with \type {\getMPdrawing}, but first we inform the
+compiler that our \METAPOST\ drawing is completed.
+
+\typebuffer[show]
+
+This results in:
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,test,show]
+\stoplinecorrection
+
+Compare this text with the text as typeset by \TEX:
+
+\blank \start \bfd MetaPost is Fun!\par \stop \blank
+
+and you will see that the text produced by \METAPOST\ is not properly kerned.
+When putting characters after each other, \TEX\ uses the information available in
+the font, to optimize the spacing between characters, while \METAPOST\ looks at
+characters as separate entities. But, since we have stored the optimal spacing in
+\type {len}, we can let \METAPOST\ do a better job. Let's first calculate the
+correction needed.
+
+\startbuffer[kern]
+\startMPdrawing
+ for i=1 upto n :
+ wid[i] := abs(xpart urcorner pic[i] - xpart llcorner pic[i]) ;
+ pos[i] := len[i]-wid[i] ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[kern]
+
+This compares well to the text as typeset by \TEX:
+
+\blank \start \bfd MetaPost is Fun!\par \stop \blank
+
+We can now use the values in \type {pos} to position the pictures according to
+what \TEX\ considered to be the best (relative) position.
+
+\startbuffer[test]
+\startMPdrawing
+ for i=1 upto n :
+ draw pic[i] shifted (pos[i],0) ;
+ draw boundingbox pic[i] shifted (pos[i],0)
+ withpen pencircle scaled .25pt withcolor red ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[test]
+
+That this correction is adequate, is demonstrated in the next graphic. If you
+look closely, you will see that for instance the \quote {o} is moved to the left,
+under the capital \quote {P}.
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,kern,test,show]
+\stoplinecorrection
+
+When we want to position the pictures along a circle, we need to apply some
+rotations, especially because we want to go clockwise. Since we don't want to use
+\quote {complicated} math or more advanced \METAPOST\ code yet, we will do it in
+steps.
+
+\startbuffer[swap]
+\startMPdrawing
+ for i=1 upto n:
+ pic[i] := pic[i] rotatedaround(origin,-270) ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[swap]
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,kern,swap,test,show]
+\stoplinecorrection
+
+\startbuffer[cent]
+\startMPdrawing
+ for i=1 upto n :
+ pic[i] := pic[i]
+ shifted (0,ypart -.5[ulcorner pic[i],llcorner pic[i]]) ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+We will now center the pictures around the baseline. Centering comes down to
+shifting over half the height of the picture. This can be expressed by:
+
+\starttyping
+ypart -.5[ulcorner pic[i],llcorner pic[i]]
+\stoptyping
+
+but different ways of calculating the distance are possible
+too.
+
+\typebuffer[cent]
+
+So, now we have:
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,kern,swap,cent,test,show]
+\stoplinecorrection
+
+When we typeset on a (half) circle, we should map the actual length onto a
+partial circle. We denote the radius with an~\type {r} and shift the pictures to
+the left.
+
+\startbuffer[shif]
+\startMPdrawing
+ numeric r ; r := len[n]/pi ;
+ for i=1 upto n :
+ pic[i] := pic[i] shifted (-r,0) ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[shif]
+
+You can now use the following code to test the current state of the pictures. Of
+course this code should not end up in the final definitions.
+
+\startbuffer[test]
+\startMPdrawing
+ draw origin
+ withpen pencircle scaled 5pt withcolor red ;
+ for i=1 upto n :
+ draw pic[i] ;
+ draw boundingbox pic[i]
+ withpen pencircle scaled .25pt withcolor red ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[test]
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,kern,swap,cent,shif,test,show]
+\stoplinecorrection
+
+Later we will write a compact, efficient macro to take care of rotation. However,
+for the moment, so as not to overwhelm you with complicated code, we will rotate
+each individual picture with the following code fragment.
+
+\startbuffer[rots]
+\startMPdrawing
+ numeric delta, extra, radius, rot[] ;
+
+ delta := extra := radius := 0 ;
+
+ for i=1 upto n :
+ rot[i] := extra+delta-((pos[i]+.5wid[i])/len[n])*(180+2delta) ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[rots]
+
+Here we introduce a few variables that we can use later to tune the result a bit.
+With \type {delta}, the space between the characters can be increased, while
+\type {extra} rotates the whole string around the origin. The \type {radius}
+variable can be used to increase the distance to the origin. Without these
+variables, the assignment would have been:
+
+\starttyping
+rot[i] := ((pos[i]+.5wid[i])/len[n])*180 ;
+\stoptyping
+
+Placing the pictures is now rather easy:
+
+\startbuffer[done]
+\startMPdrawing
+ for i=1 upto n :
+ draw pic[i] shifted (-radius,0) rotatedaround(origin,rot[i]) ;
+ endfor ;
+\stopMPdrawing
+\stopbuffer
+
+\typebuffer[done]
+
+The pictures are now positioned on half a circle, properly kerned.
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,kern,swap,cent,shif,rots,done,show]
+\stoplinecorrection
+
+A bit more insight is given in the next picture:
+
+\startbuffer[test]
+\startMPdrawing
+ def moved(expr i) =
+ shifted (-radius,0) rotatedaround(origin,rot[i])
+ enddef ;
+ pickup pencircle scaled .5pt ;
+ for i=1 upto n :
+ draw pic[i] moved(i) ;
+ draw boundingbox pic[i] moved(i) withcolor red ;
+ draw origin -- center pic[i] moved(i) withcolor green ;
+ endfor ;
+ draw tcircle scaled 2r withcolor blue ;
+\stopMPdrawing
+\stopbuffer
+
+\startlinecorrection[blank]
+\getbuffer[init,toks,kern,swap,cent,shif,rots,test,show]
+\stoplinecorrection
+
+This was defined as follows. The path variable \type {tcycle} is predefined to
+the top half of a fullcircle.
+
+\typebuffer[test]
+
+We will now package all of this into a nice, efficient macro, using, of course,
+the predefined scratch registers \type {\MPtoks} and \type {\MPbox}. First we
+define the token processor. Note again the expansion inhibition switch \type
+{[-]}.
+
+\startbuffer
+\def\processrotationtoken#1%
+ {\appendtoks#1\to\MPtoks
+ \setbox\MPbox=\hbox{\RotFont\the\MPtoks}%
+ \startMPdrawing
+ n := n + 1 ; len[n] := \the\wd\MPbox ;
+ \stopMPdrawing
+ \startMPdrawing[-]
+ pic[n] := textext("\RotFont\setstrut\strut#1") ;
+ pic[n] := pic[n] shifted - llcorner pic[n] ;
+ \stopMPdrawing}
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+The main macro is a bit more complicated but by using a few scratch numerics, we
+can keep it readable.
+
+\startbuffer
+\def\rotatetokens#1#2#3#4% delta extra radius tokens
+ {\vbox\bgroup
+ \MPtoks\emptytoks
+ \resetMPdrawing
+ \startMPdrawing
+ picture pic[] ;
+ numeric wid, len[], rot ;
+ numeric delta, extra, radius, n, r ;
+ len[0] := n := 0 ;
+ delta := #1 ; extra := #2 ; radius := #3 ;
+ \stopMPdrawing
+ \handletokens#4\with\processrotationtoken
+ \startMPdrawing
+ r := len[n]/pi ;
+ for i=1 upto n :
+ wid := abs(xpart lrcorner pic[i] -
+ xpart llcorner pic[i]) ;
+ rot := extra + delta -
+ ((len[i]-.5wid)/len[n]) * (180+2delta) ;
+ draw pic[i]
+ rotatedaround (origin,-270) shifted (-r-radius,
+ ypart -.5[ulcorner pic[i], llcorner pic[i]])
+ rotatedaround (origin,rot) ;
+ endfor ;
+ \stopMPdrawing
+ \MPdrawingdonetrue
+ \getMPdrawing
+ \resetMPdrawing
+ \egroup}
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+\startbuffer
+\startcombination[3*1]
+ {\rotatetokens {0} {0}{0}{Does it work ok?}} {A}
+ {\rotatetokens{20} {0}{0}{Does it work ok?}} {B}
+ {\rotatetokens{20}{30}{0}{Does it work ok?}} {C}
+\stopcombination
+\stopbuffer
+
+We can use this macro as follows:
+
+\typebuffer
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+The previous macro is not really an example of generalization, but we used it for
+demonstrating how to build graphics in a stepwise way. If you put the steps in
+buffers, you can even combine steps and replace them at will. This is how we made
+the previous step by step examples: We put each sub||graphic in a buffer and then
+called the ones we wanted.
+
+We now present a more general approach to typesetting along a given path. This
+method is not only more robust and general, it is also a more compact definition,
+especially if we omit the tracing and testing code. We use a familiar auxiliary
+definition. The \type {\setstrut} and \type {\strut} commands ensure that the
+lines have the proper depth and height.
+
+\startbuffer
+\def\processfollowingtoken#1%
+ {\appendtoks#1\to\MPtoks
+ \setbox\MPbox=\hbox{\RotFont\setstrut\strut\the\MPtoks}%
+ \startMPdrawing
+ n := n + 1 ; len[n] := \the\wd\MPbox ;
+ \stopMPdrawing
+ \startMPdrawing[-]
+ pic[n] := btex \RotFont\setstrut\strut#1 etex ;
+ pic[n] := pic[n] shifted -llcorner pic[n] ;
+ \stopMPdrawing}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+In \MKII\ the previous code is collected in the macro \type {\followtokens} but
+in \MKIV\ we use a different approach. There we use a mix of \TEX, \METAPOST, and
+\LUA\ to define that macro. The principles remain the same but the code is more
+robust.
+
+\input meta-imp-txt.mkiv % we need to force a reload \useMPlibrary[txt]
+
+So, how does this compare to earlier results? The original, full text as typeset
+by \TEX, looks like:
+
+\blank \start \RotFont We now follow some arbitrary path ... \stop \blank
+
+In the examples, the text is typeset along the path with:
+
+\startbuffer[toks]
+\followtokens{We now follow some arbitrary path ...}
+\stopbuffer
+
+\typebuffer[toks]
+
+\startlinecorrection[blank]
+\getbuffer[toks]
+\stoplinecorrection
+
+Since we did not set a path, a dummy path is used. We can provide a path by
+(re)defining the graphic \type {followtokens}.
+
+\startbuffer[trac]
+\startMPinclusions
+ boolean TraceRot ; TraceRot := true ;
+\stopMPinclusions
+\stopbuffer
+
+\startbuffer[draw]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := fullcircle ;
+\stopuseMPgraphic
+\stopbuffer
+
+\startbuffer
+\typebuffer[draw]
+\startlinecorrection[blank]
+\hbox
+ {\getbuffer[draw,toks]\hskip1cm
+ \getbuffer[trac,draw,toks]}
+\stoplinecorrection
+\stopbuffer
+
+\getbuffer
+
+\startbuffer[draw]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := reverse fullcircle ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer
+
+\startbuffer[draw]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := (-3cm,-1cm)--(0,1cm)--(3cm,-1cm) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer
+
+\startbuffer[draw]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := (-3cm,0)--(3cm,1cm) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer
+
+\startbuffer[draw]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := (-3cm,0)..(-1cm,1cm)..(3cm,0) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer
+
+\startbuffer[draw]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := (-3cm,0)..(-1cm,1cm)..(0cm,-2cm)..(3cm,0) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\getbuffer
+
+When turned on, tracing will produce bounding boxes as well as draw the path.
+Tracing can be turned on by saying:
+
+\typebuffer[trac]
+
+% let's turn it off now
+
+\startMPinclusions
+ boolean TraceRot ; TraceRot := false ;
+\stopMPinclusions
+
+The next example is dedicated to Giuseppe Bilotta who wants to handle multiple
+strings and uses a patched version of \type {\followtokens}. To avoid a
+complicated explanation, we will present an alternative here that uses overlays.
+This method also avoids complicated path definitions.
+
+\startbuffer
+\startoverlay
+ {\startuseMPgraphic{followtokens}
+ draw fullcircle scaled 5cm .
+ withpen pencircle scaled 1pt withcolor .625yellow ;
+ draw fullsquare scaled 5.25cm
+ withpen pencircle scaled 1pt withcolor .625red ;
+ drawoptions (withcolor .625red) ;
+ path RotPath ; RotPath := halfcircle scaled 5cm ;
+ setbounds currentpicture to boundingbox fullcircle scaled 5.25cm ;
+ \stopuseMPgraphic
+ \followtokens { Met{\`a} superiore }}
+ {\startuseMPgraphic{followtokens}
+ drawoptions (withcolor .625red) ;
+ path RotPath ; RotPath := halfcircle rotated 90 scaled 5cm ;
+ setbounds currentpicture to boundingbox fullcircle scaled 5.25cm ;
+ \stopuseMPgraphic
+ \followtokens { {$\star$} }}
+ {\startuseMPgraphic{followtokens}
+ drawoptions (withcolor .625red) ;
+ path RotPath ; RotPath := halfcircle rotated 180 scaled 5cm ;
+ setbounds currentpicture to boundingbox fullcircle scaled 5.25cm ;
+ \stopuseMPgraphic
+ \followtokens { Met{\`a} inferiore }}
+ {\startuseMPgraphic{followtokens}
+ drawoptions (withcolor .625red) ;
+ path RotPath ; RotPath := halfcircle rotated 270 scaled 5cm ;
+ setbounds currentpicture to boundingbox fullcircle scaled 5.25cm ;
+ \stopuseMPgraphic
+ \followtokens { {$\star$} }}
+\stopoverlay
+\stopbuffer
+
+\typebuffer
+
+In order to fool the overlay macro that each graphic has the same size, we force
+a bounding box.
+
+\startlinecorrection[blank]
+\getbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title={Talking to \TEX}]
+
+Sometimes, others may say oftentimes, we are in need for some fancy typesetting.
+If we want to typeset a paragraph of text in a non standard shape, like a circle,
+we have to fall back on \type {\parshape}. Unfortunately, \TEX\ is not that
+strong in providing the specifications of more complicated shapes, unless you are
+willing to do some complicated arithmetic \TEX. Given that \METAPOST\ knows how
+to deal with shapes, the question is: \quotation {Can \METAPOST\ be of help?}
+
+In the process of finding out how to deal with this, we first define a simple
+path. Because we are going to replace pieces of code, we will compose the graphic
+from components. First, we create the path.
+
+\startbuffer
+\startuseMPgraphic{text path}
+ path p ; p := ((0,1)..(-1,0)..(1,0)--cycle) scaled 65pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This shape is not that beautiful, but it has a few characteristics that will help
+us to identify bordercases.
+
+\startbuffer
+\startuseMPgraphic{text draw}
+ drawarrow p withpen pencircle scaled 1pt withcolor red ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Now we use \CONTEXT's \type {\includeMPgraphic} command to build our graphic from
+the previously defined components.
+
+\startbuffer
+\startuseMPgraphic{text}
+ \includeMPgraphic{text path}
+ \includeMPgraphic{text draw}
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+When called with \type {\useMPgraphic{text}}, we get:
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+For the moment we start the path at $(x=0,y>0)$, but later using more complicated
+macros, we will see that we can use arbitrary paths.
+
+We are going to split the path in two, and will use the points that make up the
+bounding box as calcutated by \METAPOST. The next graphic shows one of these
+points, the lower left corner, available as point \typ {llcorner p}.
+
+\startbuffer
+\startuseMPgraphic{text draw}
+ draw p withpen pencircle scaled 3pt withcolor red ;
+ draw boundingbox p withpen pencircle scaled 1pt ;
+ draw llcorner p withpen pencircle scaled 5pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+The five points that \METAPOST\ can report for each path or picture are:
+
+\starttabulate[|Tl|l|]
+\NC llcorner \NC lower left corner \NC \NR
+\NC lrcorner \NC lower right corner \NC \NR
+\NC urcorner \NC upper right corner \NC \NR
+\NC ulcorner \NC upper left corner \NC \NR
+\NC center \NC intersection of the diagonals \NC \NR
+\stoptabulate
+
+If we want to typeset text inside this circle, we need to know where a line
+starts and ends. Given that lines are horizontal and straight, we therefore need
+to calculate the intersection points of the lines and the path. As a first step,
+we calculate the top and bottom of the path and after that we split off the left
+and right path.
+
+\startbuffer
+\startuseMPgraphic{text split}
+ pair t, b ; path l, r ;
+
+ t := (ulcorner p -- urcorner p) intersectionpoint p ;
+ b := (llcorner p -- lrcorner p) intersectionpoint p ;
+
+ l := p cutbefore t ; l := l cutafter b ;
+ r := p cutbefore b ; r := r cutafter t ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The \type {intersectionpoint} macro returns the point where two paths cross. If
+the paths don't cross, an error is reported, when the paths cross more times,
+just one point is returned. The \type {cutafter} and \type {cutbefore} commands
+do as their names say and return a path.
+
+In the \type {text split} code fragment, \type {t} and \type {b} are the top
+points of the main path, while \type {l} and \type {r} become the left and right
+half of path \type {p}.
+
+We now draw the original path using a thick pen and both halves with a thinner
+pen on top of the original. The arrows show the direction.
+
+\startbuffer
+\startuseMPgraphic{text draw}
+ draw p withpen pencircle scaled 3pt withcolor red ;
+ drawarrow l withpen pencircle scaled 1pt withcolor green ;
+ drawarrow r withpen pencircle scaled 1pt withcolor blue ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We use \type {\includeMPgraphic} to assemble the components:
+
+\startbuffer
+\startuseMPgraphic{text}
+ \includeMPgraphic{text path}
+ \includeMPgraphic{text split}
+ \includeMPgraphic{text draw}
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This graphic is typeset with \type {\useMPgraphic{text}}:
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+Before we are going to use them, we define some variables that specify the text.
+We use a baseline distance of 8~points. The part of the line above the baseline
+is 7.2~points, while the (maximum) depth is 2.8~points. These ratios are the ones
+we use in \CONTEXT. Because we don't want the text to touch the circle so we
+define an offset too.
+
+\startbuffer
+\startuseMPgraphic{text vars}
+ baselineskip := 8pt ;
+ strutheight := (7.2/10) * baselineskip ;
+ strutdepth := (2.8/10) * baselineskip ;
+ offset := baselineskip/2 ;
+ topskip := strutheight ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We more or less achieve the offset by scaling the path. In doing so, we use the
+width and height, which we call \type {hsize} and \type {vsize}, thereby
+conforming to the \TEX\ naming scheme.
+
+First we calculate both dimensions from the bounding box of the path. Next we
+down scale the path to compensate for the offset. When done, we recalculate the
+dimensions.
+
+\startbuffer
+\startuseMPgraphic{text move}
+ pair t, b ; path q, l, r ;
+
+ hsize := xpart lrcorner p - xpart llcorner p ;
+ vsize := ypart urcorner p - ypart lrcorner p ;
+
+ q := p xscaled ((hsize-2offset)/hsize)
+ yscaled ((vsize-2offset)/vsize) ;
+
+ hsize := xpart lrcorner q - xpart llcorner q ;
+ vsize := ypart urcorner q - ypart lrcorner q ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startuseMPgraphic{text split}
+ t := (ulcorner q -- urcorner q) intersectionpoint q ;
+ b := (llcorner q -- lrcorner q) intersectionpoint q ;
+
+ l := q cutbefore t ; l := l cutafter b ;
+ r := q cutbefore b ; r := r cutafter t ;
+\stopuseMPgraphic
+\stopbuffer
+
+We adapt the \type {text split} code to use the reduced path
+instead of the original.
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startuseMPgraphic{text draw}
+ drawarrow p withpen pencircle scaled 1pt withcolor red ;
+ draw t withpen pencircle scaled 2pt ;
+ draw b withpen pencircle scaled 2pt ;
+ drawarrow l withpen pencircle scaled 1pt withcolor green ;
+ drawarrow r withpen pencircle scaled 1pt withcolor blue ;
+\stopuseMPgraphic
+\stopbuffer
+
+In order to test what we have reached so far, we draw the original path, the left
+and right part of the reduced path, and both the top and bottom point.
+
+\typebuffer \getbuffer
+
+Again we use \type {\includeMPgraphic} to combine the
+components into a graphic.
+
+\startbuffer
+\startuseMPgraphic{text}
+ \includeMPgraphic{text path} \includeMPgraphic{text vars}
+ \includeMPgraphic{text move} \includeMPgraphic{text split}
+ \includeMPgraphic{text draw}
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Then we use \type {\useMPgraphic{text}} to call up the picture.
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+The offset is not optimal. Note the funny gap at the top. We could try to fix
+this, but there is a better way to optimize both paths.
+
+We lower the top edge of \type {q}'s bounding box by \type {topskip}, then cut
+any part of the left and right pieces of \type {q} that lie above it. Similarly,
+we raise the bottom edge and cut off the pieces that fall below this line.
+
+\startbuffer
+\startuseMPgraphic{text cutoff}
+ path tt, bb ;
+
+ tt := (ulcorner q -- urcorner q) shifted (0,-topskip) ;
+ bb := (llcorner q -- lrcorner q) shifted (0,strutdepth) ;
+
+ l := l cutbefore (l intersectionpoint tt) ;
+ l := l cutafter (l intersectionpoint bb) ;
+ r := r cutbefore (r intersectionpoint bb) ;
+ r := r cutafter (r intersectionpoint tt) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Because we use \type {\includeMPgraphic} to construct the graphic, we can
+redefine \type {text draw} to show the result of this effort.
+
+\startbuffer
+\startuseMPgraphic{text draw}
+ drawarrow p withpen pencircle scaled 1pt withcolor red ;
+ drawarrow l withpen pencircle scaled 1pt withcolor green ;
+ drawarrow r withpen pencircle scaled 1pt withcolor blue ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The \type {text} graphic now becomes:
+
+\startbuffer
+\startuseMPgraphic{text}
+ \includeMPgraphic{text path} \includeMPgraphic{text vars}
+ \includeMPgraphic{text move} \includeMPgraphic{text split}
+ \includeMPgraphic{text cutoff} \includeMPgraphic{text draw}
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Or, as graphic:
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+We are now ready for an attempt to calculate the shape of the text. For each
+line, we have to calculate the left and right intersection points, and since a
+line has a height and depth, we have to determine which part touches first.
+
+\startbuffer
+\startuseMPgraphic{text calc}
+ vardef found_point (expr lin, pat, sig) =
+ pair a, b ;
+ a := pat intersection_point (lin shifted (0,strutheight)) ;
+ if intersection_found :
+ a := a shifted (0,-strutheight) ;
+ else :
+ a := pat intersection_point lin ;
+ fi ;
+ b := pat intersection_point (lin shifted (0,-strutdepth)) ;
+ if intersection_found :
+ if sig :
+ if xpart b > xpart a : a := b shifted (0,strutdepth) fi ;
+ else :
+ if xpart b < xpart a : a := b shifted (0,strutdepth) fi ;
+ fi ;
+ fi ;
+ a
+ enddef ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Instead of using \METAPOST's \type {intersectionpoint} macro, we use one that
+comes with \CONTEXT. That way we don't get an error message when no point is
+found, and can use a boolean flag to take further action. Since we use a \type
+{vardef}, all calculations are hidden and the~\type {a} at the end is returned,
+so that we can use this macro in an assignment. The \type {sig} variable is used
+to distinguish between the beginning and end of a line (the left and right
+subpath).
+
+\startbuffer
+\startuseMPgraphic{text step}
+ path line; pair lll, rrr ;
+
+ for i=topskip step baselineskip until vsize :
+
+ line := (ulcorner q -- urcorner q) shifted (0,-i) ;
+
+ lll := found_point(line,l,true ) ;
+ rrr := found_point(line,r,false) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Here we divide the available space in lines. The first line starts at \type
+{strutheight} from the top.
+
+We can now finish our graphic by visualizing the lines. Both the height and depth
+of the lines are shown.
+
+\startbuffer
+\startuseMPgraphic{text line}
+ fill (lll--rrr--rrr shifted (0,strutheight)--lll
+ shifted (0,strutheight)--cycle) withcolor .5white ;
+ fill (lll--rrr--rrr shifted (0,-strutdepth)--lll
+ shifted (0,-strutdepth)--cycle) withcolor .7white ;
+ draw lll withpen pencircle scaled 2pt ;
+ draw rrr withpen pencircle scaled 2pt ;
+ draw (lll--rrr) withpen pencircle scaled .5pt ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{text done}
+ endfor ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The result is still a bit disappointing.
+
+\startbuffer
+\startuseMPgraphic{text}
+ \includeMPgraphic{text path} \includeMPgraphic{text vars}
+ \includeMPgraphic{text move} \includeMPgraphic{text split}
+ \includeMPgraphic{text cutoff} \includeMPgraphic{text draw}
+ \includeMPgraphic{text calc} \includeMPgraphic{text step}
+ \includeMPgraphic{text line} \includeMPgraphic{text done}
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+In order to catch the overflow at the bottom, we need to change the \type
+{for}||loop a bit, so that the number of lines does not exceed the available
+space. The test that surrounds the assignment of \type {vvsize} makes sure that
+we get better results when we (on purpose) take a smaller height.
+
+\startbuffer
+\startuseMPgraphic{text step}
+ path line; pair lll, rrr ; numeric vvsize ;
+
+ if (strutheight+strutdepth<baselineskip) :
+ vvsize := vsize ;
+ else :
+ vvsize := (vsize div baselineskip) * baselineskip ;
+ fi ;
+
+ for i=topskip step baselineskip until vvsize :
+
+ line := (ulcorner q -- urcorner q) shifted (0,-i) ;
+
+ lll := found_point(line,l,true ) ;
+ rrr := found_point(line,r,false) ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+We can manipulate the heigth and depth of the lines to give different (and maybe
+better) results.
+
+\startbuffer
+\startuseMPgraphic{text vars}
+baselineskip := 8pt ;
+strutheight := 4pt ;
+strutdepth := 2pt ;
+offset := 4pt ;
+topskip := 3pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[blank]
+\useMPgraphic{text}
+\stoplinecorrection
+
+This kind of graphic trickery in itself is not enough to get \TEX\ into
+typesetting within the bounds of a closed curve. Since \METAPOST\ can write
+information to a file, and \TEX\ can read such a file, a natural way to handle
+this is to let \METAPOST\ write a \type {\parshape} specification.
+
+\startbuffer
+\startuseMPgraphic{text macro}
+ def provide_parshape (expr p, offset, baselineskip,
+ strutheight, strutdepth, topskip) =
+
+ \includeMPgraphic{text move}
+ \includeMPgraphic{text split}
+ \includeMPgraphic{text cutoff}
+ \includeMPgraphic{text draw}
+ \includeMPgraphic{text calc}
+ \includeMPgraphic{text loop}
+ \includeMPgraphic{text save}
+
+ enddef ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We have to adapt the for||loop to register the information about the lines. After
+the loop we write those values to a file using another loop.
+
+\startbuffer
+\startuseMPgraphic{text loop}
+ path line; pair lll, rrr ; numeric vvsize, n ; n := 0 ;
+
+ if (strutheight+strutdepth<baselineskip) :
+ vvsize := vsize ;
+ else :
+ vvsize := (vsize div baselineskip) * baselineskip ;
+ fi ;
+
+ for i=topskip step baselineskip until vvsize :
+
+ line := (ulcorner q -- urcorner q) shifted (0,-i) ;
+
+ lll := found_point(line,l,true ) ;
+ rrr := found_point(line,r,false) ;
+
+ n := n + 1 ;
+
+ indent[n] := abs(xpart lll - xpart llcorner q) ;
+ width[n] := abs(xpart rrr - xpart lll) ;
+
+ endfor ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{text save}
+ write "\parshape " & decimal n to "mfun-mp-data.txt" ;
+ for i=1 upto n:
+ write decimal indent[i]&"bp " &
+ decimal width[i]&"bp " to "mfun-mp-data.txt" ;
+ endfor ;
+ write EOF to "mfun-mp-data.txt" ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We can call this macro using the part we used in the previous examples.
+
+\startbuffer
+\startuseMPgraphic{text}
+ \includeMPgraphic{text macro}
+
+ path p ; p := ((0,1)..(-1,0)..(1,0)--cycle) scaled 65pt ;
+
+ provide_parshape
+ (p, % shape path
+ .5*\baselinedistance, % offset
+ \baselinedistance, % distance between lines
+ \strutheight, % height of a line
+ \strutdepth, % depth of a line
+ \strutheight) ; % height of first line
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+After we called \type {\useMPgraphic{text}}, the resulting file looks as follows.
+You can call up this file by its anonymous name \type {\MPdatafile}, since this
+macro gets the value of the graphic at hand.
+
+\startnointerference
+ \useMPgraphic{text}
+\stopnointerference
+
+\typefile{mfun-mp-data.txt}
+
+% \blank{\em todo: mp data file}\blank
+% \writestatus{!!!!}{todo: mp data file}
+
+So, reading in this file at the start of a paragraph will setup \TEX\ to follow
+this shape.
+
+The final implementation is a bit more complicated since it takes care of paths
+that are not centered around the origin and don't start at the top point. We
+achieve this by moving the path to the center:
+
+\starttyping
+cp := center p ; q := p shifted - cp ;
+\stoptyping
+
+The arbitrary starting point is taken care of by a slightly more complicated path
+cutter. First we make sure that the path runs counterclockwise.
+
+\starttyping
+if xpart directionpoint t of q < 0 : q := reverse q fi ;
+\stoptyping
+
+Knowing this, we can split the path in two, using a slightly different splitter:
+
+\starttyping
+l := q cutbefore t ;
+l := l if xpart point 0 of q < 0 : & q fi cutafter b ;
+r := q cutbefore b ;
+r := r if xpart point 0 of q > 0 : & q fi cutafter t ;
+\stoptyping
+
+As always, when implementing a feature like this, some effort goes into a proper
+user interface. In doing so, we need some \TEX\ trickery that goes beyond this
+text, like collecting text and splitting of the part needed. Also, we want to be
+able to handle multiple shapes at once, like the next example demonstrates.
+
+\stopsection
+
+\startsection[title={Libraries}]
+
+\index{graphics+libraries}
+
+The macro discussed in the previous section is included in one of the \METAPOST\
+libraries, so we first have to say:
+
+\startbuffer
+\useMPlibrary[txt]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+We define four shapes. They are not really beautiful, but they demonstrate what
+happens in border cases. For instance, too small first lines are ignored. First
+we define a circle. Watch how the dimensions are set in the graphic. The
+arguments passed to \type {build_parshape} are: path, an offset, an additional
+horizontal and vertical displacement, the baseline distance, the height and depth
+of the line, and the height of the first line (topskip in \TEX\ terminology). The
+height and depth of a line are often called strut height and depth, with a strut
+being an invisible character with maximum dimensions.
+
+\startbuffer
+\startuseMPgraphic{test 1}
+ path p ; p := fullcircle scaled 6cm ;
+
+ build_parshape(p,6pt,0,0,\baselinedistance,
+ \strutheight,\strutdepth,\strutheight) ;
+
+ draw p withpen pencircle scaled 1pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The second shape is a diamond. This is a rather useless shape, unless the text
+suits the small lines at the top and bottom.
+
+\startbuffer
+\startuseMPgraphic{test 2}
+ path p ; p := fullsquare rotated 45 scaled 5cm ;
+
+ build_parshape(p,6pt,0,0,\baselinedistance,
+ \strutheight,\strutdepth,\strutheight) ;
+
+ draw p withpen pencircle scaled 1pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The third and fourth shape demonstrate that providing a suitable offset is not
+always trivial.
+
+\startbuffer
+\startuseMPgraphic{test 3}
+ numeric w, h ; w := h := 6cm ;
+ path p ; p := (.5w,h) -- (0,h) -- (0,0) -- (w,0) &
+ (w,0) .. (.75w,.5h) .. (w,h) & (w,h) -- cycle ;
+
+ build_parshape(p,6pt,0,0,\baselinedistance,
+ \strutheight,\strutdepth,\strutheight) ;
+
+ draw p withpen pencircle scaled 1pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Contrary to the first three shapes, here we use a different path for the
+calculations and the drawing. Watch carefully! If, instead of an offset, we pass
+a path, \METAPOST\ is able to calculate the right dimensions and offsets. This is
+needed, since we need these later on.
+
+\startbuffer
+\startuseMPgraphic{test 4}
+ numeric w, h, o ;
+
+ def shape = (o,o) -- (w-o,o) & (w-o,o) .. (.75w-o,.5h) ..
+ (w-2o,h-o) & (w-2o,h-o) -- (o,h-o) -- cycle
+ enddef ;
+
+ w := h := 6cm ; o := 6pt ; path p ; p := shape ;
+ w := h := 6cm ; o := 0pt ; path q ; q := shape ;
+
+ build_parshape(p,q,6pt,6pt,\baselinedistance,
+ \strutheight,\strutdepth,\strutheight) ;
+
+ draw q withpen pencircle scaled 1pt ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Since we also want these graphics as backgrounds, we define them as overlays. If
+you don't want to show the graphic, you may omit this step.
+
+\startbuffer
+\defineoverlay[test 1][\useMPgraphic{test 1}]
+\defineoverlay[test 2][\useMPgraphic{test 2}]
+\defineoverlay[test 3][\useMPgraphic{test 3}]
+\defineoverlay[test 4][\useMPgraphic{test 4}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+As text, we use a quote from Douglas R.~Hofstadter's book \quotation {Metamagical
+Themas, Questing for the Essence of Mind and Pattern}. Watch how we pass a list
+of shapes.
+
+\startbuffer[text]
+\startshapetext[test 1,test 2,test 3,test 4]
+ \forgetall % as it says
+ \setupalign[verytolerant,stretch,normal]%
+ \input douglas % Douglas R. Hofstadter
+\stopshapetext
+\stopbuffer
+
+\typebuffer[text]
+
+Finally we combine text and shapes. Since we also want a background, we use \type
+{\framed}. The macros \type {\parwidth} and \type {\parheight} are automatically
+set to the current shape dimensions. The normal result is shown in \in {figure}
+[fig:shapes].
+
+\startbuffer[shapes]
+\startbuffer
+\setupframed
+ [offset=overlay,align=normal,frame=off,
+ width=\parwidth,height=\parheight]
+\startcombination[2*2]
+ {\framed[background=test 1]{\getshapetext}} {test 1}
+ {\framed[background=test 2]{\getshapetext}} {test 2}
+ {\framed[background=test 3]{\getshapetext}} {test 3}
+ {\framed[background=test 4]{\getshapetext}} {test 4}
+\stopcombination
+\stopbuffer
+\stopbuffer
+
+\typebuffer[shapes]
+
+\getbuffer[shapes]
+
+By using a buffer we keep \type {\placefigure} readable.
+
+\startbuffer[a]
+\placefigure
+ [here][fig:shapes]
+ {A continuous text, typeset in a non||standard shape,
+ spread over four areas, and right aligned.}
+ {\getbuffer}
+\stopbuffer
+
+\startbuffer[b]
+\placefigure
+ [here][fig:shapes]
+ {A continuous text, typeset in a non||standard shape,
+ spread over four areas.}
+ {\scale[factor=max,height=.9\textheight]{\getbuffer}}
+\stopbuffer
+
+\typebuffer[a]
+
+\doifmodeelse{screen}{\getbuffer[text,b]}{\getbuffer[text,a]}
+
+The traced alternative is shown in \in {figure} [fig:traced shapes]. This one is
+defined as:
+
+\startbuffer[a]
+\placefigure
+ [here][fig:traced shapes]
+ {A continuous text, typeset in a non||standard shape,
+ spread over four areas (tracing on).}
+ {\startMPinclusions
+ boolean trace_parshape ; trace_parshape := true ;
+ \stopMPinclusions
+ \getbuffer}
+\stopbuffer
+
+\startbuffer[b]
+\placefigure
+ [here][fig:traced shapes]
+ {A continuous text, typeset in a non||standard shape,
+ spread over four areas (tracing on).}
+ {\startMPinclusions
+ boolean trace_parshape ; trace_parshape := true ;
+ \stopMPinclusions
+ \scale[factor=max,height=.9\textheight]{\getbuffer}}
+\stopbuffer
+
+\typebuffer[a]
+
+\doifmodeelse{screen}{\getbuffer[text,b]}{\getbuffer[text,a]}
+
+% {\em This mechanism is still somewhat experimental and will be optimized and
+% extended with name spaces and more.}
+
+\blank
+
+We can combine all those tricks, although the input is somewhat fuzzy. First we
+define a quote typeset in a circular paragraph shape.
+
+\startbuffer[shape]
+\startuseMPgraphic{center}
+ build_parshape(fullcircle scaled 8cm,0,0,0,\baselinedistance,
+ \strutheight,\strutdepth,\strutheight) ;
+\stopuseMPgraphic
+
+\startshapetext[center]
+ \input douglas
+\stopshapetext
+
+\defineoverlay[center][\useMPgraphic{center}]
+\stopbuffer
+
+\typebuffer[shape]
+
+We will surround this text with a circular line, that we define as follows. By
+using a buffer we keep things organized.
+
+\startbuffer
+\startbuffer[circle]
+\startuseMPgraphic{followtokens}
+ path RotPath ; RotPath := reverse fullcircle
+ rotatedaround(origin,90)
+ xscaled \overlaywidth yscaled \overlayheight ;
+ drawoptions (withcolor .625red) ;
+\stopuseMPgraphic
+
+\followtokens
+ {This is just a dummy text, kerned by \TeX\ and typeset
+ in a circle using \MetaPost.\quad}
+\stopbuffer
+
+\defineoverlay[edge][{\getbuffer[circle]}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The text and graphics come together in a framed text:
+
+\startbuffer
+\startbuffer[quote]
+\framed
+ [offset=24pt,
+ background=edge,
+ frame=off,
+ backgroundoffset=-18pt]
+ {\getshapetext}
+\stopbuffer
+
+\placefigure
+ {One more time Hofstadter's quotation (normal).}
+ {\getbuffer[shape,quote]}
+
+\placefigure
+ {One more time Hofstadter's quotation (traced).}
+ {\startMPinclusions
+ boolean TraceRot ; TraceRot := true ;
+ \stopMPinclusions
+ \getbuffer[shape,quote]}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+% {\em Here also, I will rewrite things a bit so that we can avoid \type
+% {\startMPdrawing} outside the macro, and thereby avoid problems. I can also add
+% the maps cdrom cover as example.}
+
+\stopsection
+
+% \startsection[title={Visualizing \TEX}]
+%
+% The next example is a bit out of place in this manual, but nevertheless
+% demonstrates how one can use \METAPOST\ to get insight in what \TEX\ is doing
+% inside.
+%
+% The author of \PDFTEX, \THANH, has extended the paragraph builder with a
+% provision for protruding characters and glyphs substitution, also known as {\it
+% hz} (which stands for Hermann Zapf). The {\it hz} optimization involves an
+% additional pass over the lines and|/|or paragraph, in order to determine how
+% inconsistency in gaps can be reduced by substituting an \quote {\scale [sx=1.01]
+% {a}} by an \quote {\scale [sx=5] {a}} or \quote {\scale [sx=.5] {a}}. In \in
+% {figure} [fig:hz] you can find the visualization in action. By means of colors we
+% indicate in what way glyphs are substituted by slightly larger or smaller values.
+% More details on how the {\it hz} optimization works can be found in \THANH's
+% thesis.
+%
+% \placefigure
+% [page][fig:hz]
+% {When we feed \TEX\ code into \METAPOST\ and back, we
+% can visualize {\it hz}||optimization in a colorful way.}
+% {\doifmodeelse{screen}
+% {\externalfigure[mfun-hzs.pdf][height=.8\textheight]}
+% {\externalfigure[mfun-hzp.pdf][height=.8\textheight]}}
+%
+% In order to avoid a complicated discussion about how to set up \PDFTEX\ to use
+% {\it hz} |<|this can best be left over to the macro package that you use|>| we
+% will illustrate the method behind this kind of visualizations in a more simple
+% case.
+%
+% When you include a \METAPOST\ graphic in \PDFTEX, the output produced by
+% \METAPOST\ is interpreted by a bunch of macros and converted into raw \PDF\ code.
+% In the process special extensions, like shading, transparency, graphic inclusion,
+% are taken care of. When the converter encounters a font inclusion directive,
+% i.e.\ the \POSTSCRIPT\ \type {fshow} operator, it uses the \TEX\ font handler to
+% take care of the font. A benefit of this approach is that \TEX\ and \METAPOST\
+% share the same font resources and therefore the inclusion is done in the way
+% expected.
+%
+% The low level macro that takes care of the font inclusion provides a couple of so
+% called hooks, that permit us to do additional manipulations with the character
+% sequences that are encountered.
+%
+% \startbuffer[demo]
+% draw
+% btex \definedfont[cmr10]%
+% Combine the power of \TeX\ and \MetaPost !
+% etex scaled 2 ;
+% \stopbuffer
+%
+% \typebuffer[demo]
+%
+% When processed, this gives the graphic:
+%
+% \startlinecorrection[blank]
+% \processMPbuffer[demo]
+% \stoplinecorrection
+%
+% The result is not spectacular, and there is no indication that \METAPOST\ has
+% been in action. The following line of code sets the hook \type {\MPfshowcommand}
+% |<|this commands takes one argument|>| to produce a ruled horizontal box.
+%
+% \startbuffer
+% \let\MPfshowcommand\ruledhbox
+% \stopbuffer
+%
+% \typebuffer
+%
+% \startlinecorrection[blank]
+% \getbuffer \processMPbuffer[demo]
+% \stoplinecorrection
+%
+% If you watch closely, you will see that the ruled boxes contain one or more
+% characters (or more precise glyphs). This is a result from \TEX\ explicitely
+% kerning characters.
+%
+% A second hook is provided in the macro that takes care of the font switch. This
+% command is defined as follows:
+%
+% \starttyping
+% \def\setMPfshowfont#1#2%
+% {\font\temp=#1\space at #2\relax\temp}
+% \stoptyping
+%
+% The first argument is the raw font name, and the second argument specifies the
+% desired size. If we want to see what fonts are involved, we can redefine the
+% hooks as follows.
+%
+% \starttyping
+% \def\setMPfshowfont#1#2%
+% {\message{[using #1 at #2 in mp graphic]}%
+% \font\temp=#1\space at #2\relax\temp}
+% \stoptyping
+%
+% It happens that two fonts are used: \type {cmr10} and \type {logo10}. Once we
+% know this, we can apply some magic: we set the color to the fontname and define a
+% couple of colors that match the name.
+%
+% \startbuffer
+% \definecolor [cmr10] [darkred]
+% \definecolor [logo10] [darkyellow]
+%
+% \def\setMPfshowfont#1#2%
+% {\color[#1]\font\temp=#1\space at #2\relax\temp}
+% \stopbuffer
+%
+% \typebuffer
+%
+% In the case of the \type {\it hz} examples we had to define a couple of more
+% colors, but the principle remains.
+%
+% \startlinecorrection[blank]
+% \getbuffer \processMPbuffer[demo]
+% \stoplinecorrection
+%
+% We don't expect the user to use tricks like this on a daily basis, but it
+% demonstrates that with a bit of knowlegde of the internals of \CONTEXT, you can
+% produce nice examples of typographic programming.
+%
+% \stopsection
+
+\stopchapter
+
+\stopcomponent