% 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
