texlive[50510] Master/texmf-dist: luamplib (21mar19)

commits+karl at tug.org commits+karl at tug.org
Thu Mar 21 21:54:31 CET 2019


Revision: 50510
          http://tug.org/svn/texlive?view=revision&revision=50510
Author:   karl
Date:     2019-03-21 21:54:31 +0100 (Thu, 21 Mar 2019)
Log Message:
-----------
luamplib (21mar19)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/luatex/luamplib/NEWS
    trunk/Master/texmf-dist/doc/luatex/luamplib/luamplib.pdf
    trunk/Master/texmf-dist/doc/luatex/luamplib/test-luamplib-latex.tex
    trunk/Master/texmf-dist/doc/luatex/luamplib/test-luamplib-plain.tex
    trunk/Master/texmf-dist/source/luatex/luamplib/luamplib.dtx
    trunk/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua
    trunk/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty

Modified: trunk/Master/texmf-dist/doc/luatex/luamplib/NEWS
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luamplib/NEWS	2019-03-21 20:54:17 UTC (rev 50509)
+++ trunk/Master/texmf-dist/doc/luatex/luamplib/NEWS	2019-03-21 20:54:31 UTC (rev 50510)
@@ -1,5 +1,18 @@
                        History of the luamplib package
 
+2019/03/20 2.20.0
+    * huge changes, but mostly internal, so apparently not much difference
+      from previous version.
+    * '\mplibforcehmode' makes mplibcode typeset in horizontal mode.
+      '\mplibnoforcehmode' reverts the setting. The latter is default.
+    * '\mpliblegacybehavior{disable}' triggers a new mode of processing
+      verbatimtex .. etex: along with btex .. etex, they will be processed
+      sequentially one by one. Old behavior, being default, can be restored
+      by declaring '\mpliblegacybehavior{enable}'.
+      Incidentally, verbatimtex .. etex in MP input files is honored
+      from this version, save those that contain '\documentclass'
+      or '\begin{document}' etc, which is totally ignored.
+
 2018/09/27 2.12.5
     * change dash.offset pattern from "%i" to "%f" (PR #77)
     * remove unnecessary variables that go back to context (issue #76)

Modified: trunk/Master/texmf-dist/doc/luatex/luamplib/luamplib.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/luatex/luamplib/test-luamplib-latex.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luamplib/test-luamplib-latex.tex	2019-03-21 20:54:17 UTC (rev 50509)
+++ trunk/Master/texmf-dist/doc/luatex/luamplib/test-luamplib-latex.tex	2019-03-21 20:54:31 UTC (rev 50510)
@@ -3,6 +3,7 @@
 \usepackage{xcolor}
 \everymplib{ beginfig(0); }
 \everyendmplib{ endfig; }
+\mpliblegacybehavior{true}%
 \begin{document}
 \tracingcommands1
 A%

Modified: trunk/Master/texmf-dist/doc/luatex/luamplib/test-luamplib-plain.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luamplib/test-luamplib-plain.tex	2019-03-21 20:54:17 UTC (rev 50509)
+++ trunk/Master/texmf-dist/doc/luatex/luamplib/test-luamplib-plain.tex	2019-03-21 20:54:31 UTC (rev 50510)
@@ -2,6 +2,7 @@
 \input color
 \definecolor{orange}{rgb}{1,0.5,0}
 \input luamplib.sty
+\mpliblegacybehavior{true}%
 \everymplib{ beginfig(0); }\everyendmplib{ endfig; }
 \tracingcommands1
 A%

Modified: trunk/Master/texmf-dist/source/luatex/luamplib/luamplib.dtx
===================================================================
--- trunk/Master/texmf-dist/source/luatex/luamplib/luamplib.dtx	2019-03-21 20:54:17 UTC (rev 50509)
+++ trunk/Master/texmf-dist/source/luatex/luamplib/luamplib.dtx	2019-03-21 20:54:31 UTC (rev 50510)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment -- by the way, this file contains UTF-8
 %
-% Copyright (C) 2008-2018 by Hans Hagen, Taco Hoekwater, Elie Roux,
+% Copyright (C) 2008-2019 by Hans Hagen, Taco Hoekwater, Elie Roux,
 % Manuel Pégourié-Gonnard, Philipp Gesang and Kim Dohyun.
 % Currently maintained by the LuaLaTeX development team.
 % Support: <lualatex-dev at tug.org>
@@ -85,7 +85,7 @@
 %<*driver>
 \NeedsTeXFormat{LaTeX2e}
 \ProvidesFile{luamplib.drv}%
-  [2018/09/27 v2.12.5 Interface for using the mplib library]%
+  [2019/03/20 v2.20.0 Interface for using the mplib library]%
 \documentclass{ltxdoc}
 \usepackage{metalogo,multicol,mdwlist,fancyvrb,xspace}
 \usepackage[x11names]{xcolor}
@@ -153,18 +153,18 @@
 % \author{Hans Hagen, Taco Hoekwater, Elie Roux, Philipp Gesang and Kim Dohyun\\
 % Maintainer: LuaLaTeX Maintainers ---
 % Support: \email{lualatex-dev at tug.org}}
-% \date{2018/09/27 v2.12.5}
+% \date{2019/03/20 v2.20.0}
 %
 % \maketitle
 %
 % \begin{abstract}
-% Package to have metapost code typeset directly in a document with Lua\TeX .
+% Package to have metapost code typeset directly in a document with \LuaTeX.
 % \end{abstract}
 %
 % \section{Documentation}
 %
 % This packages aims at providing a simple way to typeset directly metapost
-% code in a document with \LuaTeX . \LuaTeX\ is built with the lua
+% code in a document with \LuaTeX. \LuaTeX\ 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.
@@ -194,15 +194,29 @@
 %   |textext()| is a more versatile macro equivalent to |TEX()| from TEX.mp.
 %   |TEX()| is also allowed and is a synomym of |textext()|.\par\smallskip
 %   \textsc{n.b.} Since v2.5, |btex ... etex| input from external |mp| files
-%   will also be processed by \textsf{luamplib}. However,
-%   |verbatimtex ... etex| will be entirely ignored in this case.
-% \item |verbatimtex ... etex| (in \TeX\ file) that comes just before |beginfig()|
-%   is not ignored, but the \TeX\ code inbetween will be inserted before the
+%   will also be processed by \textsf{luamplib}.\par\smallskip
+%   \textsc{n.b.} Since v2.20, |verbatimtex ... etex| from external |mp| files
+%    will be also processed by \textsf{luamplib}. Warning: This is a change
+%   from previous version.
+% \end{itemize}
+%
+% Some more changes and cuations are:
+%
+% \paragraph{\cs{mplibforcehmode}}
+%   When this macro is declared, every mplibcode figure box will be
+%   typeset in horizontal mode, so \cs{centering}, \cs{raggedleft} etc
+%   will have effects. |\mplibnoforcehmode|, being default, reverts this
+%   setting.
+%
+% \paragraph{\cs{mpliblegacybehavior\{enable\}}}
+%   By default, |\mpliblegacybehavior{enable}| is already declared,
+%   in which case
+%   a |verbatimtex ... etex| that comes just before |beginfig()|
+%   is not ignored, but the \TeX\ code will be inserted before the
 %   following mplib hbox.  Using this command,
 %   each mplib box can be freely moved horizontally and/or vertically.
 %   Also, a box number might be assigned to mplib box, allowing it to be
 %   reused later (see test files).
-%   \textsc{e.g.}
 %   \begin{verbatim}
 %     \mplibcode
 %     verbatimtex \moveright 3cm etex; beginfig(0); ... endfig;
@@ -213,11 +227,10 @@
 %   \end{verbatim}
 %   \textsc{n.b.} \cs{endgraf} should be used instead of \cs{par} inside
 %   |verbatimtex ... etex|.
-% \item
-%   \TeX\ code in |VerbatimTeX(...)| or |verbatimtex ... etex| (in \TeX\ file)
+%
+%   By contrast, \TeX\ code in |VerbatimTeX(...)| or |verbatimtex ... etex|
 %   between |beginfig()| and |endfig| will be inserted
 %   after flushing out the mplib figure.
-%   \textsc{e.g.}
 %   \begin{verbatim}
 %     \mplibcode
 %       D := sqrt(2)**7;
@@ -228,32 +241,48 @@
 %     \endmplibcode
 %     diameter: \Dia bp.
 %   \end{verbatim}
-% \item Notice that, after each figure is processed, macro \cs{MPwidth} stores
+%
+% \paragraph{\cs{mpliblegacybehavior\{disable\}}}
+%   If |\mpliblegacybehavior{disabled}| is declared by user, any
+%   |verbatimtex ... etex| will be executed, along with |btex ... etex|,
+%   sequentially one by one.
+%   So, some \TeX\ code in |verbatimtex ... etex| will have effects on
+%   |btex ... etex| codes that follows.
+%   \begin{verbatim}
+%     \begin{mplibcode}
+%       beginfig(0);
+%       draw btex ABC etex;
+%       verbatimtex \bfseries etex;
+%       draw btex DEF etex shifted (1cm,0); % bold face
+%       draw btex GHI etex shifted (2cm,0); % bold face
+%       endfig;
+%     \end{mplibcode}
+%   \end{verbatim}
+%
+% \paragraph{About figure box metrics}
+%   Notice that, after each figure is processed, macro \cs{MPwidth} stores
 %   the width value of latest figure; \cs{MPheight}, the height value.
 %   Incidentally, also note that \cs{MPllx}, \cs{MPlly}, \cs{MPurx}, and
 %   \cs{MPury} store the bounding box information of latest figure
 %   without the unit |bp|.
-% \item Since v2.3, new macros \cs{everymplib} and \cs{everyendmplib} redefine
+%
+% \paragraph{\cs{everymplib}, \cs{everyendmplib}}
+%   Since v2.3, new macros \cs{everymplib} and \cs{everyendmplib} redefine
 %   token lists \cs{everymplibtoks} and \cs{everyendmplibtoks} respectively,
 %   which will
 %   be automatically inserted at the beginning and ending of each mplib code.
-%   \textsc{e.g.}
 %   \begin{verbatim}
-%     \everymplib{ verbatimtex \leavevmode etex; beginfig(0); }
+%     \everymplib{ beginfig(0); }
 %     \everyendmplib{ endfig; }
-%     \mplibcode % beginfig/endfig not needed; always in horizontal mode
+%     \mplibcode % beginfig/endfig not needed
 %       draw fullcircle scaled 1cm;
 %     \endmplibcode
 %   \end{verbatim}
-%   \textsc{n.b.} Many users have complained that mplib figures do not
-%   respect alignment commands such as \cs{centering} or \cs{raggedleft}.
-%   That's because \textsf{luamplib} does not force horizontal or vertical mode.
-%   If you want all mplib figures center- (or right-) aligned, please use
-%   \cs{everymplib} command with \cs{leavevmode} as shown above.
-% \item Since v2.3, \cs{mpdim} and other raw \TeX\ commands are allowed
+%
+% \paragraph{\cs{mpdim}}
+%   Since v2.3, \cs{mpdim} and other raw \TeX\ commands are allowed
 %   inside mplib code. This feature is inpired by gmp.sty authored by
 %   Enrico Gregorio. Please refer the manual of gmp package for details.
-%   \textsc{e.g.}
 %   \begin{verbatim}
 %     \begin{mplibcode}
 %       draw origin--(\mpdim{\linewidth},0) withpen pencircle scaled 4
@@ -264,17 +293,24 @@
 %   |btex ... etex| as provided by gmp package. As \textsf{luamplib}
 %   automatically protects \TeX\ code inbetween, \cs{btex} is not supported
 %   here.
-% \item With \cs{mpcolor} command, color names or expressions of
+%
+% \paragraph{\cs{mpcolor}}
+%   With \cs{mpcolor} command, color names or expressions of
 %   \textsf{color}/\textsf{xcolor} packages can be used inside mplibcode
 %   enviroment, though \textsf{luamplib} does not automatically load these
 %   packages. See the example code above. For spot colors, \textsf{(x)spotcolor}
 %   (in PDF mode) and \textsf{xespotcolor} (in DVI mode) packages are supported
 %   as well.
-% \item Users can choose |numbersystem| option since v2.4.
-%   The default value |scaled| can be changed to |double| by declaring
-%   |\mplibnumbersystem{double}|. For details see
+%
+% \paragraph{\cs{mplibnumbersystem}}
+%   Users can choose |numbersystem| option since v2.4.
+%   The default value |scaled| can be changed to |double| or |decimal|
+%   by declaring |\mplibnumbersystem{double}| or |\mplibnumbersystem{decimal}|.
+%   For details see
 %   \url{http://github.com/lualatex/luamplib/issues/21}.
-% \item To support |btex ... etex| in external |.mp| files, \textsf{luamplib}
+%
+% \paragraph{Settings regarding cache files}
+%   To support |btex ... etex| in external |.mp| files, \textsf{luamplib}
 %   inspects the content of each and every |.mp| input files and makes caches
 %   if nececcsary, before returning their paths to \LuaTeX's mplib library.
 %   This would make the compilation time longer wastefully, as most |.mp| files
@@ -288,14 +324,17 @@
 %   where |<filename>| is a file name excluding |.mp| extension.
 %   Note that |.mp| files under |$TEXMFMAIN/metapost/base| and
 %   |$TEXMFMAIN/metapost/context/base| are already registered by default.
-% \item By default, cache files will be stored in |$TEXMFVAR/luamplib_cache|
-%   or, if it's not available, in the same directory as where pdf/dvi output file
+%
+%   By default, cache files will be stored in |$TEXMFVAR/luamplib_cache| or,
+%   if it's not available, in the same directory as where pdf/dvi output file
 %   is saved. This however can be changed by the command
 %   |\mplibcachedir{<directory path>}|, where tilde (|~|) is interpreted
 %   as the user's home directory (on a windows machine as well).
 %   As backslashes (|\|) should be escaped by users, it would be easier to use
 %   slashes (|/|) instead.
-% \item Starting with v2.6, |\mplibtextextlabel{enable}| enables
+%
+% \paragraph{\cs{mplibtextextlabel}}
+%   Starting with v2.6, |\mplibtextextlabel{enable}| enables
 %   string labels typeset via |textext()| instead of |infont| operator.
 %   So, |label("my text",origin)| thereafter is exactly the same as
 %   |label(textext("my text"),origin)|. \textsc{n.b.} In the background,
@@ -304,13 +343,15 @@
 %   therefore will be typeset with current \TeX\ font.
 %   Also take care of |char| operator in the left side argument,
 %   as this might bring unpermitted characters into \TeX.
-% \item Starting with v2.9, |\mplibcodeinherit{enable}| enables the inheritance
+%
+% \paragraph{\cs{mplibcodeinherit}}
+%   Starting with v2.9, |\mplibcodeinherit{enable}| enables the inheritance
 %   of variables, constants, and macros defined by previous |mplibcode| chunks.
 %   On the contrary, the default value |\mplibcodeinherit{disable}| will make
 %   each code chunks being treated as an independent instance, and never
 %   affected by previous code chunks.
 %
-%   \textsc{n.b.}
+% \paragraph{\cs{mplibglobaltextext}}
 %   To inherit |btex ... etex| labels as well as metapost variables,
 %   it is necessary to declare \cs{mplibglobaltextext\{enable\}} in advance.
 %   On this case, be careful that normal \TeX\ boxes can conflict with
@@ -331,17 +372,22 @@
 %     currentpicture := pic scaled 2;
 %   \endmplibcode
 %   \end{verbatim}
-% \item Starting with v2.11, users can issue |\mplibverbatim{enable}|, after which
+%
+% \paragraph{\cs{mplibverbatim}}
+%   Starting with v2.11, users can issue |\mplibverbatim{enable}|, after which
 %   the contents of mplibcode environment will be read verbatim. As a result,
-%   users cannot use |\mpdim|, |\mpcolor| etc. All \TeX\ commands outside of
+%   users cannot use |\mpdim|, but |\mpcolor| is OK.
+%   All other \TeX\ commands outside
 %   |btex ... etex| or |verbatimtex ... etex| are not expanded and will be fed
 %   literally into the mplib process.
-% \item At the end of package loading, \textsf{luamplib} searches
+%
+% \paragraph{luamplib.cfg}
+%   At the end of package loading, \textsf{luamplib} searches
 %   |luamplib.cfg| and, if found, reads the file in automatically.
-%   Frequently used settings such as \cs{everymplib} or \cs{mplibcachedir}
+%   Frequently used settings such as \cs{everymplib} or \cs{mplibforcehmode}
 %   are suitable for going into this file.
 %
-% \end{itemize}
+% \bigskip
 %
 % There are (basically) two formats for metapost: \emph{plain} and
 % \emph{metafun}. By default, the \emph{plain} format is used, but you can set
@@ -355,46 +401,38 @@
 % \iffalse
 %<*lua>
 % \fi
-%    Use the |luamplib| namespace, since |mplib| is for the metapost library
-%    itself. \ConTeXt{} uses |metapost|.
 %
 %    \begin{macrocode}
 
-luamplib          = luamplib or { }
+luatexbase.provides_module {
+  name          = "luamplib",
+  version       = "2.20.0",
+  date          = "2019/03/20",
+  description   = "Lua package to typeset Metapost with LuaTeX's MPLib.",
+}
 
+local format, abs = string.format, math.abs
+
+local err  = function(...) return luatexbase.module_error  ("luamplib", format(...)) end
+local warn = function(...) return luatexbase.module_warning("luamplib", format(...)) end
+local info = function(...) return luatexbase.module_info   ("luamplib", format(...)) end
+
 %    \end{macrocode}
-%    Identification.
 %
+%    Use the |luamplib| namespace, since |mplib| is for the metapost library
+%    itself. \ConTeXt{} uses |metapost|.
 %    \begin{macrocode}
+luamplib          = luamplib or { }
+local luamplib    = luamplib
 
-local luamplib    = luamplib
 luamplib.showlog  = luamplib.showlog or false
 luamplib.lastlog  = ""
 
-luatexbase.provides_module {
-  name          = "luamplib",
-  version       = "2.12.5",
-  date          = "2018/09/27",
-  description   = "Lua package to typeset Metapost with LuaTeX's MPLib.",
-}
-
 %    \end{macrocode}
+%
 %    This module is a stripped down version of libraries that are used by
 %    \ConTeXt. Provide a few ``shortcuts'' expected by the imported code.
-%
 %    \begin{macrocode}
-
-local format, abs = string.format, math.abs
-
-local err  = function(...) return luatexbase.module_error  ("luamplib", format(...)) end
-local warn = function(...) return luatexbase.module_warning("luamplib", format(...)) end
-local info = function(...) return luatexbase.module_info   ("luamplib", format(...)) end
-
-local stringgsub    = string.gsub
-local stringfind    = string.find
-local stringmatch   = string.match
-local stringgmatch  = string.gmatch
-local stringexplode = string.explode
 local tableconcat   = table.concat
 local texsprint     = tex.sprint
 local textprint     = tex.tprint
@@ -402,7 +440,13 @@
 local texget      = tex.get
 local texgettoks  = tex.gettoks
 local texgetbox   = tex.getbox
+local texruntoks  = tex.runtoks
+local texscantoks = tex.scantoks
 
+if not texruntoks then
+  err("Your LuaTeX version is too old. Please upgrade it to the latest")
+end
+
 local mplib = require ('mplib')
 local kpse  = require ('kpse')
 local lfs   = require ('lfs')
@@ -413,25 +457,19 @@
 local lfstouch      = lfs.touch
 local ioopen        = io.open
 
-local file = file or { }
 %    \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)|.
 %
-%    A few helpers, taken from |l-file.lua|.
-%
+%    Some helper functions, prepared for the case when |l-file| etc
+%    is not loaded.
 %    \begin{macrocode}
+local file = file or { }
 local replacesuffix = file.replacesuffix or function(filename, suffix)
-  return (stringgsub(filename,"%.[%a%d]+$","")) .. "." .. suffix
+  return (filename:gsub("%.[%a%d]+$","")) .. "." .. suffix
 end
 local stripsuffix = file.stripsuffix or function(filename)
-  return (stringgsub(filename,"%.[%a%d]+$",""))
+  return (filename:gsub("%.[%a%d]+$",""))
 end
 
-%    \end{macrocode}
-%     |btex ... etex| in input .mp files will be replaced in finder.
-%    \begin{macrocode}
 local is_writable = file.is_writable or function(name)
   if lfsisdir(name) then
     name = name .. "/_luam_plib_temp_file_"
@@ -444,12 +482,18 @@
 end
 local mk_full_path = lfs.mkdirs or function(path)
   local full = ""
-  for sub in stringgmatch(path,"(/*[^\\/]+)") do
+  for sub in path:gmatch("(/*[^\\/]+)") do
     full = full .. sub
     lfsmkdir(full)
   end
 end
 
+%    \end{macrocode}
+%
+%    |btex ... etex| in input |.mp| files will be replaced in finder.
+%    Because of the limitation of MPLib regarding |make_text|,
+%    we might have to make cache files modified from input files.
+%    \begin{macrocode}
 local luamplibtime = kpse.find_file("luamplib.lua")
 luamplibtime = luamplibtime and lfsattributes(luamplibtime,"modification")
 
@@ -459,7 +503,7 @@
 if lfstouch then
   local texmfvar = kpse.expand_var('$TEXMFVAR')
   if texmfvar and texmfvar ~= "" and texmfvar ~= '$TEXMFVAR' then
-    for _,dir in next,stringexplode(texmfvar,os.type == "windows" and ";" or ":") do
+    for _,dir in next, texmfvar:explode(os.type == "windows" and ";" or ":") do
       if not lfsisdir(dir) then
         mk_full_path(dir)
       end
@@ -475,7 +519,7 @@
 if not outputdir then
   outputdir = "."
   for _,v in ipairs(arg) do
-    local t = stringmatch(v,"%-output%-directory=(.+)")
+    local t = v:match("%-output%-directory=(.+)")
     if t then
       outputdir = t
       break
@@ -500,48 +544,32 @@
   end
 end
 
+%    \end{macrocode}
+%
+%    Some basic MetaPost files not necessary to make cache files.
+%    \begin{macrocode}
 local noneedtoreplace = {
-  ["boxes.mp"] = true,
-  --  ["format.mp"] = true,
-  ["graph.mp"] = true,
-  ["marith.mp"] = true,
-  ["mfplain.mp"] = true,
-  ["mpost.mp"] = true,
-  ["plain.mp"] = true,
-  ["rboxes.mp"] = true,
-  ["sarith.mp"] = true,
-  ["string.mp"] = true,
-  ["TEX.mp"] = true,
-  ["metafun.mp"] = true,
-  ["metafun.mpiv"] = true,
-  ["mp-abck.mpiv"] = true,
-  ["mp-apos.mpiv"] = true,
-  ["mp-asnc.mpiv"] = true,
-  ["mp-bare.mpiv"] = true,
-  ["mp-base.mpiv"] = true,
-  ["mp-butt.mpiv"] = true,
-  ["mp-char.mpiv"] = true,
-  ["mp-chem.mpiv"] = true,
-  ["mp-core.mpiv"] = true,
-  ["mp-crop.mpiv"] = true,
-  ["mp-figs.mpiv"] = true,
-  ["mp-form.mpiv"] = true,
-  ["mp-func.mpiv"] = true,
-  ["mp-grap.mpiv"] = true,
-  ["mp-grid.mpiv"] = true,
-  ["mp-grph.mpiv"] = true,
-  ["mp-idea.mpiv"] = true,
-  ["mp-luas.mpiv"] = true,
-  ["mp-mlib.mpiv"] = true,
-  ["mp-node.mpiv"] = true,
-  ["mp-page.mpiv"] = true,
-  ["mp-shap.mpiv"] = true,
-  ["mp-step.mpiv"] = true,
-  ["mp-text.mpiv"] = true,
+  ["boxes.mp"] = true, --  ["format.mp"] = true,
+  ["graph.mp"] = true, ["marith.mp"] = true, ["mfplain.mp"] = true,
+  ["mpost.mp"] = true, ["plain.mp"] = true, ["rboxes.mp"] = true,
+  ["sarith.mp"] = true, ["string.mp"] = true, -- ["TEX.mp"] = true,
+  ["metafun.mp"] = true, ["metafun.mpiv"] = true, ["mp-abck.mpiv"] = true,
+  ["mp-apos.mpiv"] = true, ["mp-asnc.mpiv"] = true, ["mp-bare.mpiv"] = true,
+  ["mp-base.mpiv"] = true, ["mp-blob.mpiv"] = true, ["mp-butt.mpiv"] = true,
+  ["mp-char.mpiv"] = true, ["mp-chem.mpiv"] = true, ["mp-core.mpiv"] = true,
+  ["mp-crop.mpiv"] = true, ["mp-figs.mpiv"] = true, ["mp-form.mpiv"] = true,
+  ["mp-func.mpiv"] = true, ["mp-grap.mpiv"] = true, ["mp-grid.mpiv"] = true,
+  ["mp-grph.mpiv"] = true, ["mp-idea.mpiv"] = true, ["mp-luas.mpiv"] = true,
+  ["mp-mlib.mpiv"] = true, ["mp-node.mpiv"] = true, ["mp-page.mpiv"] = true,
+  ["mp-shap.mpiv"] = true, ["mp-step.mpiv"] = true, ["mp-text.mpiv"] = true,
   ["mp-tool.mpiv"] = true,
 }
 luamplib.noneedtoreplace = noneedtoreplace
 
+%    \end{macrocode}
+%
+%    |format.mp| is much complicated, so specially treated.
+%    \begin{macrocode}
 local function replaceformatmp(file,newfile,ofmodify)
   local fh = ioopen(file,"r")
   if not fh then return file end
@@ -560,26 +588,16 @@
   return newfile
 end
 
-local esctex  = "!!!T!!!E!!!X!!!"
-local esclbr  = "!!!!!LEFTBRCE!!!!!"
-local escrbr  = "!!!!!RGHTBRCE!!!!!"
-local escpcnt = "!!!!!PERCENT!!!!!"
-local eschash = "!!!!!HASH!!!!!"
-local begname = "%f[A-Z_a-z]"
-local endname = "%f[^A-Z_a-z]"
+%    \end{macrocode}
+%
+%    Replace |btex ... etex| and |verbatimtex ... etex| in input files,
+%    if needed.
+%    \begin{macrocode}
+local name_b = "%f[A-Z_a-z]"
+local name_e = "%f[^A-Z_a-z]"
+local btex_etex = name_b.."btex"..name_e.."%s*(.-)%s*"..name_b.."etex"..name_e
+local verbatimtex_etex = name_b.."verbatimtex"..name_e.."%s*(.-)%s*"..name_b.."etex"..name_e
 
-local btex_etex        = begname.."btex"..endname.."%s*(.-)%s*"..begname.."etex"..endname
-local verbatimtex_etex = begname.."verbatimtex"..endname.."%s*(.-)%s*"..begname.."etex"..endname
-
-local function protecttexcontents(str)
-  return str:gsub("\\%%", "\\"..escpcnt)
-            :gsub("%%.-\n", "")
-            :gsub("%%.-$",  "")
-            :gsub('"', '"&ditto&"')
-            :gsub("\n%s*", " ")
-            :gsub(escpcnt, "%%")
-end
-
 local function replaceinputmpfile (name,file)
   local ofmodify = lfsattributes(file,"modification")
   if not ofmodify then return file end
@@ -588,10 +606,12 @@
   newfile = cachedir .."/luamplib_input_"..newfile
   if newfile and luamplibtime then
     local nf = lfsattributes(newfile)
-    if nf and nf.mode == "file" and ofmodify == nf.modification and luamplibtime < nf.access then
+    if nf and nf.mode == "file" and
+      ofmodify == nf.modification and luamplibtime < nf.access then
       return nf.size == 0 and file or newfile
     end
   end
+
   if name == "format.mp" then return replaceformatmp(file,newfile,ofmodify) end
 
   local fh = ioopen(file,"r")
@@ -598,23 +618,17 @@
   if not fh then return file end
   local data = fh:read("*all"); fh:close()
 
+%    \end{macrocode}
+%
+%    ``|etex|'' must be followed by a space or semicolon as specified in
+%    \LuaTeX\ manual, which is not the case of standalone MetaPost though.
+%    \begin{macrocode}
   local count,cnt = 0,0
-
-  data = data:gsub("\"[^\n]-\"", function(str)
-    return str:gsub("([bem])tex"..endname,"%1"..esctex)
-  end)
-
-  data, cnt = data:gsub(btex_etex, function(str)
-    return format("rawtextext(\"%s\")",protecttexcontents(str))
-  end)
+  data, cnt = data:gsub(btex_etex, "btex %1 etex ") -- space
   count = count + cnt
-  data, cnt = data:gsub(verbatimtex_etex, "")
+  data, cnt = data:gsub(verbatimtex_etex, "verbatimtex %1 etex;") -- semicolon
   count = count + cnt
 
-  data = data:gsub("\"[^\n]-\"", function(str) -- restore string btex .. etex
-    return str:gsub("([bem])"..esctex, "%1tex")
-  end)
-
   if count == 0 then
     noneedtoreplace[name] = true
     fh = ioopen(newfile,"w");
@@ -624,6 +638,7 @@
     end
     return file
   end
+
   fh = ioopen(newfile,"w")
   if not fh then return file end
   fh:write(data); fh:close()
@@ -631,14 +646,12 @@
   return newfile
 end
 
-local randomseed = nil
 %    \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).
 %
+%    As the finder function for MPLib, use the |kpse| library and
+%    make it behave like as if MetaPost was used. And replace it with
+%    cache files if needed.
 %    \begin{macrocode}
-
 local mpkpse = kpse.new(arg[0], "mpost")
 
 local special_ftype = {
@@ -658,156 +671,126 @@
       end
       return replaceinputmpfile(name,file)
     end
-    return mpkpse:find_file(name,stringmatch(name,"[a-zA-Z]+$"))
+    return mpkpse:find_file(name, name:match("[a-zA-Z]+$"))
   end
 end
 luamplib.finder = finder
 
 %    \end{macrocode}
-% The rest of this module is not documented. More info can be found in the
-% \LuaTeX{} manual, articles in user group journals and the files that
-% ship with \ConTeXt.
 %
+%    Create and load MPLib instances.
+%    We do not support ancient version of MPLib any more.
+%    (Don't know which version of MPLib started to support
+%    |make_text| and |run_script|; let the users find it.)
 %    \begin{macrocode}
+if tonumber(mplib.version()) <= 1.50 then
+  err("luamplib no longer supports mplib v1.50 or lower. "..
+  "Please upgrade to the latest version of LuaTeX")
+end
 
-function luamplib.resetlastlog()
+local preamble = [[
+  boolean mplib ; mplib := true ;
+  let dump = endinput ;
+  let normalfontsize = fontsize;
+  input %s ;
+]]
+
+local function luamplibresetlastlog()
   luamplib.lastlog = ""
 end
 
-%    \end{macrocode}
-% Below included is section that defines fallbacks for older
-% versions of mplib.
-%
-%    \begin{macrocode}
-local mplibone = tonumber(mplib.version()) <= 1.50
-
-if mplibone then
-
-  luamplib.make = luamplib.make or function(name,mem_name,dump)
-    local t = os.clock()
-    local mpx = mplib.new {
-      ini_version = true,
-      find_file = luamplib.finder,
-      job_name = stripsuffix(name)
-    }
-    mpx:execute(format("input %s ;",name))
-    if dump then
-      mpx:execute("dump ;")
-      info("format %s made and dumped for %s in %0.3f seconds",mem_name,name,os.clock()-t)
-    else
-      info("%s read in %0.3f seconds",name,os.clock()-t)
+local function reporterror (result)
+  if not result then
+    err("no result object returned")
+  else
+    local t, e, l = result.term, result.error, result.log
+    local log = t or l or "no-term"
+    log = log:gsub("^%s+","\n")
+    luamplib.lastlog = luamplib.lastlog .. "\n" .. (l or t or "no-log")
+    if result.status > 0 then
+      warn("%s",log)
+      if result.status > 1 then
+        err("%s",e or "see above messages")
+      end
     end
-    return mpx
+    return log
   end
+end
 
-  function luamplib.load(name)
-    local mem_name = replacesuffix(name,"mem")
-    local mpx = mplib.new {
-      ini_version = false,
-      mem_name = mem_name,
-      find_file = luamplib.finder
-    }
-    if not mpx and type(luamplib.make) == "function" then
-      -- when i have time i'll locate the format and dump
-      mpx = luamplib.make(name,mem_name)
-    end
-    if mpx then
-      info("using format %s",mem_name,false)
-      return mpx, nil
-    else
-      return nil, { status = 99, error = "out of memory or invalid format" }
-    end
-  end
-
-else
-
+local function luamplibload (name)
+  local mpx = mplib.new {
+    ini_version = true,
+    find_file   = luamplib.finder,
 %    \end{macrocode}
-% These are the versions called with sufficiently recent mplib.
 %
-%    \begin{macrocode}
-  local preamble = [[
-    boolean mplib ; mplib := true ;
-    let dump = endinput ;
-    let normalfontsize = fontsize;
-    input %s ;
-  ]]
-
-  luamplib.make = luamplib.make or function()
-  end
-
-  function luamplib.load(name,verbatim)
-    local mpx = mplib.new {
-      ini_version = true,
-      find_file = luamplib.finder,
-%    \end{macrocode}
-%    Provides |numbersystem| option since v2.4. Default value |"scaled"|
-%    can be changed by declaring |\mplibnumbersystem{double}|.
+%    Make use of |make_text| and |run_script|, which will co-operate
+%    with \LuaTeX's |tex.runtoks|. And we
+%    provide |numbersystem| option since v2.4. Default value ``|scaled|''
+%    can be changed by declaring |\mplibnumbersystem{double}|
+%    or |\mplibnumbersystem{decimal}|.
 %    See \url{https://github.com/lualatex/luamplib/issues/21}.
 %    \begin{macrocode}
-      math_mode = luamplib.numbersystem,
-      random_seed = randomseed,
-    }
+    make_text   = luamplib.maketext,
+    run_script  = luamplib.runscript,
+    math_mode   = luamplib.numbersystem,
+    extensions  = 1,
+  }
 %    \end{macrocode}
-%     Append our own preamble to the preamble above.
+%
+%    Append our own MetaPost preamble to the preamble above.
 %    \begin{macrocode}
-    local preamble = preamble .. (verbatim and "" or luamplib.mplibcodepreamble)
-    if luamplib.textextlabel then
-      preamble = preamble .. (verbatim and "" or luamplib.textextlabelpreamble)
-    end
-    local result
-    if not mpx then
-      result = { status = 99, error = "out of memory"}
-    else
-      result = mpx:execute(format(preamble, replacesuffix(name,"mp")))
-    end
-    luamplib.reporterror(result)
-    return mpx, result
+  local preamble = preamble .. luamplib.mplibcodepreamble
+  if luamplib.legacy_verbatimtex then
+    preamble = preamble .. luamplib.legacyverbatimtexpreamble
   end
-
+  if luamplib.textextlabel then
+    preamble = preamble .. luamplib.textextlabelpreamble
+  end
+  local result
+  if not mpx then
+    result = { status = 99, error = "out of memory"}
+  else
+    result = mpx:execute(format(preamble, replacesuffix(name,"mp")))
+  end
+  reporterror(result)
+  return mpx, result
 end
 
+%    \end{macrocode}
+%
+%    |plain| or |metafun|,
+%    though we cannot support |metafun| format fully.
+%    \begin{macrocode}
 local currentformat = "plain"
 
-local function setformat (name) --- used in .sty
+local function setformat (name)
   currentformat = name
 end
 luamplib.setformat = setformat
 
-
-luamplib.reporterror = function (result)
-  if not result then
-    err("no result object returned")
-  else
-    local t, e, l = result.term, result.error, result.log
-    local log = stringgsub(t or l or "no-term","^%s+","\n")
-    luamplib.lastlog = luamplib.lastlog .. "\n " .. (l or t or "no-log")
-    if result.status > 0 then
-      warn("%s",log)
-      if result.status > 1 then
-        err("%s",e or "see above messages")
-      end
-    end
-    return log
-  end
-end
-
-local function process_indeed (mpx, data, indeed)
+%    \end{macrocode}
+%
+%    Here, excute each |mplibcode| data,
+%    ie |\begin{mplibcode} ... \end{mplibcode}|.
+%    \begin{macrocode}
+local function process_indeed (mpx, data)
   local converted, result = false, {}
   if mpx and data then
     result = mpx:execute(data)
-    local log = luamplib.reporterror(result)
-    if indeed and log then
+    local log = reporterror(result)
+    if log then
       if luamplib.showlog then
         info("%s",luamplib.lastlog)
-        luamplib.resetlastlog()
+        luamplibresetlastlog()
       elseif result.fig then
 %    \end{macrocode}
+%
 %    v2.6.1: now luamplib does not disregard |show| command,
 %    even when |luamplib.showlog| is false.  Incidentally,
-%    it does not raise error, but just prints a warning,
+%    it does not raise error but just prints a warning,
 %    even if output has no figure.
 %    \begin{macrocode}
-        if stringfind(log,"\n>>") then info("%s",log) end
+        if log:find("\n>>") then info("%s",log) end
         converted = luamplib.convert(result)
       else
         info("%s",log)
@@ -821,211 +804,279 @@
 end
 
 %    \end{macrocode}
-%     v2.9 has introduced the concept of `code inherit'
+%
+%    v2.9 has introduced the concept of ``code inherit''
 %    \begin{macrocode}
 luamplib.codeinherit = false
 local mplibinstances = {}
-local process = function (data,indeed,verbatim)
+
+local function process (data)
 %    \end{macrocode}
-%     workaround issue \#70
+%
+%    Workaround issue \#70
 %    \begin{macrocode}
-  if not stringfind(data, begname.."beginfig%s*%([%+%-%s]*%d[%.%d%s]*%)") then
+  if not data:find(name_b.."beginfig%s*%([%+%-%s]*%d[%.%d%s]*%)") then
     data = data .. "beginfig(-1);endfig;"
   end
-  local standalone, firstpass = not luamplib.codeinherit, not indeed
+  local standalone = not luamplib.codeinherit
   local currfmt = currentformat .. (luamplib.numbersystem or "scaled")
-  currfmt = firstpass and currfmt or (currfmt.."2")
+    .. tostring(luamplib.textextlabel) .. tostring(luamplib.legacy_verbatimtex)
   local mpx = mplibinstances[currfmt]
+  if mpx and standalone then
+    mpx:finish()
+  end
   if standalone or not mpx then
-    randomseed = firstpass and math.random(65535) or randomseed
-    mpx = luamplib.load(currentformat,verbatim)
+    mpx = luamplibload(currentformat)
     mplibinstances[currfmt] = mpx
   end
-  return process_indeed(mpx, data, indeed)
+  return process_indeed(mpx, data)
 end
-luamplib.process = process
 
-local function getobjects(result,figure,f)
-  return figure:objects()
+%    \end{macrocode}
+%
+%    |make_text| and some |run_script| uses \LuaTeX's |tex.runtoks|,
+%    which made possible running \TeX\ code snippets inside |\directlua|.
+%    \begin{macrocode}
+local catlatex = luatexbase.registernumber("catcodetable at latex")
+local catat11  = luatexbase.registernumber("catcodetable at atletter")
+
+%    \end{macrocode}
+%
+%    |tex.scantoks| sometimes fail to read catcode properly, especially
+%    |\#|, |\&|, or |\%|. After some experiment, we dropped using it.
+%    Instead, a function containing |tex.script| seems to work nicely.
+%    \begin{macrocode}
+local function run_tex_code_no_use (str, cat)
+  cat = cat or catlatex
+  texscantoks("mplibtmptoks", cat, str)
+  texruntoks("mplibtmptoks")
 end
 
-local function convert(result, flusher)
-  luamplib.flush(result, flusher)
-  return true -- done
+local function run_tex_code (str, cat)
+  cat = cat or catlatex
+  texruntoks(function() texsprint(cat, str) end)
 end
-luamplib.convert = convert
 
-local function pdf_startfigure(n,llx,lly,urx,ury)
 %    \end{macrocode}
-%     The following line has been slightly modified by Kim.
+%
+%    Indefinite number of boxes are needed for |btex ... etex|.
+%    So starts at somewhat huge number of box registry. Of course,
+%    this may conflict with other packages using many many boxes.
+%    (When |codeinherit| feature is enabled, boxes must be globally defined.)
+%    But I don't know any reliable way to escape this danger.
 %    \begin{macrocode}
-  texsprint(format("\\mplibstarttoPDF{%f}{%f}{%f}{%f}",llx,lly,urx,ury))
+local tex_box_id = 2047
+%    \end{macrocode}
+%
+%    For conversion of |sp| to |bp|.
+%    \begin{macrocode}
+local factor = 65536*(7227/7200)
+
+local function process_tex_text (str)
+  if str then
+    tex_box_id = tex_box_id + 1
+    local global = luamplib.globaltextext and "\\global" or ""
+    run_tex_code(format("%s\\setbox%i\\hbox{%s}", global, tex_box_id, str))
+    local box = texgetbox(tex_box_id)
+    local wd  = box.width  / factor
+    local ht  = box.height / factor
+    local dp  = box.depth  / factor
+    return format("image(addto currentpicture doublepath unitsquare "..
+    "xscaled %f yscaled %f shifted (0,-%f) "..
+    "withprescript \"mplibtexboxid=%i:%f:%f\")",
+    wd, ht+dp, dp, tex_box_id, wd, ht+dp)
+  end
+  return ""
 end
 
-local function pdf_stopfigure()
-  texsprint("\\mplibstoptoPDF")
+%    \end{macrocode}
+%
+%    Make |color| or |xcolor|'s color expressions usable,
+%    with \cs{mpcolor} or |mplibcolor|
+%    \begin{macrocode}
+local function process_color (str)
+  if str then
+    if not str:find("{.-}") then
+      str = format("{%s}",str)
+    end
+    run_tex_code(format(
+      "\\def\\set at color{\\toks0\\expandafter{\\current at color}}\\color %s", str),
+      catat11)
+    return format("1 withprescript \"MPlibOverrideColor=%s\"", texgettoks(0))
+  end
+  return ""
 end
 
 %    \end{macrocode}
-%    |tex.tprint| and catcode regime -2, as sometimes |#| gets doubled
-%    in the argument of pdfliteral. --- modified by Kim
+%
+%    \cs{mpdim} is expanded before MPLib process, so code below will not be
+%    used for |mplibcode| data. But who knows anyone would want it
+%    in |.mp| input file. If then, you can say |mplibdimen(".5\textwidth")|
+%    for example.
 %    \begin{macrocode}
-local function pdf_literalcode(fmt,...) -- table
-  textprint({"\\mplibtoPDF{"},{-2,format(fmt,...)},{"}"})
+local function process_dimen (str)
+  if str then
+    str = str:gsub("{(.+)}","%1")
+    run_tex_code(format("\\toks0\\expandafter{\\the\\dimexpr %s\\relax}", str))
+    return format("begingroup %s endgroup", texgettoks(0))
+  end
+  return ""
 end
-luamplib.pdf_literalcode = pdf_literalcode
 
-local function pdf_textfigure(font,size,text,width,height,depth)
 %    \end{macrocode}
-%     The following three lines have been modified by Kim.
+%
+%    Newly introduced method of processing |verbatimtex ... etex|.
+%    Used when |\mpliblegacybehavior{false}| is declared.
 %    \begin{macrocode}
-  -- if text == "" then text = "\0" end -- char(0) has gone
-  text = text:gsub(".",function(c)
-    return format("\\hbox{\\char%i}",string.byte(c)) -- kerning happens in metapost
-  end)
-  texsprint(format("\\mplibtextext{%s}{%f}{%s}{%s}{%f}",font,size,text,0,-( 7200/ 7227)/65536*depth))
+local function process_verbatimtex_text (str)
+  if str then
+    run_tex_code(str)
+  end
+  return ""
 end
-luamplib.pdf_textfigure = pdf_textfigure
 
-local bend_tolerance = 131/65536
+%    \end{macrocode}
+%
+%    For legacy verbatimtex process.
+%    |verbatimtex ... etex| before |beginfig()| is not ignored,
+%    but the \TeX\ code is inserted just before the mplib box. And
+%    \TeX\ code inside |beginfig() ... endfig| is inserted after the mplib box.
+%    \begin{macrocode}
+local tex_code_pre_mplib = {}
+luamplib.figid = 1
+luamplib.in_the_fig = false
 
-local rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1
-
-local function pen_characteristics(object)
-  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
+local function legacy_mplibcode_reset ()
+  tex_code_pre_mplib = {}
+  luamplib.figid = 1
 end
 
-local function concat(px, py) -- no tx, ty here
-  return (sy*px-ry*py)/divider,(sx*py-rx*px)/divider
+local function process_verbatimtex_prefig (str)
+  if str then
+    tex_code_pre_mplib[luamplib.figid] = str
+  end
+  return ""
 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
+local function process_verbatimtex_infig (str)
+  if str then
+    return format("special \"postmplibverbtex=%s\";", str)
   end
-  return true
+  return ""
 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)
+local runscript_funcs = {
+  luamplibtext    = process_tex_text,
+  luamplibcolor   = process_color,
+  luamplibdimen   = process_dimen,
+  luamplibprefig  = process_verbatimtex_prefig,
+  luamplibinfig   = process_verbatimtex_infig,
+  luamplibverbtex = process_verbatimtex_text,
+}
+
+%    \end{macrocode}
+%
+%    As of 2019-03, |metafun| format is not usable (issue \#79).
+%    This might workarounds the problem.
+%    \begin{macrocode}
+mp = mp or {}
+local mp = mp
+mp.mf_path_reset = mp.mf_path_reset or function() end
+mp.mf_finish_saving_data = mp.mf_finish_saving_data or function() end
+LUATEXFUNCTIONALITY = LUATEXFUNCTIONALITY or 0
+
+%    \end{macrocode}
+%
+%    A function from \ConTeXt\ general.
+%    \begin{macrocode}
+local function mpprint(buffer,...)
+  for i=1,select("#",...) do
+    local value = select(i,...)
+    if value ~= nil then
+      local t = type(value)
+      if t == "number" then
+        buffer[#buffer+1] = format("%.16f",value)
+      elseif t == "string" then
+        buffer[#buffer+1] = value
+      elseif t == "table" then
+        buffer[#buffer+1] = "(" .. concat(value,",") .. ")"
+      else -- boolean or whatever
+        buffer[#buffer+1] = tostring(value)
+      end
     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
 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))
+function luamplib.runscript (code)
+  local id, str = code:match("(.-){(.+)}")
+  if id and str and str ~= "" then
+    local f = runscript_funcs[id]
+    if f then
+      local t = f(str)
+      if t then return t end
     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))
+  local f = loadstring(code)
+  if type(f) == "function" then
+    local buffer = {}
+    function mp.print(...)
+      mpprint(buffer,...)
     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))
+    f()
+    return tableconcat(buffer,"")
   end
+  return ""
 end
 
 %    \end{macrocode}
-%     Below code has been contributed by Dohyun Kim.
-%     It implements |btex| / |etex| functions.
 %
-%     v2.1: |textext()| is now available, which is equivalent to |TEX()| macro from TEX.mp.
-%           |TEX()| is synonym of |textext()| unless TEX.mp is loaded.
-%
-%     v2.2: Transparency and Shading
-%
-%     v2.3: \cs{everymplib}, \cs{everyendmplib},
-%           and allows naked \TeX\ commands.
+%    |make_text| must be one liner, so comment sign is not allowed.
 %    \begin{macrocode}
-local further_split_keys = {
-  ["MPlibTEXboxID"] = true,
-  ["sh_color_a"]    = true,
-  ["sh_color_b"]    = true,
-}
+local function protecttexcontents (str)
+  return str:gsub("\\%%", "\0PerCent\0")
+            :gsub("%%.-\n", "")
+            :gsub("%%.-$",  "")
+            :gsub("%zPerCent%z", "\\%%")
+            :gsub("%s+", " ")
+end
 
-local function script2table(s)
-  local t = {}
-  for _,i in ipairs(stringexplode(s,"\13+")) do
-    local k,v = stringmatch(i,"(.-)=(.*)") -- v may contain = or empty.
-    if k and v and k ~= "" then
-      if further_split_keys[k] then
-        t[k] = stringexplode(v,":")
-      else
-        t[k] = v
+luamplib.legacy_verbatimtex = true
+
+function luamplib.maketext (str, what)
+  if str and str ~= "" then
+    str = protecttexcontents(str)
+    if what == 1 then
+      if not str:find("\\documentclass"..name_e) and
+         not str:find("\\begin%s*{document}") and
+         not str:find("\\documentstyle"..name_e) and
+         not str:find("\\usepackage"..name_e) then
+        if luamplib.legacy_verbatimtex then
+          if luamplib.in_the_fig then
+            return process_verbatimtex_infig(str)
+          else
+            return process_verbatimtex_prefig(str)
+          end
+        else
+          return process_verbatimtex_text(str)
+        end
       end
+    else
+      return process_tex_text(str)
     end
   end
-  return t
+  return ""
 end
 
+%    \end{macrocode}
+%
+%    Our MetaPost preambles
+%    \begin{macrocode}
 local mplibcodepreamble = [[
-vardef rawtextext (expr t) =
-  if unknown TEXBOX_:
-    image( special "MPlibmkTEXbox="&t;
-      addto currentpicture doublepath unitsquare; )
-  else:
-    TEXBOX_ := TEXBOX_ + 1;
-    if known TEXBOX_wd_[TEXBOX_]:
-      image ( addto currentpicture doublepath unitsquare
-        xscaled TEXBOX_wd_[TEXBOX_]
-        yscaled (TEXBOX_ht_[TEXBOX_] + TEXBOX_dp_[TEXBOX_])
-        shifted (0, -TEXBOX_dp_[TEXBOX_])
-        withprescript "MPlibTEXboxID=" &
-          decimal TEXBOX_ & ":" &
-          decimal TEXBOX_wd_[TEXBOX_] & ":" &
-          decimal(TEXBOX_ht_[TEXBOX_]+TEXBOX_dp_[TEXBOX_]); )
-    else:
-      image( special "MPlibTEXError=1"; )
-    fi
-  fi
-enddef;
+texscriptmode := 2;
+def rawtextext (expr t) = runscript("luamplibtext{"&t&"}") enddef;
+def mplibcolor (expr t) = runscript("luamplibcolor{"&t&"}") enddef;
+def mplibdimen (expr t) = runscript("luamplibdimen{"&t&"}") enddef;
+def VerbatimTeX (expr t) = runscript("luamplibverbtex{"&t&"}") enddef;
 if known context_mlib:
   defaultfont := "cmtt10";
   let infont = normalinfont;
@@ -1055,14 +1106,21 @@
   draw rawtextext("\includegraphics{"& filename &"}")
 enddef;
 def TEX = textext enddef;
-def specialVerbatimTeX (text t) = special "MPlibVerbTeX="&t; enddef;
-def normalVerbatimTeX  (text t) = special "PostMPlibVerbTeX="&t; enddef;
-let VerbatimTeX = specialVerbatimTeX;
-extra_beginfig := extra_beginfig & " let VerbatimTeX = normalVerbatimTeX;" ;
-extra_endfig   := extra_endfig   & " let VerbatimTeX = specialVerbatimTeX;" ;
 ]]
 luamplib.mplibcodepreamble = mplibcodepreamble
 
+local legacyverbatimtexpreamble = [[
+def specialVerbatimTeX (text t) = runscript("luamplibprefig{"&t&"}") enddef;
+def normalVerbatimTeX  (text t) = runscript("luamplibinfig{"&t&"}") enddef;
+let VerbatimTeX = specialVerbatimTeX;
+extra_beginfig := extra_beginfig & " let VerbatimTeX = normalVerbatimTeX;"&
+  "runscript(" &ditto& "luamplib.in_the_fig=true" &ditto& ");";
+extra_endfig := extra_endfig & " let VerbatimTeX = specialVerbatimTeX;"&
+  "runscript(" &ditto&
+  "luamplib.in_the_fig=false luamplib.figid=luamplib.figid+1" &ditto& ");";
+]]
+luamplib.legacyverbatimtexpreamble = legacyverbatimtexpreamble
+
 local textextlabelpreamble = [[
 primarydef s infont f = rawtextext(s) enddef;
 def fontsize expr f =
@@ -1076,150 +1134,241 @@
 ]]
 luamplib.textextlabelpreamble = textextlabelpreamble
 
-local TeX_code_t = {}
-local texboxnum = { 2047 }
+%    \end{macrocode}
+%
+%    When \cs{mplibverbatim} is enabled, do not expand |mplibcode| data.
+%    \begin{macrocode}
+luamplib.verbatiminput = false
 
-local function domakeTEXboxes (data)
-  local num = texboxnum[1]
-  texboxnum[2] = num
-  local global = luamplib.globaltextext and "\\global" or ""
-  if data and data.fig then
-    local figures = data.fig
-    for f=1, #figures do
-      TeX_code_t[f] = nil
-      local figure = figures[f]
-      local objects = getobjects(data,figure,f)
-      if objects then
-        for o=1,#objects do
-          local object    = objects[o]
-          local prescript = object.prescript
-          prescript = prescript and script2table(prescript)
-          local str = prescript and prescript.MPlibmkTEXbox
-          if str then
-            num = num + 1
-            texsprint(format("%s\\setbox%i\\hbox{%s}", global, num, str))
-          end
 %    \end{macrocode}
-%     |verbatimtex ... etex| before |beginfig()| is not ignored,
-%     but the \TeX\ code inbetween is inserted before the mplib box.
+%
+%    Do not expand |btex ... etex|, |verbatimtex ... etex|, and
+%    string expressions.
 %    \begin{macrocode}
-          local texcode = prescript and prescript.MPlibVerbTeX
-          if texcode and texcode ~= "" then
-            TeX_code_t[f] = texcode
-          end
-        end
-      end
-    end
+local function protect_expansion (str)
+  if str then
+    str = str:gsub("\\","\1Control\1")
+             :gsub("%%","\1Comment\1")
+             :gsub("#", "\1HashSign\1")
+             :gsub("{", "\1LBrace\1")
+             :gsub("}", "\1RBrace\1")
+    return format("\\unexpanded{%s}",str)
   end
-  if luamplib.globaltextext then
-    texboxnum[1] = num
+end
+
+local function unprotect_expansion (str)
+  if str then
+    return str:gsub("\1Control\1", "\\")
+              :gsub("\1Comment\1", "%%")
+              :gsub("\1HashSign\1","#")
+              :gsub("\1LBrace\1",  "{")
+              :gsub("\1RBrace\1",  "}")
   end
 end
 
-local function protect_tex_text_common (data)
+local function process_mplibcode (data)
+%    \end{macrocode}
+%
+%    This is needed for legacy behavior regarding |verbatimtex|
+%    \begin{macrocode}
+  legacy_mplibcode_reset()
+
   local everymplib    = texgettoks('everymplibtoks')    or ''
   local everyendmplib = texgettoks('everyendmplibtoks') or ''
-  data = format("\n%s\n%s\n%s",everymplib, data, everyendmplib)
+  data = format("\n%s\n%s\n%s\n",everymplib, data, everyendmplib)
   data = data:gsub("\r","\n")
 
-  data = data:gsub("\"[^\n]-\"", function(str)
-    return str:gsub("([bem])tex"..endname,"%1"..esctex)
-  end)
+  data = data:gsub("\\mpcolor%s+(.-%b{})","mplibcolor(\"%1\")")
 
   data = data:gsub(btex_etex, function(str)
-    return format("rawtextext(\"%s\")",protecttexcontents(str))
+    return format("btex %s etex ", -- space
+      luamplib.verbatiminput and str or protect_expansion(str))
   end)
   data = data:gsub(verbatimtex_etex, function(str)
-    return format("VerbatimTeX(\"%s\")",protecttexcontents(str))
+    return format("verbatimtex %s etex;", -- semicolon
+      luamplib.verbatiminput and str or protect_expansion(str))
   end)
 
-  return data
+%    \end{macrocode}
+%
+%    If not |mplibverbatim|, expand |mplibcode| data,
+%    so that users can use \TeX\ codes in it.
+%    It has turned out that no comment sign is allowed.
+%    \begin{macrocode}
+  if not luamplib.verbatiminput then
+    data = data:gsub("\".-\"", protect_expansion)
+    data = data:gsub("%%.-\n","")
+    run_tex_code(format("\\toks0\\expanded{{%s}}",data))
+    data = texgettoks(0)
+%    \end{macrocode}
+%
+%    Next line to address issue \#55
+%    \begin{macrocode}
+    data = data:gsub("##", "#")
+    data = data:gsub("\".-\"", unprotect_expansion)
+    data = data:gsub(btex_etex, function(str)
+      return format("btex %s etex", unprotect_expansion(str))
+    end)
+    data = data:gsub(verbatimtex_etex, function(str)
+      return format("verbatimtex %s etex", unprotect_expansion(str))
+    end)
+  end
+
+  process(data)
 end
+luamplib.process_mplibcode = process_mplibcode
 
-local function protecttextextVerbatim(data)
-  data = protect_tex_text_common(data)
+%    \end{macrocode}
+%
+%    For parsing |prescript| materials.
+%    \begin{macrocode}
+local further_split_keys = {
+  ["mplibtexboxid"] = true,
+  ["sh_color_a"]    = true,
+  ["sh_color_b"]    = true,
+}
 
-  data = data:gsub("\"[^\n]-\"", function(str) -- restore string btex .. etex
-    return str:gsub("([bem])"..esctex, "%1tex")
-  end)
+local function script2table(s)
+  local t = {}
+  for _,i in ipairs(s:explode("\13+")) do
+    local k,v = i:match("(.-)=(.*)") -- v may contain = or empty.
+    if k and v and k ~= "" then
+      if further_split_keys[k] then
+        t[k] = v:explode(":")
+      else
+        t[k] = v
+      end
+    end
+  end
+  return t
+end
 
-  local _,result = process(data, false)
-  domakeTEXboxes(result)
-  return data
+%    \end{macrocode}
+%
+%    Codes below for inserting PDF lieterals are mostly from ConTeXt general,
+%    with small changes when needed.
+%    \begin{macrocode}
+local function getobjects(result,figure,f)
+  return figure:objects()
 end
 
-luamplib.protecttextextVerbatim = protecttextextVerbatim
+local function convert(result, flusher)
+  luamplib.flush(result, flusher)
+  return true -- done
+end
+luamplib.convert = convert
 
-luamplib.mpxcolors = {}
+local function pdf_startfigure(n,llx,lly,urx,ury)
+  texsprint(format("\\mplibstarttoPDF{%f}{%f}{%f}{%f}",llx,lly,urx,ury))
+end
 
-local function protecttextext(data)
-  data = protect_tex_text_common(data)
+local function pdf_stopfigure()
+  texsprint("\\mplibstoptoPDF")
+end
 
-  data = data:gsub("\"[^\n]-\"", function(str)
-    str = str:gsub("([bem])"..esctex, "%1tex")
-             :gsub("%%", escpcnt)
-             :gsub("{",  esclbr)
-             :gsub("}",  escrbr)
-             :gsub("#",  eschash)
-    return format("\\detokenize{%s}",str)
-  end)
-
-  data = data:gsub("%%.-\n", "")
-
-  local grouplevel = tex.currentgrouplevel
-  luamplib.mpxcolors[grouplevel] = {}
-  data = data:gsub("\\mpcolor"..endname.."(.-){(.-)}", function(opt,str)
-    local cnt = #luamplib.mpxcolors[grouplevel] + 1
-    luamplib.mpxcolors[grouplevel][cnt] = format(
-      "\\expandafter\\mplibcolor\\csname mpxcolor%i:%i\\endcsname%s{%s}",
-      grouplevel,cnt,opt,str)
-    return format("\\csname mpxcolor%i:%i\\endcsname",grouplevel,cnt)
-  end)
-
 %    \end{macrocode}
-%    Next line to address bug \#55
+%
+%    |tex.tprint| with catcode regime -2, as sometimes |#| gets doubled
+%    in the argument of pdfliteral.
 %    \begin{macrocode}
-  data = data:gsub("([^`\\])#","%1##")
+local function pdf_literalcode(fmt,...) -- table
+  textprint({"\\mplibtoPDF{"},{-2,format(fmt,...)},{"}"})
+end
 
-  texsprint(data)
+local function pdf_textfigure(font,size,text,width,height,depth)
+  text = text:gsub(".",function(c)
+    return format("\\hbox{\\char%i}",string.byte(c)) -- kerning happens in metapost
+  end)
+  texsprint(format("\\mplibtextext{%s}{%f}{%s}{%s}{%f}",font,size,text,0,-( 7200/ 7227)/65536*depth))
 end
 
-luamplib.protecttextext = protecttextext
+local bend_tolerance = 131/65536
 
-local function makeTEXboxes (data)
-  data = data:gsub("##","#")
-             :gsub(escpcnt,"%%")
-             :gsub(esclbr,"{")
-             :gsub(escrbr,"}")
-             :gsub(eschash,"#")
-  local _,result = process(data, false)
-  domakeTEXboxes(result)
-  return data
+local rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1
+
+local function pen_characteristics(object)
+  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
 end
 
-luamplib.makeTEXboxes = makeTEXboxes
+local function concat(px, py) -- no tx, ty here
+  return (sy*px-ry*py)/divider,(sx*py-rx*px)/divider
+end
 
-local factor = 65536*(7227/7200)
+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 processwithTEXboxes (data)
-  if not data then return end
-  local num = texboxnum[2]
-  local prepreamble = format("TEXBOX_:=%i;\n",num)
-  while true do
-    num = num + 1
-    local box = texgetbox(num)
-    if not box then break end
-    prepreamble = format(
-      "%sTEXBOX_wd_[%i]:=%f;\nTEXBOX_ht_[%i]:=%f;\nTEXBOX_dp_[%i]:=%f;\n",
-      prepreamble,
-      num, box.width /factor,
-      num, box.height/factor,
-      num, box.depth /factor)
+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
-  process(prepreamble .. data, true)
+  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
 end
-luamplib.processwithTEXboxes = processwithTEXboxes
 
+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
+end
+
+%    \end{macrocode}
+%
+%    |dvipdfmx| is supported, though nobody seems to use it.
+%    \begin{macrocode}
 local pdfoutput = tonumber(texget("outputmode")) or tonumber(texget("pdfoutput"))
 local pdfmode = pdfoutput > 0
 
@@ -1238,8 +1387,13 @@
   end
 end
 
-local function putTEXboxes (object,prescript)
-  local box = prescript.MPlibTEXboxID
+%    \end{macrocode}
+%
+%    Now we process hboxes created from |btex ... etex| or
+%    |textext(...)| or |TEX(...)|, all being the same internally.
+%    \begin{macrocode}
+local function put_tex_boxes (object,prescript)
+  local box = prescript.mplibtexboxid
   local n,tw,th = box[1],tonumber(box[2]),tonumber(box[3])
   if n and tw and th then
     local op = object.path
@@ -1264,7 +1418,8 @@
 end
 
 %    \end{macrocode}
-%    Transparency and Shading
+%
+%    Colors and Transparency
 %    \begin{macrocode}
 local pdf_objs = {}
 local token, getpageres, setpageres = newtoken or token
@@ -1278,7 +1433,6 @@
             "\\special{pdf:obj @MPlibSh<<>>}")
 end
 
