summaryrefslogtreecommitdiff
path: root/doc/context/sources/general/manuals/mk/mk-mplib.tex
diff options
context:
space:
mode:
Diffstat (limited to 'doc/context/sources/general/manuals/mk/mk-mplib.tex')
-rw-r--r--doc/context/sources/general/manuals/mk/mk-mplib.tex924
1 files changed, 924 insertions, 0 deletions
diff --git a/doc/context/sources/general/manuals/mk/mk-mplib.tex b/doc/context/sources/general/manuals/mk/mk-mplib.tex
new file mode 100644
index 000000000..78e7b8f97
--- /dev/null
+++ b/doc/context/sources/general/manuals/mk/mk-mplib.tex
@@ -0,0 +1,924 @@
+% language=uk
+
+\useMPlibrary[dum]
+
+\startcomponent mk-mplib
+
+\environment mk-environment
+
+\definetextbackground
+ [sideline]
+ [mp=mpos:par:sideline,
+ framecolor=mkcolor,
+ frameoffset=5mm]
+
+\startuseMPgraphic{mpos:par:sideline}{linecolor,lineoffset}
+ for i=1 upto nofmultipars :
+ fill leftboundary multipars[i]
+ shifted (-\MPvar{lineoffset},0)
+ rightenlarged 1mm withcolor \MPvar{linecolor} ;
+ endfor ;
+\stopuseMPgraphic
+
+\chapter{The MetaPost Library}
+
+% \subject{Hans Hagen \& Taco Hoekwater} \blank[3*big]
+
+This chapter is written by Taco and Hans around the time
+that \MPLIB\ was integrated into \LUATEX.
+It is part of our torture test.
+
+\subject{introduction}
+
+If \METAPOST\ support had not been as tightly integrated into
+\CONTEXT\ as it is, at least half of the projects \PRAGMA\ has
+been doing in the last decade could not have been done at all.
+\starttextbackground[sideline]Take for instance
+backgrounds behind text or graphic markers alongside text. These are
+probably the most complex mechanisms in \CONTEXT: positions are
+stored, and positional information is passed on to
+\METAPOST, where intersections between the text areas and the running
+text are converted into graphics that are then positioned in the
+background of the text.\stoptextbackground{} Underlining of text
+(sometimes used in the educational documents that we typeset) and
+change bars (in the margins) are implemented using the same
+mechanism because those are basically a background with only one of the
+frame sides drawn.
+
+You can probably imagine that a 300 page document with several such
+graphics per page takes a while to process. A nice example of such
+integrated graphics is the \LUATEX\ reference manual, that has an
+unique graphic at each page: a stylized image of a revolving moon.
+
+\startuseMPgraphic{lualogo-x}{angle}
+color luaplanetcolor ; luaplanetcolor := .5blue ;
+color luaholecolor ; luaholecolor := white ;
+numeric luaextraangle ; luaextraangle := \MPvar{angle} ;
+
+vardef lualogo = image (
+ % Graphic design by A. Nakonechnyj. Copyright (c) 1998, All rights reserved.
+ save luaorbitcolor, d, r, p ; color luaorbitcolor ; numeric d, r, p ;
+ luaorbitcolor := .5luaholecolor ; d := sqrt(2)/4 ; r := 1/4 ; p := r/8 ;
+ fill fullcircle scaled 1 withcolor luaplanetcolor ;
+ draw fullcircle rotated 40.5 scaled (1+r) dashed evenly scaled p withpen pencircle scaled (p/2) withcolor luaorbitcolor ;
+ fill fullcircle scaled r shifted (d+1/8,d+1/8) rotated luaextraangle withcolor luaplanetcolor ;
+ fill fullcircle scaled r shifted (d-1/8,d-1/8) withcolor luaholecolor ;
+ setbounds currentpicture to fullsquare scaled 1.3;
+) enddef ;
+
+draw lualogo scaled 1cm ;
+\stopuseMPgraphic
+
+\startlinecorrection[blank]
+\hbox to \hsize
+ {\hss\dostepwiserecurse{0}{360}{60}{\useMPgraphic{lualogo-x}{angle=\recurselevel}\hss}}
+\stoplinecorrection
+
+Most of the running time integrating such graphics seemed to be
+caused by the mechanics of the process: starting the separate
+\METAPOST\ interpreter and having to deal with a number of
+temporary files. Therefore our expectations were high with regards
+to integrating \METAPOST\ more tightly into \LUATEX. Besides the
+speed gain, it also true that the simpler the process of using
+such use of graphics becomes, the more modern a \TEX\ runs looks
+and the less problems new users will have with understanding how
+all the processes cooperate.
+
+This article will not discuss the application interface of the
+\MPLIB\ library in detail, for that there is the \LUATEX\ manual. In short,
+using the embedded \METAPOST\ interpreter in \LUATEX\ boils
+down to the following:
+
+\startitemize[packed]
+\item Open an instance using \type {mplib.new}, either to process
+ images with a format to be loaded, or to create such a format.
+ This function returns a library object.
+\item Execute sequences of \METAPOST\ commands, using the object's
+ \type{execute} method. This returns a result.
+\item Check if the result is valid and (if it is okay) request the list
+ of objects. Do whatever you want with them, most probably
+ convert them to some output format. You can also request a
+ string representation of a graphic in \POSTSCRIPT\ format.
+\stopitemize
+
+There is no need to close the library object. As long as you didn't make
+any fatal errors, the library recovers well and can stay alive during
+the entire \LUATEX\ run.
+
+Support for \MPLIB\ depends on a few components: integration,
+conversion and extensions. This article shows some of the code
+involved in supporting the library. Let's start with the conversion.
+
+\subject{conversion}
+
+The result of a \METAPOST\ run traditionally is a \POSTSCRIPT\
+language description of the generated graphic(s). When
+\PDF\ is needed, that \POSTSCRIPT\ code has to be converted to the target
+format. This includes embedded text as well as penshapes used for
+drawing. To demonstrate, here is a simple example graphic:
+
+\startluacode
+document.sample_mp_graphic = [[
+ draw fullcircle
+ scaled 2cm
+ withpen pencircle xscaled 1mm yscaled .5mm rotated 30
+ withcolor .75red ;
+]]
+\stopluacode
+
+\startbuffer[mpexample]
+draw fullcircle
+ scaled 2cm
+ withpen pencircle xscaled 1mm yscaled .5mm rotated 30
+ withcolor .75red ;
+\stopbuffer
+
+\placefigure
+ [left]
+ {}
+ {\startMPcode \ctxlua{tex.sprint(document.sample_mp_graphic)}\stopMPcode}
+
+\typebuffer[mpexample]
+
+Notice how the pen is not a circle but a rotated ellipse. Later on it
+will become clear what the consequences of that are for the conversion.
+
+How does this output look in \POSTSCRIPT ? If the preamble is left out
+it looks like this:
+
+\startbuffer
+\startluacode
+do
+ local mpx = metapost.format("metafun")
+ local result = mpx:execute(string.format("beginfig(0);%s;endfig;",document.sample_mp_graphic))
+ local str = result.fig[1]:postscript()
+ str = str:gsub("%%BeginProlog.-%%EndProlog","%% <<stripped preamble was here>>")
+ tex.sprint(tex.ctxcatcodes,"\\starttyping\n")
+ tex.sprint((str:gsub("[\n\r]$","")))
+ tex.sprint("\\stoptyping")
+end
+\stopluacode
+\stopbuffer
+
+\getbuffer
+
+The most prominent code here concerns the path. The numbers in brackets define
+the transformation matrix for the pen we used. The \PDF\ variant looks as follows:
+
+\startbuffer
+\startluacode
+do
+ local mpx = metapost.format("metafun")
+ local result = mpx:execute(string.format("beginfig(0);%s;endfig;",document.sample_mp_graphic))
+ local list = metapost.pdfliterals(result)
+ tex.sprint(tex.ctxcatcodes,"\\starttyping")
+ tex.sprint(table.concat(list,"\n"))
+ tex.sprint("\\stoptyping")
+end
+\stopluacode
+\stopbuffer
+
+\getbuffer
+
+The operators don't look much different from the \POSTSCRIPT, which is
+mostly due to the fact that in the \POSTSCRIPT\ code, the preamble
+defines shortcuts like \type {c} for \type {curveto}. Again, most code
+involves the path. However, this time the numbers are different and
+the transformation comes before the path.
+
+In the case of \PDF\ output, we could use \TEX\ itself to do the
+conversion: a generic converter is implemented in \type
+{supp-pdf.tex}, while a converter optimized for \CONTEXT\ \MKII\ is
+defined in the files whose names start with \type {meta-pdf}. But in
+\CONTEXT\ \MKIV\ we use \LUA\ code for the conversion instead. Thanks to
+\LUA's powerful \LPEG\ parsing library, this gives cleaner code and is
+also faster. This converter currently lives in \type {mlib-pdf.lua}.
+
+Now, with the embedded \METAPOST\ library, conversion goes different
+still because now it is possible to request the drawn result and
+associated information in the form of \LUA\ tables.
+
+\startbuffer
+\startluacode
+do
+ local mpx = metapost.format("metafun")
+ local result = mpx:execute(string.format("beginfig(0);%s;endfig;",document.sample_mp_graphic))
+ local str = table.serialize(metapost.totable(result), "figure")
+ tex.sprint(tex.ctxcatcodes,"\\starttyping")
+ tex.sprint((str:gsub("[\n\r]$","")))
+ tex.sprint("\\stoptyping")
+end
+\stopluacode
+\stopbuffer % $<-emacs font-lock
+
+% \startsimplecolumns[n=3,width=18.5cm]
+% \getbuffer
+% \stopsimplecolumns
+
+\getbuffer
+
+This means that instead of parsing \POSTSCRIPT\ output, we now can operate on
+a proper datastructure and get code like the following:
+
+\starttyping
+function convertgraphic(result)
+ if result then
+ local figures = result.fig
+ if figures then
+ for fig in ipairs(figures) do
+ local llx, lly, urx, ury = unpack(fig:boundingbox())
+ if urx > llx then
+ startgraphic(llx, lly, urx, ury)
+ for object in ipairs(fig:objects()) do
+ if object.type == "..." then
+ ...
+ flushgraphic(...)
+ ...
+ else
+ ...
+ end
+ end
+ finishgraphic()
+ end
+ end
+ end
+ end
+end
+\stoptyping
+
+Here \type {result} is what the library returns when one or more
+graphics are processed. As you can deduce from this snippet, a
+result can contain multiple figures. Each figure corresponds with a
+\type {beginfig} \type {...} \type {endfig}. The graphic operators that
+the converter generates (so called \PDF\ literals) have to be
+encapsulated in a proper box so this is why we have:
+
+\startitemize[packed]
+\item \type {startgraphic}: start packaging the graphic
+\item \type {flushgraphic}: pipe literals to \TEX
+\item \type {finishgraphic}: finish packaging the graphic
+\stopitemize
+
+It does not matter what number you passed to \type {beginfig}, the
+graphics come out in the natural order.
+
+Little over half a dozen different object types are possible. The example
+\METAPOST\ \type{draw} command from above results in an \type {outline} object.
+This object contains not only path information but also carries
+rendering data, like the color and the pen. So, in the end we will
+flush code like \type {1 M} which sets the \type {miterlimit} to one
+or \type {.5 g} which sets the color to 50\% gray, in addition to a
+path.
+
+Because objects are returned in a way that closely resembles a
+\METAPOST's internals, some extra work needs to be done in order to
+calculate paths with elliptical pens. An example of a helper function
+in somewhat simplified form is shown next:
+
+\starttyping
+function pen_characteristics(object)
+ local p = object.pen[1]
+ local wx, wy, width
+ if p.right_x == p.x_coord and p.left_y == p.y_coord then
+ wx = abs(p.left_x - p.x_coord)
+ wy = abs(p.right_y - p.y_coord)
+ else -- pyth: sqrt(a^2 +b^2)
+ wx = pyth(p.left_x - p.x_coord, p.right_x - p.x_coord)
+ wy = pyth(p.left_y - p.y_coord, p.right_y - p.y_coord)
+ end
+ if wy/coord_range_x(object.path, wx) >=
+ wx/coord_range_y(object.path, wy) then
+ width = wy
+ else
+ width = wx
+ end
+ local sx, sy = p.left_x, p.right_y
+ local rx, ry = p.left_y, p.right_x
+ local tx, ty = p.x_coord, p.y_coord
+ if width ~= 1 then
+ if width == 0 then
+ sx, sy = 1, 1
+ else
+ rx, ry, sx, sy = rx/width, ry/width, sx/width, sy/width
+ end
+ end
+ if abs(sx) < eps then sx = eps end
+ if abs(sy) < eps then sy = eps end
+ return sx, rx, ry, sy, tx, ty, width
+end
+\stoptyping
+
+If \type {sx} and \type {sy} are 1, there is no need to transform
+the path, otherwise a suitable transformation matrix is calculated
+and returned. The function itself uses a few helpers that make the
+calculations even more obscure. This kind of code does not fall in
+the category trivial and as already mentioned, these basic
+algorithms were derived from the \METAPOST\ sources. Even so,
+these snippets demonstrate that interfacing using \LUA\ does not
+look that bad.
+
+In the actual \MKIV\ code things look a bit different because it does
+a bit more and uses optimized code. There you will also find the code
+dealing with the actual transformation, of which these helpers are
+just a portion.
+
+If you compare the \POSTSCRIPT\ and the \PDF\ code you will notice
+that the paths looks different. This is because the use and
+application of a transformation matrix in \PDF\ is different from how
+it is handled in \POSTSCRIPT. In \PDF\ more work is assumed to be
+done by the \PDF\ generating application. This is why in both the
+\TEX\ and the \LUA\ based converters you will find transformation code
+and the library follows the same pattern. In that respect \PDF\
+differs fundamentally from \POSTSCRIPT.
+
+Within the \TEX\ based converter there was the problem of keeping the
+needed calculations within \TEX's accuracy, which fortunately permits
+larger values that \METAPOST\ can produce. This plus the parsing code
+resulted in a not-that-easy to follow bunch of \TEX\ code. The \LUA\
+based parser is more readable, but since it also operates on
+\POSTSCRIPT\ code it is kind of unnatural too, but at least there are
+less problems with keeping the calculations sane. The \MPLIB\ based
+converter is definitely the cleanest and least sensitive to future
+changes in the \POSTSCRIPT\ output. Does this mean that there is no
+ugly code left? Alas, as we will see in the next section, dealing with
+extensions is still somewhat messy. In practice users will not be
+bothered with such issues, because writing a converter is a one time
+job by macro package writers.
+
+\subject{extensions}
+
+In \METAFUN, which is the \METAPOST\ format used with \CONTEXT,
+a few extensions are provided, like:
+
+\startitemize[packed]
+\item cmyk, spot and multitone colors
+\item including external graphics
+\item lineair and circulair shades
+\item texts converted to outlines
+\item inserting arbitrary texts
+\stopitemize
+
+Until now, most of these extensions have been implemented by using
+specially coded colors and by injecting so called specials (think of
+them as comments) into the output. On one of our trips to a \TEX\
+conference, we discussed ways to pass information along with
+paths and eventually we arrived at associating text strings with paths
+as a simple and efficient solution. As a result, recently \METAPOST\
+was extended by \type {withprescript} and \type {withpostscript}
+directives. For those who are unfamiliar with these new scripts,
+they are used as follows:
+
+\starttyping
+draw fullcircle withprescript "hello" withpostscript "world" ;
+\stoptyping
+
+In the \POSTSCRIPT\ output these scripts end up before and after the
+path, but in the \PDF\ converter they can be overloaded to implement
+extensions, and that works reasonably well. However, at the moment
+there cannot be multiple pre- and postscripts associated with a single
+path inside the \METAPOST\ internals. This means that for the moment,
+the scripts mechanism is only used for a few of the extensions.
+Future versions of \MPLIB\ may provide more sophisticated methods
+for carrying information around.
+
+The \MKIV\ conversion mechanism uses scripts for graphic inclusion,
+shading and text processing but unfortunately cannot use them for
+more advanced color support.
+
+A nasty complication is that the color spaces in \METAPOST\ don't
+cast, which means that one cannot assign any color to a color
+variables: each colorspace has it's own type of variable.
+
+\starttyping
+color one ; one := (1,1,0) ; % correct
+cmykcolor two ; two := (1,0,0,1) ; % correct
+one := two ; % error
+fill fullcircle scaled 1cm withcolor .5[one,two] ; % error
+\stoptyping
+
+In \CONTEXT\ we use constructs like this:
+
+\starttyping
+\startreusableMPgraphic{test}
+ fill fullcircle scaled 1cm withcolor \MPcolor{mycolor} ;
+\stopreusableMPgraphic
+
+\reuseMPgraphic{test}
+\stoptyping
+
+Because \type {withcolor} is clever enough to understand what color
+type it receives, this is ok, but how about:
+
+\starttyping
+\startreusableMPgraphic{test}
+ color c ; c := \MPcolor{mycolor} ;
+ fill fullcircle scaled 1cm withcolor c ;
+\stopreusableMPgraphic
+\stoptyping
+
+Here the color variable only accepts an \RGB\ color and because in
+\CONTEXT\ there is mixed color space support combined with
+automatic colorspace conversions, it doesn't know in advance what type
+it is going to get. By implementing color spaces other than \RGB\
+using special colors (as before) such type mismatches can be avoided.
+
+The two techniques (coding specials in colors and pre|/|postscripts)
+cannot be combined because a script is associated with a path and
+cannot be bound to a variable like \type{c}. So this again is an argument
+for using special colors that remap onto \CMYK\, spot or
+multi|-|tone colors.
+
+Another area of extensions is text. In previous versions of
+\CONTEXT\ the text processing was already isolated: text ended
+up in a separate file and was processed in an separate run. More
+recent versions of \CONTEXT\ use a more abstract model of boxes that
+are preprocessed before a run, which avoids the external run(s). In
+the new approach everything can be kept internal. The conversion
+even permits constructs like:
+
+\starttyping
+for i=1 upto 100 :
+ draw btex oeps etex rotated i ;
+endfor ;
+\stoptyping
+
+but since this construct is kind of obsolete (at least in the library
+version of \METAPOST) it is better to use:
+
+\starttyping
+for i=1 upto 100 :
+ draw textext("cycle " & decimal i) rotated i ;
+endfor ;
+\stoptyping
+
+Internally a trial pass is done so that indeed 100 different texts will
+be drawn. The throughput of texts is so high that in practice one will
+not even notice that this happens.
+
+Dealing with text is yet another example of using \LPEG. The following
+snippet of code sheds some light on how text in graphics is dealt with.
+Actually this is a variation on a previous implementation. That one
+was slightly faster but looked more complex. It was also not robust for
+complex texts defined in macros in a format.
+
+\starttyping
+local P, S, V, Cs = lpeg.P, lpeg.S, lpeg.V, lpeg.Cs
+
+local btex = P("btex")
+local etex = P(" etex")
+local vtex = P("verbatimtex")
+local ttex = P("textext")
+local gtex = P("graphictext")
+local spacing = S(" \n\r\t\v")^0
+local dquote = P('"')
+
+local found = false
+
+local function convert(str)
+ found = true
+ return "textext(\"" .. str .. "\")"
+end
+local function ditto(str)
+ return "\" & ditto & \""
+end
+local function register()
+ found = true
+end
+
+local parser = P {
+ [1] = Cs((V(2)/register + V(3)/convert + 1)^0),
+ [2] = ttex + gtex,
+ [3] = (btex + vtex) * spacing *
+ Cs((dquote/ditto + (1-etex))^0) * etex,
+}
+
+function metapost.check_texts(str)
+ found = false
+ return parser:match(str), found
+end
+\stoptyping
+
+If you are unfamiliar with \LPEG\ it may take a while to see what
+happens here: we replace the text between \type {btex} and \type {etex}
+by a call to \type {textext}, a macro. Special care is given to
+embedded double quotes.
+
+When text is found, the graphic is processed two times. The definition
+of \type {textext} is different for each run. The first run we have:
+
+\starttyping
+vardef textext(expr str) =
+ image (
+ draw unitsquare
+ withprescript "tf"
+ withpostscript str ;
+ )
+enddef ;
+\stoptyping
+
+After the first run the result is not really converted, but just
+the outlines with the \type {tf} prescript are filtered. In the
+loop over the object there is code like:
+
+\starttyping
+local prescript = object.prescript
+if prescript then
+ local special = metapost.specials[prescript]
+ if special then
+ special(object.postscript,object)
+ end
+end
+\stoptyping
+
+Here, \type {metapost} is just the namespace used by the
+converter. The prescript tag \type {tf} triggers a function:
+
+\starttyping
+function metapost.specials.tf(specification,object)
+ tex.sprint(tex.ctxcatcodes,format("\\MPLIBsettext{%s}{%s}",
+ metapost.textext_current,specification))
+ if metapost.textext_current < metapost.textext_last then
+ metapost.textext_current = metapost.textext_current + 1
+ end
+ ...
+end
+\stoptyping
+
+Again, you can forget about the details of this function. Important is
+that there is a call out to \TEX\ that will process the text. Each snippet
+gets the number of the box that holds the content. The macro that is
+called just puts stuff in a box:
+
+\starttyping
+\def\MPLIBsettext#1#2%
+ {\global\setbox#1\hbox{#2}}
+\stoptyping
+
+In the next processing cycle of the \METAPOST\ code, the \type {textext}
+macro does something different :
+
+\starttyping
+vardef textext(expr str) =
+ image (
+ _tt_n_ := _tt_n_ + 1 ;
+ draw unitsquare
+ xscaled _tt_w_[_tt_n_]
+ yscaled (_tt_h_[_tt_n_] + _tt_d_[_tt_n_])
+ withprescript "ts"
+ withpostscript decimal _tt_n_ ;
+ )
+enddef ;
+\stoptyping
+
+This time the by then known dimensions of the box that is used to
+store the snippet are used. These are stored in the \type {_tt_w_},
+\type {_tt_h_} and \type {_tt_d_} arrays. The arrays are defined by
+\LUA\ using information about the boxes, and passed to the library
+before the second run. The result from the second \METAPOST\ run
+is converted, and again the prescript is used as trigger:
+
+\starttyping
+function metapost.specials.ts(specification,object,result)
+ local op = object.path
+ local first, second, fourth = op[1], op[2], op[4]
+ local tx, ty = first.x_coord , first.y_coord
+ local sx, sy = second.x_coord - tx, fourth.y_coord - ty
+ local rx, ry = second.y_coord - ty, fourth.x_coord - tx
+ if sx == 0 then sx = 0.00001 end
+ if sy == 0 then sy = 0.00001 end
+ metapost.flushfigure(result)
+ tex.sprint(tex.ctxcatcodes,format(
+ "\\MPLIBgettext{%f}{%f}{%f}{%f}{%f}{%f}{%s}",
+ sx,rx,ry,sy,tx,ty,metapost.textext_current))
+ ...
+end
+\stoptyping
+
+At this point the converter is actually converting the graphic and
+passing \PDF\ literals to \TEX. As soon as it encounters a text,
+it flushes the \PDF\ code collected so far and injects some \TEX\
+code. The \TEX\ macro looks like:
+
+\starttyping
+\def\MPLIBgettext#1#2#3#4#5#6#7%
+ {\ctxlua{metapost.sxsy(\number\wd#7,\number\ht#7,\number\dp#7)}%
+ \pdfliteral{q #1 #2 #3 #4 #5 #6 cm}%
+ \vbox to \zeropoint{\vss\hbox to \zeropoint
+ {\scale[sx=\sx,sy=\sy]{\raise\dp#7\box#7}\hss}}%
+ \pdfliteral{Q}}
+\stoptyping
+
+Because text can be transformed, it needs to be scale back to the right
+dimensions, using both the original box dimensions and the transformation
+of the unitquare associated with the text.
+
+\starttyping
+local factor = 65536*(7200/7227)
+
+function metapost.sxsy(wd,ht,dp) -- helper for text
+ commands.edef("sx",(wd ~= 0 and 1/( wd /(factor))) or 0)
+ commands.edef("sy",(wd ~= 0 and 1/((ht+dp)/(factor))) or 0)
+end
+\stoptyping
+
+So, in fact there are the following two processing alternatives:
+
+\startitemize[packed]
+\item tex: calls a \LUA\ function that processed the graphic
+\item lua: parse the \METAPOST\ code for texts and decide if two
+ runs are needed
+\stopitemize
+
+Now, if there was no text to be found, the continuation is:
+
+\startitemize[packed]
+\item lua: process the code using the library
+\item lua: convert the resulting graphic (if needed) and check
+ if texts are used
+\stopitemize
+
+Otherwise, the next steps are:
+
+\startitemize[packed]
+\item lua: process the code using the library
+\item lua: parse the resulting graphic for texts (in the postscripts)
+ and signal \TEX\ to process these texts afterwards
+\item tex: process the collected text and put the result in boxes
+\item lua: process the code again using the library but this time let
+ the unitsquare be transformed using the text dimensions
+\item lua: convert the resulting graphic and replace the transformed
+ unitsquare by the boxes with text
+\stopitemize
+
+The processor itself is used in the \MKIV\ graphic function that takes
+care of the multiple passes mentioned before. To give you an idea of
+how it works, here is how the main graphic processing function roughly
+looks.
+
+\starttyping
+local current_format, current_graphic
+
+function metapost.graphic_base_pass(mpsformat,str,preamble)
+ local prepared, done = metapost.check_texts(str)
+ metapost.textext_current = metapost.first_box
+ if done then
+ current_format, current_graphic = mpsformat, prepared
+ metapost.process(mpsformat, {
+ preamble or "",
+ "beginfig(1); ",
+ "_trial_run_ := true ;",
+ prepared,
+ "endfig ;"
+ }, true ) -- true means: trialrun
+ tex.sprint(tex.ctxcatcodes,
+ "\\ctxlua{metapost.graphic_extra_pass()}")
+ else
+ metapost.process(mpsformat, {
+ preamble or "",
+ "beginfig(1); ",
+ "_trial_run_ := false ;",
+ str,
+ "endfig ;"
+ } )
+ end
+end
+
+function metapost.graphic_extra_pass()
+ metapost.textext_current = metapost.first_box
+ metapost.process(current_format, {
+ "beginfig(0); ",
+ "_trial_run_ := false ;",
+ table.concat(metapost.texttextsdata()," ;\n"),
+ current_graphic,
+ "endfig ;"
+ })
+end
+\stoptyping
+
+The box information is generated as follows:
+
+\starttyping
+function metapost.texttextsdata()
+ local t, n = { }, 0
+ for i = metapost.first_box, metapost.last_box do
+ n = n + 1
+ local box_i = tex.box[i]
+ if box_i then
+ t[#t+1] = format(
+ "_tt_w_[%i]:=%f;_tt_h_[%i]:=%f;_tt_d_[%i]:=%f;",
+ n, box_i.width /factor,
+ n, box_i.height/factor,
+ n, box_i.depth /factor
+ )
+ else
+ break
+ end
+ end
+ return t
+end
+\stoptyping
+
+This is a typical example of accessing information available inside
+\TEX\ from \LUA, in this case information about boxes.
+
+The \type {trial_run} flag is used at the \METAPOST\ end, in fact the
+\type {textext} macro looks as follows:
+
+\starttyping
+vardef textext(expr str) =
+ if _trial_run_ :
+ % see first variant above
+ else :
+ % see second variant above
+ fi
+enddef ;
+\stoptyping
+
+This trickery is not new. We used it already in \CONTEXT\ for some
+time, but until now the multiple runs took way more time and from
+the perspective of the user this all looked much more complex.
+
+It may not be that obvious, but: in the case of a trial run (for
+instance when texts are found), after the first processing stage,
+and during the parsing of the result, the commands that typeset the
+content will be printed to \TEX. After processing, the command to do
+an extra pass is printed to \TEX\ also. So, once control is passed
+back to \TEX, at some point \TEX\ itself will pass control back to
+\LUA\ and do the extra pass.
+
+The base function is called in:
+
+\starttyping
+function metapost.graphic(mpsformat,str,preamble)
+ local mpx = metapost.format(mpsformat or "metafun")
+ metapost.graphic_base_pass(mpx,str,preamble)
+end
+\stoptyping
+
+The \type {metapost.format} function is part of \type {mlib-run}.
+It loads the \type{metafun} format, possibly after (re|)|generating it.
+
+Now, admittedly all this looks a bit messy, but in pure \TEX\ macros
+it would be even more so. Sometime in the future, the postponed calls to
+\tex{ctxlua} and the explicit \tex{pdfliteral}s can and will be
+replaced by using direct node generation, but that requires a rewrite
+of the internal \LUATEX\ support for \PDF\ literals.
+
+The snippets are part of the \type {mlib-*} files of \MKIV. These files are
+tagged as experimental and will stay that way for a while yet. This is
+proved by the fact that by now we use a slightly different approach.
+
+Summarizing the impact of \MPLIB\ on extensions, we can conclude that
+some are done better and some more or less the same. There are some
+conceptual problems that prohibit using pre- and postscripts for
+everything (at least currently).
+
+\subject{integrating}
+
+The largest impact of \MPLIB\ is processing graphics at runtime.
+In \MKII\ there are two methods: real runtime processing (each
+graphic triggered a call to \METAPOST) and collective processing
+(between \TEX\ runs). The first method slows down the \TEX\ run,
+the second method generates a whole lot of intermediate \POSTSCRIPT\
+files. In both cases there is a lot of file \IO\ involved.
+
+In \MKIV, the integrated library is capable of processing
+thousands of graphics per second, including conversion. The
+preliminary tests (which involved no extensions) involved graphics
+with 10 random circles drawn with penshapes in random colors, and
+the thoughput was around 2000 such graphics per second on a
+2.3 MHz Core Duo:
+
+\startlinecorrection[blank]
+\hbox to \textwidth{\strut\dorecurse{5}{\startMPcode
+numeric w ; w := \the\textwidth/6 ;
+for k:=1 upto 10 :
+ draw fullcircle
+ scaled uniformdeviate(w)
+ withpen pencircle xscaled (w/20) yscaled (w/40) rotated 30
+ withcolor (red/(k/4)) ;
+endfor ;
+setbounds currentpicture to fullsquare scaled w ;
+\stopMPcode\hss}\unskip}
+\stoplinecorrection
+
+In practice there will be some more overhead involved than in the
+tests. For instance, in \CONTEXT\ information about the current state
+of \TEX\ has to be passed on also: page dimensions, font information,
+typesetting related parameters, preamble code, etc.
+
+The whole \TEX\ interface is written around one process function:
+
+\starttyping
+metapost.graphic(metapost.format("metafun"),"mp code")
+\stoptyping
+
+optionally a preamble can be passed as the third argument.
+This one function is used in several other macros, like:
+
+\starttyping
+\startMPcode ... \stopMPcode
+\startMPpage ... \stopMPpage
+\startuseMPgraphic {name} ... \stopuseMPgraphic
+\startreusableMPgraphic{name} ... \stopreusableMPgraphic
+\startuniqueMPgraphic {name} ... \stopuniqueMPgraphic
+
+\useMPgraphic{name}
+\reuseMPgraphic{name}
+\uniqueMPgraphic{name}
+\stoptyping
+
+The user interface is downward compatible: in \MKIV\ the same
+top-level commands are provided as in \MKII. However, the
+(previously required) configuration macros and flags are obsolete.
+
+This time, the conclusion is that the impact on \CONTEXT\ is immense:
+The code for embedding graphics is very clean, and the running time
+for graphics inclusion is now negligible. Support for text in graphics is
+more natural now, and takes no runtime either (in \MKII\ some
+parsing in \TEX\ takes place, and if needed long lines are split;
+all this takes time).
+
+In the styles that \PRAGMA\ uses internally, there is support for the
+generation of placeholders for missing graphics. These placeholders
+are \METAPOST\ graphics that have some 60 randomly scaled circles with randomized
+colors. The time involved in generating 50 such graphics is (on Hans'
+machine) some 14 seconds, while in \LUATEX\ only half a second is needed.
+
+\startlinecorrection[blank]
+\hbox to \textwidth \bgroup
+\hss\dorecurse{4}{\externalfigure[dummy][width=.2\textwidth]\hss}%
+\egroup
+\stoplinecorrection
+
+Because \LUATEX\ needs more startup time and deals with larger fonts
+resources, \PDFTEX\ is generally faster, but now that we have \MPLIB,
+\LUATEX\ suddenly is the winner.
+
+% We end this article by showing a few graphics. \CONTEXT\ ships with a module
+% that permits tracking of resource usage. Users can add the following line
+% to their document:
+
+% \starttyping
+% \usemodule[timing]
+% \stoptyping
+
+% After that one can use commands like
+
+% \starttyping
+% \ShowNamedUsage{\jobname-luatex-progress}{luastate_bytes}{elapsed_time}
+% \ShowNamedUsage{\jobname-luatex-progress}{dyn_used}{elapsed_time}
+% \ShowNamedUsage{\jobname-luatex-progress}{str_ptr}{elapsed_time}
+% \ShowNamedUsage{\jobname-luatex-progress}{pdf_literal}{elapsed_time}
+% \ShowNamedUsage{\jobname-luatex-progress}{glyph}{elapsed_time}
+% \stoptyping
+
+% In this document, \LUA\ memory usage is as follows. The blue lines
+% represent runtime, on Hans' machine some 3.5 seconds, including
+% startuptime, which clearly shows in the graphic. Keep in mind that
+% garbage collection only happens at certain moment, so \LUA\ memory
+% usage is normally a sawtooth graphic. The horizontal axis reflects the
+% number of pages.
+
+% \startlinecorrection[blank]
+% \ShowNamedUsage{\jobname-luatex-progress}{luastate_bytes}{elapsed_time}
+% \stoplinecorrection
+
+% Dynamic memory usage of \TEX\ grows a bit because at the \TEX\ end we need
+% to store data as well.
+
+% \startlinecorrection[blank]
+% \ShowNamedUsage{\jobname-luatex-progress}{dyn_used}{elapsed_time}
+% \stoplinecorrection
+
+% Currently we use \type {\pdfliteral}, which means that all
+% literals go through \TEX's tokenizer and string pool. With large
+% graphics this can be a real memory hog.
+
+% Unfortunately not all this memory is freed, so eventually Hartmut
+% Henkel (the third member of the \LUATEX\ team) will reimplement
+% this part of the backend.
+
+% \startlinecorrection[blank]
+% \ShowNamedUsage{\jobname-luatex-progress}{str_ptr}{elapsed_time}
+% \stoplinecorrection
+
+% Just to complete this picture, we show the usage of literals next. Although
+% the converter collects as much data as possible before flushing, we see
+% some peaks.
+
+% \startlinecorrection[blank]
+% \ShowNamedUsage{\jobname-luatex-progress}{pdf_literal}{elapsed_time}
+% \stoplinecorrection
+
+% Compare this to the glyph usage. Indeed: the more graphics we use, the
+% less glyphs we encounter.
+
+% \startlinecorrection[blank]
+% \ShowNamedUsage{\jobname-luatex-progress}{glyph}{elapsed_time}
+% \stoplinecorrection
+
+% Of course these graphics were integrated, generated and converted
+% using \MPLIB.
+
+\stopcomponent