% \iffalse meta-comment -- by the way, this file contains UTF-8
%
% Copyright (C) 2008-2010 by Hans Hagen, Taco Hoekwater, Elie Roux, and
% Manuel Pégourié-Gonnard.
% Currently maintained by Manuel Pégourié-Gonnard <mpg@elzevir.fr>
% Support: <lualatex-dev@tug.org>
%
% This work is under the CC0 license.
%
% This work consists of the main source file luamplib.dtx
% and the derived files
%    luamplib.sty, luamplib.lua and luamplib.pdf.
%
% Unpacking:
%    tex luamplib.dtx
%
% Documentation:
%    pdflatex luamplib.dtx
%
%<*ignore>
\begingroup
  \def\x{LaTeX2e}%
\expandafter\endgroup
\ifcase 0\ifx\install y1\fi\expandafter
         \ifx\csname processbatchFile\endcsname\relax\else1\fi
         \ifx\fmtname\x\else 1\fi\relax
\else\csname fi\endcsname
%</ignore>
%<*install>
\input docstrip.tex
\Msg{************************************************************************}
\Msg{* Installation}
\Msg{* Package: luamplib - metapost package for LuaTeX.}
\Msg{************************************************************************}

\keepsilent
\askforoverwritefalse

\let\MetaPrefix\relax

\preamble

See source file '\inFileName' for licencing and contact information.

\endpreamble

\let\MetaPrefix\DoubleperCent

\generate{%
  \usedir{tex/luatex/mplib}%
  \file{luamplib.sty}{\from{luamplib.dtx}{package}}%
}

\def\MetaPrefix{-- }

