From c1d888aa68857ae06aff4ab7695e38486a12a6d6 Mon Sep 17 00:00:00 2001
From: Hans Hagen <pragma@wxs.nl>
Date: Thu, 5 Jan 2012 19:27:32 +0100
Subject: beta 2011.11.24 15:52

---
 tex/context/base/cont-new.mkii                     |   2 +-
 tex/context/base/cont-new.mkiv                     |   2 +-
 tex/context/base/context-version.pdf               | Bin 4075 -> 4069 bytes
 tex/context/base/context-version.png               | Bin 106394 -> 106436 bytes
 tex/context/base/context.mkii                      |   2 +-
 tex/context/base/context.mkiv                      |   3 +-
 tex/context/base/lxml-lpt.lua                      |   2 +-
 tex/context/base/lxml-tex.lua                      | 447 ++++++++++++---------
 tex/context/base/lxml-xml.lua                      | 217 +++++-----
 tex/context/base/math-for.mkiv                     |  78 +---
 tex/context/base/math-scr.mkiv                     |   4 +-
 tex/context/base/mult-mps.lua                      |   7 +-
 tex/context/base/page-mbk.mkvi                     | 236 +++++++++++
 tex/context/base/page-mis.mkiv                     | 134 ------
 tex/context/base/status-files.pdf                  | Bin 23996 -> 24020 bytes
 tex/context/base/status-lua.pdf                    | Bin 167932 -> 167927 bytes
 tex/context/base/strc-flt.mkvi                     |  15 +-
 tex/context/base/strc-mat.mkiv                     | 309 +++++++-------
 tex/generic/context/luatex/luatex-fonts-merged.lua |   2 +-
 19 files changed, 822 insertions(+), 638 deletions(-)
 create mode 100644 tex/context/base/page-mbk.mkvi

(limited to 'tex')

diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii
index ba80f1b11..197d60d3d 100644
--- a/tex/context/base/cont-new.mkii
+++ b/tex/context/base/cont-new.mkii
@@ -11,7 +11,7 @@
 %C therefore copyrighted by \PRAGMA. See mreadme.pdf for
 %C details.
 
-\newcontextversion{2011.11.23 18:58}
+\newcontextversion{2011.11.24 15:52}
 
 %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/cont-new.mkiv b/tex/context/base/cont-new.mkiv
index cd0cb09b3..15f20a3ad 100644
--- a/tex/context/base/cont-new.mkiv
+++ b/tex/context/base/cont-new.mkiv
@@ -11,7 +11,7 @@
 %C therefore copyrighted by \PRAGMA. See mreadme.pdf for
 %C details.
 
-\newcontextversion{2011.11.23 18:58}
+\newcontextversion{2011.11.24 15:52}
 
 %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-version.pdf b/tex/context/base/context-version.pdf
index d62417df9..5a97ce700 100644
Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ
diff --git a/tex/context/base/context-version.png b/tex/context/base/context-version.png
index 297460688..c66071a58 100644
Binary files a/tex/context/base/context-version.png and b/tex/context/base/context-version.png differ
diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii
index 683a629ee..4e70f3769 100644
--- a/tex/context/base/context.mkii
+++ b/tex/context/base/context.mkii
@@ -20,7 +20,7 @@
 %D your styles an modules.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2011.11.23 18:58}
+\edef\contextversion{2011.11.24 15:52}
 
 %D For those who want to use this:
 
diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv
index 4f64155ba..32be1327a 100644
--- a/tex/context/base/context.mkiv
+++ b/tex/context/base/context.mkiv
@@ -20,7 +20,7 @@
 %D your styles an modules.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2011.11.23 18:58}
+\edef\contextversion{2011.11.24 15:52}
 
 %D For those who want to use this:
 
@@ -254,6 +254,7 @@
 \loadmkvifile{strc-flt}
 
 \loadmarkfile{page-mis}
+\loadmkvifile{page-mbk}
 \loadmarkfile{page-mul}
 \loadmarkfile{page-set}
 \loadmarkfile{pack-lyr}
diff --git a/tex/context/base/lxml-lpt.lua b/tex/context/base/lxml-lpt.lua
index a5667ab50..11922cf18 100644
--- a/tex/context/base/lxml-lpt.lua
+++ b/tex/context/base/lxml-lpt.lua
@@ -942,7 +942,7 @@ local function profiled_apply(list,parsed,nofparsed,order)
         elseif kind == "expression" then
             collected = apply_expression(collected,pi.evaluator,order)
         elseif kind == "finalizer" then
-            collected = pi.finalizer(collected)
+            collected = pi.finalizer(collected) -- no check on # here
             p.matched = p.matched + 1
             p.finalized = p.finalized + 1
             return collected
diff --git a/tex/context/base/lxml-tex.lua b/tex/context/base/lxml-tex.lua
index 3e5522099..eb708782b 100644
--- a/tex/context/base/lxml-tex.lua
+++ b/tex/context/base/lxml-tex.lua
@@ -665,8 +665,11 @@ end
 function lxml.setaction(id,pattern,action)
     local collected = xmlapplylpath(getid(id),pattern)
     if collected then
-        for c=1,#collected do
-            collected[c].command = action
+        local nc = #collected
+        if nc > 0 then
+            for c=1,nc do
+                collected[c].command = action
+            end
         end
     end
 end
@@ -878,40 +881,45 @@ function lxml.setsetup(id,pattern,setup)
     if not setup or setup == "" or setup == "*" or setup == "-" or setup == "+" then
         local collected = xmlapplylpath(getid(id),pattern)
         if collected then
-            if trace_setups then
-                for c=1, #collected do
-                    local e = collected[c]
-                    local ix = e.ix or 0
-                    if setup == "-" then
-                        e.command = false
-                        report_lxml("lpath matched (a) %5i: %s = %s -> skipped",c,ix,setup)
-                    elseif setup == "+" then
-                        e.command = true
-                        report_lxml("lpath matched (b) %5i: %s = %s -> text",c,ix,setup)
-                    else
-                        local tg = e.tg
-                        if tg then -- to be sure
-                            e.command = tg
-                            local ns = e.rn or e.ns
-                            if ns == "" then
-                                report_lxml("lpath matched (c) %5i: %s = %s -> %s",c,ix,tg,tg)
-                            else
-                                report_lxml("lpath matched (d) %5i: %s = %s:%s -> %s",c,ix,ns,tg,tg)
+            local nc = #collected
+            if nc > 0 then
+                if trace_setups then
+                    for c=1,nc do
+                        local e = collected[c]
+                        local ix = e.ix or 0
+                        if setup == "-" then
+                            e.command = false
+                            report_lxml("lpath matched (a) %5i: %s = %s -> skipped",c,ix,setup)
+                        elseif setup == "+" then
+                            e.command = true
+                            report_lxml("lpath matched (b) %5i: %s = %s -> text",c,ix,setup)
+                        else
+                            local tg = e.tg
+                            if tg then -- to be sure
+                                e.command = tg
+                                local ns = e.rn or e.ns
+                                if ns == "" then
+                                    report_lxml("lpath matched (c) %5i: %s = %s -> %s",c,ix,tg,tg)
+                                else
+                                    report_lxml("lpath matched (d) %5i: %s = %s:%s -> %s",c,ix,ns,tg,tg)
+                                end
                             end
                         end
                     end
-                end
-            else
-                for c=1, #collected do
-                    local e = collected[c]
-                    if setup == "-" then
-                        e.command = false
-                    elseif setup == "+" then
-                        e.command = true
-                    else
-                        e.command = e.tg
+                else
+                    for c=1,nc do
+                        local e = collected[c]
+                        if setup == "-" then
+                            e.command = false
+                        elseif setup == "+" then
+                            e.command = true
+                        else
+                            e.command = e.tg
+                        end
                     end
                 end
+            elseif trace_setups then
+                report_lxml("zero lpath matches for %s",pattern)
             end
         elseif trace_setups then
             report_lxml("no lpath matches for %s",pattern)
@@ -921,44 +929,49 @@ function lxml.setsetup(id,pattern,setup)
         if a and b then
             local collected = xmlapplylpath(getid(id),pattern)
             if collected then
-                if trace_setups then
-                    for c=1, #collected do
-                        local e = collected[c]
-                        local ns, tg, ix = e.rn or e.ns, e.tg, e.ix or 0
-                        if b == "-" then
-                            e.command = false
-                            if ns == "" then
-                                report_lxml("lpath matched (e) %5i: %s = %s -> skipped",c,ix,tg)
+                local nc = #collected
+                if nc > 0 then
+                    if trace_setups then
+                        for c=1,nc do
+                            local e = collected[c]
+                            local ns, tg, ix = e.rn or e.ns, e.tg, e.ix or 0
+                            if b == "-" then
+                                e.command = false
+                                if ns == "" then
+                                    report_lxml("lpath matched (e) %5i: %s = %s -> skipped",c,ix,tg)
+                                else
+                                    report_lxml("lpath matched (f) %5i: %s = %s:%s -> skipped",c,ix,ns,tg)
+                                end
+                            elseif b == "+" then
+                                e.command = true
+                                if ns == "" then
+                                    report_lxml("lpath matched (g) %5i: %s = %s -> text",c,ix,tg)
+                                else
+                                    report_lxml("lpath matched (h) %5i: %s = %s:%s -> text",c,ix,ns,tg)
+                                end
                             else
