From 2e0934d99d3af014bd95c68d52f2d24816a11b8c Mon Sep 17 00:00:00 2001
From: Marius <mariausol@gmail.com>
Date: Thu, 2 Dec 2010 13:20:14 +0200
Subject: beta 2010.12.02 12:05

---
 scripts/context/lua/mtx-interface.lua            |  23 ++
 scripts/context/lua/mtxrun.lua                   |   1 +
 scripts/context/stubs/mswin/mtxrun.lua           |   1 +
 scripts/context/stubs/unix/mtxrun                |   1 +
 tex/context/base/cont-new.tex                    |   2 +-
 tex/context/base/context.tex                     |   2 +-
 tex/context/base/luat-mac.lua                    |  14 +-
 tex/context/base/tabl-ntb.mkiv                   |  19 +
 tex/context/base/tabl-tab.mkiv                   |   2 +-
 tex/generic/context/luatex-fonts-merged.lua      |   2 +-
 tex/generic/context/luatex-fonts.tex             |   3 +-
 tex/generic/context/luatex-mplib.lua             | 491 -----------------------
 tex/generic/context/luatex-mplib.tex             |   3 +-
 tex/generic/context/luatex-preprocessor-test.tex |  30 ++
 tex/generic/context/luatex-preprocessor.lua      | 163 ++++++++
 tex/generic/context/luatex-preprocessor.tex      |  14 +
 16 files changed, 267 insertions(+), 504 deletions(-)
 delete mode 100644 tex/generic/context/luatex-mplib.lua
 create mode 100644 tex/generic/context/luatex-preprocessor-test.tex
 create mode 100644 tex/generic/context/luatex-preprocessor.lua
 create mode 100644 tex/generic/context/luatex-preprocessor.tex

diff --git a/scripts/context/lua/mtx-interface.lua b/scripts/context/lua/mtx-interface.lua
index ed0792d32..9659dce90 100644
--- a/scripts/context/lua/mtx-interface.lua
+++ b/scripts/context/lua/mtx-interface.lua
@@ -300,6 +300,24 @@ function scripts.interface.context()
     end
 end
 
+function scripts.interface.preprocess()
+    require("luat-mac.lua")
+    local newsuffix = environment.argument("suffix") or "tex"
+    local force = environment.argument("force")
+    for i=1,#environment.files do
+        local oldname = environment.files[i]
+        local newname = file.replacesuffix(oldname,newsuffix)
+        if oldname == newname then
+            logs.simple("skipping '%s' because old and new name are the same",oldname)
+        elseif io.exists(newname) and not force then
+            logs.simple("skipping '%s' because new file exists, use --force",oldname)
+        else
+            logs.simple("processing '%s' into '%s'",oldname,newname)
+            io.savedata(newname,resolvers.macros.preprocessed(io.loaddata(oldname)))
+        end
+    end
+end
+
 function scripts.interface.messages()
     local filename = resolvers.findfile(environment.files[1] or "mult-mes.lua") or ""
     if filename ~= "" then
@@ -338,6 +356,9 @@ messages.help = [[
 --raw                 report commands to the console
 --check               generate check file
 --context             generate context definition files
+--preprocess          preprocess mkvi files to tex files [force,suffix]
+--suffix              use given suffix for output files
+--force               force action even when in doubt
 --messages            generate context message files
 ]]
 
@@ -345,6 +366,8 @@ local ea = environment.argument
 
 if ea("context") then
     scripts.interface.context()
+elseif ea("preprocess") then
+    scripts.interface.preprocess()
 elseif ea("messages") then
     scripts.interface.messages()
 elseif ea("scite") or ea("bbedit") or ea("jedit") or ea("textpad") or ea("text") or ea("raw") then
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index bb16aaec0..a80e4c730 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -13906,6 +13906,7 @@ function runners.execute_program(fullname)
             return true
         elseif state == "run" then
             local before, after = environment.splitarguments(fullname)
+            for k=1,#after do after[k] = resolvers.resolve(after[k]) end
             environment.initializearguments(after)
             fullname = fullname:gsub("^bin:","")
             local command = fullname .. " " .. (environment.reconstructcommandline(after or "",noquote) or "")
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index bb16aaec0..a80e4c730 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -13906,6 +13906,7 @@ function runners.execute_program(fullname)
             return true
         elseif state == "run" then
             local before, after = environment.splitarguments(fullname)