--- objstr <string> => obj <number>, new <boolean>
 local function update_pdfobjs (os)
   local on = pdf_objs[os]
   if on then
@@ -1348,11 +1502,15 @@
   return on_on, off_on
 end
 
+%    \end{macrocode}
+%
+%    Shading with |metafun| format. (maybe legacy way)
+%    \begin{macrocode}
 local shading_res
 
 local function shading_initialize ()
   shading_res = {}
-  if pdfmode and luatexbase.callbacktypes and luatexbase.callbacktypes.finish_pdffile then -- ltluatex
+  if pdfmode and luatexbase.callbacktypes.finish_pdffile then -- ltluatex
     local shading_obj = pdf.reserveobj()
     setpageres(format("%s/Shading %i 0 R",getpageres() or "",shading_obj))
     luatexbase.add_to_callback("finish_pdffile", function()
@@ -1377,7 +1535,7 @@
         shading_res[#shading_res+1] = res
       else
         local pageres = getpageres() or ""
-        if not stringfind(pageres,"/Shading<<.*>>") then
+        if not pageres:find("/Shading<<.*>>") then
           pageres = pageres.."/Shading<<>>"
         end
         pageres = pageres:gsub("/Shading<<","%1"..res)
@@ -1408,7 +1566,10 @@
 local prev_override_color
 
 local function do_preobj_color(object,prescript)
-  -- transparency
+%    \end{macrocode}
+%
+%    transparency
+%    \begin{macrocode}
   local opaq = prescript and prescript.tr_transparency
   local tron_no, troff_no
   if opaq then
@@ -1417,7 +1578,10 @@
     tron_no, troff_no = tr_pdf_pageresources(mode,opaq)
     pdf_literalcode("/MPlibTr%i gs",tron_no)
   end
-  -- color
+%    \end{macrocode}
+%
+%    color
+%    \begin{macrocode}
   local override = prescript and prescript.MPlibOverrideColor
   if override then
     if pdfmode then
@@ -1439,12 +1603,15 @@
       end
     end
   end
-  -- shading
+%    \end{macrocode}
+%
+%    shading
+%    \begin{macrocode}
   local sh_type = prescript and prescript.sh_type
   if sh_type then
     local domain  = prescript.sh_domain
-    local centera = stringexplode(prescript.sh_center_a)
-    local centerb = stringexplode(prescript.sh_center_b)
+    local centera = prescript.sh_center_a:explode()
+    local centerb = prescript.sh_center_b:explode()
     for _,t in pairs({centera,centerb}) do
       for i,v in ipairs(t) do
         t[i] = format("%f",v)
@@ -1501,10 +1668,9 @@
 end
 
 %    \end{macrocode}
-%     End of |btex| -- |etex| and Transparency/Shading patch.
 %
+%    Finally, flush figures by inserting PDF literals.
 %    \begin{macrocode}
-
 local function flush(result,flusher)
   if result then
     local figures = result.fig
@@ -1513,27 +1679,32 @@
         info("flushing figure %s",f)
         local figure = figures[f]
         local objects = getobjects(result,figure,f)
-        local fignum = tonumber(stringmatch(figure:filename(),"([%d]+)$") or figure:charcode() or 0)
+        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
 %    \end{macrocode}
-%    \textsf{luamplib} silently ignores this invalid figure for those codes
+%
+%    luamplib silently ignores this invalid figure for those
 %    that do not contain |beginfig ... endfig|. (issue \#70)
+%    Original code of ConTeXt general was:
+%    \begin{verbatim}
+%    -- invalid
+%    pdf_startfigure(fignum,0,0,0,0)
+%    pdf_stopfigure()
+%    \end{verbatim}
 %    \begin{macrocode}
-          -- invalid
-          -- pdf_startfigure(fignum,0,0,0,0)
-          -- pdf_stopfigure()
         else
 %    \end{macrocode}
-%    Insert |verbatimtex| code before mplib box.
-%    And prepare for those codes that will be executed afterwards.
+%
+%    For legacy behavior. Insert `pre-fig' \TeX\ code here, and
+%    prepare a table for `in-fig' codes.
 %    \begin{macrocode}
-          if TeX_code_t[f] then
-            texsprint(TeX_code_t[f])
+          if tex_code_pre_mplib[f] then
+            texsprint(tex_code_pre_mplib[f])
           end
-          local TeX_code_bot = {} -- PostVerbatimTeX
+          local TeX_code_bot = {}
           pdf_startfigure(fignum,llx,lly,urx,ury)
           start_pdf_code()
           if objects then
@@ -1543,20 +1714,16 @@
               local object        = objects[o]
               local objecttype    = object.type
 %    \end{macrocode}
-%     Change from \ConTeXt{} code: the following 7 lines are part of the
-%     |btex...etex| patch. Again, colors are processed at this stage.
-%     Also, we collect \TeX\ codes that will be executed after flushing.
 %
+%    The following 5 lines are part of |btex...etex| patch.
+%    Again, colors are processed at this stage.
 %    \begin{macrocode}
               local prescript     = object.prescript
               prescript = prescript and script2table(prescript) -- prescript is now a table
               local tr_opaq,cr_over,shade_no = do_preobj_color(object,prescript)
-              if prescript and prescript.MPlibTEXboxID then
-                putTEXboxes(object,prescript)
-              elseif prescript and prescript.PostMPlibVerbTeX then
-                TeX_code_bot[#TeX_code_bot+1] = prescript.PostMPlibVerbTeX
-              elseif objecttype == "start_bounds" or objecttype == "stop_bounds" then
-                -- skip
+              if prescript and prescript.mplibtexboxid then
+                put_tex_boxes(object,prescript)
+              elseif objecttype == "start_bounds" or objecttype == "stop_bounds" then --skip
               elseif objecttype == "start_clip" then
                 local evenodd = not object.istext and object.postscript == "evenodd"
                 start_pdf_code()
@@ -1566,9 +1733,13 @@
                 stop_pdf_code()
                 miterlimit, linecap, linejoin, dashed = -1, -1, -1, false
               elseif objecttype == "special" then
-                -- not supported
-                if prescript and prescript.MPlibTEXError then
-                  warn("textext() anomaly. Try disabling \\mplibtextextlabel.")
+%    \end{macrocode}
+%
+%    Collect \TeX\ codes that will be executed after flushing.
+%    Legacy behavior.
+%    \begin{macrocode}
+                if prescript and prescript.postmplibverbtex then
+                  TeX_code_bot[#TeX_code_bot+1] = prescript.postmplibverbtex
                 end
               elseif objecttype == "text" then
                 local ot = object.transform -- 3,4,5,6,1,2
@@ -1577,9 +1748,6 @@
                 pdf_textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth)
                 stop_pdf_code()
               else
-%    \end{macrocode}
-%     Color stuffs are modified and moved to several lines above.
-%    \begin{macrocode}
                 local evenodd, collect, both = false, false, false
                 local postscript = object.postscript
                 if not object.istext then
@@ -1666,10 +1834,9 @@
                     end
 %    \end{macrocode}
 %
-%     Change from \ConTeXt{} code: color stuff
-%
+%    Change from ConTeXt general: there was color stuffs.
 %    \begin{macrocode}
-                    if not shade_no then ----- conflict with shading
+                    if not shade_no then -- conflict with shading
                       if objecttype == "fill" then
                         pdf_literalcode(evenodd and "h f*" or "h f")
                       elseif objecttype == "outline" then
@@ -1723,9 +1890,8 @@
               end
 %    \end{macrocode}
 %
-%     Added to \ConTeXt{} code: color stuff.
-%     And execute |verbatimtex| codes.
-%
+%    Added to ConTeXt general: color stuff.
+%    And execute legacy |verbatimtex| code.
 %    \begin{macrocode}
               do_postobj_color(tr_opaq,cr_over,shade_no)
             end
@@ -1732,9 +1898,7 @@
           end
           stop_pdf_code()
           pdf_stopfigure()
-          if #TeX_code_bot > 0 then
-            texsprint(TeX_code_bot)
-          end
+          if #TeX_code_bot > 0 then texsprint(TeX_code_bot) end
         end
       end
     end
@@ -1764,6 +1928,7 @@
 %
 %    \subsection{\texorpdfstring{\TeX}{TeX} package}
 %
+%
 %    \begin{macrocode}
 %<*package>
 %    \end{macrocode}
@@ -1777,7 +1942,7 @@
 \else
   \NeedsTeXFormat{LaTeX2e}
   \ProvidesPackage{luamplib}
-    [2018/09/27 v2.12.5 mplib package for LuaTeX]
+    [2019/03/20 v2.20.0 mplib package for LuaTeX]
   \ifx\newluafunction\@undefined
   \input ltluatex
   \fi
@@ -1785,12 +1950,11 @@
 %    \end{macrocode}
 %
 %    Loading of lua code.
-%
 %    \begin{macrocode}
 \directlua{require("luamplib")}
 %    \end{macrocode}
 %
-% Support older formats
+%    Support older engine. Seems we don't need it, but no harm.
 %    \begin{macrocode}
 \ifx\scantextokens\undefined
   \let\scantextokens\luatexscantextokens
@@ -1798,20 +1962,18 @@
 \ifx\pdfoutput\undefined
   \let\pdfoutput\outputmode
   \protected\def\pdfliteral{\pdfextension literal}
+  \def\pdffontsize{\dimexpr\pdffeedback fontsize\relax}
 \fi
 %    \end{macrocode}
-
 %
 %    Set the format for metapost.
-%
 %    \begin{macrocode}
 \def\mplibsetformat#1{\directlua{luamplib.setformat("#1")}}
 %    \end{macrocode}
 %
-%    \textsf{luamplib} works in both PDF and DVI mode,
+%    luamplib works in both PDF and DVI mode,
 %    but only DVIPDFMx is supported currently among a number of DVI tools.
 %    So we output a warning.
-%
 %    \begin{macrocode}
 \ifnum\pdfoutput>0
   \let\mplibtoPDF\pdfliteral
@@ -1825,8 +1987,19 @@
     \write128{}
   \fi
 \fi
+%    \end{macrocode}
+%
+%    Make |mplibcode| typesetted always in horizontal mode.
+%    \begin{macrocode}
+\def\mplibforcehmode{\let\mplibhmodeornot\leavevmode}
+\def\mplibnoforcehmode{\let\mplibhmodeornot\relax}
+\mplibnoforcehmode
+%    \end{macrocode}
+%
+%    Catcode. We want to allow comment sign in |mplibcode|.
+%    \begin{macrocode}
 \def\mplibsetupcatcodes{%
-  %catcode`\{=12 %catcode`\}=12
+  \mplibhmodeornot %catcode`\{=12 %catcode`\}=12
   \catcode`\#=12 \catcode`\^=12 \catcode`\~=12 \catcode`\_=12
   \catcode`\&=12 \catcode`\$=12 \catcode`\%=12 \catcode`\^^M=12 \endlinechar=10
 }
@@ -1833,9 +2006,13 @@
 %    \end{macrocode}
 %
 %    Make |btex...etex| box zero-metric.
+%    \begin{macrocode}
+\def\mplibputtextbox#1{\vbox to 0pt{\vss\hbox to 0pt{\raise\dp#1\copy#1\hss}}}
+%    \end{macrocode}
 %
+%    As we have changed |^^J| catcode, the last line containing
+%    |\end{mplibcode}| has |\n| at the end. Replace it with |^^M|.
 %    \begin{macrocode}
-\def\mplibputtextbox#1{\vbox to 0pt{\vss\hbox to 0pt{\raise\dp#1\copy#1\hss}}}
 \newcount\mplibstartlineno
 \def\mplibpostmpcatcodes{%
   \catcode`\{=12 \catcode`\}=12 \catcode`\#=12 \catcode`\%=12 }
@@ -1846,7 +2023,6 @@
 %    \end{macrocode}
 %
 %    The Plain-specific stuff.
-%
 %    \begin{macrocode}
 \bgroup\expandafter\expandafter\expandafter\egroup
 \expandafter\ifx\csname selectfont\endcsname\relax
@@ -1863,15 +2039,7 @@
 }
 \long\def\mplibdocode#1\endmplibcode{%
   \endgroup