-                                report_lxml("lpath matched (f) %5i: %s = %s:%s -> skipped",c,ix,ns,tg)
+                                e.command = a .. tg
+                                if ns == "" then
+                                    report_lxml("lpath matched (i) %5i: %s = %s -> %s",c,ix,tg,e.command)
+                                else
+                                    report_lxml("lpath matched (j) %5i: %s = %s:%s -> %s",c,ix,ns,tg,e.command)
+                                end
                             end
-                        elseif b == "+" then
-                            e.command = true
-                            if ns == "" then
-                                report_lxml("lpath matched (g) %5i: %s = %s -> text",c,ix,tg)
-                            else
-                                report_lxml("lpath matched (h) %5i: %s = %s:%s -> text",c,ix,ns,tg)
-                            end
-                        else
-                            e.command = a .. tg
-                            if ns == "" then
-                                report_lxml("lpath matched (i) %5i: %s = %s -> %s",c,ix,tg,e.command)
+                        end
+                    else
+                        for c=1,nc do
+                            local e = collected[c]
+                            if b == "-" then
+                                e.command = false
+                            elseif b == "+" then
+                                e.command = true
                             else
-                                report_lxml("lpath matched (j) %5i: %s = %s:%s -> %s",c,ix,ns,tg,e.command)
+                                e.command = a .. e.tg
                             end
                         end
                     end
-                else
-                    for c=1, #collected do
-                        local e = collected[c]
-                        if b == "-" then
-                            e.command = false
-                        elseif b == "+" then
-                            e.command = true
-                        else
-                            e.command = a .. e.tg
-                        end
-                    end
+                elseif trace_setups then
+                    report_lxml("zero lpath matches for %s",pattern)
                 end
             elseif trace_setups then
                 report_lxml("no lpath matches for %s",pattern)
@@ -966,21 +979,26 @@ function lxml.setsetup(id,pattern,setup)
         else
             local collected = xmlapplylpath(getid(id),pattern)
             if collected then
-                if trace_setups then
-                    for c=1, #collected do
-                        local e = collected[c]
-                        e.command = setup
-                        local ns, tg, ix = e.rn or e.ns, e.tg, e.ix or 0
-                        if ns == "" then
-                            report_lxml("lpath matched (k) %5i: %s = %s -> %s",c,ix,tg,setup)
-                        else
-                            report_lxml("lpath matched (l) %5i: %s = %s:%s -> %s",c,ix,ns,tg,setup)
+                local nc = #collected
+                if nc > 0 then
+                    if trace_setups then
+                        for c=1,nc do
+                            local e = collected[c]
+                            e.command = setup
+                            local ns, tg, ix = e.rn or e.ns, e.tg, e.ix or 0
+                            if ns == "" then
+                                report_lxml("lpath matched (k) %5i: %s = %s -> %s",c,ix,tg,setup)
+                            else
+                                report_lxml("lpath matched (l) %5i: %s = %s:%s -> %s",c,ix,ns,tg,setup)
+                            end
+                        end
+                    else
+                        for c=1,nc do
+                            collected[c].command = setup
                         end
                     end
-                else
-                    for c=1, #collected do
-                        collected[c].command = setup
-                    end
+                elseif trace_setups then
+                    report_lxml("zero lpath matches for %s",pattern)
                 end
             elseif trace_setups then
                 report_lxml("no lpath matches for %s",pattern)
@@ -994,65 +1012,89 @@ end
 local finalizers = xml.finalizers.tex
 
 local function first(collected)
-    if collected then
+    if collected and #collected > 0 then
         xmlsprint(collected[1])
     end
 end
 
 local function last(collected)
     if collected then