+            for k=1,#after do after[k] = resolvers.resolve(after[k]) end
             environment.initializearguments(after)
             fullname = fullname:gsub("^bin:","")
             local command = fullname .. " " .. (environment.reconstructcommandline(after or "",noquote) or "")
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index bb16aaec0..a80e4c730 100644
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -13906,6 +13906,7 @@ function runners.execute_program(fullname)
             return true
         elseif state == "run" then
             local before, after = environment.splitarguments(fullname)
+            for k=1,#after do after[k] = resolvers.resolve(after[k]) end
             environment.initializearguments(after)
             fullname = fullname:gsub("^bin:","")
             local command = fullname .. " " .. (environment.reconstructcommandline(after or "",noquote) or "")
diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex
index 2bc978f54..a9a9051d3 100644
--- a/tex/context/base/cont-new.tex
+++ b/tex/context/base/cont-new.tex
@@ -11,7 +11,7 @@
 %C therefore copyrighted by \PRAGMA. See mreadme.pdf for
 %C details.
 
-\newcontextversion{2010.12.02 08:51}
+\newcontextversion{2010.12.02 12:05}
 
 %D This file is loaded at runtime, thereby providing an
 %D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/context.tex b/tex/context/base/context.tex
index 0e5c6fcb4..2f21c79c7 100644
--- a/tex/context/base/context.tex
+++ b/tex/context/base/context.tex
@@ -20,7 +20,7 @@
 %D your styles an modules.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2010.12.02 08:51}
+\edef\contextversion{2010.12.02 12:05}
 
 %D For those who want to use this:
 
diff --git a/tex/context/base/luat-mac.lua b/tex/context/base/luat-mac.lua
index 4a9e53b0e..8010f34a5 100644
--- a/tex/context/base/luat-mac.lua
+++ b/tex/context/base/luat-mac.lua
@@ -10,7 +10,7 @@ local P, V, S, R, C, Cs, Cmt = lpeg.P, lpeg.V, lpeg.S, lpeg.R, lpeg.C, lpeg.Cs,
 local lpegmatch, patterns = lpeg.match, lpeg.patterns
 
 local insert, remove = table.insert, table.remove
-local rep = string.rep
+local rep, sub = string.rep, string.sub
 local setmetatable = setmetatable
 
 local report_macros = logs.new("macros")
@@ -55,7 +55,7 @@ local function pop()
     top = remove(stack)
 end
 
-local leftbrace   = P("{")
+local leftbrace   = P("{")   -- will be in patterns
 local rightbrace  = P("}")
 local escape      = P("\\")
 
@@ -64,8 +64,12 @@ local spaces      = space^1
 local newline     = patterns.newline
 local nobrace     = 1 - leftbrace - rightbrace
 
+local longleft    = leftbrace  -- P("(")
+local longright   = rightbrace -- P(")")
+local nolong      = 1 - longleft - longright
+
 local name        = R("AZ","az")^1 -- @?! -- utf?
-local longname    = (leftbrace/"") * (nobrace^1) * (rightbrace/"")
+local longname    = (longleft/"") * (nolong^1) * (longright/"")
 local variable    = P("#") * Cs(name + longname)
 local escapedname = escape * name
 local definer     = escape * (P("def") + P("egdx") * P("def"))
@@ -80,7 +84,7 @@ local declaration = variable / set
 local identifier  = variable / get
 
 local function matcherror(str,pos)