-  \ifdefined\mplibverbatimYes
-    \directlua{luamplib.tempdata\the\currentgrouplevel=luamplib.protecttextextVerbatim([===[\detokenize{#1}]===])}%
-    \directlua{luamplib.processwithTEXboxes(luamplib.tempdata\the\currentgrouplevel)}%
-  \else
-    \edef\mplibtemp{\directlua{luamplib.protecttextext([===[\unexpanded{#1}]===])}}%
-    \directlua{ tex.sprint(luamplib.mpxcolors[\the\currentgrouplevel]) }%
-    \directlua{luamplib.tempdata\the\currentgrouplevel=luamplib.makeTEXboxes([===[\mplibtemp]===])}%
-    \directlua{luamplib.processwithTEXboxes(luamplib.tempdata\the\currentgrouplevel)}%
-  \fi
+  \directlua{luamplib.process_mplibcode([===[\unexpanded{#1}]===])}%
   \endgroup
   \ifnum\mplibstartlineno<\inputlineno\expandafter\mplibreplacenewlinecs\fi
 }
@@ -1878,8 +2046,7 @@
 \else
 %    \end{macrocode}
 %
-%    The \LaTeX-specific parts: a new environment.
-%
+%    The \LaTeX-specific part: a new environment.
 %    \begin{macrocode}
 \newenvironment{mplibcode}{%
   \global\mplibstartlineno\inputlineno
@@ -1894,16 +2061,9 @@
 \long\def\ltxdomplibcodeindeed#1\end#2{%
   \endgroup
   \toks@\expandafter{\the\toks@#1}%
-  \def\mplibtemp at a{#2}\ifx\mplib at mplibcode\mplibtemp at a
-    \ifdefined\mplibverbatimYes
-      \directlua{luamplib.tempdata\the\currentgrouplevel=luamplib.protecttextextVerbatim([===[\the\toks@]===])}%
-      \directlua{luamplib.processwithTEXboxes(luamplib.tempdata\the\currentgrouplevel)}%
-    \else
-      \edef\mplibtemp{\directlua{luamplib.protecttextext([===[\the\toks@]===])}}%
-      \directlua{ tex.sprint(luamplib.mpxcolors[\the\currentgrouplevel]) }%
-      \directlua{luamplib.tempdata\the\currentgrouplevel=luamplib.makeTEXboxes([===[\mplibtemp]===])}%
-      \directlua{luamplib.processwithTEXboxes(luamplib.tempdata\the\currentgrouplevel)}%
-    \fi
+  \def\mplibtemp at a{#2}%
+  \ifx\mplib at mplibcode\mplibtemp at a
+    \directlua{luamplib.process_mplibcode([===[\the\toks@]===])}%
     \end{mplibcode}%
     \ifnum\mplibstartlineno<\inputlineno
       \expandafter\expandafter\expandafter\mplibreplacenewlinebr
@@ -1913,22 +2073,32 @@
   \fi
 }
 \fi
-\def\mplibverbatim#1{%
-  \begingroup
-  \def\mplibtempa{#1}\def\mplibtempb{enable}%
-  \expandafter\endgroup
-  \ifx\mplibtempa\mplibtempb
-    \let\mplibverbatimYes\relax
-  \else
-    \let\mplibverbatimYes\undefined
-  \fi
-}
 %    \end{macrocode}
 %
+%    User settings.
+%    \begin{macrocode}
+\def\mpliblegacybehavior#1{\directlua{
+    local s = string.lower("#1")
+    if s == "enable" or s == "true" or s == "yes" then
+      luamplib.legacy_verbatimtex = true
+    else
+      luamplib.legacy_verbatimtex = false
+    end
+}}
+\def\mplibverbatim#1{\directlua{
+    local s = string.lower("#1")
+    if s == "enable" or s == "true" or s == "yes" then
+      luamplib.verbatiminput = true
+    else
+      luamplib.verbatiminput = false
+    end
+}}
+%    \end{macrocode}
+%
 %    \cs{everymplib} \& \cs{everyendmplib}: macros redefining
 %    \cs{everymplibtoks} \& \cs{everyendmplibtoks} respectively
-%
 %    \begin{macrocode}
+\newtoks\mplibtmptoks
 \newtoks\everymplibtoks
 \newtoks\everyendmplibtoks
 \protected\def\everymplib{%
@@ -1953,18 +2123,24 @@
   \everyendmplibtoks{#1}%
   \ifnum\mplibstartlineno<\inputlineno\expandafter\mplibreplacenewlinebr\fi
 }
+%    \end{macrocode}
+%
+%    Allow \TeX\ dimen macros in |mplibcode|.
+%    \begin{macrocode}
 \def\mpdim#1{ begingroup \the\dimexpr #1\relax\space endgroup } % gmp.sty
 %    \end{macrocode}
 %
-%     Support color/xcolor packages.
-%     User interface is: |\mpcolor{teal}| or |\mpcolor[HTML]{008080}|,
-%     for example.
+%    MPLib's number system. Now |binary| has gone away.
 %    \begin{macrocode}
-\def\mplibcolor#1{%
-  \def\set at color{\edef#1{1 withprescript "MPlibOverrideColor=\current at color"}}%
-  \color
-}
-\def\mplibnumbersystem#1{\directlua{luamplib.numbersystem = "#1"}}
+\def\mplibnumbersystem#1{\directlua{
+  local t = "#1"
+  if t == "binary" then t = "decimal" end
+  luamplib.numbersystem = t
+}}
+%    \end{macrocode}
+%
+%    Settings for |.mp| cache files.
+%    \begin{macrocode}
 \def\mplibmakenocache#1{\mplibdomakenocache #1,*,}
 \def\mplibdomakenocache#1,{%
   \ifx\empty#1\empty
@@ -1988,46 +2164,43 @@
   \fi
 }
 \def\mplibcachedir#1{\directlua{luamplib.getcachedir("\unexpanded{#1}")}}
-\def\mplibtextextlabel#1{%
-  \begingroup
-  \def\tempa{enable}\def\tempb{#1}%
-  \ifx\tempa\tempb
-    \directlua{luamplib.textextlabel = true}%
-  \else
-    \directlua{luamplib.textextlabel = false}%
-  \fi
-  \endgroup
-}
-\def\mplibcodeinherit#1{%
-  \begingroup
-  \def\tempa{enable}\def\tempb{#1}%
-  \ifx\tempa\tempb
-    \directlua{luamplib.codeinherit = true}%
-  \else
-    \directlua{luamplib.codeinherit = false}%
-  \fi
-  \endgroup
-}
-\def\mplibglobaltextext#1{%
-  \begingroup
-  \def\tempa{enable}\def\tempb{#1}%
-  \ifx\tempa\tempb
-    \directlua{luamplib.globaltextext = true}%
-  \else
-    \directlua{luamplib.globaltextext = false}%
-  \fi
-  \endgroup
-}
 %    \end{macrocode}
 %
-%    We use a dedicated scratchbox.
+%    More user settings.
+%    \begin{macrocode}
+\def\mplibtextextlabel#1{\directlua{
+    local s = string.lower("#1")
+    if s == "enable" or s == "true" or s == "yes" then
+      luamplib.textextlabel = true
+    else
+      luamplib.textextlabel = false
+    end
+}}
+\def\mplibcodeinherit#1{\directlua{
+    local s = string.lower("#1")
+    if s == "enable" or s == "true" or s == "yes" then
+      luamplib.codeinherit = true
+    else
+      luamplib.codeinherit = false
+    end
+}}
+\def\mplibglobaltextext#1{\directlua{
+    local s = string.lower("#1")
+    if s == "enable" or s == "true" or s == "yes" then
+      luamplib.globaltextext = true
+    else
+      luamplib.globaltextext = false
+    end
+}}
+%    \end{macrocode}
 %
+%    The followings are from ConTeXt general, mostly.
+%    %    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
@@ -2042,9 +2215,6 @@
   \setbox\mplibscratchbox\vbox\bgroup
   \noindent
 }
-%    \end{macrocode}
-%
-%    \begin{macrocode}
 \def\mplibstoptoPDF{%
   \egroup %
   \setbox\mplibscratchbox\hbox %
@@ -2066,7 +2236,6 @@
 %    \end{macrocode}
 %
 %    Text items have a special handler.
-%
 %    \begin{macrocode}
 \def\mplibtextext#1#2#3#4#5{%
   \begingroup
@@ -2086,8 +2255,7 @@
 }
 %    \end{macrocode}
 %
-%    input luamplib.cfg when it exists
-%
+%    Input |luamplib.cfg| when it exists.
 %    \begin{macrocode}
 \openin0=luamplib.cfg
 \ifeof0 \else

Modified: trunk/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua	2019-03-21 20:54:17 UTC (rev 50509)
+++ trunk/Master/texmf-dist/tex/luatex/luamplib/luamplib.lua	2019-03-21 20:54:31 UTC (rev 50510)
@@ -9,21 +9,13 @@
 --  See source file 'luamplib.dtx' for licencing and contact information.
 --  
 
-luamplib          = luamplib or { }
-
-
-local luamplib    = luamplib
-luamplib.showlog  = luamplib.showlog or false
-luamplib.lastlog  = ""
-
 luatexbase.provides_module {
   name          = "luamplib",
-  version       = "2.12.5",
-  date          = "2018/09/27",
+  version       = "2.20.0",
+  date          = "2019/03/20",
   description   = "Lua package to typeset Metapost with LuaTeX's MPLib.",
 }
 
-
 local format, abs = string.format, math.abs
 
 local err  = function(...) return luatexbase.module_error  ("luamplib", format(...)) end
@@ -30,11 +22,12 @@
 local warn = function(...) return luatexbase.module_warning("luamplib", format(...)) end
 local info = function(...) return luatexbase.module_info   ("luamplib", format(...)) end
 
-local stringgsub    = string.gsub
-local stringfind    = string.find
-local stringmatch   = string.match
-local stringgmatch  = string.gmatch
-local stringexplode = string.explode
+luamplib          = luamplib or { }
+local luamplib    = luamplib
+
+luamplib.showlog  = luamplib.showlog or false
+luamplib.lastlog  = ""
+
 local tableconcat   = table.concat
 local texsprint     = tex.sprint
 local textprint     = tex.tprint
@@ -42,7 +35,13 @@
 local texget      = tex.get
 local texgettoks  = tex.gettoks
 local texgetbox   = tex.getbox
+local texruntoks  = tex.runtoks
+local texscantoks = tex.scantoks
 
+if not texruntoks then
+  err("Your LuaTeX version is too old. Please upgrade it to the latest")
+end
+
 local mplib = require ('mplib')
 local kpse  = require ('kpse')
 local lfs   = require ('lfs')
@@ -55,10 +54,10 @@
 
 local file = file or { }
 local replacesuffix = file.replacesuffix or function(filename, suffix)
-  return (stringgsub(filename,"%.[%a%d]+$","")) .. "." .. suffix
+  return (filename:gsub("%.[%a%d]+$","")) .. "." .. suffix
 end
 local stripsuffix = file.stripsuffix or function(filename)
-  return (stringgsub(filename,"%.[%a%d]+$",""))
+  return (filename:gsub("%.[%a%d]+$",""))
 end
 
 local is_writable = file.is_writable or function(name)
@@ -73,7 +72,7 @@
 end
 local mk_full_path = lfs.mkdirs or function(path)
   local full = ""
-  for sub in stringgmatch(path,"(/*[^\\/]+)") do
+  for sub in path:gmatch("(/*[^\\/]+)") do
     full = full .. sub
     lfsmkdir(full)
   end
@@ -88,7 +87,7 @@
 if lfstouch then
   local texmfvar = kpse.expand_var('$TEXMFVAR')
   if texmfvar and texmfvar ~= "" and texmfvar ~= '$TEXMFVAR' then
-    for _,dir in next,stringexplode(texmfvar,os.type == "windows" and ";" or ":") do
+    for _,dir in next, texmfvar:explode(os.type == "windows" and ";" or ":") do
       if not lfsisdir(dir) then
         mk_full_path(dir)
       end
@@ -104,7 +103,7 @@
 if not outputdir then
   outputdir = "."
   for _,v in ipairs(arg) do
-    local t = stringmatch(v,"%-output%-directory=(.+)")
+    local t = v:match("%-output%-directory=(.+)")
     if t then
       outputdir = t
       break
@@ -130,43 +129,19 @@
 end
 
 local noneedtoreplace = {
-  ["boxes.mp"] = true,
-  --  ["format.mp"] = true,
-  ["graph.mp"] = true,
-  ["marith.mp"] = true,
-  ["mfplain.mp"] = true,
-  ["mpost.mp"] = true,
-  ["plain.mp"] = true,
-  ["rboxes.mp"] = true,
-  ["sarith.mp"] = true,
-  ["string.mp"] = true,
-  ["TEX.mp"] = true,
-  ["metafun.mp"] = true,
-  ["metafun.mpiv"] = true,
-  ["mp-abck.mpiv"] = true,
-  ["mp-apos.mpiv"] = true,
-  ["mp-asnc.mpiv"] = true,
-  ["mp-bare.mpiv"] = true,
-  ["mp-base.mpiv"] = true,
-  ["mp-butt.mpiv"] = true,
-  ["mp-char.mpiv"] = true,
-  ["mp-chem.mpiv"] = true,
-  ["mp-core.mpiv"] = true,
-  ["mp-crop.mpiv"] = true,
-  ["mp-figs.mpiv"] = true,
-  ["mp-form.mpiv"] = true,
-  ["mp-func.mpiv"] = true,
-  ["mp-grap.mpiv"] = true,
-  ["mp-grid.mpiv"] = true,
-  ["mp-grph.mpiv"] = true,
-  ["mp-idea.mpiv"] = true,
-  ["mp-luas.mpiv"] = true,
-  ["mp-mlib.mpiv"] = true,
-  ["mp-node.mpiv"] = true,
-  ["mp-page.mpiv"] = true,
-  ["mp-shap.mpiv"] = true,
-  ["mp-step.mpiv"] = true,
-  ["mp-text.mpiv"] = true,
+  ["boxes.mp"] = true, --  ["format.mp"] = true,
+  ["graph.mp"] = true, ["marith.mp"] = true, ["mfplain.mp"] = true,
+  ["mpost.mp"] = true, ["plain.mp"] = true, ["rboxes.mp"] = true,
+  ["sarith.mp"] = true, ["string.mp"] = true, -- ["TEX.mp"] = true,
+  ["metafun.mp"] = true, ["metafun.mpiv"] = true, ["mp-abck.mpiv"] = true,
+  ["mp-apos.mpiv"] = true, ["mp-asnc.mpiv"] = true, ["mp-bare.mpiv"] = true,
+  ["mp-base.mpiv"] = true, ["mp-blob.mpiv"] = true, ["mp-butt.mpiv"] = true,
+  ["mp-char.mpiv"] = true, ["mp-chem.mpiv"] = true, ["mp-core.mpiv"] = true,
+  ["mp-crop.mpiv"] = true, ["mp-figs.mpiv"] = true, ["mp-form.mpiv"] = true,
+  ["mp-func.mpiv"] = true, ["mp-grap.mpiv"] = true, ["mp-grid.mpiv"] = true,
+  ["mp-grph.mpiv"] = true, ["mp-idea.mpiv"] = true, ["mp-luas.mpiv"] = true,
+  ["mp-mlib.mpiv"] = true, ["mp-node.mpiv"] = true, ["mp-page.mpiv"] = true,
+  ["mp-shap.mpiv"] = true, ["mp-step.mpiv"] = true, ["mp-text.mpiv"] = true,
   ["mp-tool.mpiv"] = true,
 }
 luamplib.noneedtoreplace = noneedtoreplace
@@ -189,26 +164,11 @@
   return newfile
 end
 
-local esctex  = "!!!T!!!E!!!X!!!"
-local esclbr  = "!!!!!LEFTBRCE!!!!!"
-local escrbr  = "!!!!!RGHTBRCE!!!!!"
-local escpcnt = "!!!!!PERCENT!!!!!"
-local eschash = "!!!!!HASH!!!!!"
-local begname = "%f[A-Z_a-z]"
-local endname = "%f[^A-Z_a-z]"
+local name_b = "%f[A-Z_a-z]"
+local name_e = "%f[^A-Z_a-z]"
+local btex_etex = name_b.."btex"..name_e.."%s*(.-)%s*"..name_b.."etex"..name_e
+local verbatimtex_etex = name_b.."verbatimtex"..name_e.."%s*(.-)%s*"..name_b.."etex"..name_e
 
-local btex_etex        = begname.."btex"..endname.."%s*(.-)%s*"..begname.."etex"..endname
-local verbatimtex_etex = begname.."verbatimtex"..endname.."%s*(.-)%s*"..begname.."etex"..endname
-
-local function protecttexcontents(str)
-  return str:gsub("\\%%", "\\"..escpcnt)
-            :gsub("%%.-\n", "")
-            :gsub("%%.-$",  "")
-            :gsub('"', '"&ditto&"')
-            :gsub("\n%s*", " ")
-            :gsub(escpcnt, "%%")
-end
-
 local function replaceinputmpfile (name,file)
   local ofmodify = lfsattributes(file,"modification")
   if not ofmodify then return file end
@@ -217,10 +177,12 @@
   newfile = cachedir .."/luamplib_input_"..newfile
   if newfile and luamplibtime then
     local nf = lfsattributes(newfile)
-    if nf and nf.mode == "file" and ofmodify == nf.modification and luamplibtime < nf.access then
+    if nf and nf.mode == "file" and
+      ofmodify == nf.modification and luamplibtime < nf.access then
       return nf.size == 0 and file or newfile
     end
   end
+
   if name == "format.mp" then return replaceformatmp(file,newfile,ofmodify) end
 
   local fh = ioopen(file,"r")
@@ -228,22 +190,11 @@
   local data = fh:read("*all"); fh:close()
 
   local count,cnt = 0,0
-
-  data = data:gsub("\"[^\n]-\"", function(str)
-    return str:gsub("([bem])tex"..endname,"%1"..esctex)
-  end)
-
-  data, cnt = data:gsub(btex_etex, function(str)
-    return format("rawtextext(\"%s\")",protecttexcontents(str))
-  end)
+  data, cnt = data:gsub(btex_etex, "btex %1 etex ") -- space
   count = count + cnt
-  data, cnt = data:gsub(verbatimtex_etex, "")
+  data, cnt = data:gsub(verbatimtex_etex, "verbatimtex %1 etex;") -- semicolon
   count = count + cnt
 
-  data = data:gsub("\"[^\n]-\"", function(str) -- restore string btex .. etex
-    return str:gsub("([bem])"..esctex, "%1tex")
-  end)
-
   if count == 0 then
     noneedtoreplace[name] = true
     fh = ioopen(newfile,"w");
@@ -253,6 +204,7 @@
     end
     return file
   end
+
   fh = ioopen(newfile,"w")
   if not fh then return file end
   fh:write(data); fh:close()
@@ -260,8 +212,6 @@
   return newfile
 end
 
-local randomseed = nil
-
 local mpkpse = kpse.new(arg[0], "mpost")
 
 local special_ftype = {
@@ -281,105 +231,35 @@
       end
       return replaceinputmpfile(name,file)
     end
-    return mpkpse:find_file(name,stringmatch(name,"[a-zA-Z]+$"))
+    return mpkpse:find_file(name, name:match("[a-zA-Z]+$"))
   end
 end
 luamplib.finder = finder
 
-
-function luamplib.resetlastlog()
-  luamplib.lastlog = ""
+if tonumber(mplib.version()) <= 1.50 then
+  err("luamplib no longer supports mplib v1.50 or lower. "..
+  "Please upgrade to the latest version of LuaTeX")
 end
 
-local mplibone = tonumber(mplib.version()) <= 1.50
+local preamble = [[
+  boolean mplib ; mplib := true ;
+  let dump = endinput ;
+  let normalfontsize = fontsize;
+  input %s ;
+]]
 
-if mplibone then
-
-  luamplib.make = luamplib.make or function(name,mem_name,dump)
-    local t = os.clock()
-    local mpx = mplib.new {
-      ini_version = true,
-      find_file = luamplib.finder,
-      job_name = stripsuffix(name)
-    }
-    mpx:execute(format("input %s ;",name))
-    if dump then
-      mpx:execute("dump ;")
-      info("format %s made and dumped for %s in %0.3f seconds",mem_name,name,os.clock()-t)
-    else
-      info("%s read in %0.3f seconds",name,os.clock()-t)
-    end
-    return mpx
-  end
-
-  function luamplib.load(name)
-    local mem_name = replacesuffix(name,"mem")
-    local mpx = mplib.new {
-      ini_version = false,
-      mem_name = mem_name,
-      find_file = luamplib.finder
-    }
-    if not mpx and type(luamplib.make) == "function" then
-      -- when i have time i'll locate the format and dump
-      mpx = luamplib.make(name,mem_name)
-    end
-    if mpx then
-      info("using format %s",mem_name,false)
-      return mpx, nil
-    else
-      return nil, { status = 99, error = "out of memory or invalid format" }
-    end
-  end
-
-else
-
-  local preamble = [[
-    boolean mplib ; mplib := true ;
-    let dump = endinput ;
-    let normalfontsize = fontsize;
-    input %s ;
-  ]]
-
-  luamplib.make = luamplib.make or function()
-  end
-
-  function luamplib.load(name,verbatim)
-    local mpx = mplib.new {
-      ini_version = true,
-      find_file = luamplib.finder,
-      math_mode = luamplib.numbersystem,
-      random_seed = randomseed,
-    }
-    local preamble = preamble .. (verbatim and "" or luamplib.mplibcodepreamble)
-    if luamplib.textextlabel then
-      preamble = preamble .. (verbatim and "" or luamplib.textextlabelpreamble)
-    end
-    local result
-    if not mpx then
-      result = { status = 99, error = "out of memory"}
-    else
-      result = mpx:execute(format(preamble, replacesuffix(name,"mp")))
-    end
-    luamplib.reporterror(result)
-    return mpx, result
-  end
-
+local function luamplibresetlastlog()
+  luamplib.lastlog = ""
 end
 
-local currentformat = "plain"
-
-local function setformat (name) --- used in .sty
-  currentformat = name
-end
-luamplib.setformat = setformat
-
-luamplib.reporterror = function (result)
+local function reporterror (result)
   if not result then
     err("no result object returned")
   else
     local t, e, l = result.term, result.error, result.log
-    local log = stringgsub(t or l or "no-term","^%s+","\n")
-    luamplib.lastlog = luamplib.lastlog .. "\n " .. (l or t or "no-log")
+    local log = t or l or "no-term"
+    log = log:gsub("^%s+","\n")
+    luamplib.lastlog = luamplib.lastlog .. "\n" .. (l or t or "no-log")
     if result.status > 0 then
       warn("%s",log)
       if result.status > 1 then
@@ -390,17 +270,50 @@
   end
 end
 
-local function process_indeed (mpx, data, indeed)
+local function luamplibload (name)
+  local mpx = mplib.new {
+    ini_version = true,
+    find_file   = luamplib.finder,
+    make_text   = luamplib.maketext,
+    run_script  = luamplib.runscript,
+    math_mode   = luamplib.numbersystem,
+    extensions  = 1,
+  }
+  local preamble = preamble .. luamplib.mplibcodepreamble
+  if luamplib.legacy_verbatimtex then
+    preamble = preamble .. luamplib.legacyverbatimtexpreamble
+  end
+  if luamplib.textextlabel then
+    preamble = preamble .. luamplib.textextlabelpreamble
+  end
+  local result
+  if not mpx then
+    result = { status = 99, error = "out of memory"}
+  else
+    result = mpx:execute(format(preamble, replacesuffix(name,"mp")))
+  end
+  reporterror(result)
+  return mpx, result
+end
+
+local currentformat = "plain"
+
+local function setformat (name)
+  currentformat = name
+end
+luamplib.setformat = setformat
+
+local function process_indeed (mpx, data)
   local converted, result = false, {}
   if mpx and data then
     result = mpx:execute(data)
-    local log = luamplib.reporterror(result)
-    if indeed and log then
+    local log = reporterror(result)
+    if log then
       if luamplib.showlog then
         info("%s",luamplib.lastlog)
-        luamplib.resetlastlog()
+        luamplibresetlastlog()
       elseif result.fig then
-        if stringfind(log,"\n>>") then info("%s",log) end
+        if log:find("\n>>") then info("%s",log) end
         converted = luamplib.convert(result)
       else
         info("%s",log)
@@ -415,182 +328,206 @@
 
 luamplib.codeinherit = false
 local mplibinstances = {}
-local process = function (data,indeed,verbatim)
-  if not stringfind(data, begname.."beginfig%s*%([%+%-%s]*%d[%.%d%s]*%)") then
+
+local function process (data)
+  if not data:find(name_b.."beginfig%s*%([%+%-%s]*%d[%.%d%s]*%)") then
     data = data .. "beginfig(-1);endfig;"
   end
-  local standalone, firstpass = not luamplib.codeinherit, not indeed
+  local standalone = not luamplib.codeinherit
   local currfmt = currentformat .. (luamplib.numbersystem or "scaled")
-  currfmt = firstpass and currfmt or (currfmt.."2")
+    .. tostring(luamplib.textextlabel) .. tostring(luamplib.legacy_verbatimtex)
   local mpx = mplibinstances[currfmt]
+  if mpx and standalone then
+    mpx:finish()
+  end
   if standalone or not mpx then
-    randomseed = firstpass and math.random(65535) or randomseed
-    mpx = luamplib.load(currentformat,verbatim)
+    mpx = luamplibload(currentformat)
     mplibinstances[currfmt] = mpx
   end
-  return process_indeed(mpx, data, indeed)
+  return process_indeed(mpx, data)
 end
-luamplib.process = process
 
-local function getobjects(result,figure,f)
-  return figure:objects()
+local catlatex = luatexbase.registernumber("catcodetable at latex")
+local catat11  = luatexbase.registernumber("catcodetable at atletter")
+
+local function run_tex_code_no_use (str, cat)
+  cat = cat or catlatex
+  texscantoks("mplibtmptoks", cat, str)
+  texruntoks("mplibtmptoks")
 end
 
-local function convert(result, flusher)
-  luamplib.flush(result, flusher)
-  return true -- done
+local function run_tex_code (str, cat)
+  cat = cat or catlatex
+  texruntoks(function() texsprint(cat, str) end)
 end
-luamplib.convert = convert
 
-local function pdf_startfigure(n,llx,lly,urx,ury)
-  texsprint(format("\\mplibstarttoPDF{%f}{%f}{%f}{%f}",llx,lly,urx,ury))
+local tex_box_id = 2047
+local factor = 65536*(7227/7200)
+
+local function process_tex_text (str)
+  if str then
+    tex_box_id = tex_box_id + 1
+    local global = luamplib.globaltextext and "\\global" or ""
+    run_tex_code(format("%s\\setbox%i\\hbox{%s}", global, tex_box_id, str))
+    local box = texgetbox(tex_box_id)
+    local wd  = box.width  / factor
+    local ht  = box.height / factor
+    local dp  = box.depth  / factor
+    return format("image(addto currentpicture doublepath unitsquare "..
+    "xscaled %f yscaled %f shifted (0,-%f) "..
+    "withprescript \"mplibtexboxid=%i:%f:%f\")",
+    wd, ht+dp, dp, tex_box_id, wd, ht+dp)
+  end
+  return ""
 end
 
-local function pdf_stopfigure()
-  texsprint("\\mplibstoptoPDF")
+local function process_color (str)
+  if str then
+    if not str:find("{.-}") then
+      str = format("{%s}",str)
+    end
+    run_tex_code(format(
+      "\\def\\set at color{\\toks0\\expandafter{\\current at color}}\\color %s", str),
+      catat11)
+    return format("1 withprescript \"MPlibOverrideColor=%s\"", texgettoks(0))
+  end
+  return ""
 end
 
-local function pdf_literalcode(fmt,...) -- table
-  textprint({"\\mplibtoPDF{"},{-2,format(fmt,...)},{"}"})
+local function process_dimen (str)
+  if str then
+    str = str:gsub("{(.+)}","%1")
+    run_tex_code(format("\\toks0\\expandafter{\\the\\dimexpr %s\\relax}", str))
+    return format("begingroup %s endgroup", texgettoks(0))
+  end
+  return ""
 end
-luamplib.pdf_literalcode = pdf_literalcode
 
-local function pdf_textfigure(font,size,text,width,height,depth)
-  -- if text == "" then text = "\0" end -- char(0) has gone
-  text = text:gsub(".",function(c)
-    return format("\\hbox{\\char%i}",string.byte(c)) -- kerning happens in metapost
-  end)
-  texsprint(format("\\mplibtextext{%s}{%f}{%s}{%s}{%f}",font,size,text,0,-( 7200/ 7227)/65536*depth))
+local function process_verbatimtex_text (str)
+  if str then
+    run_tex_code(str)
+  end
+  return ""
 end
-luamplib.pdf_textfigure = pdf_textfigure
 
-local bend_tolerance = 131/65536
+local tex_code_pre_mplib = {}
+luamplib.figid = 1
+luamplib.in_the_fig = false
 
-local rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1
-
-local function pen_characteristics(object)
-  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
+local function legacy_mplibcode_reset ()
+  tex_code_pre_mplib = {}
+  luamplib.figid = 1
 end
 
-local function concat(px, py) -- no tx, ty here
-  return (sy*px-ry*py)/divider,(sx*py-rx*px)/divider
+local function process_verbatimtex_prefig (str)
+  if str then
+    tex_code_pre_mplib[luamplib.figid] = str
+  end
+  return ""
 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
+local function process_verbatimtex_infig (str)
+  if str then
+    return format("special \"postmplibverbtex=%s\";", str)
   end
-  return true
+  return ""
 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)
+local runscript_funcs = {
+  luamplibtext    = process_tex_text,
+  luamplibcolor   = process_color,
+  luamplibdimen   = process_dimen,
+  luamplibprefig  = process_verbatimtex_prefig,
+  luamplibinfig   = process_verbatimtex_infig,
+  luamplibverbtex = process_verbatimtex_text,
+}
+
+mp = mp or {}
+local mp = mp
+mp.mf_path_reset = mp.mf_path_reset or function() end
+mp.mf_finish_saving_data = mp.mf_finish_saving_data or function() end
+LUATEXFUNCTIONALITY = LUATEXFUNCTIONALITY or 0
+
+local function mpprint(buffer,...)
+  for i=1,select("#",...) do
+    local value = select(i,...)
+    if value ~= nil then
+      local t = type(value)
+      if t == "number" then
+        buffer[#buffer+1] = format("%.16f",value)
+      elseif t == "string" then
+        buffer[#buffer+1] = value
+      elseif t == "table" then
+        buffer[#buffer+1] = "(" .. concat(value,",") .. ")"
+      else -- boolean or whatever
+        buffer[#buffer+1] = tostring(value)
+      end
     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
 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))
+function luamplib.runscript (code)
+  local id, str = code:match("(.-){(.+)}")
+  if id and str and str ~= "" then
+    local f = runscript_funcs[id]
+    if f then
+      local t = f(str)
+      if t then return t end
     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))
+  local f = loadstring(code)
+  if type(f) == "function" then
+    local buffer = {}
+    function mp.print(...)
+      mpprint(buffer,...)
     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))
+    f()
+    return tableconcat(buffer,"")
   end
+  return ""
 end
 
-local further_split_keys = {
-  ["MPlibTEXboxID"] = true,
-  ["sh_color_a"]    = true,
-  ["sh_color_b"]    = true,
-}
+local function protecttexcontents (str)
+  return str:gsub("\\%%", "\0PerCent\0")
+            :gsub("%%.-\n", "")
+            :gsub("%%.-$",  "")
+            :gsub("%zPerCent%z", "\\%%")
+            :gsub("%s+", " ")
+end
 
-local function script2table(s)
-  local t = {}
-  for _,i in ipairs(stringexplode(s,"\13+")) do
-    local k,v = stringmatch(i,"(.-)=(.*)") -- v may contain = or empty.
-    if k and v and k ~= "" then
-      if further_split_keys[k] then
-        t[k] = stringexplode(v,":")
-      else
-        t[k] = v
+luamplib.legacy_verbatimtex = true
+
+function luamplib.maketext (str, what)
+  if str and str ~= "" then
+    str = protecttexcontents(str)
+    if what == 1 then
+      if not str:find("\\documentclass"..name_e) and
+         not str:find("\\begin%s*{document}") and
+         not str:find("\\documentstyle"..name_e) and
+         not str:find("\\usepackage"..name_e) then
+        if luamplib.legacy_verbatimtex then
+          if luamplib.in_the_fig then
+            return process_verbatimtex_infig(str)
+          else
+            return process_verbatimtex_prefig(str)
+          end
+        else
+          return process_verbatimtex_text(str)
+        end
       end
+    else
+      return process_tex_text(str)
     end
   end
-  return t
+  return ""
 end
 
 local mplibcodepreamble = [[
-vardef rawtextext (expr t) =
-  if unknown TEXBOX_:
-    image( special "MPlibmkTEXbox="&t;
-      addto currentpicture doublepath unitsquare; )
-  else:
-    TEXBOX_ := TEXBOX_ + 1;
-    if known TEXBOX_wd_[TEXBOX_]:
-      image ( addto currentpicture doublepath unitsquare
-        xscaled TEXBOX_wd_[TEXBOX_]
-        yscaled (TEXBOX_ht_[TEXBOX_] + TEXBOX_dp_[TEXBOX_])
-        shifted (0, -TEXBOX_dp_[TEXBOX_])
-        withprescript "MPlibTEXboxID=" &
-          decimal TEXBOX_ & ":" &
-          decimal TEXBOX_wd_[TEXBOX_] & ":" &
-          decimal(TEXBOX_ht_[TEXBOX_]+TEXBOX_dp_[TEXBOX_]); )
-    else:
-      image( special "MPlibTEXError=1"; )
-    fi
-  fi
-enddef;
+texscriptmode := 2;
+def rawtextext (expr t) = runscript("luamplibtext{"&t&"}") enddef;
+def mplibcolor (expr t) = runscript("luamplibcolor{"&t&"}") enddef;
+def mplibdimen (expr t) = runscript("luamplibdimen{"&t&"}") enddef;
+def VerbatimTeX (expr t) = runscript("luamplibverbtex{"&t&"}") enddef;
 if known context_mlib:
   defaultfont := "cmtt10";
   let infont = normalinfont;
@@ -620,14 +557,21 @@
   draw rawtextext("\includegraphics{"& filename &"}")
 enddef;
 def TEX = textext enddef;
-def specialVerbatimTeX (text t) = special "MPlibVerbTeX="&t; enddef;
-def normalVerbatimTeX  (text t) = special "PostMPlibVerbTeX="&t; enddef;
-let VerbatimTeX = specialVerbatimTeX;
-extra_beginfig := extra_beginfig & " let VerbatimTeX = normalVerbatimTeX;" ;
-extra_endfig   := extra_endfig   & " let VerbatimTeX = specialVerbatimTeX;" ;
 ]]
 luamplib.mplibcodepreamble = mplibcodepreamble
 
+local legacyverbatimtexpreamble = [[
+def specialVerbatimTeX (text t) = runscript("luamplibprefig{"&t&"}") enddef;
+def normalVerbatimTeX  (text t) = runscript("luamplibinfig{"&t&"}") enddef;
+let VerbatimTeX = specialVerbatimTeX;
+extra_beginfig := extra_beginfig & " let VerbatimTeX = normalVerbatimTeX;"&
+  "runscript(" &ditto& "luamplib.in_the_fig=true" &ditto& ");";
+extra_endfig := extra_endfig & " let VerbatimTeX = specialVerbatimTeX;"&
+  "runscript(" &ditto&
+  "luamplib.in_the_fig=false luamplib.figid=luamplib.figid+1" &ditto& ");";
+]]
+luamplib.legacyverbatimtexpreamble = legacyverbatimtexpreamble
+
 local textextlabelpreamble = [[
 primarydef s infont f = rawtextext(s) enddef;
 def fontsize expr f =
@@ -641,142 +585,199 @@
 ]]
 luamplib.textextlabelpreamble = textextlabelpreamble
 
-local TeX_code_t = {}
-local texboxnum = { 2047 }
+luamplib.verbatiminput = false
 
-local function domakeTEXboxes (data)
-  local num = texboxnum[1]
-  texboxnum[2] = num
-  local global = luamplib.globaltextext and "\\global" or ""
-  if data and data.fig then
-    local figures = data.fig
-    for f=1, #figures do
-      TeX_code_t[f] = nil
-      local figure = figures[f]
-      local objects = getobjects(data,figure,f)
-      if objects then
-        for o=1,#objects do
-          local object    = objects[o]
-          local prescript = object.prescript
-          prescript = prescript and script2table(prescript)
-          local str = prescript and prescript.MPlibmkTEXbox
-          if str then
-            num = num + 1
-            texsprint(format("%s\\setbox%i\\hbox{%s}", global, num, str))
-          end
-          local texcode = prescript and prescript.MPlibVerbTeX
-          if texcode and texcode ~= "" then
-            TeX_code_t[f] = texcode
-          end
-        end
-      end
-    end
+local function protect_expansion (str)
+  if str then
+    str = str:gsub("\\","\1Control\1")
+             :gsub("%%","\1Comment\1")
+             :gsub("#", "\1HashSign\1")
+             :gsub("{", "\1LBrace\1")
+             :gsub("}", "\1RBrace\1")
+    return format("\\unexpanded{%s}",str)
   end
-  if luamplib.globaltextext then
-    texboxnum[1] = num
+end
+
+local function unprotect_expansion (str)
+  if str then
+    return str:gsub("\1Control\1", "\\")
+              :gsub("\1Comment\1", "%%")
+              :gsub("\1HashSign\1","#")
+              :gsub("\1LBrace\1",  "{")
+              :gsub("\1RBrace\1",  "}")
   end
 end
 
-local function protect_tex_text_common (data)
+local function process_mplibcode (data)
+  legacy_mplibcode_reset()
+
   local everymplib    = texgettoks('everymplibtoks')    or ''
   local everyendmplib = texgettoks('everyendmplibtoks') or ''
-  data = format("\n%s\n%s\n%s",everymplib, data, everyendmplib)
+  data = format("\n%s\n%s\n%s\n",everymplib, data, everyendmplib)
   data = data:gsub("\r","\n")
 
-  data = data:gsub("\"[^\n]-\"", function(str)
-    return str:gsub("([bem])tex"..endname,"%1"..esctex)
-  end)
+  data = data:gsub("\\mpcolor%s+(.-%b{})","mplibcolor(\"%1\")")
 
   data = data:gsub(btex_etex, function(str)
-    return format("rawtextext(\"%s\")",protecttexcontents(str))
+    return format("btex %s etex ", -- space
+      luamplib.verbatiminput and str or protect_expansion(str))
   end)
   data = data:gsub(verbatimtex_etex, function(str)
-    return format("VerbatimTeX(\"%s\")",protecttexcontents(str))
+    return format("verbatimtex %s etex;", -- semicolon
+      luamplib.verbatiminput and str or protect_expansion(str))
   end)
 
-  return data
+  if not luamplib.verbatiminput then
+    data = data:gsub("\".-\"", protect_expansion)
+    data = data:gsub("%%.-\n","")
+    run_tex_code(format("\\toks0\\expanded{{%s}}",data))
+    data = texgettoks(0)
+    data = data:gsub("##", "#")
+    data = data:gsub("\".-\"", unprotect_expansion)
+    data = data:gsub(btex_etex, function(str)
+      return format("btex %s etex", unprotect_expansion(str))
+    end)
+    data = data:gsub(verbatimtex_etex, function(str)
+      return format("verbatimtex %s etex", unprotect_expansion(str))
+    end)
+  end
+
+  process(data)
 end
+luamplib.process_mplibcode = process_mplibcode
 
-local function protecttextextVerbatim(data)
-  data = protect_tex_text_common(data)
+local further_split_keys = {
+  ["mplibtexboxid"] = true,
+  ["sh_color_a"]    = true,
+  ["sh_color_b"]    = true,
+}
 
-  data = data:gsub("\"[^\n]-\"", function(str) -- restore string btex .. etex
-    return str:gsub("([bem])"..esctex, "%1tex")
-  end)
+local function script2table(s)
+  local t = {}
+  for _,i in ipairs(s:explode("\13+")) do
+    local k,v = i:match("(.-)=(.*)") -- v may contain = or empty.
+    if k and v and k ~= "" then
+      if further_split_keys[k] then
+        t[k] = v:explode(":")
+      else
+        t[k] = v
+      end
+    end
+  end
+  return t
+end
 
-  local _,result = process(data, false)
-  domakeTEXboxes(result)
-  return data
+local function getobjects(result,figure,f)
+  return figure:objects()
 end
 
-luamplib.protecttextextVerbatim = protecttextextVerbatim
+local function convert(result, flusher)
+  luamplib.flush(result, flusher)
+  return true -- done
+end
+luamplib.convert = convert
 
-luamplib.mpxcolors = {}
+local function pdf_startfigure(n,llx,lly,urx,ury)
+  texsprint(format("\\mplibstarttoPDF{%f}{%f}{%f}{%f}",llx,lly,urx,ury))
+end
 
-local function protecttextext(data)
-  data = protect_tex_text_common(data)
+local function pdf_stopfigure()
+  texsprint("\\mplibstoptoPDF")
+end
 
-  data = data:gsub("\"[^\n]-\"", function(str)
-    str = str:gsub("([bem])"..esctex, "%1tex")
-             :gsub("%%", escpcnt)
-             :gsub("{",  esclbr)
-             :gsub("}",  escrbr)
-             :gsub("#",  eschash)
-    return format("\\detokenize{%s}",str)
+local function pdf_literalcode(fmt,...) -- table
+  textprint({"\\mplibtoPDF{"},{-2,format(fmt,...)},{"}"})
+end
+
+local function pdf_textfigure(font,size,text,width,height,depth)
+  text = text:gsub(".",function(c)
+    return format("\\hbox{\\char%i}",string.byte(c)) -- kerning happens in metapost
   end)
+  texsprint(format("\\mplibtextext{%s}{%f}{%s}{%s}{%f}",font,size,text,0,-( 7200/ 7227)/65536*depth))
+end
 
-  data = data:gsub("%%.-\n", "")
+local bend_tolerance = 131/65536
 
-  local grouplevel = tex.currentgrouplevel
-  luamplib.mpxcolors[grouplevel] = {}
-  data = data:gsub("\\mpcolor"..endname.."(.-){(.-)}", function(opt,str)
-    local cnt = #luamplib.mpxcolors[grouplevel] + 1
-    luamplib.mpxcolors[grouplevel][cnt] = format(
-      "\\expandafter\\mplibcolor\\csname mpxcolor%i:%i\\endcsname%s{%s}",
-      grouplevel,cnt,opt,str)
-    return format("\\csname mpxcolor%i:%i\\endcsname",grouplevel,cnt)
-  end)
+local rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1
 
-  data = data:gsub("([^`\\])#","%1##")
+local function pen_characteristics(object)
+  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
+end
 
-  texsprint(data)
+local function concat(px, py) -- no tx, ty here
+  return (sy*px-ry*py)/divider,(sx*py-rx*px)/divider
 end
 
-luamplib.protecttextext = protecttextext
+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 makeTEXboxes (data)
-  data = data:gsub("##","#")
-             :gsub(escpcnt,"%%")
-             :gsub(esclbr,"{")
-             :gsub(escrbr,"}")
-             :gsub(eschash,"#")
-  local _,result = process(data, false)
-  domakeTEXboxes(result)
-  return data
+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
 end
 
-luamplib.makeTEXboxes = makeTEXboxes
-
-local factor = 65536*(7227/7200)
-
-local function processwithTEXboxes (data)
-  if not data then return end
-  local num = texboxnum[2]
-  local prepreamble = format("TEXBOX_:=%i;\n",num)
-  while true do
-    num = num + 1
-    local box = texgetbox(num)
-    if not box then break end
-    prepreamble = format(
-      "%sTEXBOX_wd_[%i]:=%f;\nTEXBOX_ht_[%i]:=%f;\nTEXBOX_dp_[%i]:=%f;\n",
-      prepreamble,
-      num, box.width /factor,
-      num, box.height/factor,
-      num, box.depth /factor)
+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
-  process(prepreamble .. data, true)
+  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
 end
-luamplib.processwithTEXboxes = processwithTEXboxes
 
 local pdfoutput = tonumber(texget("outputmode")) or tonumber(texget("pdfoutput"))
 local pdfmode = pdfoutput > 0
@@ -796,8 +797,8 @@
   end
 end
 
-local function putTEXboxes (object,prescript)
-  local box = prescript.MPlibTEXboxID
+local function put_tex_boxes (object,prescript)
+  local box = prescript.mplibtexboxid
   local n,tw,th = box[1],tonumber(box[2]),tonumber(box[3])
   if n and tw and th then
     local op = object.path
@@ -833,7 +834,6 @@
             "\\special{pdf:obj @MPlibSh<<>>}")
 end
 
--- objstr <string> => obj <number>, new <boolean>
 local function update_pdfobjs (os)
   local on = pdf_objs[os]
   if on then
@@ -907,7 +907,7 @@
 
 local function shading_initialize ()
   shading_res = {}
-  if pdfmode and luatexbase.callbacktypes and luatexbase.callbacktypes.finish_pdffile then -- ltluatex
+  if pdfmode and luatexbase.callbacktypes.finish_pdffile then -- ltluatex
     local shading_obj = pdf.reserveobj()
     setpageres(format("%s/Shading %i 0 R",getpageres() or "",shading_obj))
     luatexbase.add_to_callback("finish_pdffile", function()
@@ -932,7 +932,7 @@
         shading_res[#shading_res+1] = res
       else
         local pageres = getpageres() or ""
-        if not stringfind(pageres,"/Shading<<.*>>") then
+        if not pageres:find("/Shading<<.*>>") then
           pageres = pageres.."/Shading<<>>"
         end
         pageres = pageres:gsub("/Shading<<","%1"..res)
@@ -963,7 +963,6 @@
 local prev_override_color
 
 local function do_preobj_color(object,prescript)
-  -- transparency
   local opaq = prescript and prescript.tr_transparency
   local tron_no, troff_no
   if opaq then
@@ -972,7 +971,6 @@
     tron_no, troff_no = tr_pdf_pageresources(mode,opaq)
     pdf_literalcode("/MPlibTr%i gs",tron_no)
   end
-  -- color
   local override = prescript and prescript.MPlibOverrideColor
   if override then
     if pdfmode then
@@ -994,12 +992,11 @@
       end
     end
   end
-  -- shading
   local sh_type = prescript and prescript.sh_type
   if sh_type then
     local domain  = prescript.sh_domain
-    local centera = stringexplode(prescript.sh_center_a)
-    local centerb = stringexplode(prescript.sh_center_b)
+    local centera = prescript.sh_center_a:explode()
+    local centerb = prescript.sh_center_b:explode()
     for _,t in pairs({centera,centerb}) do
       for i,v in ipairs(t) do
         t[i] = format("%f",v)
@@ -1055,7 +1052,6 @@
   end
 end
 
-
 local function flush(result,flusher)
   if result then
     local figures = result.fig
@@ -1064,19 +1060,16 @@
         info("flushing figure %s",f)
         local figure = figures[f]
         local objects = getobjects(result,figure,f)
-        local fignum = tonumber(stringmatch(figure:filename(),"([%d]+)$") or figure:charcode() or 0)
+        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
-          if TeX_code_t[f] then
-            texsprint(TeX_code_t[f])
+          if tex_code_pre_mplib[f] then
+            texsprint(tex_code_pre_mplib[f])
           end
-          local TeX_code_bot = {} -- PostVerbatimTeX
+          local TeX_code_bot = {}
           pdf_startfigure(fignum,llx,lly,urx,ury)
           start_pdf_code()
           if objects then
@@ -1088,12 +1081,9 @@
               local prescript     = object.prescript
               prescript = prescript and script2table(prescript) -- prescript is now a table
               local tr_opaq,cr_over,shade_no = do_preobj_color(object,prescript)
-              if prescript and prescript.MPlibTEXboxID then
-                putTEXboxes(object,prescript)
-              elseif prescript and prescript.PostMPlibVerbTeX then
-                TeX_code_bot[#TeX_code_bot+1] = prescript.PostMPlibVerbTeX
-              elseif objecttype == "start_bounds" or objecttype == "stop_bounds" then
-                -- skip
+              if prescript and prescript.mplibtexboxid then
+                put_tex_boxes(object,prescript)
+              elseif objecttype == "start_bounds" or objecttype == "stop_bounds" then --skip
               elseif objecttype == "start_clip" then
                 local evenodd = not object.istext and object.postscript == "evenodd"
                 start_pdf_code()
@@ -1103,9 +1093,8 @@
                 stop_pdf_code()
                 miterlimit, linecap, linejoin, dashed = -1, -1, -1, false
               elseif objecttype == "special" then
-                -- not supported
-                if prescript and prescript.MPlibTEXError then
-                  warn("textext() anomaly. Try disabling \\mplibtextextlabel.")
+                if prescript and prescript.postmplibverbtex then
+                  TeX_code_bot[#TeX_code_bot+1] = prescript.postmplibverbtex
                 end
               elseif objecttype == "text" then
                 local ot = object.transform -- 3,4,5,6,1,2
@@ -1198,7 +1187,7 @@
                     else
                       flushnormalpath(path,open)
                     end
-                    if not shade_no then ----- conflict with shading
+                    if not shade_no then -- conflict with shading
                       if objecttype == "fill" then
                         pdf_literalcode(evenodd and "h f*" or "h f")
                       elseif objecttype == "outline" then
@@ -1255,9 +1244,7 @@
           end
           stop_pdf_code()
           pdf_stopfigure()
-          if #TeX_code_bot > 0 then
-            texsprint(TeX_code_bot)
-          end
+          if #TeX_code_bot > 0 then texsprint(TeX_code_bot) end
         end
       end
     end

Modified: trunk/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty	2019-03-21 20:54:17 UTC (rev 50509)
+++ trunk/Master/texmf-dist/tex/luatex/luamplib/luamplib.sty	2019-03-21 20:54:31 UTC (rev 50510)
@@ -14,7 +14,7 @@
 \else
   \NeedsTeXFormat{LaTeX2e}
   \ProvidesPackage{luamplib}
-    [2018/09/27 v2.12.5 mplib package for LuaTeX]
+    [2019/03/20 v2.20.0 mplib package for LuaTeX]
   \ifx\newluafunction\@undefined
   \input ltluatex
   \fi
@@ -26,8 +26,8 @@
 \ifx\pdfoutput\undefined
   \let\pdfoutput\outputmode
   \protected\def\pdfliteral{\pdfextension literal}
+  \def\pdffontsize{\dimexpr\pdffeedback fontsize\relax}
 \fi
-
 \def\mplibsetformat#1{\directlua{luamplib.setformat("#1")}}
 \ifnum\pdfoutput>0
   \let\mplibtoPDF\pdfliteral
@@ -41,8 +41,11 @@
     \write128{}
   \fi
 \fi
+\def\mplibforcehmode{\let\mplibhmodeornot\leavevmode}
+\def\mplibnoforcehmode{\let\mplibhmodeornot\relax}
+\mplibnoforcehmode
 \def\mplibsetupcatcodes{%
-  %catcode`\{=12 %catcode`\}=12
+  \mplibhmodeornot %catcode`\{=12 %catcode`\}=12
   \catcode`\#=12 \catcode`\^=12 \catcode`\~=12 \catcode`\_=12
   \catcode`\&=12 \catcode`\$=12 \catcode`\%=12 \catcode`\^^M=12 \endlinechar=10
 }
@@ -69,15 +72,7 @@
 }
 \long\def\mplibdocode#1\endmplibcode{%
   \endgroup
-  \ifdefined\mplibverbatimYes
-    \directlua{luamplib.tempdata\the\currentgrouplevel=luamplib.protecttextextVerbatim([===[\detokenize{#1}]===])}%
-    \directlua{luamplib.processwithTEXboxes(luamplib.tempdata\the\currentgrouplevel)}%
-  \else
-    \edef\mplibtemp{\directlua{luamplib.protecttextext([===[\unexpanded{#1}]===])}}%
-    \directlua{ tex.sprint(luamplib.mpxcolors[\the\currentgrouplevel]) }%
-    \directlua{luamplib.tempdata\the\currentgrouplevel=luamplib.makeTEXboxes([===[\mplibtemp]===])}%
-    \directlua{luamplib.processwithTEXboxes(luamplib.tempdata\the\currentgrouplevel)}%
-  \fi
+  \directlua{luamplib.process_mplibcode([===[\unexpanded{#1}]===])}%
   \endgroup
   \ifnum\mplibstartlineno<\inputlineno\expandafter\mplibreplacenewlinecs\fi
 }
@@ -95,16 +90,9 @@
 \long\def\ltxdomplibcodeindeed#1\end#2{%
   \endgroup
   \toks@\expandafter{\the\toks@#1}%
-  \def\mplibtemp at a{#2}\ifx\mplib at mplibcode\mplibtemp at a
-    \ifdefined\mplibverbatimYes
-      \directlua{luamplib.tempdata\the\currentgrouplevel=luamplib.protecttextextVerbatim([===[\the\toks@]===])}%
-      \directlua{luamplib.processwithTEXboxes(luamplib.tempdata\the\currentgrouplevel)}%
-    \else
-      \edef\mplibtemp{\directlua{luamplib.protecttextext([===[\the\toks@]===])}}%
-      \directlua{ tex.sprint(luamplib.mpxcolors[\the\currentgrouplevel]) }%
-      \directlua{luamplib.tempdata\the\currentgrouplevel=luamplib.makeTEXboxes([===[\mplibtemp]===])}%
-      \directlua{luamplib.processwithTEXboxes(luamplib.tempdata\the\currentgrouplevel)}%
-    \fi
+  \def\mplibtemp at a{#2}%
+  \ifx\mplib at mplibcode\mplibtemp at a
+    \directlua{luamplib.process_mplibcode([===[\the\toks@]===])}%
     \end{mplibcode}%
     \ifnum\mplibstartlineno<\inputlineno
       \expandafter\expandafter\expandafter\mplibreplacenewlinebr
@@ -114,16 +102,23 @@
   \fi
 }
 \fi
-\def\mplibverbatim#1{%
-  \begingroup
-  \def\mplibtempa{#1}\def\mplibtempb{enable}%
-  \expandafter\endgroup
-  \ifx\mplibtempa\mplibtempb
-    \let\mplibverbatimYes\relax
-  \else
-    \let\mplibverbatimYes\undefined
-  \fi
-}
+\def\mpliblegacybehavior#1{\directlua{
+    local s = string.lower("#1")
+    if s == "enable" or s == "true" or s == "yes" then
+      luamplib.legacy_verbatimtex = true
+    else
+      luamplib.legacy_verbatimtex = false
+    end
+}}
+\def\mplibverbatim#1{\directlua{
+    local s = string.lower("#1")
+    if s == "enable" or s == "true" or s == "yes" then
+      luamplib.verbatiminput = true
+    else
+      luamplib.verbatiminput = false
+    end
+}}
+\newtoks\mplibtmptoks
 \newtoks\everymplibtoks
 \newtoks\everyendmplibtoks
 \protected\def\everymplib{%
@@ -149,11 +144,11 @@
   \ifnum\mplibstartlineno<\inputlineno\expandafter\mplibreplacenewlinebr\fi
 }
 \def\mpdim#1{ begingroup \the\dimexpr #1\relax\space endgroup } % gmp.sty
-\def\mplibcolor#1{%
-  \def\set at color{\edef#1{1 withprescript "MPlibOverrideColor=\current at color"}}%
-  \color
-}
-\def\mplibnumbersystem#1{\directlua{luamplib.numbersystem = "#1"}}
+\def\mplibnumbersystem#1{\directlua{
+  local t = "#1"
+  if t == "binary" then t = "decimal" end
+  luamplib.numbersystem = t
+}}
 \def\mplibmakenocache#1{\mplibdomakenocache #1,*,}
 \def\mplibdomakenocache#1,{%
   \ifx\empty#1\empty
@@ -177,36 +172,30 @@
   \fi
 }
 \def\mplibcachedir#1{\directlua{luamplib.getcachedir("\unexpanded{#1}")}}
-\def\mplibtextextlabel#1{%
-  \begingroup
-  \def\tempa{enable}\def\tempb{#1}%
-  \ifx\tempa\tempb
-    \directlua{luamplib.textextlabel = true}%
-  \else
-    \directlua{luamplib.textextlabel = false}%
-  \fi
-  \endgroup
-}
-\def\mplibcodeinherit#1{%
-  \begingroup
-  \def\tempa{enable}\def\tempb{#1}%
-  \ifx\tempa\tempb
-    \directlua{luamplib.codeinherit = true}%
-  \else
-    \directlua{luamplib.codeinherit = false}%
-  \fi
-  \endgroup
-}
-\def\mplibglobaltextext#1{%
-  \begingroup
-  \def\tempa{enable}\def\tempb{#1}%
-  \ifx\tempa\tempb
-    \directlua{luamplib.globaltextext = true}%
-  \else
-    \directlua{luamplib.globaltextext = false}%
-  \fi
-  \endgroup
-}
+\def\mplibtextextlabel#1{\directlua{
+    local s = string.lower("#1")
+    if s == "enable" or s == "true" or s == "yes" then
+      luamplib.textextlabel = true
+    else
+      luamplib.textextlabel = false
+    end
+}}
+\def\mplibcodeinherit#1{\directlua{
+    local s = string.lower("#1")
+    if s == "enable" or s == "true" or s == "yes" then
+      luamplib.codeinherit = true
+    else
+      luamplib.codeinherit = false
+    end
+}}
+\def\mplibglobaltextext#1{\directlua{
+    local s = string.lower("#1")
+    if s == "enable" or s == "true" or s == "yes" then
+      luamplib.globaltextext = true
+    else
+      luamplib.globaltextext = false
+    end
+}}
 \ifx\mplibscratchbox\undefined \newbox\mplibscratchbox \fi
 \def\mplibstarttoPDF#1#2#3#4{%
   \hbox\bgroup



More information about the tex-live-commits mailing list