\def\luapostamble{%
  \MetaPrefix^^J%
  \MetaPrefix\space End of File `\outFileName'.%
}

\def\currentpostamble{\luapostamble}%

\generate{%
  \usedir{tex/luatex/mplib}%
  \file{luamplib.lua}{\from{luamplib.dtx}{lua}}%
}

\obeyspaces
\Msg{************************************************************************}
\Msg{*}
\Msg{* To finish the installation you have to move the following}
\Msg{* files into a directory searched by TeX:}
\Msg{*}
\Msg{*     luamplib.sty luamplib.lua}
\Msg{*}
\Msg{* Happy TeXing!}
\Msg{*}
\Msg{************************************************************************}

\endbatchfile
%</install>
%<*ignore>
\fi
%</ignore>
%<*driver>
\documentclass{ltxdoc}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{textcomp}
\usepackage{lmodern}
\usepackage{fixltx2e}

\usepackage[a4paper]{geometry}
\usepackage[english]{babel}
\usepackage[colorlinks]{hyperref}
\usepackage{bookmark}

\newcommand*\email [1] {<\href{mailto:#1}{#1}>}
\newcommand \file       {\nolinkurl}
\newcommand \pk         {\textsf}

\begin{document}
  \DocInput{luamplib.dtx}%
\end{document}
%</driver>
% \fi
%
% \CheckSum{0}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
% \title{The \textsf{luamplib} package}
% \author{Hans Hagen, Taco Hoekwater and Elie Roux \\
% Maintainer: Manuel Pégourié-Gonnard ---
% Support: \email{lualatex-dev@tug.org}}
% \date{2011/12/09 v1.09}
%
% \maketitle
%
% \begin{abstract}
% Package to have metapost code typeset directly in a document with Lua\TeX .
% \end{abstract}
%
% \section{Documentation}
%
% This packages aims at providing a simple way to typeset directly metapost
% code in a document with Lua\TeX . Lua\TeX\ is built with the lua
% \texttt{mplib} library, that runs metapost code. This package is basically a
% wrapper (in Lua) for the Lua \texttt{mplib} functions and some \TeX\
% functions to have the output of the \texttt{mplib} functions in the pdf.
%
% The package needs to be in PDF mode in order to output something, as PDF
% specials are not supported by the DVI format and tools.
%
% The metapost figures are put in a \TeX\ \texttt{hbox} with dimensions
% adjusted to the metapost code.
%
% The code is from the \texttt{supp-mpl.lua} and \texttt{supp-mpl.tex} files
% from Con\TeX t, they have been adapted to \LaTeX\ and Plain by Elie Roux.
% The changes are:
%
% \begin{itemize}
% \item a \LaTeX\ environment
% \item all \TeX\ macros start by \texttt{mplib}
% \item use of luatexbase for errors, warnings and declaration
% \end{itemize}
%
% Using this package is easy: in Plain, type your metapost code between the
% macros \texttt{mplibcode} and \texttt{endmplibcode}, and in \LaTeX\ in the
% \texttt{mplibcode} environment.
%
% There are (basically) two formats for metapost: \emph{plain} and
% \emph{mpfun}. By default, the \emph{plain} format is used, but you can set
% the format to be used by future figures at any time using
% \cs{mplibsetformat}\marg{format name}.
%
%    \section{Implementation}
%
%    \subsection{Lua module}
%
%    \begin{macrocode}
%<*lua>
%    \end{macrocode}
%
%    Use the |luamplib| namespace, since |mplib| is for the metapost library
%    itself.
%
%    \begin{macrocode}
module('luamplib', package.seeall)
%    \end{macrocode}
%
%    Identification, and additional reporting function, for compatibility with
%    the original |report()| function and associated data structure.
%
%    \begin{macrocode}
local err, warn, info, log = luatexbase.provides_module({
    name          = "luamplib",
    version       =  1.09,
    date          = "2011/11/09",
    description   = "Lua package to typeset Metapost with LuaTeX's MPLib.",
})

local function term(...)
    texio.write_nl('term', 'luamplib: ' .. string.format(...))
end

%    \end{macrocode}
%
%    This module is a stripped down version of libraries that are used by
%    Con\TeX t. Provide a few ``shortcuts'' expected by the imported code.
%
%    \begin{macrocode}
local format, concat, abs = string.format, table.concat, math.abs

%    \end{macrocode}
%
%    This is a small trick for \LaTeX . In \LaTeX\ we read the metapost code
%    line by line, but it needs to be passed entirely to |process()|, so we
%    simply add the lines in |data| and at the end we call |process(data)|.
%
%    \begin{macrocode}
local data = ""

local function resetdata()
    data = ""
end
function addline(line)
    data = data .. '\n' .. line
end
function processlines()
    process(data)
    resetdata()
end

%    \end{macrocode}
%
%    As the finder function for |mplib|, use the |kpse| library and
%    make it behave like as if MetaPost was used (or almost, since the engine
%    name is not set this way---not sure if this is a problem).
%
%    \begin{macrocode}
local mpkpse = kpse.new("luatex", "mpost")

local function finder(name, mode, ftype)
    if mode == "w" then
        return name
    else
        return mpkpse:find_file(name,ftype)
    end
end

%    \end{macrocode}
%
%    Default format name, and a public function to change it.
%
%    \begin{macrocode}
local currentformat = "plain"

function setformat (name)
    currentformat = name
end

%    \end{macrocode}
%
%    Create a new mplib object and input the correct .mp file as given by
%    |currentformat|. With older versions of MetaPost, using a |mem| file may
%    be more efficient, but newer versions don't support it any more so for
%    the sake of simplicity, don't even try to use a |mem| file.
%    |ini_version| is ignored by new versions but is useful to prevent old
%    ones from trying to load a |mem| file.
%
%    \begin{macrocode}
function load()
    local mpx = mplib.new {
        find_file   = finder,
        ini_version = true,
    }
    mpx:execute(format("input %s ;", currentformat))
    return mpx
end

%    \end{macrocode}
%
%    The rest of this module is not documented. More information can be found
%    in the Lua\TeX\ manual, articles in user group journals and the files
%    that ship with Con\TeX t.
%
%    \begin{macrocode}
function report(result)
    if not result then
        err("no result object")
    elseif result.status > 0 then
        local t, e, l, f = result.term, result.error, result.log
        if l then
            log(l)
        end
        if t then
            term(t)
        end
        if e then
            if result.status == 1 then
                warn(e)
            else
                err(e)
            end
        end
        if not t and not e and not l then
            if result.status == 1 then
                warn("unknown error, no error, terminal or log messages, maybe missing beginfig/endfig")
            else
                err("unknown error, no error, terminal or log messages, maybe missing beginfig/endfig")
            end
        end
    else
        return true
    end
    return false
end

function process(data)
    local converted, result = false, {}
    local mpx = load()
    if mpx and data then
        local result = mpx:execute(data)
        if report(result) then
            if result.fig then
                converted = convert(result)
            else
                warn("no figure output")
            end
        end
    else
        err("Mem file unloadable. Maybe generated with a different version of mplib?")
    end
    return converted, result
end

local function getobjects(result,figure,f)
    return figure:objects()
end

function convert(result, flusher)
    flush(result, flusher)
    return true -- done
end

local function pdf_startfigure(n,llx,lly,urx,ury)
    tex.sprint(format("\\mplibstarttoPDF{%s}{%s}{%s}{%s}",llx,lly,urx,ury))
end

local function pdf_stopfigure()
    tex.sprint("\\mplibstoptoPDF")
end

function pdf_literalcode(fmt,...) -- table
    tex.sprint(format("\\mplibtoPDF{%s}",format(fmt,...)))
end

function pdf_textfigure(font,size,text,width,height,depth)
    text = text:gsub(".","\\hbox{%1}") -- kerning happens in metapost
    tex.sprint(format("\\mplibtextext{%s}{%s}{%s}{%s}{%s}",font,size,text,0,-( 7200/ 7227)/65536*depth))
end

local bend_tolerance = 131/65536

local rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1

local function pen_characteristics(object)
    if mplib.pen_info then
        local t = mplib.pen_info(object)
        rx, ry, sx, sy, tx, ty = t.rx, t.ry, t.sx, t.sy, t.tx, t.ty
        divider = sx*sy - rx*ry
        return not (sx==1 and rx==0 and ry==0 and sy==1 and tx==0 and ty==0), t.width
    else
        rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1
        return false, 1
    end
end

local function concat(px, py) -- no tx, ty here
    return (sy*px-ry*py)/divider,(sx*py-rx*px)/divider
end

local function curved(ith,pth)
    local d = pth.left_x - ith.right_x
    if abs(ith.right_x - ith.x_coord - d) <= bend_tolerance and abs(pth.x_coord - pth.left_x - d) <= bend_tolerance then
        d = pth.left_y - ith.right_y
        if abs(ith.right_y - ith.y_coord - d) <= bend_tolerance and abs(pth.y_coord - pth.left_y - d) <= bend_tolerance then
            return false
        end
    end
    return true
end

local function flushnormalpath(path,open)
    local pth, ith
    for i=1,#path do
        pth = path[i]
        if not ith then
            pdf_literalcode("%f %f m",pth.x_coord,pth.y_coord)
        elseif curved(ith,pth) then
            pdf_literalcode("%f %f %f %f %f %f c",ith.right_x,ith.right_y,pth.left_x,pth.left_y,pth.x_coord,pth.y_coord)
        else
            pdf_literalcode("%f %f l",pth.x_coord,pth.y_coord)
        end
        ith = pth
    end
    if not open then
        local one = path[1]
        if curved(pth,one) then
            pdf_literalcode("%f %f %f %f %f %f c",pth.right_x,pth.right_y,one.left_x,one.left_y,one.x_coord,one.y_coord )
        else
            pdf_literalcode("%f %f l",one.x_coord,one.y_coord)
        end
    elseif #path == 1 then
        -- special case .. draw point
        local one = path[1]
        pdf_literalcode("%f %f l",one.x_coord,one.y_coord)
    end
    return t
end

local function flushconcatpath(path,open)
    pdf_literalcode("%f %f %f %f %f %f cm", sx, rx, ry, sy, tx ,ty)
    local pth, ith
    for i=1,#path do
        pth = path[i]
        if not ith then
           pdf_literalcode("%f %f m",concat(pth.x_coord,pth.y_coord))
        elseif curved(ith,pth) then
            local a, b = concat(ith.right_x,ith.right_y)
            local c, d = concat(pth.left_x,pth.left_y)
            pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(pth.x_coord, pth.y_coord))
        else
           pdf_literalcode("%f %f l",concat(pth.x_coord, pth.y_coord))
        end
        ith = pth
    end
    if not open then
        local one = path[1]
        if curved(pth,one) then
            local a, b = concat(pth.right_x,pth.right_y)
            local c, d = concat(one.left_x,one.left_y)
            pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(one.x_coord, one.y_coord))
        else
            pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord))
        end
    elseif #path == 1 then
        -- special case .. draw point
        local one = path[1]
        pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord))
    end
    return t
end

%    \end{macrocode}
%
%    Support for specials in DVI has been removed.
%
%    \begin{macrocode}
function flush(result,flusher)
    if result then
        local figures = result.fig
        if figures then
            for f=1, #figures do
                log("flushing figure %s",f)
                local figure = figures[f]
                local objects = getobjects(result,figure,f)
                local fignum = tonumber((figure:filename()):match("([%d]+)$") or figure:charcode() or 0)
                local miterlimit, linecap, linejoin, dashed = -1, -1, -1, false
                local bbox = figure:boundingbox()
                local llx, lly, urx, ury = bbox[1], bbox[2], bbox[3], bbox[4] -- faster than unpack
                if urx < llx then
                    -- invalid
                    pdf_startfigure(fignum,0,0,0,0)
                    pdf_stopfigure()
                else
                    pdf_startfigure(fignum,llx,lly,urx,ury)
                    pdf_literalcode("q")
                    if objects then
                        for o=1,#objects do
                            local object = objects[o]
                            local objecttype = object.type
                            if objecttype == "start_bounds" or objecttype == "stop_bounds" then
                                -- skip
                            elseif objecttype == "start_clip" then
                                pdf_literalcode("q")
                                flushnormalpath(object.path,t,false)
                                pdf_literalcode("W n")
                            elseif objecttype == "stop_clip" then
                                pdf_literalcode("Q")
                                miterlimit, linecap, linejoin, dashed = -1, -1, -1, false
                            elseif objecttype == "special" then
                                -- not supported
                            elseif objecttype == "text" then
                                local ot = object.transform -- 3,4,5,6,1,2
                                pdf_literalcode("q %f %f %f %f %f %f cm",ot[3],ot[4],ot[5],ot[6],ot[1],ot[2])
                                pdf_textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth)
                                pdf_literalcode("Q")
                            else
                                local cs = object.color
                                if cs and #cs > 0 then
                                    pdf_literalcode(colorconverter(cs))
                                end
                                local ml = object.miterlimit
                                if ml and ml ~= miterlimit then
                                    miterlimit = ml
                                    pdf_literalcode("%f M",ml)
                                end
                                local lj = object.linejoin
                                if lj and lj ~= linejoin then
                                    linejoin = lj
                                    pdf_literalcode("%i j",lj)
                                end
                                local lc = object.linecap
                                if lc and lc ~= linecap then
                                    linecap = lc
                                    pdf_literalcode("%i J",lc)
                                end
                                local dl = object.dash
                                if dl then
                                    local d = format("[%s] %i d",concat(dl.dashes or {}," "),dl.offset)
                                    if d ~= dashed then
                                        dashed = d
                                        pdf_literalcode(dashed)
                                    end
                                elseif dashed then
                                   pdf_literalcode("[] 0 d")
                                   dashed = false
                                end
                                local path = object.path
                                local transformed, penwidth = false, 1
                                local open = path and path[1].left_type and path[#path].right_type
                                local pen = object.pen
                                if pen then
                                   if pen.type == 'elliptical' then
                                        transformed, penwidth = pen_characteristics(object) -- boolean, value
                                        pdf_literalcode("%f w",penwidth)
                                        if objecttype == 'fill' then
                                            objecttype = 'both'
                                        end
                                   else -- calculated by mplib itself
                                        objecttype = 'fill'
                                   end
                                end
                                if transformed then
                                    pdf_literalcode("q")
                                end
                                if path then
                                    if transformed then
                                        flushconcatpath(path,open)
                                    else
                                        flushnormalpath(path,open)
                                    end
                                    if objecttype == "fill" then
                                        pdf_literalcode("h f")
                                    elseif objecttype == "outline" then
                                        pdf_literalcode((open and "S") or "h S")
                                    elseif objecttype == "both" then
                                        pdf_literalcode("h B")
                                    end
                                end
                                if transformed then
                                    pdf_literalcode("Q")
                                end
                                local path = object.htap
                                if path then
                                    if transformed then
                                        pdf_literalcode("q")
                                    end
                                    if transformed then
                                        flushconcatpath(path,open)
                                    else
                                        flushnormalpath(path,open)
                                    end
                                    if objecttype == "fill" then
                                        pdf_literalcode("h f")
                                    elseif objecttype == "outline" then
                                        pdf_literalcode((open and "S") or "h S")
                                    elseif objecttype == "both" then
                                        pdf_literalcode("h B")
                                    end
                                    if transformed then
                                        pdf_literalcode("Q")
                                    end
                                end
                                if cr then
                                    pdf_literalcode(cr)
                                end
                            end
                       end
                    end
                    pdf_literalcode("Q")
                    pdf_stopfigure()
                end
            end
        end
    end
end

function colorconverter(cr)
    local n = #cr
    if n == 4 then
        local c, m, y, k = cr[1], cr[2], cr[3], cr[4]
        return format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k), "0 g 0 G"
    elseif n == 3 then
        local r, g, b = cr[1], cr[2], cr[3]
        return format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b), "0 g 0 G"
    else
        local s = cr[1]
        return format("%.3f g %.3f G",s,s), "0 g 0 G"
    end
end
%    \end{macrocode}
%
%    \begin{macrocode}
%</lua>
%    \end{macrocode}
%
%    \subsection{\texorpdfstring{\TeX}{TeX} package}
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%
%    First we need to load fancyvrb, to define the environment mplibcode.
%
%    \begin{macrocode}
\bgroup\expandafter\expandafter\expandafter\egroup
\expandafter\ifx\csname ProvidesPackage\endcsname\relax
  \input luatexbase-modutils.sty
\else
  \NeedsTeXFormat{LaTeX2e}
  \ProvidesPackage{luamplib}
    [2011/12/09 v1.09 mplib package for LuaTeX]
  \RequirePackage{luatexbase-modutils}
  \RequirePackage{fancyvrb}
\fi
%    \end{macrocode}
%
%    Loading of lua code.
%
%    \begin{macrocode}
\RequireLuaModule{luamplib}
%    \end{macrocode}
%
%    Set the format for metapost.
%
%    \begin{macrocode}
\def\mplibsetformat#1{%
  \directlua{luamplib.setformat("\luatexluaescapestring{#1}")}}
%    \end{macrocode}
%
%    MPLib only works in PDF mode, we don't do anything if we are in DVI mode,
%    and we output a warning.
%
%    \begin{macrocode}
\ifnum\pdfoutput>0
    \let\mplibtoPDF\pdfliteral
\else
    %\def\MPLIBtoPDF#1{\special{pdf:literal direct #1}} % not ok yet
    \def\mplibtoPDF#1{}
    \expandafter\ifx\csname PackageWarning\endcsname\relax
      \write16{}
      \write16{Warning: MPLib only works in PDF mode, no figure will be output.}
      \write16{}
    \else
      \PackageWarning{mplib}{MPLib only works in PDF mode, no figure will be output.}
    \fi
\fi
%    \end{macrocode}
%
%    The Plain-specific stuff.
%
%    \begin{macrocode}
\bgroup\expandafter\expandafter\expandafter\egroup
\expandafter\ifx\csname ProvidesPackage\endcsname\relax
\def\mplibsetupcatcodes{%
  \catcode`\{=12 \catcode`\}=12 \catcode`\#=12 \catcode`\^=12 \catcode`\~=12
  \catcode`\_=12 \catcode`\%=12 \catcode`\&=12 \catcode`\$=12
}
\def\mplibcode{%
  \bgroup %
  \mplibsetupcatcodes %
  \mplibdocode %
}
\long\def\mplibdocode#1\endmplibcode{%
  \egroup %
  \mplibprocess{#1}%
}
\long\def\mplibprocess#1{%
  \directlua{luamplib.process("\luatexluaescapestring{#1}")}%
}
\else
%    \end{macrocode}
%
%    The \LaTeX-specific parts. First a Hack for the catcodes in \LaTeX .
%
%    \begin{macrocode}
\begingroup
\catcode`\,=13
\catcode`\-=13
\catcode`\<=13
\catcode`\>=13
\catcode`\^^I=13
\catcode`\`=13 % must be last...
\gdef\FV@hack{%
  \def,{\string,}%
  \def-{\string-}%
  \def<{\string<}%
  \def>{\string>}%
  \def`{\string`}%
  \def^^I{\string^^I}%
}
\endgroup
%    \end{macrocode}
%
%    In \LaTeX\ (it's not the case in plain\TeX ), we get the metapost code
%    line by line, here is the function handling a line.
%
%    \begin{macrocode}
\newcommand\mplibaddlines[1]{%
  \begingroup %
  \FV@hack %
  \def\FV@ProcessLine##1{%
    \directlua{luamplib.addline("\luatexluaescapestring{##1}")}%
  }%
  \csname FV@SV@#1\endcsname %
  \endgroup %
}
%    \end{macrocode}
%
%    The \LaTeX\ environment is a modified \texttt{verbatim} environment.
%
%    \begin{macrocode}
\newenvironment{mplibcode}{%
  \VerbatimEnvironment %
  \begin{SaveVerbatim}{memoire}%
}{%
  \end{SaveVerbatim}%
  \mplibaddlines{memoire}%
  \directlua{luamplib.processlines()}%
}

\fi
%    \end{macrocode}
%
%    We use a dedicated scratchbox.
%
%    \begin{macrocode}
\ifx\mplibscratchbox\undefined \newbox\mplibscratchbox \fi
%    \end{macrocode}
%
%    We encapsulate the litterals.
%
%    \begin{macrocode}
\def\mplibstarttoPDF#1#2#3#4{%
  \hbox\bgroup
  \xdef\MPllx{#1}\xdef\MPlly{#2}%
  \xdef\MPurx{#3}\xdef\MPury{#4}%
  \xdef\MPwidth{\the\dimexpr#3bp-#1bp\relax}%
  \xdef\MPheight{\the\dimexpr#4bp-#2bp\relax}%
  \parskip0pt%
  \leftskip0pt%
  \parindent0pt%
  \everypar{}%
  \setbox\mplibscratchbox\vbox\bgroup
  \noindent
}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\mplibstoptoPDF{%
  \egroup %
  \setbox\mplibscratchbox\hbox %
    {\hskip-\MPllx bp%
     \raise-\MPlly bp%
     \box\mplibscratchbox}%
  \setbox\mplibscratchbox\vbox to \MPheight
    {\vfill
     \hsize\MPwidth
     \wd\mplibscratchbox0pt%
     \ht\mplibscratchbox0pt%
     \dp\mplibscratchbox0pt%
     \box\mplibscratchbox}%
  \wd\mplibscratchbox\MPwidth
  \ht\mplibscratchbox\MPheight
  \box\mplibscratchbox
  \egroup
}
%    \end{macrocode}
%
%    Text items have a special handler.
%
%    \begin{macrocode}
\def\mplibtextext#1#2#3#4#5{%
  \begingroup
  \setbox\mplibscratchbox\hbox
    {\font\temp=#1 at #2bp%
     \temp
     #3}%
  \setbox\mplibscratchbox\hbox
    {\hskip#4 bp%
     \raise#5 bp%
     \box\mplibscratchbox}%
  \wd\mplibscratchbox0pt%
  \ht\mplibscratchbox0pt%
  \dp\mplibscratchbox0pt%
  \box\mplibscratchbox
  \endgroup
}
%    \end{macrocode}
%
%    That's all folks!
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
%
% \Finale
\endinput