-        xmlsprint(collected[#collected])
+        local nc = #collected
+        if nc > 0 then
+            xmlsprint(collected[nc])
+        end
     end
 end
 
 local function all(collected)
     if collected then
-        for c=1,#collected do
-            xmlsprint(collected[c])
+        local nc = #collected
+        if nc > 0 then
+            for c=1,nc do
+                xmlsprint(collected[c])
+            end
         end
     end
 end
 
 local function reverse(collected)
     if collected then
-        for c=#collected,1,-1 do
-            xmlsprint(collected[c])
+        local nc = #collected
+        if nc >0 then
+            for c=nc,1,-1 do
+                xmlsprint(collected[c])
+            end
         end
     end
 end
 
 local function count(collected)
-    contextsprint(ctxcatcodes,(collected and #collected) or 0)
+    contextsprint(ctxcatcodes,(collected and #collected) or 0) -- why ctxcatcodes
 end
 
 local function position(collected,n)
     -- todo: if not n then == match
     if collected then
-        n = tonumber(n) or 0
-        if n < 0 then
-            n = #collected + n + 1
-        end
-        if n > 0 then
-            xmlsprint(collected[n])
+        local nc = #collected
+        if nc > 0 then
+            n = tonumber(n) or 0
+            if n < 0 then
+                n = nc + n + 1
+            end
+            if n > 0 then
+                local cn = collected[n]
+                if cn then
+                    xmlsprint(cn)
+                    return
+                end
+            end
         end
     end
 end
 
 local function match(collected) -- is match in preceding collected, never change, see bibxml
     local m = collected and collected[1]
-    contextsprint(ctxcatcodes,m and m.mi or 0)
+    contextsprint(ctxcatcodes,m and m.mi or 0) -- why ctxcatcodes
 end
 
 local function index(collected,n)
     if collected then
-        n = tonumber(n) or 0
-        if n < 0 then
-            n = #collected + n + 1 -- brrr
-        end
-        if n > 0 then
-            contextsprint(ctxcatcodes,collected[n].ni or 0)
+        local nc = #collected
+        if nc > 0 then
+            n = tonumber(n) or 0
+            if n < 0 then
+                n = nc + n + 1 -- brrr
+            end
+            if n > 0 then
+                local cn = collected[n]
+                if cn then
+                    contextsprint(ctxcatcodes,cn.ni or 0) -- why ctxcatcodes
+                    return
+                end
+            end
         end
     end
+    contextsprint(ctxcatcodes,0) -- why ctxcatcodes
 end
 
 local function command(collected,cmd,otherwise)
@@ -1091,7 +1133,7 @@ local function attribute(collected,a,default)
 end
 
 local function chainattribute(collected,arguments) -- todo: optional levels
-    if collected then
+    if collected and #collected > 0 then
         local e = collected[1]
         while e do
             local at = e.at
@@ -1111,7 +1153,9 @@ end
 local function text(collected)
     if collected then
         local nc = #collected
-        if nc == 1 then -- hardly any gain so this will go
+        if nc == 0 then
+            -- nothing
+        elseif nc == 1 then -- hardly any gain so this will go
             cprint(collected[1])
         else for c=1,nc do
             cprint(collected[c])
@@ -1121,71 +1165,80 @@ end
 
 local function ctxtext(collected)
     if collected then
-        for c=1,#collected do
-            contextsprint(ctxcatcodes,collected[1].dt)
+        local nc = #collected
+        if nc > 0 then
+            for c=1,nc do
+                contextsprint(ctxcatcodes,collected[c].dt)
+            end
         end
     end
 end
 
---~     local str = xmltext(getid(id),pattern) or ""
---~     str = gsub(str,"^%s*(.-)%s*$","%1")
---~     if nolines then
---~         str = gsub(str,"%s+"," ")
---~     end
-
 local function stripped(collected) -- tricky as we strip in place
     if collected then
-        for c=1,#collected do
-            cprint(xml.stripelement(collected[c]))
+        local nc = #collected
+        if nc > 0 then
+            for c=1,nc do
+                cprint(xml.stripelement(collected[c]))
+            end
         end
     end
 end
 
 local function lower(collected)
-    if collected then
-        for c=1,#collected do
-            contextsprint(ctxcatcodes,lowerchars(collected[1].dt[1]))
+    if not collected then
+        local nc = #collected
+        if nc > 0 then
+            for c=1,nc do
+                contextsprint(ctxcatcodes,lowerchars(collected[c].dt[1]))
+            end
         end
     end
 end
 
 local function upper(collected)
     if collected then
-        for c=1,#collected do
-            contextsprint(ctxcatcodes,upperchars(collected[1].dt[1]))
+        local nc = #collected
+        if nc > 0 then
+            for c=1,nc do
+                contextsprint(ctxcatcodes,upperchars(collected[c].dt[1]))
+            end
         end
     end
 end
 
 local function number(collected)
-    if collected then
-        local n = 0
-        for c=1,#collected do
+    local nc = collected and #collected or 0
+    local n = 0
+    if nc > 0 then
+        for c=1,nc do
             n = n + tonumber(collected[c].dt[1] or 0)
         end
-        contextsprint(ctxcatcodes,n)
     end
+    contextsprint(ctxcatcodes,n)
 end
 
 local function concatrange(collected,start,stop,separator,lastseparator,textonly) -- test this on mml
     if collected then
         local nofcollected = #collected
-        local separator = separator or ""
-        local lastseparator = lastseparator or separator or ""
-        start, stop = (start == "" and 1) or tonumber(start) or 1, (stop == "" and nofcollected) or tonumber(stop) or nofcollected
-        if stop < 0 then stop = nofcollected + stop end -- -1 == last-1
-        for i=start,stop do
-            if textonly then
-                xmlcprint(collected[i])
-            else
-                xmlsprint(collected[i])
-            end
-            if i == nofcollected then
-                -- nothing
-            elseif i == nofcollected-1 and lastseparator ~= "" then
-                contextsprint(ctxcatcodes,lastseparator)
-            elseif separator ~= "" then
-                contextsprint(ctxcatcodes,separator)
+        if nofcollected > 0 then
+            local separator = separator or ""
+            local lastseparator = lastseparator or separator or ""
+            start, stop = (start == "" and 1) or tonumber(start) or 1, (stop == "" and nofcollected) or tonumber(stop) or nofcollected
+            if stop < 0 then stop = nofcollected + stop end -- -1 == last-1
+            for i=start,stop do
+                if textonly then
+                    xmlcprint(collected[i])
+                else
+                    xmlsprint(collected[i])
+                end
+                if i == nofcollected then
+                    -- nothing
+                elseif i == nofcollected-1 and lastseparator ~= "" then
+                    contextsprint(ctxcatcodes,lastseparator)
+                elseif separator ~= "" then
+                    contextsprint(ctxcatcodes,separator)
+                end
             end
         end
     end
@@ -1218,37 +1271,43 @@ finalizers.default        = all -- !!
 
 local concat = table.concat
 
-function finalizers.tag(collected)
+function finalizers.tag(collected,n)
     if collected then
-        local c
-        if n == 0 or not n then
-            c = collected[1]
-        elseif n > 1 then
-            c = collected[n]
-        else
-            c = collected[#collected-n+1]
-        end
-        if c then
-            contextsprint(ctxcatcodes,c.tg)
+        local nc = #collected
+        if nc > 0 then
+            local c
+            if n == 0 or not n then
+                c = collected[1]
+            elseif n > 1 then
+                c = collected[n]
+            else
+                c = collected[nc-n+1]
+            end
+            if c then
+                contextsprint(ctxcatcodes,c.tg)
+            end
         end
     end
 end
 
-function finalizers.name(collected)
+function finalizers.name(collected,n)
     if collected then
-        local c
-        if n == 0 or not n then
-            c = collected[1]
-        elseif n > 1 then
-            c = collected[n]
-        else
-            c = collected[#collected-n+1]
-        end
-        if c then
-            if c.ns == "" then
-                contextsprint(ctxcatcodes,c.tg)
+        local nc = #collected
+        if nc > 0 then
+            local c
+            if n == 0 or not n then
+                c = collected[1]
+            elseif n > 1 then
+                c = collected[n]
             else
-                contextsprint(ctxcatcodes,c.ns,":",c.tg)
+                c = collected[nc-n+1]
+            end
+            if c then
+                if c.ns == "" then
+                    contextsprint(ctxcatcodes,c.tg)
+                else
+                    contextsprint(ctxcatcodes,c.ns,":",c.tg)
+                end
             end
         end
     end
@@ -1256,13 +1315,16 @@ end
 
 function finalizers.tags(collected,nonamespace)
     if collected then
-        for c=1,#collected do
-            local e = collected[c]
-            local ns, tg = e.ns, e.tg
-            if nonamespace or ns == "" then
-                contextsprint(ctxcatcodes,tg)
-            else
-                contextsprint(ctxcatcodes,ns,":",tg)
+        local nc = #collected
+        if nc > 0 then
+            for c=1,nc do
+                local e = collected[c]
+                local ns, tg = e.ns, e.tg
+                if nonamespace or ns == "" then
+                    contextsprint(ctxcatcodes,tg)
+                else
+                    contextsprint(ctxcatcodes,ns,":",tg)
+                end
             end
         end
     end
@@ -1327,7 +1389,7 @@ end
 
 function lxml.raw(id,pattern) -- the content, untouched by commands
     local collected = (pattern and xmlapplylpath(getid(id),pattern)) or getid(id)
-    if collected then
+    if collected and #collected > 0 then
         contextsprint(notcatcodes,xmltostring(collected[1].dt))
     end
 end
@@ -1335,7 +1397,6 @@ end
 function lxml.context(id,pattern) -- the content, untouched by commands
     if not pattern then
         local collected = getid(id)
-    --  contextsprint(ctxcatcodes,collected.dt[1])
         ctx_text(collected.dt[1])
     else
         local collected = xmlapplylpath(getid(id),pattern) or getid(id)
@@ -1345,9 +1406,23 @@ function lxml.context(id,pattern) -- the content, untouched by commands
     end
 end
 
+function lxml.context(id,pattern) -- the content, untouched by commands
+    if pattern then
+        local collected = xmlapplylpath(getid(id),pattern) or getid(id)
+        if collected and #collected > 0 then
+            contextsprint(ctxcatcodes,collected[1].dt)
+        end
+    else
+        local collected = getid(id)
+        if collected and #collected > 0 then
+            ctx_text(collected.dt[1])
+        end
+    end
+end
+
 function lxml.text(id,pattern)
     local collected = (pattern and xmlapplylpath(getid(id),pattern)) or getid(id)
-    if collected then
+    if collected and #collected > 0 then
         text(collected)
     end
 end
@@ -1355,17 +1430,11 @@ end
 lxml.content = text
 
 function lxml.position(id,pattern,n)
-    local collected = xmlapplylpath(getid(id),pattern)
-    if collected then
-        position(collected,n)
-    end
+    position(xmlapplylpath(getid(id),pattern),n)
 end
 
 function lxml.chainattribute(id,pattern,a,default)
-    local collected = xmlapplylpath(getid(id),pattern)
-    if collected then
-        chainattribute(collected,a,default)
-    end
+    chainattribute(xmlapplylpath(getid(id),pattern),a,default)
 end
 
 function lxml.concatrange(id,pattern,start,stop,separator,lastseparator,textonly) -- test this on mml
@@ -1449,15 +1518,18 @@ function lxml.command(id,pattern,cmd)
     local i, p = getid(id,true)
     local collected = xmlapplylpath(getid(i),pattern)
     if collected then
-        local rootname = p or i.name
-        for c=1,#collected do
-            local e = collected[c]
-            local ix = e.ix
-            if not ix then
-                addindex(rootname,false,true)
-                ix = e.ix
+        local nc = #collected
+        if nc > 0 then
+            local rootname = p or i.name
+            for c=1,nc do
+                local e = collected[c]
+                local ix = e.ix
+                if not ix then
+                    addindex(rootname,false,true)
+                    ix = e.ix
+                end
+                contextsprint(ctxcatcodes,"\\xmlw{",cmd,"}{",rootname,"::",ix,"}")
             end
-            contextsprint(ctxcatcodes,"\\xmlw{",cmd,"}{",rootname,"::",ix,"}")
         end
     end
 end
@@ -1565,8 +1637,11 @@ lxml.get_id = getid   lxml.obsolete.get_id = getid
 
 function xml.finalizers.tex.lettered(collected)
     if collected then
-        for c=1,#collected do
-            contextsprint(ctxcatcodes,lettered(collected[1].dt[1]))
+        local nc = #collected
+        if nc > 0 then
+            for c=1,nc do
+                contextsprint(ctxcatcodes,lettered(collected[c].dt[1]))
+            end
         end
     end
 end
@@ -1574,7 +1649,7 @@ end
 --~ function xml.finalizers.tex.apply(collected,what) -- to be tested
 --~     if collected then
 --~         for c=1,#collected do
---~             contextsprint(ctxcatcodes,what(collected[1].dt[1]))
+--~             contextsprint(ctxcatcodes,what(collected[c].dt[1]))
 --~         end
 --~     end
 --~ end
diff --git a/tex/context/base/lxml-xml.lua b/tex/context/base/lxml-xml.lua
index 05405015d..b216d7866 100644
--- a/tex/context/base/lxml-xml.lua
+++ b/tex/context/base/lxml-xml.lua
@@ -29,16 +29,21 @@ local function all(collected)
     return collected
 end
 
---~ local function reverse(collected)
---~     if collected then
---~         local reversed, r = { }, 0
---~         for c=#collected,1,-1 do
---~             r = r + 1
---~             reversed[r] = collected[c]
---~         end
---~         return reversed
---~     end
---~ end
+-- local function reverse(collected)
+--     if collected then
+--         local nc = #collected
+--         if nc > 0 then
+--             local reversed, r = { }, 0
+--             for c=nc,1,-1 do
+--                 r = r + 1
+--                 reversed[r] = collected[c]
+--             end
+--             return reversed
+--         else
+--             return collected
+--         end
+--     end
+-- end
 
 local reverse = table.reversed
 
@@ -55,34 +60,37 @@ local function att(id,name)
 end
 
 local function count(collected)
-    return (collected and #collected) or 0
+    return collected and #collected or 0
 end
 
 local function position(collected,n)
-    if collected then
-        n = tonumber(n) or 0
-        if n < 0 then
-            return collected[#collected + n + 1]
-        elseif n > 0 then
-            return collected[n]
-        else
-            return collected[1].mi or 0
-        end
+    if not collected then
+        return 0
+    end
+    local nc = #collected
+    if nc == 0 then
+        return 0
+    end
+    n = tonumber(n) or 0
+    if n < 0 then
+        return collected[nc + n + 1]
+    elseif n > 0 then
+        return collected[n]
+    else
+        return collected[1].mi or 0
     end
 end
 
 local function match(collected)
-    return (collected and collected[1].mi) or 0 -- match
+    return collected and #collected > 0 and collected[1].mi or 0 -- match
 end
 
 local function index(collected)
-    if collected then
-        return collected[1].ni
-    end
+    return collected and #collected > 0 and collected[1].ni or 0 -- 0 is new
 end
 
 local function attributes(collected,arguments)
-    if collected then
+    if collected and #collected > 0 then
         local at = collected[1].at
         if arguments then
             return at[arguments]
@@ -93,7 +101,7 @@ local function attributes(collected,arguments)
 end
 
 local function chainattribute(collected,arguments) -- todo: optional levels
-    if collected then
+    if collected and #collected > 0 then
         local e = collected[1]
         while e do
             local at = e.at
@@ -112,7 +120,7 @@ local function chainattribute(collected,arguments) -- todo: optional levels
 end
 
 local function raw(collected) -- hybrid (not much different from text so it might go)
-    if collected then
+    if collected and #collected > 0 then
         local e = collected[1] or collected
         return e and xmltostring(e) or "" -- only first as we cannot concat function
     else
@@ -155,7 +163,7 @@ end
 --
 
 local function text(collected) -- hybrid
-    if collected then
+    if collected and #collected > 0 then
         local e = collected[1] or collected
         return (e and xmltotext(e)) or ""
     else
@@ -164,89 +172,114 @@ local function text(collected) -- hybrid
 end
 
 local function texts(collected)
-    if collected then
-        local t, n = { }, 0
-        for c=1,#collected do
-            local e = collected[c]
-            if e and e.dt then
-                n = n + 1
-                t[n] = e.dt
-            end
+    if not collected then
+        return { } -- why no nil
+    end
+    local nc = #collected
+    if nc == 0 then
+        return { } -- why no nil
+    end
+    local t, n = { }, 0
+    for c=1,nc do
+        local e = collected[c]
+        if e and e.dt then
+            n = n + 1
+            t[n] = e.dt
         end
-        return t
     end
+    return t
 end
 
 local function tag(collected,n)
-    if collected then
-        local c
-        if n == 0 or not n then
-            c = collected[1]
-        elseif n > 1 then
-            c = collected[n]
-        else
-            c = collected[#collected-n+1]
-        end
-        return c and c.tg
+    if not collected then
+        return
+    end
+    local nc = #collected
+    if nc == 0 then
+        return
+    end
+    local c
+    if n == 0 or not n then
+        c = collected[1]
+    elseif n > 1 then
+        c = collected[n]
+    else
+        c = collected[nc-n+1]
     end
+    return c and c.tg
 end
 
 local function name(collected,n)
-    if collected then
-        local c
-        if n == 0 or not n then
-            c = collected[1]
-        elseif n > 1 then
-            c = collected[n]
-        else
-            c = collected[#collected-n+1]
-        end
-        if c then
-            if c.ns == "" then
-                return c.tg
-            else
-                return c.ns .. ":" .. c.tg
-            end
-        end
+    if not collected then
+        return
+    end
+    local nc = #collected
+    if nc == 0 then
+        return
+    end
+    local c
+    if n == 0 or not n then
+        c = collected[1]
+    elseif n > 1 then
+        c = collected[n]
+    else
+        c = collected[nc-n+1]
+    end
+    if not c then
+        -- sorry
+    elseif c.ns == "" then
+        return c.tg
+    else
+        return c.ns .. ":" .. c.tg
     end
 end
 
 local function tags(collected,nonamespace)
-    if collected then
-        local t, n = { }, 0
-        for c=1,#collected do
-            local e = collected[c]
-            local ns, tg = e.ns, e.tg
-            n = n + 1
-            if nonamespace or ns == "" then
-                t[n] = tg
-            else
-                t[n] = ns .. ":" .. tg
-            end
+    if not collected then
+        return
+    end
+    local nc = #collected
+    if nc == 0 then
+        return
+    end
+    local t, n = { }, 0
+    for c=1,nc do
+        local e = collected[c]
+        local ns, tg = e.ns, e.tg
+        n = n + 1
+        if nonamespace or ns == "" then
+            t[n] = tg
+        else
+            t[n] = ns .. ":" .. tg
         end
-        return t
     end
+    return t
 end
 
 local function empty(collected)
-    if collected then
-        for c=1,#collected do
-            local e = collected[c]
-            if e then
-                local edt = e.dt
-                if edt then
-                    local n = #edt
-                    if n == 1 then
-                        local edk = edt[1]
-                        local typ = type(edk)
-                        if typ == "table" then
-                            return false
-                        elseif edk ~= "" then -- maybe an extra tester for spacing only
-                            return false
-                        end
-                    elseif n > 1 then
+    if not collected then
+        return true
+    end
+    local nc = #collected
+    if nc == 0 then
+        return true
+    end
+    for c=1,nc do
+        local e = collected[c]
+        if e then
+            local edt = e.dt
+            if edt then
+                local n = #edt
+                if n == 1 then
+                    local edk = edt[1]
+                    local typ = type(edk)
+                    if typ == "table" then
+                        return false
+                    elseif edk ~= "" then -- maybe an extra tester for spacing only
                         return false
                     end
+                elseif n > 1 then
+                    return false
                 end
             end
         end
@@ -305,7 +338,7 @@ function xml.text(id,pattern)
     if pattern then
      -- return text(xmlfilter(id,pattern))
         local collected = xmlfilter(id,pattern)
-        return (collected and xmltotext(collected[1])) or ""
+        return collected and #collected > 0 and xmltotext(collected[1]) or ""
     elseif id then
      -- return text(id)
         return xmltotext(id) or ""
diff --git a/tex/context/base/math-for.mkiv b/tex/context/base/math-for.mkiv
index 16cab9a65..ebb5ec534 100644
--- a/tex/context/base/math-for.mkiv
+++ b/tex/context/base/math-for.mkiv
@@ -18,62 +18,28 @@
 
 \unprotect
 
-\let\currentformula\s!unknown
-
-\def\formulaparameter    #1{\csname\doformulaparameter{\??fm\currentformula}#1\endcsname}
-\def\formulaparameterhash#1{\doformulaparameterhash   {\??fm\currentformula}#1}
-
-\def\doformulaparameter    #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\doformulaparentparameter    \csname#1\s!parent\endcsname#2\fi}
-\def\doformulaparameterhash#1#2{\ifcsname#1#2\endcsname  #1\else\expandafter\doformulaparentparameterhash\csname#1\s!parent\endcsname#2\fi}
-
-\def\detokenizedformulaparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??fm\currentformula#1\endcsname}}
-
-\def\doformulaparentparameter    #1#2{\ifx#1\relax\s!empty\else\doformulaparameter    #1#2\fi}
-\def\doformulaparentparameterhash#1#2{\ifx#1\relax        \else\doformulaparameterhash#1#2\fi}
-
-\def\dosetformulaattributes#1#2% style color
-  {\edef\fontattributehash {\formulaparameterhash#1}%
-   \edef\colorattributehash{\formulaparameterhash#2}%
-   \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi
-   \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi}
-
-\def\getformulaparameters{\getparameters[\??fm]}
-
-%D \macros
-%D   {setupformulas}
-
-\newtoks \everysetupformulas
-
-\unexpanded\def\setupformulas
-  {\dodoubleempty\dosetupformulas}
-
-\def\dosetupformulas[#1][#2]%
-  {\ifsecondargument
-     \edef\currentformula{#1}%
-     \getparameters[\??fm#1][#2]%
-   \else
-%      \let\currentformula\v!formula % hm
-     \let\currentformula\empty
-     \getparameters[\??fm][#1]%
-   \fi
-   \the\everysetupformulas
-   \let\currentformula\empty}
-
-%D Not yet cleanup up:
-
 %D \macros
-%D   {setuptextformulas}
-%D
-%D This command sets up in||line math. Most features deals
-%D with grid snapping and are experimental.
-
-\newtoks \everysetuptextformulas
-
-\unexpanded\def\setuptextformulas
-  {\dosingleempty\dosetuptextformulas}
-
-\def\dosetuptextformulas[#1]%
-  {\getparameters[\??mt][#1]%
-   \the\everysetuptextformulas}
+%D   {setupformulas,setupsubformulas}
+
+\installcommandhandler \??fm {formula}    \??fm
+\installcommandhandler \??fn {subformula} \??fn % maybe just setuphandler (no childs used yet)
+
+\let\setupformulas   \setupformula
+\let\setupsubformulas\setupsubformula
+
+% D \macros
+% D   {setuptextformulas}
+% D
+% D This command sets up in||line math. Most features deals
+% D with grid snapping and are experimental.
+
+% \newtoks \everysetuptextformulas
+%
+% \unexpanded\def\setuptextformulas
+%   {\dosingleempty\dosetuptextformulas}
+%
+% \def\dosetuptextformulas[#1]%
+%   {\getparameters[\??mt][#1]%
+%    \the\everysetuptextformulas}
 
 \protect \endinput
diff --git a/tex/context/base/math-scr.mkiv b/tex/context/base/math-scr.mkiv
index 280297db2..9ab61911b 100644
--- a/tex/context/base/math-scr.mkiv
+++ b/tex/context/base/math-scr.mkiv
@@ -70,7 +70,7 @@
 %D How negative such a symbol looks is demonstrated in:
 %D $\negative 10^{\negative 10^{\negative 10}}$.
 
-\setuptextformulas % why here
-  [\c!size=\v!normal]
+% \setuptextformulas % why here
+%   [\c!size=\v!normal]
 
 \protect \endinput
diff --git a/tex/context/base/mult-mps.lua b/tex/context/base/mult-mps.lua
index cb2994054..2f2c41974 100644
--- a/tex/context/base/mult-mps.lua
+++ b/tex/context/base/mult-mps.lua
@@ -27,8 +27,8 @@ return {
         "shipout", "show", "showdependencies", "showtoken", "showvariable",
         "special",
         "begingroup", "endgroup", "of", "curl", "tension", "and", "controls",
-        "reflectedabout", "rotatedaround", "interpath", "on", "off", "beginfig",
-        "endfig", "def", "vardef", "enddef", "expr", "suffix", "text", "primary", "secondary",
+        "interpath", "on", "off",
+        "def", "vardef", "enddef", "expr", "suffix", "text", "primary", "secondary",
         "tertiary", "primarydef", "secondarydef", "tertiarydef",
         "randomseed", "also", "contour", "doublepath",
         "withcolor", "withpen", "dashed", "if", "else", "elseif", "fi", "for", "endfor", "forever", "exitif",
@@ -56,6 +56,8 @@ return {
         "expandafter",
     },
     commands = {
+        "beginfig", "endfig",
+        "rotatedaround", "reflectedabout",
         "arrowhead",
         "currentpen", "currentpicture", "cuttings",
         "defaultfont", "extra_beginfig", "extra_endfig",
@@ -106,6 +108,5 @@ return {
         "bboxmargin", "ahlength", "ahangle", "labeloffset", "dotlabeldiam", "defaultpen", "defaultscale", "join_radius",
         --
         "pen_lft", "pen_rt", "pen_top", "pen_bot", -- "pen_count_",
-        --
     },
 }
diff --git a/tex/context/base/page-mbk.mkvi b/tex/context/base/page-mbk.mkvi
new file mode 100644
index 000000000..24f0913b8
--- /dev/null
+++ b/tex/context/base/page-mbk.mkvi
@@ -0,0 +1,236 @@
+%D \module
+%D   [       file=page-mbk,   % was part of page-mis.mkiv / 2008.11.17
+%D        version=2011.11.23, % was part of page-flt.tex  / 2000.10.20
+%D          title=\CONTEXT\ Page Macros,
+%D       subtitle=Margin Floats,
+%D         author=Hans Hagen,
+%D           date=\currentdate,
+%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Page Macros / Margin Floats}
+
+\unprotect
+
+%D This is an old mechanism that is quite independent of other
+%D floats. There is for instance no save/restore used here. When
+%D there is need (and demand) we can use the float cache and then
+%D flush them in the text when they are left over. On the other
+%D hand, margin float are somewhat manual so it does not make too
+%D much sense to complicate the code. As an alternative users can
+%D fall back on margin texts: they do stack but don't float.
+%D
+%D \starttyping
+%D \dorecurse{9} {
+%D   \placefigure[margin]{#1}{}
+%D   \input ward
+%D }
+%D \page \null % will flush them
+%D \stoptyping
+
+% status=start: in margin
+% status=stop : in text
+%
+% todo: flush margin floats at end of text
+
+\installcommandhandler \??mb {marginblock} \??mb
+
+\let\setupmarginblocks\setupmarginblock
+
+\newconditional\page_margin_blocks_c % not really needed as we can check each time
+
+\appendtoks
+   \doifelse{\rootmarginblockparameter\c!state}\v!start
+     \settrue\setfalse\page_margin_blocks_c
+\to \everysetupmarginblock
+
+\setupmarginblocks
+  [\c!state=\v!start,
+   \c!location=\v!inmargin,
+   \c!width=\rightmarginwidth,
+  %\c!style=,
+  %\c!color=,
+  %\c!align=,
+  %\c!left=,
+  %\c!right=,
+  %\c!top=,
+  %\c!before=,
+  %\c!after=,
+   \c!inbetween=\blank,
+   \c!bottom=\vfill]
+
+\unexpanded\def\startmarginblock
+  {\dosingleempty\start_margin_block}
+
+\unexpanded\def\stoptmarginblock
+  {\stop_margin_block}
+
+\def\start_margin_block[#tag]%
+  {\begingroup
+   \edef\currentmarginblock{#tag}%
+   \doifelse{\marginblockparameter\c!state}\v!start
+     \start_margin_block_yes
+     \start_margin_block_nop}
+
+\def\stop_margin_block
+  {\doifelse{\marginblockparameter\c!state}\v!start
+     \stop_margin_block_yes
+     \stop_margin_block_nop
+   \endgroup}
+
+\def\start_margin_block_yes % 2 maal \vbox ivm \unvbox elders
+  {\showmessage\m!layouts4\empty
+   \global\setbox\page_margin_box\vtop\bgroup\vbox\bgroup
+     \hsize\marginblockparameter\c!width
+     \ifvoid\page_margin_box\else
+       \unvbox\page_margin_box
+       \marginblockparameter\c!inbetween
+     \fi
+     \setupalign[\marginblockparameter\c!align]%
+     \dosetfloatcaptionattributes\c!style\c!color
+     \begstrut
+     \ignorespaces}
+
+\def\stop_margin_block_yes
+  {\removeunwantedspaces
+   \endstrut
+   \egroup
+   \egroup}
+
+\def\start_margin_block_nop
+  {\showmessage\m!layouts5\empty
+   \marginblockparameter\c!before
+   \bgroup
+   \dosetfloatcaptionattributes\c!style\c!color}
+
+\def\stop_margin_block_nop
+  {\egroup
+   \marginblockparameter\c!after}
+
+\newbox\page_margin_box
+\newbox\page_margin_prepared_box
+
+\def\page_margin_reshape
+  {\ifdim\ht\page_margin_prepared_box>\zeropoint
+     \beginofshapebox
+     \unvbox\page_margin_prepared_box
+     \endofshapebox
+     \reshapebox
+       {\box\shapebox}%
+     \setbox\page_margin_prepared_box\vbox to \textheight
+       {\marginblockparameter\c!top
+        \flushshapebox
+        \marginblockparameter\c!bottom}%
+   \fi}
+
+\unexpanded\def\checkmarginblocks
+  {\ifvoid\page_margin_box \else
+     \page_margin_check_indeed
+   \fi}
+
+\def\page_margin_check_indeed
+  {\ifcsname\??mb::\c!location::\marginblockparameter\c!location\endcsname
+     \page_margin_prepare_box
+     \csname\??mb::\c!location::\marginblockparameter\c!location\endcsname
+   \else
+     \global\page_margin_box\emptybox
+   \fi}
+
+\def\page_margin_prepare_box
+  {\setbox\page_margin_prepared_box\vbox
+     {\forgetall
+      \splittopskip\topskip
+      \ifvoid\page_margin_box\else
+        \ifdim\ht\page_margin_box>\textheight
+          \vsplit\page_margin_box to \textheight
+        \else
+          \unvbox\page_margin_box
+        \fi
+      \fi}%
+   \page_margin_reshape
+   \setbox\page_margin_prepared_box\vbox
+     {\marginblockparameter\c!before
+      \box\page_margin_prepared_box
+      \marginblockparameter\c!after}}
+
+\setvalue{\??mb::\c!location::\v!left    }{\page_margin_set_l_box}
+\setvalue{\??mb::\c!location::\v!right   }{\page_margin_set_r_box}
+\setvalue{\??mb::\c!location::\v!inmargin}{\doifbothsidesoverruled
+                                           \page_margin_set_r_box
+                                           \page_margin_set_r_box
+                                           \page_margin_set_l_box}
+\setvalue{\??mb::\c!location::\v!middle  }{\doifbothsidesoverruled
+                                           \page_margin_set_r_box
+                                           \page_margin_set_l_box
+                                           \page_margin_set_r_box}
+
+\unexpanded\def\place_r_margin_block_yes
+  {\setbox\page_margin_prepared_box\hbox to \rightmarginwidth
+     {\marginblockparameter\c!left
+      \box\page_margin_prepared_box
+      \marginblockparameter\c!right}%
+   \vsmashbox\page_margin_prepared_box
+   \box\page_margin_prepared_box}
+
+\unexpanded\def\place_l_margin_block_yes
+  {\setbox\page_margin_prepared_box\hbox to \leftmarginwidth
+     {\marginblockparameter\c!right
+      \box\page_margin_prepared_box
+      \marginblockparameter\c!left}%
+   \vsmashbox\page_margin_prepared_box
+   \box\page_margin_prepared_box}
+
+\unexpanded\def\place_r_margin_block_nop{\hskip\rightmarginwidth}
+\unexpanded\def\place_l_margin_block_nop{\hskip\leftmarginwidth}
+
+\let\placerightmarginblock\place_r_margin_block_nop
+\let\placeleftmarginblock \place_l_margin_block_nop
+
+\def\page_margin_set_r_box{\let\placerightmarginblock\place_r_margin_block_yes}
+\def\page_margin_set_l_box{\let\placeleftmarginblock \place_l_margin_block_yes}
+
+% margin floats (keyword 'margin' in option list)
+
+\unexpanded\def\page_margin_process_float
+  {\doifelse{\marginblockparameter\c!state}\v!start
+     \page_margin_process_float_yes
+     \page_margin_process_float_nop}
+
+\def\page_margin_process_float_yes#options%
+  {\global\setbox\page_margin_box\vbox
+     {\hsize\marginblockparameter\c!width
+      \unvcopy\page_margin_box
+      \ifvoid\page_margin_box\else
+        \expandafter\marginblockparameter\expandafter\c!inbetween
+      \fi
+      \box\floatbox
+      \filbreak}%
+   \ifdim\ht\page_margin_box>\textheight
+   % \dosavefloatinfo % no saving done anyway
+   \else
+     \doinsertfloatinfo
+   \fi}
+
+\def\page_margin_process_float_nop#options%
+  {\someelsefloat[#options,\v!here]} % still an old name
+
+\def\page_margin_float_before
+  {\ifconditional\page_margin_blocks_c
+     \doifinset\v!margin\floatlocation\endgraf
+   \fi}
+
+\def\page_margin_float_set_hsize
+  {\ifconditional\page_margin_blocks_c
+     \doifinset\v!margin\floatlocation{\hsize\rootmarginblockparameter\c!width}%
+   \fi}
+
+\appendtoks
+   \ifvoid\page_margin_box \else
+     \writestatus\m!layouts{beware: there are left-over margin floats!}%
+   \fi
+\to \everystoptext
+
+\protect \endinput
diff --git a/tex/context/base/page-mis.mkiv b/tex/context/base/page-mis.mkiv
index d3c1e5051..5ab96f0f8 100644
--- a/tex/context/base/page-mis.mkiv
+++ b/tex/context/base/page-mis.mkiv
@@ -17,140 +17,6 @@
 
 \unprotect
 
-\newif\ifmarginblocks
-
-\def\dosetupmarginblocks[#1]%
-  {\getparameters[\??mb][#1]%
-   \doifelse\@@mbstate\v!start
-     {\showmessage\m!layouts4\empty
-      \marginblockstrue
-      \let\somenextfloat\dosomenextfloat
-      \let\startmarginblock\dostartmarginblock
-      \let\stopmarginblock\dostopmarginblock}%
-     {\showmessage\m!layouts5\empty
-      \marginblocksfalse
-      \def\somenextfloat[##1]%
-        {\someelsefloat[##1,\v!here]}%
-      \let\startmarginblock\dontstartmargeblok
-      \let\stopmarginblock\dontstopmargeblok}}
-
-\unexpanded\def\setupmarginblocks
-  {\dosingleargument\dosetupmarginblocks}
-
-\newbox\marginbox
-
-\def\dosomenextfloat[#1]%
-  {\global\setbox\marginbox\vbox
-     {\hsize\@@mbwidth
-      \unvcopy\marginbox
-      \ifvoid\marginbox\else\expandafter\@@mbinbetween\fi
-      \box\floatbox\filbreak}%
-  \ifdim\ht\marginbox>\textheight
-  % \dosavefloatinfo
-  \else
-    \doinsertfloatinfo
-  \fi}
-
-\newbox\preparedmarginbox
-
-\def\reshapemargin
-  {\ifdim\ht\preparedmarginbox>\zeropoint
-     \beginofshapebox
-     \unvbox\preparedmarginbox
-     \endofshapebox
-     \reshapebox
-       {\box\shapebox}%
-     \setbox\preparedmarginbox\vbox to \textheight
-       {\@@mbtop
-        \flushshapebox
-        \@@mbbottom}%
-   \fi}
-
-\unexpanded\def\placerightmarginblock
-  {\hskip\rightmarginwidth}
-
-\unexpanded\def\placeleftmarginblock
-  {\hskip\leftmarginwidth}
-
-\def\checkmarginblocks
-  {\ifvoid\marginbox\else\docheckmarginblocks\fi}
-
-\def\docheckmarginblocks % erg inefficient
-  {\setbox\preparedmarginbox\vbox
-     {\forgetall
-      \splittopskip\topskip
-      \ifvoid\marginbox\else
-        \ifdim\ht\marginbox>\textheight
-          \vsplit\marginbox to \textheight
-        \else
-          \unvbox\marginbox
-        \fi
-      \fi}%
-   \reshapemargin
-   \setbox\preparedmarginbox\vbox
-      {\@@mbbefore\box\preparedmarginbox\@@mbafter}%
-   \def\rightmarginbox
-     {\unexpanded\def\placerightmarginblock
-        {\setbox\preparedmarginbox\hbox to \rightmarginwidth
-           {\@@mbleft\box\preparedmarginbox\@@mbright}%
-         \vsmashbox\preparedmarginbox
-         \box\preparedmarginbox}}%
-   \def\leftmarginbox
-     {\unexpanded\def\placeleftmarginblock
-        {\setbox\preparedmarginbox\hbox to \leftmarginwidth
-           {\@@mbright\box\preparedmarginbox\@@mbleft}%
-         \vsmashbox\preparedmarginbox
-         \box\preparedmarginbox}}%
-   \processaction % traag
-     [\@@mblocation]
-     [ \v!inmargin=>\doifbothsidesoverruled\rightmarginbox\rightmarginbox\leftmarginbox,
-         \v!middle=>\doifbothsidesoverruled\rightmarginbox\leftmarginbox\rightmarginbox,
-           \v!left=>\leftmarginbox,
-          \v!right=>\rightmarginbox,
-        \s!unknown=>\setbox\preparedmarginbox\emptyhbox]}
-
-\def\dostartmarginblock % 2 maal \vbox ivm \unvbox elders
-  {\global\setbox\marginbox\vtop\bgroup\vbox\bgroup
-     \hsize\@@mbwidth
-     \ifvoid\marginbox\else
-       \unvbox\marginbox
-       \@@mbinbetween
-     \fi
-     \setupalign[\@@mbalign]%
-     \dostartattributes\??mb\c!style\c!color{}%
-     \begstrut\ignorespaces}
-
-\def\dostopmarginblock
-  {\unskip\endstrut
-   \dostopattributes
-   \egroup
-   \egroup}
-
-\def\dontstartmargeblok
-  {\@@mbbefore
-   \bgroup
-   \dostartattributes\??mb\c!style\c!color\empty}
-
-\def\dontstopmargeblok
-  {\dostopattributes
-   \egroup
-   \@@mbafter}
-
-\setupmarginblocks
-  [\c!state=\v!start,
-   \c!location=\v!inmargin,
-   \c!width=\rightmarginwidth,
-   \c!style=,
-   \c!color=,
-   \c!align=,
-   \c!left=,
-   \c!right=,
-   \c!top=,
-   \c!inbetween=\blank,
-   \c!bottom=\vfill,
-   \c!before=,
-   \c!after=]
-
 % postponing
 
 \newevery\everytopofpage\relax
diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf
index 4d659188f..14972afff 100644
Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ
diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf
index 915145f56..129f122ed 100644
Binary files a/tex/context/base/status-lua.pdf and b/tex/context/base/status-lua.pdf differ
diff --git a/tex/context/base/strc-flt.mkvi b/tex/context/base/strc-flt.mkvi
index ed5215dce..22585b465 100644
--- a/tex/context/base/strc-flt.mkvi
+++ b/tex/context/base/strc-flt.mkvi
@@ -514,7 +514,10 @@
 \def\float_begin_text_group {\begingroup\let\float_end_group\relax}
 \def\float_end_text_group   {\endgroup}
 
-% implemenation
+% implementation
+
+\ifdefined\page_margin_float_before    \else \let\page_margin_float_before   \relax \fi
+\ifdefined\page_margin_float_set_hsize \else \let\page_margin_float_set_hsize\relax \fi
 
 \def\flushfloatslist
   {\v!left,\v!right,\v!inner,\v!outer,%
@@ -537,14 +540,10 @@
        {\doifcommonelse\floatlocation\flushfloatslist\doflushfloats\donothing}%
      % but which should be done before using box \floatbox
    \fi
-   \ifmarginblocks
-     \doifinset\v!margin\floatlocation\endgraf
-   \fi
+   \page_margin_float_before % todo: each float handler gets a before
    \global\insidefloattrue
    \dostarttagged\t!float\currentfloat
-   \ifmarginblocks
-     \doifinset\v!margin\floatlocation{\hsize\@@mbwidth}%
-   \fi
+   \page_margin_float_set_hsize % todo: each float handler gets a set_hsize
    \the\everyinsidefloat
    \float_analyze_variables_one
    \dostarttagged\t!floatcontent\empty
@@ -1878,7 +1877,7 @@
 \def\sometopfloat          [#1]{\someelsefloat[#1]\nonoindentation}
 \def\somebottomfloat       [#1]{\someelsefloat[#1]}
 \def\someautofloat         [#1]{\someelsefloat[#1]}
-\def\somemarginfloat       [#1]{\somenextfloat[#1]\nonoindentation}
+\def\somemarginfloat       [#1]{\page_margin_process_float{#1}\nonoindentation}
 \def\someinleftmarginfloat [#1]{\somesidefloat[#1]}
 \def\someinrightmarginfloat[#1]{\somesidefloat[#1]}
 \def\someinleftedgefloat   [#1]{\somesidefloat[#1]}
diff --git a/tex/context/base/strc-mat.mkiv b/tex/context/base/strc-mat.mkiv
index 97c2e7581..a782e292f 100644
--- a/tex/context/base/strc-mat.mkiv
+++ b/tex/context/base/strc-mat.mkiv
@@ -21,52 +21,116 @@
 
 \unprotect
 
-\definestructureconversionset[\v!formula][numbers,characters]
-
 \setupformulas
-  [%\c!way=\@@nrway,
+  [%\c!way=,
    %\c!blockway=,
-   %\c!sectionnumber=\@@nrsectionnumber,
+   %\c!sectionnumber=,
    %\c!conversion=\v!numbers,
+   %\c!numberstyle=,
+   %\c!numbercolor=,
+   %\c!numbercommand=,
+   %\c!margin=,
+   %\c!align=,
+   %\c!separator=,
+   %\c!grid=,
    \c!location=\v!right,
    \c!left=(,
    \c!right=),
    \c!expansion=\v!yes, % maybe automatically
-   %\c!numberstyle=,
-   %\c!numbercolor=,
-   %\c!numbercommand=,
    \c!spacebefore=\v!big,
    \c!spaceafter=\formulaparameter\c!spacebefore,
    \c!leftmargin=\!!zeropoint,
    \c!rightmargin=\!!zeropoint,
-   %\c!margin=,
    \c!indentnext=\v!no,
    \c!alternative=\s!default,
-   %\c!align=,
    \c!strut=\v!no,
-   %\c!separator=\@@koseparator,
-   %\c!grid=,
    \c!distance=1em]
 
+\setupsubformulas % subformulas could be last in chain
+  [\c!indentnext=\formulaparameter\c!indentnext]
+
 \definestructurecounter
   [\v!formula]
 
-\presetstructurecountersetup\setupformulas\sharedstructurecounterparameter
+\definestructureconversionset
+  [\v!formula]
+  [numbers,characters]
 
+\presetstructurecountersetup\setupformulas\sharedstructurecounterparameter
 
 \appendtoks
     \dostructurecountersetup\v!formula\formulaparameter
     \docheckstructurecountersetup\v!formula % yes or no
-\to \everysetupformulas
+\to \everysetupformula
 
 \setupformulas
   [\c!numberconversionset=\v!formula] % why forgotten
 
+\appendtoks
+    \normalexpanded{\definelist[\currentformula]}% is expansion needed?
+    \setuevalue{\e!start\currentformula\v!formula}{\dostartformula{\currentformula}}%
+    \setuevalue{\e!stop \currentformula\v!formula}{\dostopformula}%
+\to \everydefineformula
+
+\definelist[\v!formula]
+
+\setuvalue{\e!start\v!formula}{\dostartformula{}}
+\setuvalue{\e!stop \v!formula}{\dostopformula}
+
+\let\dostartformula\relax % defined later
+\let\dostopformula \relax % defined later
+
+\unexpanded\def\defineformulaalternative         % this might change ... start and stop can become keys
+  {\dotripleargument\dodefineformulaalternative} % to the general define .. s!startcommand
+
+\def\dodefineformulaalternative[#1][#2][#3]%
+  {\setvalue{\e!start#1\v!formula}{#2}%
+   \setvalue{\e!stop #1\v!formula}{#3}}
+
+% sp = single line paragraph  sd = single line display
+% mp = multi  line paragraph  md = multy  line display
+
+\defineformulaalternative[\s!default][\startdisplaymath][\stopdisplaymath]
+\defineformulaalternative[\s!single] [\startdisplaymath][\stopdisplaymath]
+\defineformulaalternative[\s!multi]  [\startdisplaymath][\stopdisplaymath]
+
+\defineformula
+  [sp]
+  [\c!spacebefore=\v!none,
+   \c!spaceafter=\v!none,
+   \c!indentnext=\v!no,
+   \c!alternative=\s!single]
+
+\defineformula
+  [sd]
+  [\c!spacebefore=\v!none,
+   \c!spaceafter=\v!none,
+   \c!indentnext=\v!yes,
+   \c!alternative=\s!single]
+
+\defineformula
+  [mp]
+  [\c!indentnext=\v!no,
+   \c!alternative=\s!multi]
+
+\defineformula
+  [md]
+  [\c!indentnext=\v!yes,
+   \c!alternative=\s!multi]
+
+\newtoks\everyresetformulas
+
+\appendtoks
+    \let\currentformula\empty % to be checked:
+\to \everyresetformulas
+
+% implementation
+
 \def\storecurrentformulanumber#1#2#3#4#5% ref, todo:str, \sync % todo: title etc (like float)
   {\settrue\handleformulanumber
    \dostructurecountercomponent
      {formula}%
-     \getformulaparameters \formulaparameter \detokenizedformulaparameter
+     \setupcurrentformula \formulaparameter \detokenizedformulaparameter
      \relax \relax \relax
      [\c!name=\v!formula,\s!counter=\v!formula,%
       \s!hascaption=\v!yes,\s!hastitle=\v!yes,\s!hasnumber=\v!yes,%\s!haslevel=#6,%
@@ -77,26 +141,32 @@
    \globallet#4\laststructurecountersynchronize
    \globallet#5\laststructurecounterattribute}
 
-\newif\ifnoformulanumber
-
-\newconditional\handleformulanumber
-\newconditional\incrementformulanumber
-
-\newtoks\everyresetformulas
-
-% 0=unset, 1=forced, 2=none, 3=reference
+% modes: 0=unset, 1=forced, 2=none, 3=reference
 
 \newconstant\placeformulanumbermode
 \newconstant\formulasnumbermode
 \newconstant\subformulasnumbermode
 \newconstant\nestedformulanumbermode
 
+\appendtoks
+    \placeformulanumbermode \zerocount
+    \formulasnumbermode     \zerocount
+    \subformulasnumbermode  \zerocount
+    \nestedformulanumbermode\zerocount
+\to \everyresetformulas
+
+\newconditional\handleformulanumber
+\newconditional\incrementformulanumber
+
 \newconditional\insideplaceformula
 \newconditional\insideplacesubformula
 \newconditional\insideformulas
 \newconditional\insidesubformulas
 
-% 0=unset, 1=forced, 2=none, 3=reference
+\appendtoks
+    \global\setfalse\insideplaceformula
+    \global\setfalse\insideplacesubformula
+\to \everyresetformulas
 
 \def\handleplaceformulanumbering % place formula
   {\settrue\handleformulanumber
@@ -118,8 +188,23 @@
      \currentsubformulasattribute
   }
 
-\def\tracedformulamode
-  {\hbox{\quad\tt\txx[\number\placeformulanumbermode,\number\formulasnumbermode,\number\subformulasnumbermode,\number\nestedformulanumbermode]}}
+\let\dotraceformulareferencestate\relax
+\let\doshowformulareferencestate \relax
+
+% \def\dotraceformulareferencestate
+%   {\rlap{\hbox{\quad\tt\txx[%
+%       \number\placeformulanumbermode,%
+%       \number\formulasnumbermode,%
+%       \number\subformulasnumbermode,%
+%       \number\nestedformulanumbermode
+%    ]}}}
+
+% \def\doshowformulareferencestate
+%   {\writestatus{\v!formula}%
+%      {place:      \number\placeformulanumbermode,\space
+%       formula:    \number\formulasnumbermode,\space
+%       subformula: \number\subformulasnumbermode,\space
+%       nested:     \number\nestedformulanumbermode]}}
 
 \unexpanded\def\placecurrentformulanumber
   {\rm % nodig ?
@@ -148,25 +233,54 @@
      \glet#1\relax
    \fi\fi\fi}
 
+\let\currentplaceformulaattribute\relax
+\let\currentformulaattribute     \relax
+\let\currentsubformulaattribute  \relax
+\let\currentformulasattribute    \relax
+
+\let\currentplaceformulanumber\relax
+\let\currentformulanumber     \relax
+\let\currentsubformulanumber  \relax
+\let\currentformulasnumber    \relax
+
+\let\currentformulasreference     \empty
+\let\currentformulareference      \empty
+\let\currentsubformulareference   \empty
+\let\currentnestedformulareference\empty
+
+\appendtoks
+    \glet\currentformulasreference     \empty
+    \glet\currentformulareference      \empty
+    \glet\currentsubformulareference   \empty
+    \glet\currentnestedformulareference\empty
+\to \everyresetformulas
+
+\let\currentformulassuffix     \empty
+\let\currentformulasuffix      \empty
+\let\currentsubformulasuffix   \empty
+\let\currentnestedformulasuffix\empty
+
+\appendtoks
+    \glet\currentformulassuffix     \empty
+    \glet\currentformulasuffix      \empty
+    \glet\currentsubformulasuffix   \empty
+    \glet\currentnestedformulasuffix\empty
+\to \everyresetformulas
+
+\let\currentplaceformulasynchronize\relax
+\let\currentformulasynchronize     \relax
+\let\currentsubformulasynchronize  \relax
+\let\currentformulassynchronize    \relax
+
 \appendtoks
     \glet\currentplaceformulasynchronize \relax
     \glet\currentformulassynchronize     \relax
     \glet\currentsubformulassynchronize  \relax
     \glet\currentnestedformulasynchronize\relax
-    \let\currentformula\empty
 \to \everyresetformulas
 
 % currently we do the number, some day we will do the (sub) formula
 
-\let\doshowformulareferencestate\relax
-
-% \def\doshowformulareferencestate
-%   {\writestatus{\v!formula}%
-%      {place:      \number\placeformulanumbermode,\space
-%       formula:    \number\formulasnumbermode,\space
-%       subformula: \number\subformulasnumbermode,\space
-%       nested:     \number\nestedformulanumbermode]}}
-
 \def\dohandlecurrentformulareferences
   {\doshowformulareferencestate
    \ifnum\placeformulanumbermode=\plusthree
@@ -209,16 +323,6 @@
 
 % needs checking ... too many:
 
-\let\currentplaceformulaattribute\relax \let\currentplaceformulasynchronize\relax \let\currentplaceformulanumber\relax
-\let\currentformulaattribute     \relax \let\currentformulasynchronize     \relax \let\currentformulanumber     \relax
-\let\currentsubformulaattribute  \relax \let\currentsubformulasynchronize  \relax \let\currentsubformulanumber  \relax
-\let\currentformulasattribute    \relax \let\currentformulassynchronize    \relax \let\currentformulasnumber    \relax
-
-\let\currentformulasreference     \empty \let\currentformulassuffix     \empty
-\let\currentformulareference      \empty \let\currentformulasuffix      \empty
-\let\currentsubformulareference   \empty \let\currentsubformulasuffix   \empty
-\let\currentnestedformulareference\empty \let\currentnestedformulasuffix\empty
-
 \def\dohandleformulanumbering
   {\doincrementsubstructurecounter[\v!formula][1]%
    \doiftext\currentplaceformulasuffix{\setsubstructurecounterown[\v!formula][2]{\currentplaceformulasuffix}}%
@@ -267,12 +371,10 @@
            \dohandlesubformulanumbering
          \fi
        \fi
-      %\rlap{\tracedformulamode}%
+      \dotraceformulareferencestate
      \egroup
    \fi}
 
-\definelist[\v!formula]
-
 \installstructurelistprocessor\v!formula % to be checked ...
   {\dodolistelement
      \currentlist
@@ -282,35 +384,6 @@
      \structurelistpagenumber
      \structurelistrealpagenumber}
 
-\appendtoks
-    \global\setfalse\insideplaceformula
-    \global\setfalse\insideplacesubformula
-\to \everyresetformulas
-
-\appendtoks
-    \placeformulanumbermode            \zerocount
-    \formulasnumbermode                \zerocount
-    \subformulasnumbermode             \zerocount
-    \nestedformulanumbermode           \zerocount
-    \glet\currentformulasreference     \empty
-    \glet\currentformulareference      \empty
-    \glet\currentsubformulareference   \empty
-    \glet\currentnestedformulareference\empty
-    \glet\currentformulassuffix        \empty
-    \glet\currentformulasuffix         \empty
-    \glet\currentsubformulasuffix      \empty
-    \glet\currentnestedformulasuffix   \empty
-\to \everyresetformulas
-
-\let\currentformulasreference     \empty
-\let\currentformulareference      \empty
-\let\currentsubformulareference   \empty
-\let\currentnestedformulareference\empty
-\let\currentformulassuffix        \empty
-\let\currentformulasuffix         \empty
-\let\currentsubformulasuffix      \empty
-\let\currentnestedformulasuffix   \empty
-
 \newif\ifinformula
 
 %D We need a hook into the plain math alignment macros
@@ -328,69 +401,9 @@
    \let\normalreqno\gobbleoneargument \let\eqno \gobbleoneargument
    \let\doplaceformulanumber\empty}
 
-%D
-
-\unexpanded\def\defineformula
-  {\dodoubleempty\dodefineformula}
-
-\def\dodefineformula[#1][#2]%
-  {\doifsomething{#1}
-     {\getparameters[\??fm#1][\s!parent=\??fm,#2]%
-      \definelist[#1]%
-      \setvalue{\e!start#1\v!formula}{\dostartformula{#1}}%
-      \setvalue{\e!stop #1\v!formula}{\dostopformula}}}
-
-\unexpanded\def\defineformulaalternative
-  {\dotripleargument\dodefineformulaalternative}
-
-\def\dodefineformulaalternative[#1][#2][#3]%
-  {\setvalue{\e!start#1\v!formula}{#2}%
-   \setvalue{\e!stop #1\v!formula}{#3}}
-
-% sp = single line paragraph  sd = single line display
-% mp = multi  line paragraph  md = multy  line display
-
-\defineformulaalternative[\s!default][\startdisplaymath][\stopdisplaymath]
-\defineformulaalternative[\s!single] [\startdisplaymath][\stopdisplaymath]
-\defineformulaalternative[\s!multi]  [\startdisplaymath][\stopdisplaymath]
-
-\defineformula
-  [sp]
-  [\c!spacebefore=\v!none,
-   \c!spaceafter=\v!none,
-   \c!indentnext=\v!no,
-   \c!alternative=\s!single]
-
-\defineformula
-  [sd]
-  [\c!spacebefore=\v!none,
-   \c!spaceafter=\v!none,
-   \c!indentnext=\v!yes,
-   \c!alternative=\s!single]
-
-\defineformula
-  [mp]
-  [\c!indentnext=\v!no,
-   \c!alternative=\s!multi]
-
-\defineformula
-  [md]
-  [\c!indentnext=\v!yes,
-   \c!alternative=\s!multi]
-
 %D \macros
-%D   {setupsubformulas, startsubformulas}
-
-\def\subformulaparameter#1{\ifcsname\??fn#1\endcsname\csname\??fn#1\endcsname\fi}
-
-\unexpanded\def\setupsubformulas
-  {\dodoubleargument\getparameters[\??fn]}
+%D   {startsubformulas}
 
-\setupsubformulas
-  [\c!indentnext=\formulaparameter\c!indentnext]
-
-% \setupsubformulas[conversion=romannumerals]
-%
 % \placeformula
 % \startsubformulas[Maxwell]
 %     \startformulas
@@ -427,9 +440,6 @@
    \abovedisplayshortskip\zeropoint
    \belowdisplayshortskip\zeropoint}
 
-\setvalue{\e!start\v!formula}{\dostartformula{}}
-\setvalue{\e!stop \v!formula}{\dostopformula}
-
 \def\predisplaysizethreshhold{2em} % was 3em
 
 \def\leftdisplayskip    {\leftskip}
@@ -457,7 +467,7 @@
    \advance\displaywidth\dimexpr-\displayindent-\rightdisplayskip-\rightdisplaymargin\relax
    \hsize\displaywidth} % new, else overfull in itemize
 
-\def\dostartformula#1%
+\unexpanded\def\dostartformula#1%
   {\dodoubleempty\dodostartformula[#1]}
 
 \newskip\formulaparskip
@@ -500,7 +510,7 @@
 
 % tagging of formulanumbers is not ok (we get two display maths blobs)
 
-\def\dostopformula
+\unexpanded\def\dostopformula
   {\dostarttagged\t!formulacaption\empty
    \doplaceformulanumber
    \dostoptagged
@@ -528,7 +538,7 @@
 
 \def\switchtoformulabodyfont{\switchtobodyfont}
 
-\setvalue{\v!formula}{\dosingleempty\doformula}
+\setuvalue{\v!formula}{\dosingleempty\doformula}
 
 \def\doformula[#1]#2% todo: tagged
   {\begingroup
@@ -567,9 +577,6 @@
    \par
    \egroup}
 
-\newif\ifclipdisplaymath \clipdisplaymathtrue
-\def\displaymathclipfactor{1.1}
-
 % already defined
 %
 % \let\startinnermath\empty
@@ -735,8 +742,8 @@
 
 % to be checked
 
-\glet\doplaceformulanumber \relax
-\glet\donestedformulanumber\gobbletwoarguments
+\let\doplaceformulanumber \relax
+\let\donestedformulanumber\gobbletwoarguments
 
 \def\donestedformulanumberindeed#1#2%
   {\def\currentnestedformulareference{#1}%
@@ -773,9 +780,9 @@
    \setformulalistentry{#2}%
    \next}
 
-\glet\namedformulaentry\empty % \relax % this will become a key/value so that we can do bookmarks
+\let\namedformulaentry\empty % \relax % this will become a key/value so that we can do bookmarks
 
-\def\setformulalistentry#1%
+\unexpanded\def\setformulalistentry#1%
   {\gdef\namedformulaentry{#1}}
 
 \protect \endinput
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 2be7de33c..78855b32b 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
 -- merged file : luatex-fonts-merged.lua
 -- parent file : luatex-fonts.lua
--- merge date  : 11/23/11 18:58:55
+-- merge date  : 11/24/11 15:52:09
 
 do -- begin closure to overcome local limits and interference
 
-- 
cgit v1.2.3