-    report_macros("runaway definition at: %s",string.sub(str,pos-30,pos))
+    report_macros("runaway definition at: %s",sub(str,pos-30,pos))
 end
 
 local grammar = { "converter",
@@ -132,7 +136,7 @@ function macros.preprocessed(str)
     return lpegmatch(parser,str)
 end
 
-function macros.convertfile(oldname,newname)
+function macros.convertfile(oldname,newname) -- beware, no testing on oldname == newname
     local data = resolvers.loadtexfile(oldname)
     data = interfaces.preprocessed(data) or ""
     io.savedata(newname,data)
diff --git a/tex/context/base/tabl-ntb.mkiv b/tex/context/base/tabl-ntb.mkiv
index d5eee61a0..34c4e8bb2 100644
--- a/tex/context/base/tabl-ntb.mkiv
+++ b/tex/context/base/tabl-ntb.mkiv
@@ -14,6 +14,7 @@
 %D This is an unfinished, preliminary module. At least two
 %D runs are needed to get the table fixed. Ugly code.
 
+% todo: TABLE TBL -> ntb
 % todo: special parsetb for argless variant
 % todo: protect \tbl...
 % todo: tblnx also count
@@ -21,6 +22,24 @@
 % todo: fast if
 % todo: avoid halign (just do it manual) and thereby globals
 
+
+% \unexpanded\def\startrow            {\bTR}
+% \unexpanded\def\stoprow             {\eTR}
+% \unexpanded\def\startcell#1\stopcell{\bTD#1\eTD}
+%            \let\stopcell             \relax
+%            \let\startcelltable       \bTABLE
+%            \let\stopcelltable        \eTABLE
+
+% \starttext
+%     \startcelltable[|c|c|]
+%         \startrow \startcell a \stopcell \stoprow
+%         \startrow \startcell a \stopcell \stoprow
+%         \startrow \startcell a \stopcell \stoprow
+%         \startrow \startcell a \stopcell \stoprow
+%     \stopcelltable
+% \stoptext
+
+
 % optie=rek beschrijven
 
 \writestatus{loading}{ConTeXt Table Macros / Natural Tables}
diff --git a/tex/context/base/tabl-tab.mkiv b/tex/context/base/tabl-tab.mkiv
index b5f79ff4b..fd05aae55 100644
--- a/tex/context/base/tabl-tab.mkiv
+++ b/tex/context/base/tabl-tab.mkiv
@@ -2269,7 +2269,7 @@
 \to \localtabledefinitions
 
 \def\dochecktabledivision
-  {\ifcondition\istabledivision\else
+  {\ifconditional\istabledivision\else
      \dochucktableautorow
      \global\currenttablecolumn\zerocount
      \global\settrue\istabledivision
diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua
index d8f9ccbdb..371a61edf 100644
--- a/tex/generic/context/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
 -- merged file : luatex-fonts-merged.lua
 -- parent file : luatex-fonts.lua
--- merge date  : 12/02/10 08:51:01
+-- merge date  : 12/02/10 12:05:11
 
 do -- begin closure to overcome local limits and interference
 
diff --git a/tex/generic/context/luatex-fonts.tex b/tex/generic/context/luatex-fonts.tex
index 644d168f5..8ccc9f3d5 100644
--- a/tex/generic/context/luatex-fonts.tex
+++ b/tex/generic/context/luatex-fonts.tex
@@ -4,8 +4,7 @@
 %D          title=\LUATEX\ Support Macros,
 %D       subtitle=Generic \OPENTYPE\ Font Handler,
 %D         author=Hans Hagen,
-%D           date=\currentdate,
-%D      copyright=public domain]
+%D      copyright=see context related readme files]
 
 %D \subject{Welcome}
 %D
diff --git a/tex/generic/context/luatex-mplib.lua b/tex/generic/context/luatex-mplib.lua
deleted file mode 100644
index c6628acb3..000000000
--- a/tex/generic/context/luatex-mplib.lua
+++ /dev/null
@@ -1,491 +0,0 @@
-if not modules then modules = { } end modules ['luatex-mplib'] = {
-    version   = 1.001,
-    comment   = "companion to luatex-mplib.tex",
-    author    = "Hans Hagen & Taco Hoekwater",
-    copyright = "ConTeXt Development Team",
-    license   = "public domain",
-}
-
---[[ldx--
-<p>This module is a stripped down version of libraries that are used
-by <l n='context'/>. It can be used in other macro packages and/or
-serve as an example. Embedding in a macro package is upto others and
-normally boils down to inputting <t>supp-mpl.tex</t>.</p>
---ldx]]--
-
-if metapost and metapost.version then
-
-    --[[ldx--
-    <p>Let's silently quit and make sure that no one loads it
-    manually in <l n='context'/>.</p>
-    --ldx]]--
-
-else
-
-    local format, concat, abs, match = string.format, table.concat, math.abs, string.match
-
-    local mplib = require ('mplib')
-    local kpse  = require ('kpse')
-
-    --[[ldx--
-    <p>We create a namespace and some variables to it. If a namespace is
-    already defined it wil not be initialized. This permits hooking
-    in code beforehand.</p>
-
-    <p>We don't make a format automatically. After all, distributions
-    might have their own preferences and normally a format (mem) file will
-    have some special place in the <l n='tex'/> tree. Also, there can already
-    be format files, different memort settings and other nasty pitfalls that
-    we don't want to interfere with. If you want, you can define a function
-    <t>metapost.make(name,mem_name) that does the job.</t></p>
-    --ldx]]--
-
-    metapost          = metapost or { }
-    metapost.version  = 1.00
-    metapost.showlog  = metapost.showlog or false
-    metapost.lastlog  = ""
-
-    --[[ldx--
-    <p>A few helpers, taken from <t>l-file.lua</t>.</p>
-    --ldx]]--
-
-    local file = file or { }
-
-    function file.replacesuffix(filename, suffix)
-        return (string.gsub(filename,"%.[%a%d]+$","")) .. "." .. suffix
-    end
-
-    function file.stripsuffix(filename)
-        return (string.gsub(filename,"%.[%a%d]+$",""))
-    end
-
-    --[[ldx--
-    <p>We use the <l n='kpse'/> library unless a finder is already
-    defined.</p>
-    --ldx]]--
-
-    local mpkpse = kpse.new("luatex","mpost")
-
-    metapost.finder = metapost.finder or function(name, mode, ftype)
-        if mode == "w" then
-            return name
-        else
-            return mpkpse:find_file(name,ftype)
-        end
-    end
-
-    --[[ldx--
-    <p>You can use your own reported if needed, as long as it handles multiple
-    arguments and formatted strings.</p>
-    --ldx]]--
-
-    metapost.report = metapost.report or function(...)
-        texio.write(format("<mplib: %s>",format(...)))
-    end
-
-    --[[ldx--
-    <p>The rest of this module is not documented. More info can be found in the
-    <l n='luatex'/> manual, articles in user group journals and the files that
-    ship with <l n='context'/>.</p>
-    --ldx]]--
-
-    function metapost.resetlastlog()
-        metapost.lastlog = ""
-    end
-
-    local mplibone = tonumber(mplib.version()) <= 1.50
-
-    if mplibone then
-
-        metapost.make = metapost.make or function(name,mem_name,dump)
-            local t = os.clock()
-            local mpx = mplib.new {
-                ini_version = true,
-                find_file = metapost.finder,
-                job_name = file.stripsuffix(name)
-            }
-            mpx:execute(string.format("input %s ;",name))
-            if dump then
-                mpx:execute("dump ;")
-                metapost.report("format %s made and dumped for %s in %0.3f seconds",mem_name,name,os.clock()-t)
-            else
-                metapost.report("%s read in %0.3f seconds",name,os.clock()-t)
-            end
-            return mpx
-        end
-
-        function metapost.load(name)
-            local mem_name = file.replacesuffix(name,"mem")
-            local mpx = mplib.new {
-                ini_version = false,
-                mem_name = mem_name,
-                find_file = metapost.finder
-            }
-            if not mpx and type(metapost.make) == "function" then
-                -- when i have time i'll locate the format and dump
-                mpx = metapost.make(name,mem_name)
-            end
-            if mpx then
-                metapost.report("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 ;
-            input %s ;
-        ]]
-
-        metapost.make = metapost.make or function()
-        end
-
-        function metapost.load(name)
-            local mpx = mplib.new {
-                ini_version = true,
-                find_file = metapost.finder,
-            }
-            local result
-            if not mpx then
-                result = { status = 99, error = "out of memory"}
-            else
-                result = mpx:execute(format(preamble, file.replacesuffix(name,"mp")))
-            end
-            metapost.reporterror(result)
-            return mpx, result
-        end
-
-    end
-
-    function metapost.unload(mpx)
-        if mpx then
-            mpx:finish()
-        end
-    end
-
-    function metapost.reporterror(result)
-        if not result then
-            metapost.report("mp error: no result object returned")
-        elseif result.status > 0 then
-            local t, e, l = result.term, result.error, result.log
-            if t then
-                metapost.report("mp terminal: %s",t)
-            end
-            if e then
-                metapost.report("mp error: %s", e)
-            end
-            if not t and not e and l then
-                metapost.lastlog = metapost.lastlog .. "\n " .. l
-                metapost.report("mp log: %s",l)
-            else
-                metapost.report("mp error: unknown, no error, terminal or log messages")
-            end
-        else
-            return false
-        end
-        return true
-    end
-
-    function metapost.process(mpx, data)
-        local converted, result = false, {}
-        mpx = metapost.load(mpx)
-        if mpx and data then
-            local result = mpx:execute(data)
-            if not result then
-                metapost.report("mp error: no result object returned")
-            elseif result.status > 0 then
-                metapost.report("mp error: %s",(result.term or "no-term") .. "\n" .. (result.error or "no-error"))
-            elseif metapost.showlog then
-                metapost.lastlog = metapost.lastlog .. "\n" .. result.term
-                metapost.report("mp info: %s",result.term or "no-term")
-            elseif result.fig then
-                converted = metapost.convert(result)
-            else
-                metapost.report("mp error: unknown error, maybe no beginfig/endfig")
-            end
-        else
-           metapost.report("mp error: mem file not found")
-        end
-        return converted, result
-    end
-
-    local function getobjects(result,figure,f)
-        return figure:objects()
-    end
-
-    function metapost.convert(result, flusher)
-        metapost.flush(result, flusher)
-        return true -- done
-    end
-
-    --[[ldx--
-    <p>We removed some message and tracing code. We might even remove the flusher</p>
-    --ldx]]--
-
-    local function pdf_startfigure(n,llx,lly,urx,ury)
-        tex.sprint(format("\\startMPLIBtoPDF{%s}{%s}{%s}{%s}",llx,lly,urx,ury))
-    end
-
-    local function pdf_stopfigure()
-        tex.sprint("\\stopMPLIBtoPDF")
-    end
-
-    function pdf_literalcode(fmt,...) -- table
-        tex.sprint(format("\\MPLIBtoPDF{%s}",format(fmt,...)))
-    end
-
-    function pdf_textfigure(font,size,text,width,height,depth)
-        text = text:gsub(".","\\hbox{%1}") -- kerning happens in metapost
-        tex.sprint(format("\\MPLIBtextext{%s}{%s}{%s}{%s}{%s}",font,size,text,0,-( 7200/ 7227)/65536*depth))
-    end
-
-    local bend_tolerance = 131/65536
-
-    local rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1
-
-    local function pen_characteristics(object)
-        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
-
-    local function concat(px, py) -- no tx, ty here
-        return (sy*px-ry*py)/divider,(sx*py-rx*px)/divider
-    end
-
-    local function curved(ith,pth)
-        local d = pth.left_x - ith.right_x
-        if abs(ith.right_x - ith.x_coord - d) <= bend_tolerance and abs(pth.x_coord - pth.left_x - d) <= bend_tolerance then
-            d = pth.left_y - ith.right_y
-            if abs(ith.right_y - ith.y_coord - d) <= bend_tolerance and abs(pth.y_coord - pth.left_y - d) <= bend_tolerance then
-                return false
-            end
-        end
-        return true
-    end
-
-    local function flushnormalpath(path,open)
-        local pth, ith
-        for i=1,#path do
-            pth = path[i]
-            if not ith then
-                pdf_literalcode("%f %f m",pth.x_coord,pth.y_coord)
-            elseif curved(ith,pth) then
-                pdf_literalcode("%f %f %f %f %f %f c",ith.right_x,ith.right_y,pth.left_x,pth.left_y,pth.x_coord,pth.y_coord)
-            else
-                pdf_literalcode("%f %f l",pth.x_coord,pth.y_coord)
-            end
-            ith = pth
-        end
-        if not open then
-            local one = path[1]
-            if curved(pth,one) then
-                pdf_literalcode("%f %f %f %f %f %f c",pth.right_x,pth.right_y,one.left_x,one.left_y,one.x_coord,one.y_coord )
-            else
-                pdf_literalcode("%f %f l",one.x_coord,one.y_coord)
-            end
-        elseif #path == 1 then
-            -- special case .. draw point
-            local one = path[1]
-            pdf_literalcode("%f %f l",one.x_coord,one.y_coord)
-        end
-        return t
-    end
-
-    local function flushconcatpath(path,open)
-        pdf_literalcode("%f %f %f %f %f %f cm", sx, rx, ry, sy, tx ,ty)
-        local pth, ith
-        for i=1,#path do
-            pth = path[i]
-            if not ith then
-               pdf_literalcode("%f %f m",concat(pth.x_coord,pth.y_coord))
-            elseif curved(ith,pth) then
-                local a, b = concat(ith.right_x,ith.right_y)
-                local c, d = concat(pth.left_x,pth.left_y)
-                pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(pth.x_coord, pth.y_coord))
-            else
-               pdf_literalcode("%f %f l",concat(pth.x_coord, pth.y_coord))
-            end
-            ith = pth
-        end
-        if not open then
-            local one = path[1]
-            if curved(pth,one) then
-                local a, b = concat(pth.right_x,pth.right_y)
-                local c, d = concat(one.left_x,one.left_y)
-                pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(one.x_coord, one.y_coord))
-            else
-                pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord))
-            end
-        elseif #path == 1 then
-            -- special case .. draw point
-            local one = path[1]
-            pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord))
-        end
-        return t
-    end
-
-    --[[ldx--
-    <p>Support for specials has been removed.</p>
-    --ldx]]--
-
-    function metapost.flush(result,flusher)
-        if result then
-            local figures = result.fig
-            if figures then
-                for f=1, #figures do
-                    metapost.report("flushing figure %s",f)
-                    local figure = figures[f]
-                    local objects = getobjects(result,figure,f)
-                    local fignum = tonumber(match(figure:filename(),"([%d]+)$") or figure:charcode() or 0)
-                    local miterlimit, linecap, linejoin, dashed = -1, -1, -1, false
-                    local bbox = figure:boundingbox()
-                    local llx, lly, urx, ury = bbox[1], bbox[2], bbox[3], bbox[4] -- faster than unpack
-                    if urx < llx then
-                        -- invalid
-                        pdf_startfigure(fignum,0,0,0,0)
-                        pdf_stopfigure()
-                    else
-                        pdf_startfigure(fignum,llx,lly,urx,ury)
-                        pdf_literalcode("q")
-                        if objects then
-                            for o=1,#objects do
-                                local object = objects[o]
-                                local objecttype = object.type
-                                if objecttype == "start_bounds" or objecttype == "stop_bounds" then
-                                    -- skip
-                                elseif objecttype == "start_clip" then
-                                    pdf_literalcode("q")
-                                    flushnormalpath(object.path,t,false)
-                                    pdf_literalcode("W n")
-                                elseif objecttype == "stop_clip" then
-                                    pdf_literalcode("Q")
-                                    miterlimit, linecap, linejoin, dashed = -1, -1, -1, false
-                                elseif objecttype == "special" then
-                                    -- not supported
-                                elseif objecttype == "text" then
-                                    local ot = object.transform -- 3,4,5,6,1,2
-                                    pdf_literalcode("q %f %f %f %f %f %f cm",ot[3],ot[4],ot[5],ot[6],ot[1],ot[2])
-                                    pdf_textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth)
-                                    pdf_literalcode("Q")
-                                else
-                                    local cs = object.color
-                                    if cs and #cs > 0 then
-                                        pdf_literalcode(metapost.colorconverter(cs))
-                                    end
-                                    local ml = object.miterlimit
-                                    if ml and ml ~= miterlimit then
-                                        miterlimit = ml
-                                        pdf_literalcode("%f M",ml)
-                                    end
-                                    local lj = object.linejoin
-                                    if lj and lj ~= linejoin then
-                                        linejoin = lj
-                                        pdf_literalcode("%i j",lj)
-                                    end
-                                    local lc = object.linecap
-                                    if lc and lc ~= linecap then
-                                        linecap = lc
-                                        pdf_literalcode("%i J",lc)
-                                    end
-                                    local dl = object.dash
-                                    if dl then
-                                        local d = format("[%s] %i d",concat(dl.dashes or {}," "),dl.offset)
-                                        if d ~= dashed then
-                                            dashed = d
-                                            pdf_literalcode(dashed)
-                                        end
-                                    elseif dashed then
-                                       pdf_literalcode("[] 0 d")
-                                       dashed = false
-                                    end
-                                    local path = object.path
-                                    local transformed, penwidth = false, 1
-                                    local open = path and path[1].left_type and path[#path].right_type
-                                    local pen = object.pen
-                                    if pen then
-                                       if pen.type == 'elliptical' then
-                                            transformed, penwidth = pen_characteristics(object) -- boolean, value
-                                            pdf_literalcode("%f w",penwidth)
-                                            if objecttype == 'fill' then
-                                                objecttype = 'both'
-                                            end
-                                       else -- calculated by mplib itself
-                                            objecttype = 'fill'
-                                       end
-                                    end
-                                    if transformed then
-                                        pdf_literalcode("q")
-                                    end
-                                    if path then
-                                        if transformed then
-                                            flushconcatpath(path,open)
-                                        else
-                                            flushnormalpath(path,open)
-                                        end
-                                        if objecttype == "fill" then
-                                            pdf_literalcode("h f")
-                                        elseif objecttype == "outline" then
-                                            pdf_literalcode((open and "S") or "h S")
-                                        elseif objecttype == "both" then
-                                            pdf_literalcode("h B")
-                                        end
-                                    end
-                                    if transformed then
-                                        pdf_literalcode("Q")
-                                    end
-                                    local path = object.htap
-                                    if path then
-                                        if transformed then
-                                            pdf_literalcode("q")
-                                        end
-                                        if transformed then
-                                            flushconcatpath(path,open)
-                                        else
-                                            flushnormalpath(path,open)
-                                        end
-                                        if objecttype == "fill" then
-                                            pdf_literalcode("h f")
-                                        elseif objecttype == "outline" then
-                                            pdf_literalcode((open and "S") or "h S")
-                                        elseif objecttype == "both" then
-                                            pdf_literalcode("h B")
-                                        end
-                                        if transformed then
-                                            pdf_literalcode("Q")
-                                        end
-                                    end
-                                    if cr then
-                                        pdf_literalcode(cr)
-                                    end
-                                end
-                           end
-                        end
-                        pdf_literalcode("Q")
-                        pdf_stopfigure()
-                    end
-                end
-            end
-        end
-    end
-
-    function metapost.colorconverter(cr)
-        local n = #cr
-        if n == 4 then
-            local c, m, y, k = cr[1], cr[2], cr[3], cr[4]
-            return format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k), "0 g 0 G"
-        elseif n == 3 then
-            local r, g, b = cr[1], cr[2], cr[3]
-            return format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b), "0 g 0 G"
-        else
-            local s = cr[1]
-            return format("%.3f g %.3f G",s,s), "0 g 0 G"
-        end
-    end
-
-end
diff --git a/tex/generic/context/luatex-mplib.tex b/tex/generic/context/luatex-mplib.tex
index 206518d7d..691958646 100644
--- a/tex/generic/context/luatex-mplib.tex
+++ b/tex/generic/context/luatex-mplib.tex
@@ -4,8 +4,7 @@
 %D          title=\LUATEX\ Support Macros,
 %D       subtitle=\METAPOST\ to \PDF\ conversion,
 %D         author=Taco Hoekwater \& Hans Hagen,
-%D           date=\currentdate,
-%D      copyright=public domain]
+%D      copyright=see context related readme files]
 
 %D This is the companion to the \LUA\ module \type {supp-mpl.lua}. Further
 %D embedding is up to others. A simple example of usage in plain \TEX\ is:
diff --git a/tex/generic/context/luatex-preprocessor-test.tex b/tex/generic/context/luatex-preprocessor-test.tex
new file mode 100644
index 000000000..857b28f83
--- /dev/null
+++ b/tex/generic/context/luatex-preprocessor-test.tex
@@ -0,0 +1,30 @@
+\ifdefined\inputpreprocessed
+
+    \def\TestOne[#1]%
+      {test one: [#1]\par}
+
+    \def\TestTwo#some%
+      {test two: #some\par}
+
+    \def\TestThree[#whatever][#more]%
+      {test three: [#more] and [#whatever]\par}
+
+    \def\TestFour[#one]#two%
+      {\def\TestFive[#alpha][#one]%
+         {test four and five: [#one], [#two] and [#alpha]}\par}
+
+    \def\TestSix[#{one}]#{two}%
+      {test six: [#{one}] and #{two}\par}
+
+    \TestOne  [one]
+    \TestTwo  {one}
+    \TestThree[one][two]
+    \TestFour [one]{two}
+    \TestFive [one][two]
+    \TestSix  [one]{two}
+
+\else
+    \input{luatex-preprocessor.tex}
+    \inputpreprocessed{luatex-preprocessor-test.tex}
+    \expandafter \end
+\fi
diff --git a/tex/generic/context/luatex-preprocessor.lua b/tex/generic/context/luatex-preprocessor.lua
new file mode 100644
index 000000000..8faa0b47e
--- /dev/null
+++ b/tex/generic/context/luatex-preprocessor.lua
@@ -0,0 +1,163 @@
+if not modules then modules = { } end modules ['luatex-preprocessor'] = {
+    version   = 1.001,
+    comment   = "companion to luatex-preprocessor.tex",
+    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+    copyright = "PRAGMA ADE / ConTeXt Development Team",
+    license   = "see context related readme files"
+}
+
+--[[ldx
+<p>This is a stripped down version of the preprocessor. In
+<l n='context'/> we have a bit more, use a different logger, and
+use a few optimizations. A few examples are shown at the end.</p>
+--ldx]]
+
+local rep, sub, gmatch = string.rep, string.sub, string.gmatch
+local insert, remove = table.insert, table.remove
+local setmetatable = setmetatable
+
+local stack, top, n, hashes = { }, nil, 0, { }
+
+local function set(s)
+    if top then
+        n = n + 1
+        if n > 9 then
+            texio.write_nl("number of arguments > 9, ignoring: " .. s)
+        else
+            local ns = #stack
+            local h = hashes[ns]
+            if not h then
+                h = rep("#",ns)
+                hashes[ns] = h
+            end
+            m = h .. n
+            top[s] = m
+            return m
+        end
+    end
+end
+
+local function get(s)
+    local m = top and top[s] or s
+    return m
+end
+
+local function push()
+    top = { }
+    n = 0
+    local s = stack[#stack]
+    if s then
+        setmetatable(top,{ __index = s })
+    end
+    insert(stack,top)
+end
+
+local function pop()
+    top = remove(stack)
+end
+
+local leftbrace   = lpeg.P("{")
+local rightbrace  = lpeg.P("}")
+local escape      = lpeg.P("\\")
+
+local space       = lpeg.P(" ")
+local spaces      = space^1
+local newline     = lpeg.S("\r\n")
+local nobrace     = 1 - leftbrace - rightbrace
+
+local name        = lpeg.R("AZ","az")^1
+local longname    = (leftbrace/"") * (nobrace^1) * (rightbrace/"")
+local variable    = lpeg.P("#") * lpeg.Cs(name + longname)
+local escapedname = escape * name
+local definer     = escape * (lpeg.P("def") + lpeg.P("egdx") * lpeg.P("def"))
+local anything    = lpeg.P(1)
+local always      = lpeg.P(true)
+
+local pushlocal   = always   / push
+local poplocal    = always   / pop
+local declaration = variable / set
+local identifier  = variable / get
+
+local function matcherror(str,pos)
+    texio.write_nl("runaway definition at: " .. sub(str,pos-30,pos))
+end
+
+local parser = lpeg.Cs { "converter",
+    definition  = pushlocal
+                * definer
+                * escapedname
+                * (declaration + (1-leftbrace))^0
+                * lpeg.V("braced")
+                * poplocal,
+    braced      = leftbrace
+                * (   lpeg.V("definition")
+                    + identifier
+                    + lpeg.V("braced")
+                    + nobrace
+                  )^0
+                * (rightbrace + lpeg.Cmt(always,matcherror)),
+    converter   = (lpeg.V("definition") + anything)^1,
+}
+
+--[[ldx
+<p>We provide a few commands.</p>
+--ldx]]
+
+-- local texkpse
+
+local function find_file(...)
+ -- texkpse = texkpse or kpse.new("luatex","tex")
+ -- return texkpse:find_file(...) or ""
+    return kpse.find_file(...) or ""
+end
+
+commands = commands or { }
+
+function commands.preprocessed(str)
+    return lpeg.match(parser,str)
+end
+
+function commands.inputpreprocessed(name)
+    local name = find_file(name) or ""
+    if name ~= "" then
+     -- we could use io.loaddata as it's loaded in luatex-plain
+        local f = io.open(name,'rb')
+        if f then
+            texio.write("("..name)
+            local d = commands.preprocessed(f:read("*a"))
+            if d and d ~= "" then
+                texio.write("processed: " .. name)
+                for s in gmatch(d,"[^\n\r]+") do
+                    tex.print(s) -- we do a dumb feedback
+                end
+            end
+            f:close()
+            texio.write(")")
+        else
+            tex.error("preprocessor error, invalid file: " .. name)
+        end
+    else
+        tex.error("preprocessor error, unknown file: " .. name)
+    end
+end
+
+function commands.preprocessfile(oldfile,newfile) -- no checking
+    if oldfile and oldfile ~= newfile then
+        local f = io.open(oldfile,'rb')
+        if f then
+            local g = io.open(newfile,'wb')
+            if g then
+                g:write(lpeg.match(parser,f:read("*a") or ""))
+                g:close()
+            end
+            f:close()
+        end
+    end
+end
+
+--~ print(preprocessed([[\def\test#oeps{test:#oeps}]]))
+--~ print(preprocessed([[\def\test#oeps{test:#{oeps}}]]))
+--~ print(preprocessed([[\def\test#{oeps:1}{test:#{oeps:1}}]]))
+--~ print(preprocessed([[\def\test#{oeps}{test:#oeps}]]))
+--~ preprocessed([[\def\test#{oeps}{test:#oeps \halign{##\cr #oeps\cr}]])
+--~ print(preprocessed([[\def\test#{oeps}{test:#oeps \halign{##\cr #oeps\cr}}]]))
diff --git a/tex/generic/context/luatex-preprocessor.tex b/tex/generic/context/luatex-preprocessor.tex
new file mode 100644
index 000000000..fe4872d61
--- /dev/null
+++ b/tex/generic/context/luatex-preprocessor.tex
@@ -0,0 +1,14 @@
+%D \module
+%D   [       file=luatex-preprocessor,
+%D        version=2010.12.02,
+%D          title=\LUATEX\ Support Macros,
+%D       subtitle=Generic Preprocessor,
+%D         author=Hans Hagen,
+%D      copyright=public domain]
+
+\directlua{dofile(kpse.find_file('luatex-preprocessor.lua'))}
+
+\def\inputpreprocessed#1%
+  {\directlua{commands.inputpreprocessed("#1")}}
+
+\endinput
-- 
cgit v1.2.3