From 5ee86a080221db05e1dc12c361959e7d2fc5366b Mon Sep 17 00:00:00 2001
From: Marius <mariausol@gmail.com>
Date: Tue, 29 Nov 2011 20:00:15 +0200
Subject: beta 2011.11.29 18:47

---
 tex/context/base/back-exp.lua                      |   2 +-
 tex/context/base/cont-new.mkii                     |   2 +-
 tex/context/base/cont-new.mkiv                     |   2 +-
 tex/context/base/context-version.pdf               | Bin 4068 -> 4076 bytes
 tex/context/base/context-version.png               | Bin 106551 -> 106398 bytes
 tex/context/base/context.mkii                      |   2 +-
 tex/context/base/context.mkiv                      |   2 +-
 tex/context/base/l-lpeg.lua                        |  66 +-
 tex/context/base/lang-lab.lua                      |  14 +-
 tex/context/base/lang-lab.mkiv                     |  92 +-
 tex/context/base/lpdf-fld.lua                      |   2 +-
 tex/context/base/phys-dim.lua                      | 956 +++++++++++++--------
 tex/context/base/phys-dim.mkiv                     | 178 ++--
 tex/context/base/s-phy-01.mkiv                     |  90 +-
 tex/context/base/status-files.pdf                  | Bin 24047 -> 24036 bytes
 tex/context/base/status-lua.pdf                    | Bin 168854 -> 169513 bytes
 tex/context/base/strc-flt.mkvi                     |   7 +-
 tex/context/base/type-otf.mkiv                     |   4 +-
 tex/generic/context/luatex/luatex-fonts-merged.lua |  68 +-
 19 files changed, 921 insertions(+), 566 deletions(-)

(limited to 'tex')

diff --git a/tex/context/base/back-exp.lua b/tex/context/base/back-exp.lua
index 6a05889c3..750b26fe1 100644
--- a/tex/context/base/back-exp.lua
+++ b/tex/context/base/back-exp.lua
@@ -1200,7 +1200,7 @@ function extras.tabulate(result,element,detail,n,fulltag,di)
             local content = false
             for i=1,#did do
                 local d = did[i].data
-                local c = d and c.content
+                local c = d and d.content
                 if c and #c > 0 then
                     content = true
                     break
diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii
index 9722ce612..8b24f4548 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.25 21:29}
+\newcontextversion{2011.11.29 18:47}
 
 %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 f179f1feb..6b0b7821c 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.25 21:29}
+\newcontextversion{2011.11.29 18:47}
 
 %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 858d49e7b..719e68b01 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 6dbdc2bca..d5c91793d 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 da9357673..984774ac2 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.25 21:29}
+\edef\contextversion{2011.11.29 18:47}
 
 %D For those who want to use this:
 
diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv
index 395e6dc15..08c785b5e 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.25 21:29}
+\edef\contextversion{2011.11.29 18:47}
 
 %D For those who want to use this:
 
diff --git a/tex/context/base/l-lpeg.lua b/tex/context/base/l-lpeg.lua
index 018aa996e..9fb22e1b5 100644
--- a/tex/context/base/l-lpeg.lua
+++ b/tex/context/base/l-lpeg.lua
@@ -598,32 +598,72 @@ function lpeg.is_lpeg(p)
     return p and lpegtype(p) == "pattern"
 end
 
--- For the moment here, but it might move to utilities:
+-- For the moment here, but it might move to utilities. Beware, we need to
+-- have the longest keyword first, so 'aaa' comes beforte 'aa' which is why we
+-- loop back from the end.
 
-local sort, fastcopy, sortedpairs = table.sort, table.fastcopy, table.sortedpairs -- dependency!
+local sort, fastcopy, sortedkeys = table.sort, table.fastcopy, table.sortedkeys -- dependency!
 
-function lpeg.append(list,pp,delayed)
+function lpeg.append(list,pp,delayed,checked)
     local p = pp
     if #list > 0 then
-        list = fastcopy(list)
-        sort(list)
-        for l=1,#list do
+        local keys = fastcopy(list)
+        sort(keys)
+        for i=#keys,1,-1 do
+            local k = keys[i]
             if p then
-                p = P(list[l]) + p
+                p = P(k) + p
             else
-                p = P(list[l])
+                p = P(k)
             end
         end
-    elseif delayed then
-        for k, v in sortedpairs(list) do
-            if p then
+    elseif delayed then -- hm, it looks like the lpeg parser resolves anyway
+        local keys = sortedkeys(list)
+        if p then
+            for i=#keys,1,-1 do
+                local k = keys[i]
+                local v = list[k]
                 p = P(k)/list + p
+            end
+        else
+            for i=#keys,1,-1 do
+                local k = keys[i]
+                local v = list[k]
+                if p then
+                    p = P(k) + p
+                else
+                    p = P(k)
+                end
+            end
+            if p then
+                p = p / list
+            end
+        end
+    elseif checked then
+        -- problem: substitution gives a capture
+        local keys = sortedkeys(list)
+        for i=#keys,1,-1 do
+            local k = keys[i]
+            local v = list[k]
+            if p then
+                if k == v then
+                    p = P(k) + p
+                else
+                    p = P(k)/v + p
+                end
             else
-                p = P(k)/list
+                if k == v then
+                    p = P(k)
+                else
+                    p = P(k)/v
+                end
             end
         end
     else
-        for k, v in sortedpairs(list) do
+        local keys = sortedkeys(list)
+        for i=#keys,1,-1 do
+            local k = keys[i]
+            local v = list[k]
             if p then
                 p = P(k)/v + p
             else
diff --git a/tex/context/base/lang-lab.lua b/tex/context/base/lang-lab.lua
index 64d102768..360f2aa11 100644
--- a/tex/context/base/lang-lab.lua
+++ b/tex/context/base/lang-lab.lua
@@ -97,8 +97,10 @@ local function definelanguagelabels(data,command,tag,rawtag)
     end
 end
 
-local function definelabels(command,list,prefixed)
+function languages.labels.define(command,name,prefixed)
+    local list = languages.data.labels[name]
     if list then
+        report_labels("defining label set '%s'",name)
         context.pushcatcodes(prtcatcodes) -- context.unprotect
         for tag, data in next, list do
             if data.hidden then
@@ -127,17 +129,11 @@ local function definelabels(command,list,prefixed)
             end
         end
         context.popcatcodes() -- context.protect
+    else
+        report_labels("unknown label set '%s'",name)
     end
 end
 
-function languages.labels.define()
-    local data = languages.data.labels
-    definelabels("setupheadtext", data.titles, true)
-    definelabels("setuplabeltext", data.texts, true)
-    definelabels("setupmathlabeltext", data.functions)
-    definelabels("setuptaglabeltext", data.tags)
-end
-
 --~ function languages.labels.check()
 --~     for category, list in next, languages.data.labels do
 --~         for tag, specification in next, list do
diff --git a/tex/context/base/lang-lab.mkiv b/tex/context/base/lang-lab.mkiv
index 31ad760d0..8af23b101 100644
--- a/tex/context/base/lang-lab.mkiv
+++ b/tex/context/base/lang-lab.mkiv
@@ -18,6 +18,10 @@
 
 \unprotect
 
+%D Left-overs:
+
+\ifdefined\sixperemspace \else \def\sixperemspace{ } \fi % \utfchar{2006"} % we could embed 0x2006 but it does not show up in a editor
+
 %C The UPPERCASE variants are obsolete as we can now use \WORD
 %C in an non-interfering way.
 
@@ -61,12 +65,14 @@
 %D
 %D The last two cases concern the current language.
 
+\let\currentlabelcategory\empty
+
 \def\definelabelclass
-  {\dodoubleempty\dodefinelabelclass}
+  {\dodoubleempty\define_label_class}
 
-\def\dodefinelabelclass[#1][#2]%
+\def\define_label_class[#1][#2]%
   {\normalexpanded
-     {\noexpand\dododefinelabelclass
+     {\define_label_class_indeed
         {#1}%
         {\ifsecondargument#2\else\zerocount\fi}%
         \expandafter\noexpand\csname   dogetupsome#1text\endcsname
@@ -77,12 +83,10 @@
         \expandafter\noexpand\csname             #1texts\endcsname
         \expandafter\noexpand\csname              #1text\endcsname}}
 
-\let\currentlabelcategory\empty
-
-\def\dododefinelabelclass#1#2#3#4#5#6#7#8#9%
-  {\setuvalue{setup#1text}{\protecttextprefixes#2\def\currenttextprefixclass{#1}\dodoubleempty\dosetupsometextprefix}%
-   \setuvalue{preset#1text}{\protecttextprefixes1\def\currenttextprefixclass{#1}\dodoubleempty\dosetupsometextprefix}%
-   \setuvalue{start#1text}{\protecttextprefixes1\def\currenttextprefixclass{#1}\dotripleempty\dostartsometextprefix[#1]}%
+\unexpanded\def\define_label_class_indeed#1#2#3#4#5#6#7#8#9%
+  {\setuvalue{setup#1text}{\protecttextprefixes#2\def\currenttextprefixclass{#1}\dodoubleempty\setup_some_text_prefix}%
+   \setuvalue{preset#1text}{\protecttextprefixes1\def\currenttextprefixclass{#1}\dodoubleempty\setup_some_text_prefix}%
+   \setuvalue{start#1text}{\protecttextprefixes1\def\currenttextprefixclass{#1}\dotripleempty\start_some_text_prefix[#1]}%
    \letvalue{stop#1text}\relax
    \def#4{\reallanguagetag{\defaultlanguage\currentmainlanguage}}%
    \ifnum#2=\plustwo
@@ -159,11 +163,6 @@
 %D These macros enable us to automatically define head and label
 %D texts without replacing predefined ones. They are internal macros.
 
-\definelabelclass [head]      [0] % titles
-\definelabelclass [label]     [0] % texts
-\definelabelclass [mathlabel] [0] % functions
-\definelabelclass [taglabel]  [2] % tags
-
 \appendtoks \let\labellanguage\currentlanguage \to \everycurrentdate
 
 \newconstant\protecttextprefixes
@@ -171,7 +170,7 @@
 \let\currenttextprefixtag  \s!unknown
 \let\currenttextprefixclass\s!unknown
 
-\def\dostartsometextprefix[#1][#2][#3]% class language name
+\def\start_some_text_prefix[#1][#2][#3]% class language name
   {\ifthirdargument
      \edef\currenttextprefixtag{\reallanguagetag{#2}}%
      \edef\currenttextprefixname{#3}%
@@ -179,43 +178,43 @@
      \edef\currenttextprefixtag{\reallanguagetag\currentmainlanguage}%
      \edef\currenttextprefixname{#2}%
    \fi
-   \grabuntil{stop#1text}\dodostartsometextprefix}
+   \grabuntil{stop#1text}\start_some_text_prefix_indeed}
 
-\def\dodostartsometextprefix#1% text (not special checking done here yet, only for long texts anyway)
+\def\start_some_text_prefix_indeed#1% text (not special checking done here yet, only for long texts anyway)
   {\expandafter\edef\csname\??ml:\currenttextprefixclass:\currenttextprefixtag:\currenttextprefixname\endcsname{{\ctxlua{context(string.strip(\!!bs#1\!!es))}}\empty}}
 
-\def\dosetupsometextprefix[#1][#2]%
+\def\setup_some_text_prefix[#1][#2]%
   {\ifsecondargument
      \edef\currenttextprefixtag{\reallanguagetag{#1}}%
-     \processcommalist[#2]\dodosetupsometextprefix
+     \processcommalist[#2]\setup_some_text_prefix_indeed
    \else
      \edef\currenttextprefixtag{\reallanguagetag\currentmainlanguage}%
-     \processcommalist[#1]\dodosetupsometextprefix
+     \processcommalist[#1]\setup_some_text_prefix_indeed
    \fi}
 
-\def\dodosetupsometextprefix#1%
-  {\dododosetupsometextprefix[#1]}
+\def\setup_some_text_prefix_indeed#1%
+  {\assign_some_text_prefix[#1]}
 
-\def\dododosetupsometextprefix[#1=#2]%
-  {\doassignsometextprefix{#1}[#2,,]}
+\def\assign_some_text_prefix[#1=#2]%
+  {\assign_some_text_prefix_indeed{#1}[#2,,]}
 
-\def\doassignsometextprefix#1%
+\def\assign_some_text_prefix_indeed#1%
   {\ifcase\protecttextprefixes
      % no checking
-     \expandafter\doassignsometextprefixyes
+     \expandafter\assign_some_text_prefix_yes
    \or
      % checking
      \ifcsname\??ml:\currenttextprefixclass:\currenttextprefixtag:#1\endcsname
-       \expandafter\expandafter\expandafter\doassignsometextprefixnop
+       \expandafter\expandafter\expandafter\assign_some_text_prefix_nop
      \else
-       \expandafter\expandafter\expandafter\doassignsometextprefixyes
+       \expandafter\expandafter\expandafter\assign_some_text_prefix_yes
      \fi
    \or
      % simple assignment (a bit overkill but it fits in the whole)
-     \expandafter\doassignsometextprefixdumb
+     \expandafter\assign_some_text_prefix_dumb
    \fi{#1}}
 
-\def\doassignsometextprefixyes#1[#2,#3,#4]%
+\def\assign_some_text_prefix_yes#1[#2,#3,#4]%
   {\edef\!!stringa{#2}%
    \edef\!!stringb{#3}%
    \ifx\!!stringb\empty
@@ -228,12 +227,24 @@
      \expandafter\def\csname\??ml:\currenttextprefixclass:\currenttextprefixtag:#1\endcsname{{#2}{#3}}%
    \fi}
 
-\def\doassignsometextprefixnop#1[#2]%
+\def\assign_some_text_prefix_nop#1[#2]%
   {}
 
-\def\doassignsometextprefixdumb#1[#2,#3]%
+\def\assign_some_text_prefix_dumb#1[#2,#3]%
   {\expandafter\def\csname\??ml:\currenttextprefixclass:\currenttextprefixtag:#1\endcsname{#2}}
 
+\definelabelclass [head]      [0] % titles
+\definelabelclass [label]     [0] % texts
+\definelabelclass [mathlabel] [0] % functions
+\definelabelclass [taglabel]  [2] % tags
+
+\ctxlua{
+    languages.labels.define("setupheadtext","titles",true)%
+    languages.labels.define("setuplabeltext","texts",true)%
+    languages.labels.define("setupmathlabeltext","functions",false)%
+    languages.labels.define("setuptaglabeltext","tags",false)%
+}
+
 %D \macros
 %D   {translate}
 %D
@@ -252,7 +263,11 @@
 %D which expands to {\em something} or {\em iets}, depending on
 %D de current language.
 
-\def\dotranslate[#1]%
+
+\unexpanded\def\translate
+  {\dosingleempty\translate_indeed}
+
+\def\translate_indeed[#1]%
   {\getparameters[\??lg][#1]%
    \ifcsname\??lg\currentlanguage\endcsname
      \csname\??lg\currentlanguage\endcsname
@@ -262,9 +277,6 @@
      [translation #1]%
    \fi\fi}
 
-\unexpanded\def\translate
-  {\dosingleempty\dotranslate}
-
 %D When used without argument, the last defined values are
 %D used. This enables repetitive use like
 %D
@@ -286,12 +298,4 @@
   {\getparameters[\??lg][#1]%
    \edef#2{\csname\??lg\currentlanguage\endcsname}}
 
-%D Now we load the labels:
-
-\ifdefined\sixperemspace \else \def\sixperemspace{ } \fi % \utfchar{2006"} % we could embed 0x2006 but it does not show up in a editor
-
-%D Now we can load the labels:
-
-\ctxlua{languages.labels.define()} % no user command
-
 \protect \endinput
diff --git a/tex/context/base/lpdf-fld.lua b/tex/context/base/lpdf-fld.lua
index 0b78821b6..5f59c951c 100644
--- a/tex/context/base/lpdf-fld.lua
+++ b/tex/context/base/lpdf-fld.lua
@@ -820,7 +820,7 @@ function methods.line(name,specification)
 end
 
 function methods.text(name,specification)
-    return makelinechine(name,enhance(specification,"MultiLine"))
+    return makelinechild(name,enhance(specification,"MultiLine"))
 end
 
 local function makechoiceparent(field,specification)
diff --git a/tex/context/base/phys-dim.lua b/tex/context/base/phys-dim.lua
index 0cf878470..9b9b59372 100644
--- a/tex/context/base/phys-dim.lua
+++ b/tex/context/base/phys-dim.lua
@@ -16,14 +16,35 @@ if not modules then modules = { } end modules ['phys-dim'] = {
 -- todo: collect used units for logging (and list of units, but then we need
 -- associations too).
 
--- todo: degrees celsius    0x2103
--- todo: degrees fahrenheit 0x2109
-
-local V, P, S, R, C, Cc, Cs, matchlpeg, Carg = lpeg.V, lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.match, lpeg.Carg
+-- The lists have been checked and completed by Robin Kirkham.
+
+-- dubious/wrong
+
+--  Atom                        = [[u]], -- should be amu (atomic mass unit)
+--  Bell                        = [[B]], -- should be bel
+--  Sterant                     = [[sr]], -- should be steradian
+--  Equivalent                  = [[eql]], -- qualifier?
+--  At                          = [[at]], -- qualifier?
+--  Force                       = [[f]], -- qualifier?
+--  eVolt                       = [[eV]],
+--  -- AC or DC voltages should be qualified in the text
+--  VoltAC                      = [[V\unitsbackspace\unitslower{ac}]],
+--  VoltDC                      = [[V\unitsbackspace\unitslower{dc}]],
+--  AC                          = [[V\unitsbackspace\unitslower{ac}]],
+--  DC                          = [[V\unitsbackspace\unitslower{dc}]],
+--  -- probably not harmful but there are better alternatives
+--  -- e.g., revolution per second (rev/s)
+--  RPS                         = [[RPS]],
+--  RPM                         = [[RPM]],
+--  RevPerSec                   = [[RPS]],
+--  RevPerMin                   = [[RPM]],
+
+local V, P, S, R, C, Cc, Cs, matchlpeg = lpeg.V, lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.match
 local format, lower = string.format, string.lower
 local appendlpeg = lpeg.append
 local mergetable, mergedtable, keys, loweredkeys = table.merge, table.merged, table.keys, table.loweredkeys
 local setmetatablenewindex = table.setmetatablenewindex
+local utfchar = utf.char
 
 physics            = physics or { }
 physics.units      = physics.units or { }
@@ -39,6 +60,9 @@ trackers.register("physics.units", function(v) trace_units = v end)
 
 -- digits parser (todo : use patterns)
 
+local math_one       = Cs((P("$")    /"") * (1-P("$"))^1 * (P("$")/"")) / context.m
+local math_two       = Cs((P("\\m {")/"") * (1-P("}"))^1 * (P("}")/"")) / context.m -- watch the space after \m
+
 local digit          = R("09")
 local sign           = S("+-")
 local power          = S("^e")
@@ -59,17 +83,15 @@ local space          = P(" ")
 local digits         = digit^1
 
 local ddigitspace    = digitspace  / "" / context.digitsspace
-local dcommayes      = semicolon   / "" / context.digitsfinalcomma
-local dcommanop      = semicolon   / "" / context.digitsseparatorspace
-local dperiodyes     = colon       / "" / context.digitsfinalperiod
-local dperiodnop     = colon       / "" / context.digitsseparatorspace
 local ddigit         = digits           / context.digitsdigit
+local dsemicomma     = semicolon   / "" / context.digitsseparatorspace
+local dsemiperiod    = colon       / "" / context.digitsseparatorspace
 local dfinalcomma    = comma       / "" / context.digitsfinalcomma
 local dfinalperiod   = period      / "" / context.digitsfinalperiod
-local dintercomma    = comma  * #(digitspace) / "" / context.digitsseparatorspace
-                     + comma                  / "" / context.digitsintermediatecomma
-local dinterperiod   = period * #(digitspace) / "" / context.digitsseparatorspace
-                     + period                 / "" / context.digitsintermediateperiod
+local dintercomma    = comma       / "" / context.digitsintermediatecomma
+local dinterperiod   = period      / "" / context.digitsintermediateperiod
+local dskipcomma     = comma       / "" / context.digitsseparatorspace
+local dskipperiod    = period      / "" / context.digitsseparatorspace
 local dsignspace     = signspace   / "" / context.digitssignspace
 local dpositive      = positive    / "" / context.digitspositive
 local dnegative      = negative    / "" / context.digitsnegative
@@ -87,28 +109,35 @@ local dleader        = (dpositive + dnegative + dhighspace + dsomesign + dsignsp
 local dtrailer       = dpower^0
 local dfinal         = P(-1) + #P(1 - comma - period - semicolon - colon)
 local dnumber        = (ddigitspace + ddigit)^1
-local dtemplate      = ddigitspace^1
-
--- probably too complex, due to lookahead (lookback with state is probably easier)
-
-local dpcfinalnumber = dtemplate * (dfinalcomma  + dcommanop ) + dnumber * (dfinalcomma  + dcommayes )
-local dcpfinalnumber = dtemplate * (dfinalperiod + dperiodnop) + dnumber * (dfinalperiod + dperiodyes)
-
-local dpcinternumber = dtemplate * (dintercomma  + dcommanop ) + dnumber * (dintercomma  + dcommayes )
-local dcpinternumber = dtemplate * (dinterperiod + dperiodnop) + dnumber * (dinterperiod + dperiodyes)
-
-local dfallback      = (dtemplate * (dcommanop + dperiodnop)^0)^0 * (dcommayes + dperiodyes + ddigit)^0
-
-local p_c_number     = (dcpinternumber)^0 * (dpcfinalnumber)^0 * ddigit + dfallback -- 000.000.000,00
-local c_p_number     = (dpcinternumber)^0 * (dcpfinalnumber)^0 * ddigit + dfallback -- 000,000,000.00
-
--- ony signs before numbers (otherwise we get s / seconds issues)
-
-local p_c_dparser    = dleader * p_c_number * dtrailer * dfinal
-local c_p_dparser    = dleader * c_p_number * dtrailer * dfinal
 
--- local p_c_dparser    = p_c_number * dtrailer * dfinal
--- local c_p_dparser    = c_p_number * dtrailer * dfinal
+-- ___,000,000  ___,___,000  ___,___,__0  000,000,000  000.00  000,000,000.00  000,000,000.==
+
+-- : ; for the moment not used, maybe for invisible fraction . , when no leading number
+
+local c_p = (ddigitspace^1 * dskipcomma)^0            -- ___,
+          * (ddigitspace^0 * ddigit * dintercomma)^0  -- _00, 000,
+          * ddigitspace^0  * ddigit^0                 -- _00 000
+          * (
+             dfinalperiod * ddigit                    -- .00
+           + dskipperiod  * dpadding^1                -- .==
+           + dsemiperiod  * ddigit                    -- :00
+           + dsemiperiod  * dpadding^1                -- :==
+            )^0
+          + ddigit                                    -- 00
+
+local p_c = (ddigitspace^1 * dskipperiod)^0           -- ___.
+          * (ddigitspace^0 * ddigit * dinterperiod)^0 -- _00. 000.
+          * ddigitspace^0  * ddigit^0                 -- _00 000
+          * (
+             dfinalcomma * ddigit                     -- ,00
+           + dskipcomma  * dpadding^1                 -- ,==
+           + dsemicomma  * ddigit                     -- :00
+           + dsemicomma  * dpadding^1                 -- :==
+            )^0
+          + ddigit                                    -- 00
+
+local p_c_dparser = math_one + math_two + dleader * p_c * dtrailer * dfinal
+local c_p_dparser = math_one + math_two + dleader * c_p * dtrailer * dfinal
 
 function commands.digits(str,p_c)
     if p_c == v_reverse then
@@ -121,225 +150,313 @@ end
 -- tables:
 
 local long_prefixes = {
-    Yocto = [[y]],  -- 10^{-24}
-    Zepto = [[z]],  -- 10^{-21}
-    Atto  = [[a]],  -- 10^{-18}
-    Femto = [[f]],  -- 10^{-15}
-    Pico  = [[p]],  -- 10^{-12}
-    Nano  = [[n]],  -- 10^{-9}
-    Micro = [[\mu]],-- 10^{-6}
-    Milli = [[m]],  -- 10^{-3}
-    Centi = [[c]],  -- 10^{-2}
-    Deci  = [[d]],  -- 10^{-1}
-
-    Deca  = [[da]], -- 10^{1}
-    Hecto = [[h]],  -- 10^{2}
-    Kilo  = [[k]],  -- 10^{3}
-    Mega  = [[M]],  -- 10^{6}
-    Giga  = [[G]],  -- 10^{9}
-    Tera  = [[T]],  -- 10^{12}
-    Peta  = [[P]],  -- 10^{15}
-    Exa   = [[E]],  -- 10^{18}
-    Zetta = [[Z]],  -- 10^{21}
-    Yotta = [[Y]],  -- 10^{24}
-
-    Kibi  = [[ki]], -- 2^{10}
-    Mebi  = [[Mi]], -- 2^{20}
-    Gibi  = [[Gi]], -- 2^{30}
-    Tebi  = [[Ti]], -- 2^{40}
-    Pebi  = [[Pi]], -- 2^{50}
-
-    Kibi  = [[Ki]], -- binary
-    Mebi  = [[Mi]], -- binary
-    Gibi  = [[Gi]], -- binary
-    Tebi  = [[Ti]], -- binary
-    Pebi  = [[Pi]], -- binary
-    Exbi  = [[Ei]], -- binary
-    Zebi  = [[Zi]], -- binary
-    Yobi  = [[Yi]], -- binary
-
-    Micro = [[µ]],  -- 0x00B5 \textmu
-    Root  = [[√]],  -- 0x221A
+
+    -- Le Système international d'unités (SI) 8e édition (Table 5)
+
+    Yocto = "yocto",  -- 10^{-24}
+    Zepto = "zepto",  -- 10^{-21}
+    Atto  = "atto",   -- 10^{-18}
+    Femto = "femto",  -- 10^{-15}
+    Pico  = "pico",   -- 10^{-12}
+    Nano  = "nano",   -- 10^{-9}
+    Micro = "micro",  -- 10^{-6}
+    Milli = "milli",  -- 10^{-3}
+    Centi = "centi",  -- 10^{-2}
+    Deci  = "deci",   -- 10^{-1}
+
+    Deca  = "deca",   -- 10^{1}
+    Hecto = "hecto",  -- 10^{2}
+    Kilo  = "kilo",   -- 10^{3}
+    Mega  = "mega",   -- 10^{6}
+    Giga  = "giga",   -- 10^{9}
+    Tera  = "tera",   -- 10^{12}
+    Peta  = "peta",   -- 10^{15}
+    Exa   = "exa",    -- 10^{18}
+    Zetta = "zetta",  -- 10^{21}
+    Yotta = "yotta",  -- 10^{24}
+
+    -- IEC 60027-2: 2005, third edition, Part 2
+
+    Kibi  = "kibi", -- 2^{10} (not ki)
+    Mebi  = "mebi", -- 2^{20}
+    Gibi  = "gibi", -- 2^{30}
+    Tebi  = "tebi", -- 2^{40}
+    Pebi  = "pebi", -- 2^{50}
+    Exbi  = "exbi", -- 2^{60}
+
+    -- not standard
+
+    Zebi  = "zebi", -- binary
+    Yobi  = "yobi", -- binary
+
+    Micro = "micro",
+    Root  = "root",
 }
 
 local long_units = {
-    Meter             = [[m]],
-    Hertz             = [[Hz]],
-    Second            = [[s]],
-    Hour              = [[h]],
-    Liter             = [[l]],
---  Litre             = [[l]],
-    Gram              = [[g]],
-    Newton            = [[N]],
-    Pascal            = [[Pa]],
-    Atom              = [[u]],
-    Bell              = [[B]],
-    Katal             = [[kat]],
-    Dalton            = [[Da]],
-    Joule             = [[J]],
-    Watt              = [[W]],
-    Celsius           = [[C]], -- no SI
-    Kelvin            = [[K]],
-    Fahrenheit        = [[F]], -- no SI
-    Mol               = [[mol]],
-    Mole              = [[mol]],
-    Equivalent        = [[eql]],
-    Farad             = [[F]],
-    Ohm               = [[\Omega]],
-    Siemens           = [[S]],
-    Ampere            = [[A]],
-    Coulomb           = [[C]],
-    Volt              = [[V]],
-    eVolt             = [[eV]],
-    eV                = [[eV]],
-    Tesla             = [[T]],
-    VoltAC            = [[V\unitsbackspace\unitslower{ac}]],
-    VoltDC            = [[V\unitsbackspace\unitslower{dc}]],
-    AC                = [[V\unitsbackspace\unitslower{ac}]],
-    DC                = [[V\unitsbackspace\unitslower{dc}]],
-    Bit               = [[bit]],
-    Baud              = [[Bd]],
-    Byte              = [[B]],
-    Erlang            = [[E]],
-    Bequerel          = [[Bq]],
-    Sievert           = [[Sv]],
-    Candela           = [[cd]],
-    Bel               = [[B]],
-    At                = [[at]],
-    Atm               = [[atm]],
-    Bar               = [[bar]],
-    Foot              = [[ft]],
-    Inch              = [[inch]],
-    Cal               = [[cal]],
-    Force             = [[f]],
-    Lux               = [[lx]],
-    Gray              = [[Gr]],
-    Weber             = [[Wb]],
-    Henry             = [[H]],
-    Sterant           = [[sr]],
-    Tonne             = [[t]],
-    Angstrom          = [[Å]],
-    Gauss             = [[G]],
-    Rad               = [[rad]],
-    RPS               = [[RPS]],
-    RPM               = [[RPM]],
-    RevPerSec         = [[RPS]],
-    RevPerMin         = [[RPM]],
-    Ohm               = [[Ω]], -- 0x2126 \textohm
-    ["Metric Ton"]    = [[t]],
-    ["Electron Volt"] = [[eV]],
+
+    -- Le Système international d'unités (SI) 8e édition (except synonyms)
+    -- SI base units (Table 1)
+
+    Meter                       = "meter",
+    Gram                        = "gram",
+    Second                      = "second",
+    Ampere                      = "ampere",
+    Kelvin                      = "kelvin",
+    Mole                        = "mole",
+    Candela                     = "candela",
+
+    -- synonyms
+
+    Mol                         = "mole",
+    Metre                       = "meter",
+
+    -- SI derived units with special names (Table 3)
+
+    Radian                      = "radian",
+    Steradian                   = "steradian",
+    Hertz                       = "hertz",
+    Newton                      = "newton",
+    Pascal                      = "pascal",
+    Joule                       = "joule",
+    Watt                        = "watt",
+    Coulomb                     = "coulomb",
+    Volt                        = "volt",
+    Farad                       = "farad",
+    Ohm                         = "ohm",
+    Siemens                     = "siemens",
+    Weber                       = "weber",
+    Tesla                       = "tesla",
+    Henry                       = "henry",
+    Celsius                     = "celsius",
+    Lumen                       = "lumen",
+    Lux                         = "lux",
+    Bequerel                    = "bequerel",
+    Gray                        = "gray",
+    Sievert                     = "sievert",
+    Katal                       = "katal",
+
+    -- non SI units accepted for use with SI (Table 6)
+
+    Minute                      = "minute",
+    Hour                        = "hour",
+    Day                         = "day",
+
+    -- (degree, minute, second of arc are treated specially later)
+
+    Gon                         = "gon",
+    Grad                        = "grad",
+    Hectare                     = "hectare",
+    Liter                       = "liter",
+
+    Tonne                       = "tonne",
+
+    -- synonyms
+
+    ["Metric Ton"]              = "tonne",
+    Litre                       = "liter",
+
+    -- non-SI units whose values must be obtained experimentally (Table 7)
+
+    ["Electron Volt"]           = "electronvolt",
+    Dalton                      = "dalton",
+    ["Atomic Mass Unit"]        = "atomicmassunit",
+    ["Astronomical Unit"]       = "astronomicalunit",
+
+    -- special cases (catch doubles, okay, a bit over the top)
+
+    ["Degrees Celsius"]         = "celsius",
+    ["Degrees Fahrenheit"]      = "fahrenheit",
+    ["Degree Celsius"]          = "celsius",
+    ["Degree Fahrenheit"]       = "fahrenheit",
+
+ -- too late as we already have connected symbols catched:
+ --
+ -- ["° Celsius"]               = "celsius",
+ -- ["° Fahrenheit"]            = "fahrenheit",
+ -- ["°Celsius"]                = "celsius",
+ -- ["°Fahrenheit"]             = "fahrenheit",
+
+    -- the "natural units" and "atomic units" are omitted for now
+    -- synonyms
+
+    eV                          = "electronvolt",
+    AMU                         = "atomicmassunit",
+
+    -- other non-SI units (Table 8)
+
+    Bar                         = "bar",
+ -- ["Millimetre Of Mercury"]   = [[mmHg]],
+    Angstrom                    = "angstrom", -- strictly Ångström
+    ["Nautical Mile"]           = "nauticalmile",
+    Barn                        = "barn",
+    Knot                        = "knot",
+    Neper                       = "neper",
+    Bel                         = "bel", -- in practice only decibel used
+
+    -- other non-SI units from CGS system (Table 9)
+
+    Erg                         = "erg",
+    Dyne                        = "dyne",
+    Poise                       = "poise",
+    Stokes                      = "stokes",
+    Stilb                       = "stilb",
+    Phot                        = "phot",
+    Gal                         = "gal",
+    Maxwell                     = "maxwell",
+    Gauss                       = "gauss",
+    Oersted                     = "oersted",
+
+    -- end of SI
+
+    -- data: for use with the binary prefixes (except Erlang)
+
+    Bit                         = "bit",
+    Byte                        = "byte" ,
+    Baud                        = "baud",
+    Erlang                      = "erlang",
+
+    -- common units, not part of SI
+
+    Atmosphere                  = "atmosphere",
+    Revolution                  = "revolution",
+
+    -- synonyms
+
+    Atm                         = "atmosphere",
+    Rev                         = "revolution",
+
+    -- imperial units (very incomplete)
+
+    Fahrenheit                  = "fahrenheit",
+    Foot                        = "foot",
+    Inch                        = "inch",
+    Calorie                     = "calorie",
+
+    -- synonyms
+
+    Cal                         = "calorie",
+
 }
 
 local long_operators = {
-    Times   = [[\unitsTIMES]], -- cdot
-    Solidus = [[\unitsSOLIDUS]],
-    Per     = [[\unitsSOLIDUS]],
-    OutOf   = [[\unitsOUTOF]],
+
+    Times   = "times",
+    Solidus = "solidus",
+    Per     = "per",
+    OutOf   = "outof",
+
 }
 
 local long_suffixes = {
-    Linear  = [[1]],
-    Square  = [[2]],
-    Cubic   = [[3]],
-    Inverse = [[-1]],
-    ILinear = [[-1]],
-    ISquare = [[-2]],
-    ICubic  = [[-3]],
+
+    Linear  = "linear",
+    Square  = "square",
+    Cubic   = "cubic",
+    Inverse = "inverse",
+    ILinear = "ilinear",
+    ISquare = "isquare",
+    ICubic  = "icubic",
+
 }
 
-local short_prefixes_to_long = {
-    y  = "Yocto",
-    z  = "Zetto",
-    a  = "Atto",
-    f  = "Femto",
-    p  = "Pico",
-    n  = "Nano",
-    u  = "Micro",
-    m  = "Milli",
-    c  = "Centi",
-    d  = "Deci",
-    da = "Deca",
-    h  = "Hecto",
-    k  = "Kilo",
-    M  = "Mega",
-    G  = "Giga",
-    T  = "Tera",
-    P  = "Peta",
-    E  = "Exa",
-    Z  = "Zetta",
-    Y  = "Yotta",
+local short_prefixes = {
+
+    y  = "yocto",
+    z  = "zetto",
+    a  = "atto",
+    f  = "femto",
+    p  = "pico",
+    n  = "nano",
+    u  = "micro",
+    m  = "milli",
+    c  = "centi",
+    d  = "deci",
+    da = "deca",
+    h  = "hecto",
+    k  = "kilo",
+    M  = "mega",
+    G  = "giga",
+    T  = "tera",
+    P  = "peta",
+    E  = "exa",
+    Z  = "zetta",
+    Y  = "yotta",
+
 }
 
-local short_units_to_long = { -- I'm not sure about casing
-    m       = "Meter",
-    Hz      = "Hertz",
-    hz      = "Hertz",
-    B       = "Bel",
-    b       = "Bel",
-    lx      = "Lux",
- -- da      = "Dalton",
-    u       = "Hour",
-    h       = "Hour",
-    s       = "Second",
-    g       = "Gram",
-    n       = "Newton",
-    v       = "Volt",
-    t       = "Tonne",
-
-    l       = "Liter",
- -- w       = "Watt",
-    W       = "Watt",
- -- a       = "Ampere",
-    A       = "Ampere",
-
-    Litre   = "Liter",
-    Metre   = "Meter",
+local short_units = { -- I'm not sure about casing
+
+    m  = "meter",
+    Hz = "hertz",
+    hz = "hertz",
+    B  = "bel",
+    b  = "bel",
+    lx = "lux",
+ -- da = "dalton",
+    h  = "hour",
+    s  = "second",
+    g  = "gram",
+    n  = "newton",
+    v  = "volt",
+    t  = "tonne",
+    l  = "liter",
+ -- w  = "watt",
+    W  = "watt",
+ -- a  = "ampere",
+    A  = "ampere",
+
+    [utfchar(0x2103)] = "celsius",
+    [utfchar(0x2109)] = "fahrenheit",
 }
 
-local short_operators_to_long = {
-    ["."] = "Times",
-    ["*"] = "Times",
-    ["/"] = "Solidus",
-    [":"] = "OutOf",
+local short_operators = {
+    ["."] = "times",
+    ["*"] = "times",
+    ["/"] = "solidus",
+    [":"] = "outof",
 }
 
 local short_suffixes = { -- maybe just raw digit match
-    ["1"]   = long_suffixes.Linear,
-    ["2"]   = long_suffixes.Square,
-    ["3"]   = long_suffixes.Cubic,
-    ["+1"]  = long_suffixes.Linear,
-    ["+2"]  = long_suffixes.Square,
-    ["+3"]  = long_suffixes.Cubic,
-    ["-1"]  = long_suffixes.Inverse,
-    ["-1"]  = long_suffixes.ILinear,
-    ["-2"]  = long_suffixes.ISquare,
-    ["-3"]  = long_suffixes.ICubic,
-    ["^1"]  = long_suffixes.Linear,
-    ["^2"]  = long_suffixes.Square,
-    ["^3"]  = long_suffixes.Cubic,
-    ["^+1"] = long_suffixes.Linear,
-    ["^+2"] = long_suffixes.Square,
-    ["^+3"] = long_suffixes.Cubic,
-    ["^-1"] = long_suffixes.Inverse,
-    ["^-1"] = long_suffixes.ILinear,
-    ["^-2"] = long_suffixes.ISquare,
-    ["^-3"] = long_suffixes.ICubic,
+    ["1"]   = "linear",
+    ["2"]   = "square",
+    ["3"]   = "cubic",
+    ["+1"]  = "linear",
+    ["+2"]  = "square",
+    ["+3"]  = "cubic",
+    ["-1"]  = "inverse",
+    ["-1"]  = "ilinear",
+    ["-2"]  = "isquare",
+    ["-3"]  = "icubic",
+    ["^1"]  = "linear",
+    ["^2"]  = "square",
+    ["^3"]  = "cubic",
+    ["^+1"] = "linear",
+    ["^+2"] = "square",
+    ["^+3"] = "cubic",
+    ["^-1"] = "inverse",
+    ["^-1"] = "ilinear",
+    ["^-2"] = "isquare",
+    ["^-3"] = "icubic",
 }
 
 local symbol_units = {
-    Degrees    = [[°]],
-    Degree     = [[°]],
-    Deg        = [[°]],
-    ["°"]      = [[°]],
-    ArcMinute  = [[\checkedtextprime]],        -- ′ 0x2032
-    ArcSecond  = [[\checkedtextdoubleprime]],  -- ″ 0x2033
-    Percent    = [[\percent]],
-    Promille   = [[\promille]],
-    Permille   = [[\promille]],
+    Degrees    = "degree",
+    Degree     = "degree",
+    Deg        = "degree",
+    ["°"]      = "degree",
+    ArcMinute  = "arcminute",
+    ["′"]      = "arcminute", -- 0x2032
+    ArcSecond  = "arcsecond",
+    ["″"]      = "arcsecond", -- 0x2033
+    Percent    = "percent",
+    ["%"]      = "percent",
+    Promille   = "permille",
+    Permille   = "permille",
 }
 
 local packaged_units = {
-    Micron = [[\textmu m]],
+    Micron = "micron",
 }
 
 -- rendering:
@@ -357,41 +474,143 @@ local unitsC      = context.unitsC
 local unitsNstart = context.unitsNstart
 local unitsNstop  = context.unitsNstop
 
-local l_prefixes  = allocate()
-local l_units     = allocate()
-local l_operators = allocate()
-
-local labels = languages.data.labels or { }
+local labels = languages.data.labels
+
+labels.prefixes = {
+    yocto = { labels = { en = [[y]]   } }, -- 10^{-24}
+    zepto = { labels = { en = [[z]]   } }, -- 10^{-21}
+    atto  = { labels = { en = [[a]]   } }, -- 10^{-18}
+    femto = { labels = { en = [[f]]   } }, -- 10^{-15}
+    pico  = { labels = { en = [[p]]   } }, -- 10^{-12}
+    nano  = { labels = { en = [[n]]   } }, -- 10^{-9}
+    micro = { labels = { en = [[\mu]] } }, -- 10^{-6}
+    milli = { labels = { en = [[m]]   } }, -- 10^{-3}
+    centi = { labels = { en = [[c]]   } }, -- 10^{-2}
+    deci  = { labels = { en = [[d]]   } }, -- 10^{-1}
+    deca  = { labels = { en = [[da]]  } }, -- 10^{1}
+    hecto = { labels = { en = [[h]]   } }, -- 10^{2}
+    kilo  = { labels = { en = [[k]]   } }, -- 10^{3}
+    mega  = { labels = { en = [[M]]   } }, -- 10^{6}
+    giga  = { labels = { en = [[G]]   } }, -- 10^{9}
+    tera  = { labels = { en = [[T]]   } }, -- 10^{12}
+    peta  = { labels = { en = [[P]]   } }, -- 10^{15}
+    exa   = { labels = { en = [[E]]   } }, -- 10^{18}
+    zetta = { labels = { en = [[Z]]   } }, -- 10^{21}
+    yotta = { labels = { en = [[Y]]   } }, -- 10^{24}
+    kibi  = { labels = { en = [[Ki]]  } }, -- 2^{10} (not ki)
+    mebi  = { labels = { en = [[Mi]]  } }, -- 2^{20}
+    gibi  = { labels = { en = [[Gi]]  } }, -- 2^{30}
+    tebi  = { labels = { en = [[Ti]]  } }, -- 2^{40}
+    pebi  = { labels = { en = [[Pi]]  } }, -- 2^{50}
+    exbi  = { labels = { en = [[Ei]]  } }, -- 2^{60}
+    zebi  = { labels = { en = [[Zi]]  } }, -- binary
+    yobi  = { labels = { en = [[Yi]]  } }, -- binary
+    micro = { labels = { en = [[µ]]   } }, -- 0x00B5 \textmu
+    root  = { labels = { en = [[√]]   } }, -- 0x221A
+}
 
-labels.prefixes  = l_prefixes
-labels.units     = l_units
-labels.operators = l_operators
+labels.units = {
+    meter                       = { labels = { en = [[m]]                        } },
+    gram                        = { labels = { en = [[g]]                        } }, -- strictly kg is the base unit
+    second                      = { labels = { en = [[s]]                        } },
+    ampere                      = { labels = { en = [[A]]                        } },
+    kelvin                      = { labels = { en = [[K]]                        } },
+    mole                        = { labels = { en = [[mol]]                      } },
+    candela                     = { labels = { en = [[cd]]                       } },
+    mol                         = { labels = { en = [[mol]]                      } },
+    radian                      = { labels = { en = [[rad]]                      } },
+    steradian                   = { labels = { en = [[sr]]                       } },
+    hertz                       = { labels = { en = [[Hz]]                       } },
+    newton                      = { labels = { en = [[N]]                        } },
+    pascal                      = { labels = { en = [[Pa]]                       } },
+    joule                       = { labels = { en = [[J]]                        } },
+    watt                        = { labels = { en = [[W]]                        } },
+    coulomb                     = { labels = { en = [[C]]                        } },
+    volt                        = { labels = { en = [[V]]                        } },
+    farad                       = { labels = { en = [[F]]                        } },
+    ohm                         = { labels = { en = [[Ω]]                        } }, -- 0x2126 \textohm
+    siemens                     = { labels = { en = [[S]]                        } },
+    weber                       = { labels = { en = [[Wb]]                       } },
+    tesla                       = { labels = { en = [[T]]                        } },
+    henry                       = { labels = { en = [[H]]                        } },
+    celsius                     = { labels = { en = [[\checkedtextcelsius]]      } }, -- 0x2103
+    lumen                       = { labels = { en = [[lm]]                       } },
+    lux                         = { labels = { en = [[lx]]                       } },
+    bequerel                    = { labels = { en = [[Bq]]                       } },
+    gray                        = { labels = { en = [[Gr]]                       } },
+    sievert                     = { labels = { en = [[Sv]]                       } },
+    katal                       = { labels = { en = [[kat]]                      } },
+    minute                      = { labels = { en = [[min]]                      } },
+    hour                        = { labels = { en = [[h]]                        } },
+    day                         = { labels = { en = [[d]]                        } },
+    gon                         = { labels = { en = [[gon]]                      } },
+    grad                        = { labels = { en = [[grad]]                     } },
+    hectare                     = { labels = { en = [[ha]]                       } },
+    liter                       = { labels = { en = [[l]]                        } }, -- symbol l or L
+    tonne                       = { labels = { en = [[t]]                        } },
+    electronvolt                = { labels = { en = [[eV]]                       } },
+    dalton                      = { labels = { en = [[Da]]                       } },
+    atomicmassunit              = { labels = { en = [[u]]                        } },
+    astronomicalunit            = { labels = { en = [[ua]]                       } },
+    bar                         = { labels = { en = [[bar]]                      } },
+--  ["Millimetre Of Mercury"]   = { labels = { en = [[mmHg]]                     } },
+    angstrom                    = { labels = { en = [[Å]]                        } }, -- strictly Ångström
+    nauticalmile                = { labels = { en = [[M]]                        } },
+    barn                        = { labels = { en = [[b]]                        } },
+    knot                        = { labels = { en = [[kn]]                       } },
+    neper                       = { labels = { en = [[Np]]                       } },
+    bel                         = { labels = { en = [[B]]                        } }, -- in practice only decibel used
+    erg                         = { labels = { en = [[erg]]                      } },
+    dyne                        = { labels = { en = [[dyn]]                      } },
+    poise                       = { labels = { en = [[P]]                        } },
+    stokes                      = { labels = { en = [[St]]                       } },
+    stilb                       = { labels = { en = [[sb]]                       } },
+    phot                        = { labels = { en = [[phot]]                     } },
+    gal                         = { labels = { en = [[gal]]                      } },
+    maxwell                     = { labels = { en = [[Mx]]                       } },
+    gauss                       = { labels = { en = [[G]]                        } },
+    oersted                     = { labels = { en = [[Oe]]                       } }, -- strictly Œrsted
+    bit                         = { labels = { en = [[bit]]                      } },
+    byte                        = { labels = { en = [[B]]                        } },
+    baud                        = { labels = { en = [[Bd]]                       } },
+    erlang                      = { labels = { en = [[E]]                        } },
+    atmosphere                  = { labels = { en = [[atm]]                      } },
+    revolution                  = { labels = { en = [[rev]]                      } },
+    fahrenheit                  = { labels = { en = [[\checkedtextfahrenheit]]   } }, -- 0x2109
+    foot                        = { labels = { en = [[ft]]                       } },
+    inch                        = { labels = { en = [[inch]]                     } },
+    calorie                     = { labels = { en = [[cal]]                      } },
+    --
+    degree                      = { labels = { en = [[°]]} },
+    arcminute                   = { labels = { en = [[\checkedtextprime]]        } }, -- ′ 0x2032
+    arcsecond                   = { labels = { en = [[\checkedtextdoubleprime]]  } }, -- ″ 0x2033
+    percent                     = { labels = { en = [[\percent]]                 } },
+    permille                    = { labels = { en = [[\promille]]                } },
+    --
+    micron                      = { labels = { en = [[\textmu m]]                } },
+}
 
-l_prefixes .test = { Kilo = "kilo" }
-l_units    .test = { Meter = "meter", Second = "second" }
-l_operators.test = { Solidus = " per " }
+labels.operators = {
+    times   = { labels = { en = [[\unitsTIMES]]   } },
+    solidus = { labels = { en = [[\unitsSOLIDUS]] } },
+    per     = { labels = { en = [[\unitsSOLIDUS]] } },
+    outof   = { labels = { en = [[\unitsOUTOF]]   } },
+}
 
-local prefixes   =  { }
-local units      =  { }
-local operators  =  { }
-local suffixes   =  { }
+labels.suffixes = {
+    linear  = { labels = { en = [[1]]  } },
+    square  = { labels = { en = [[2]]  } },
+    cubic   = { labels = { en = [[3]]  } },
+    inverse = { labels = { en = [[-1]] } },
+    ilinear = { labels = { en = [[-1]] } },
+    isquare = { labels = { en = [[-2]] } },
+    icubic  = { labels = { en = [[-3]] } },
+}
 
-local function dimpus(p,u,s,wherefrom)
+local function dimpus(p,u,s)
     if trace_units then
-        report_units("w: [%s], p: [%s], u: [%s], s: [%s]",wherefrom or "?",p or "?",u or "?",s or "?")
-    end
- -- local c = connected[u]
-    if wherefrom == "" then
-        p = prefixes[p] or p
-        u = units   [u] or u
-    else
-        local lp = l_prefixes[wherefrom]
-        local lu = l_units   [wherefrom]
-        p = lp and lp[p] or prefixes[p] or p
-        u = lu and lu[u] or units   [u] or u
-    end
-    s = suffixes[s] or s
-    --
+        report_units("p: [%s], u: [%s], s: [%s]",p or "?",u or "?",s or "?")
+    end    --
     if p ~= "" then
         if u ~= ""  then
             if s ~= ""  then
@@ -421,28 +640,22 @@ local function dimpus(p,u,s,wherefrom)
     end
 end
 
-local function dimspu(s,p,u,wherefrom)
-    return dimpus(p,u,s,wherefrom)
+local function dimspu(s,p,u)
+    return dimpus(p,u,s)
 end
 
-local function dimop(o,wherefrom)
+local function dimop(o)
     if trace_units then
-        report_units("w: [%s], o: [%s]",wherefrom or "?",o or "?")
-    end
-    if wherefrom == "" then
-        o = operators[o] or o
-    else
-        local lo = l_operators[wherefrom]
-        o = lo and lo[o] or operators[o] or o
+        report_units("o: [%s]",o or "?")
     end
     if o then
         unitsO(o)
     end
 end
 
-local function dimsym(s,wherefrom) -- Do we need to support wherefrom here?
+local function dimsym(s)
     if trace_units then
-        report_units("w: [%s], s: [%s]",wherefrom,s or "?")
+        report_units("s: [%s]",s or "?")
     end
     s = symbol_units[s] or s
     if s then
@@ -450,9 +663,9 @@ local function dimsym(s,wherefrom) -- Do we need to support wherefrom here?
     end
 end
 
-local function dimpre(p,wherefrom) -- Do we need to support wherefrom here?
+local function dimpre(p)
     if trace_units then
-        report_units("w: [%s], p: [%s]",wherefrom,p or "?")
+        report_units("p: [%s]",p or "?")
     end
     p = packaged_units[p] or p
     if p then
@@ -466,88 +679,103 @@ end
 --
 -- square centi meter per square kilo seconds
 
-local function update_parsers()
-
-    local long_prefixes_to_long  = { } for k, v in next, long_prefixes           do long_prefixes_to_long [lower(k)] = k                 end
-    local long_units_to_long     = { } for k, v in next, long_units              do long_units_to_long    [lower(k)] = k                 end
-    local long_operators_to_long = { } for k, v in next, long_operators          do long_operators_to_long[lower(k)] = k                 end
-    local short_prefixes         = { } for k, v in next, short_prefixes_to_long  do short_prefixes        [k]        = long_prefixes [v] end
-    local short_units            = { } for k, v in next, short_units_to_long     do short_units           [k]        = long_units    [v] end
-    local short_operators        = { } for k, v in next, short_operators_to_long do short_operators       [k]        = long_operators[v] end
-
-    mergetable(long_suffixes, loweredkeys(long_suffixes))
-    mergetable(symbol_units,  loweredkeys(symbol_units))
-    mergetable(packaged_units,loweredkeys(packaged_units))
-
-    prefixes   = long_prefixes   -- used in above functions
-    units      = long_units      -- used in above functions
-    operators  = long_operators  -- used in above functions
-    suffixes   = long_suffixes   -- used in above functions
-
-    local somespace  = P(" ")^0/""
-
-    local l_prefix   = appendlpeg(keys(long_prefixes))
-    local l_unit     = appendlpeg(keys(long_units))
-    local l_operator = appendlpeg(keys(long_operators))
-    local l_suffix   = appendlpeg(keys(long_suffixes))
-
-    local l_prefix   = appendlpeg(long_prefixes_to_long,l_prefix)
-    local l_unit     = appendlpeg(long_units_to_long,l_unit)
-    local l_operator = appendlpeg(long_operators_to_long,l_operator)
-
-    local s_prefix   = appendlpeg(short_prefixes_to_long)
-    local s_unit     = appendlpeg(short_units_to_long)
-    local s_operator = appendlpeg(short_operators_to_long)
-
-    local s_suffix   = appendlpeg(keys(short_suffixes))
-
-    local c_symbol   = appendlpeg(keys(symbol_units))
-    local p_unit     = appendlpeg(keys(packaged_units))
-
-    local combination = P { "start",
-        l_prefix = Cs(somespace * l_prefix) + Cc(""),
-        s_prefix = Cs(somespace * s_prefix) + Cc(""),
-        l_unit   = Cs(somespace * l_unit),
-        s_unit   = Cs(somespace * s_unit),
-        start    = V("l_prefix") * V("l_unit")   -- centi meter
-                 + V("s_prefix") * V("s_unit")   -- c m
-                 + V("l_prefix") * V("s_unit")   -- centi m
-                 + V("s_prefix") * V("l_unit"),  -- c meter
+-- todo 0x -> rm
+
+local function update_parsers() -- todo: don't remap utf sequences
+
+    local all_long_prefixes  = { }
+    local all_long_units     = { }
+    local all_long_operators = { }
+    local all_long_suffixes  = { }
+    local all_symbol_units   = { }
+    local all_packaged_units = { }
+
+    for k, v in next, long_prefixes  do all_long_prefixes [k] = v all_long_prefixes [lower(k)] = v end
+    for k, v in next, long_units     do all_long_units    [k] = v all_long_units    [lower(k)] = v end
+    for k, v in next, long_operators do all_long_operators[k] = v all_long_operators[lower(k)] = v end
+    for k, v in next, long_suffixes  do all_long_suffixes [k] = v all_long_suffixes [lower(k)] = v end
+    for k, v in next, symbol_units   do all_symbol_units  [k] = v all_symbol_units  [lower(k)] = v end
+    for k, v in next, packaged_units do all_packaged_units[k] = v all_packaged_units[lower(k)] = v end
+
+    local somespace        = P(" ")^0/""
+
+    local p_long_prefix    = appendlpeg(all_long_prefixes,nil,true)
+    local p_long_unit      = appendlpeg(all_long_units,nil,true)
+    local p_long_operator  = appendlpeg(all_long_operators,nil,true)
+    local p_long_suffix    = appendlpeg(all_long_suffixes,nil,true)
+    local p_symbol         = appendlpeg(all_symbol_units,nil,true)
+    local p_packaged       = appendlpeg(all_packaged_units,nil,true)
+
+    local p_short_prefix   = appendlpeg(short_prefixes)
+    local p_short_unit     = appendlpeg(short_units)
+    local p_short_operator = appendlpeg(short_operators)
+    local p_short_suffix   = appendlpeg(short_suffixes)
+
+    -- we can can cleanup some space issues here (todo)
+
+    local unitparser = P { "unit",
+        --
+        longprefix    = Cs(V("somespace") * p_long_prefix),
+        shortprefix   = Cs(V("somespace") * p_short_prefix),
+        longsuffix    = Cs(V("somespace") * p_long_suffix),
+        shortsuffix   = Cs(V("somespace") * p_short_suffix),
+        shortunit     = Cs(V("somespace") * p_short_unit),
+        longunit      = Cs(V("somespace") * p_long_unit),
+        longoperator  = Cs(V("somespace") * p_long_operator),
+        shortoperator = Cs(V("somespace") * p_short_operator),
+        packaged      = Cs(V("somespace") * p_packaged),
+        --
+        nothing       = Cc(""),
+        somespace     = somespace,
+        nospace       = (1-somespace)^0,
+        ignore        = P(-1),
+        --
+        somesymbol    = V("somespace")
+                      * (p_symbol/dimsym)
+                      * V("somespace"),
+        somepackaged  = V("somespace")
+                      * (V("packaged") / dimpre)
+                      * V("somespace"),
+        someunknown   = V("somespace")
+                      * (V("nospace")/unitsU)
+                      * V("somespace"),
+        --
+        combination   = V("longprefix")  * V("longunit")   -- centi meter
+                      + V("nothing")     * V("longunit")
+                      + V("shortprefix") * V("shortunit")  -- c m
+                      + V("nothing")     * V("shortunit")
+                      + V("longprefix")  * V("shortunit")  -- centi m
+                      + V("shortprefix") * V("longunit"),  -- c meter
+        dimension     = V("somespace")
+                      * (
+                            V("packaged") / dimpre
+                          + (V("longsuffix") * V("combination")) / dimspu
+                          + (V("combination") * (V("shortsuffix") + V("nothing"))) / dimpus
+                        )
+                      * V("somespace"),
+        operator      = V("somespace")
+                      * ((V("longoperator") + V("shortoperator")) / dimop)
+                      * V("somespace"),
+        snippet       = V("somesymbol")
+                      * V("dimension")
+                      + V("dimension")
+                      + V("somesymbol"),
+        unit          = V("snippet")^1
+                      * (V("operator") * V("snippet"))^-1 -- V("snippet")^1 ?
+                      + V("somesymbol")
+                      + V("somepackaged")
+                      + V("someunknown")
+                      + V("ignore"),
     }
 
-    local l_suffix   = Cs(somespace * l_suffix)
-    local s_suffix   = Cs(somespace * s_suffix) + Cc("")
-    local l_operator = Cs(somespace * l_operator)
-    local p_unit     = Cs(somespace * p_unit)
-
-    -- todo 0x -> rm
-    -- pretty large lpeg (maybe do dimension lookup otherwise)
-    -- not ok yet ... we have this p n s problem
-
-    local dimension = (p_unit                    * Carg(1)) / dimpre
-                    + ((l_suffix * combination)  * Carg(1)) / dimspu
-                    + ((combination * s_suffix)  * Carg(1)) / dimpus
-    local number    = lpeg.patterns.number                  / unitsN
-    local operator  = ((l_operator + s_operator) * Carg(1)) / dimop  -- weird, why is the extra C needed here
-    local whatever  = (P(1)^0)                              / unitsU
-    local symbol    = c_symbol                              / dimsym
-    local packaged  = p_unit                                / dimpre
-
-    local number    = (1-R("az","AZ")-P(" "))^1 / unitsN -- todo: catch { }
+-- lpeg.print(unitparser) -- 20111127: 2384 long
 
-    symbol    = somespace * symbol    * somespace
-    packaged  = somespace * packaged  * somespace
-    dimension = somespace * dimension * somespace
-    number    = somespace * number    * somespace
-    operator  = somespace * operator  * somespace
+    local number = lpeg.patterns.number
 
-    dimension = symbol * dimension + dimension + symbol -- too many space tests
-
-    local unitparser = dimension^1 * (operator * dimension^1)^-1 -- dimension^-1 ?
-                     + symbol
-                     + packaged
-                     + whatever
-                     + P(-1)
+    local number = Cs( P("$")     * (1-P("$"))^1 * P("$")
+                     + P([[\m{]]) * (1-P("}"))^1 * P("}")
+                     + (1-R("az","AZ")-P(" "))^1 -- todo: catch { } -- not ok
+                   ) / unitsN
 
     local p_c_unitdigitparser = (Cc(nil)/unitsNstart) * p_c_dparser * (Cc(nil)/unitsNstop) --
     local c_p_unitdigitparser = (Cc(nil)/unitsNstart) * c_p_dparser * (Cc(nil)/unitsNstop) --
@@ -562,7 +790,7 @@ local p_c_parser = nil
 local c_p_parser = nil
 local dirty      = true
 
-function commands.unit(str,wherefrom,p_c)
+function commands.unit(str,p_c)
     if dirty then
         if trace_units then
             report_units("initializing parser")
@@ -571,9 +799,9 @@ function commands.unit(str,wherefrom,p_c)
         dirty = false
     end
     if p_c == v_reverse then
-        matchlpeg(p_c_parser,str,1,wherefrom or "")
+        matchlpeg(p_c_parser,str)
     else
-        matchlpeg(c_p_parser,str,1,wherefrom or "")
+        matchlpeg(c_p_parser,str)
     end
 end
 
@@ -592,9 +820,9 @@ local t_units = {
 }
 
 local t_shortcuts = {
-    prefixes  = setmetatablenewindex(short_prefixes_to_long,trigger),
-    units     = setmetatablenewindex(short_units_to_long,trigger),
-    operators = setmetatablenewindex(short_operators_to_long,trigger),
+    prefixes  = setmetatablenewindex(short_prefixes,trigger),
+    units     = setmetatablenewindex(short_units,trigger),
+    operators = setmetatablenewindex(short_operators,trigger),
     suffixes  = setmetatablenewindex(short_suffixes,trigger),
 }
 
@@ -603,17 +831,25 @@ physics.units.tables = {
     shortcuts = t_shortcuts,
 }
 
+local mapping = {
+    prefix   = "prefixes",
+    unit     = "units",
+    operator = "operators",
+    suffixe  = "suffixes",
+    symbol   = "symbols",
+    packaged = "packaged",
+}
+
 function commands.registerunit(category,list)
     if not list or list == "" then
         list = category
-        category = "units"
+        category = "unit"
     end
-    local t = t_units[category]
+    local t = t_units[mapping[category]]
     if t then
         for k, v in next, utilities.parsers.settings_to_hash(list or "") do
             t[k] = v
         end
     end
-    inspect(tables)
+ -- inspect(tables)
 end
-
diff --git a/tex/context/base/phys-dim.mkiv b/tex/context/base/phys-dim.mkiv
index eaac72bb6..b31d746ba 100644
--- a/tex/context/base/phys-dim.mkiv
+++ b/tex/context/base/phys-dim.mkiv
@@ -86,48 +86,44 @@
 %D the grouped call.
 %D
 %D \starttabulate[|l|l|l|]
-%D \NC \type{.}  \NC , .           \NC comma or period            \NC \NR
-%D \NC \type{,}  \NC , .           \NC comma or period            \NC \NR
-%D \NC \type{@}  \NC               \NC invisible space            \NC \NR
-%D \NC \type{_}  \NC               \NC invisible space            \NC \NR
-%D \NC \type{/}  \NC               \NC invisible sign             \NC \NR
-%D \NC \type{-}  \NC $-$           \NC minus sign                 \NC \NR
-%D \NC \type{+}  \NC $+$           \NC plus sign                  \NC \NR
-%D \NC \type{//} \NC               \NC invisible high sign        \NC \NR
-%D \NC \type{--} \NC $\negative$   \NC high minus sign            \NC \NR
-%D \NC \type{++} \NC $\positive$   \NC high plus sign             \NC \NR
-%D \NC \type{=}  \NC $\zeroamount$ \NC zero padding               \NC \NR
+%D \starttabulate[|l|l|l|]
+%D \NC \type{.}  \NC , .           \NC comma or period     \NC \NR
+%D \NC \type{,}  \NC , .           \NC comma or period     \NC \NR
+%D \NC \type{:}  \NC               \NC invisible period    \NC \NR
+%D \NC \type{;}  \NC               \NC invisible comma     \NC \NR
+%D \NC \type{_}  \NC               \NC invisible space     \NC \NR
+%D \NC \type{/}  \NC               \NC invisible sign      \NC \NR
+%D \NC \type{-}  \NC $-$           \NC minus sign          \NC \NR
+%D \NC \type{+}  \NC $+$           \NC plus sign           \NC \NR
+%D \NC \type{//} \NC               \NC invisible high sign \NC \NR
+%D \NC \type{--} \NC $\negative$   \NC high minus sign     \NC \NR
+%D \NC \type{++} \NC $\positive$   \NC high plus sign      \NC \NR
+%D \NC \type{=}  \NC $\zeroamount$ \NC zero padding        \NC \NR
+%D \stoptabulate
 %D \stoptabulate
 %D
 %D These triggers are used in the following examples.
 %D
-%D \startbuffer
-%D \digits{12}
-%D \digits{~~~.~~~.~~~.68.712,34}
-%D \digits{___.___.111.68.712,34}
-%D \digits{111.111.111.68.712,34}
-%D \digits{12.345,90}
-%D \digits{12.345.000}
-%D \digits{12,34}
-%D \digits{392.857.230.68.712,34}
-%D \digits{1234}
-%D \digits{123.222,00}
-%D \digits{123.222,==}
-%D \digits{123.222,00^10}
-%D \digits{123.222,00e10}
-%D \digits{/123.222,00e-12}
-%D \digits{-123.222,00e-12}
-%D \digits{+123.222,00e-12}
-%D \digits{n123.222,00e-12}
-%D \digits{s123.222,00e-12}
-%D \digits{p123.222,00e-12}
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \startlines
-%D \getbuffer
-%D \stoplines
+%D \starttabulate[|l|r|]
+%D \NC \type{1}                      \NC \ruledhbox{\strut\digits{1}}                      \NC \NR
+%D \NC \type{12}                     \NC \ruledhbox{\strut\digits{12}}                     \NC \NR
+%D \NC \type{12.34}                  \NC \ruledhbox{\strut\digits{12.34}}                  \NC \NR
+%D \NC \type{123,456}                \NC \ruledhbox{\strut\digits{123,456}}                \NC \NR
+%D \NC \type{123,456.78}             \NC \ruledhbox{\strut\digits{123,456.78}}             \NC \NR
+%D \NC \type{12,34}                  \NC \ruledhbox{\strut\digits{12,34}}                  \NC \NR
+%D \NC \type{.1234}                  \NC \ruledhbox{\strut\digits{.1234}}                  \NC \NR
+%D \NC \type{1234}                   \NC \ruledhbox{\strut\digits{1234}}                   \NC \NR
+%D \NC \type{123,456.78^9}           \NC \ruledhbox{\strut\digits{123,456.78^9}}           \NC \NR
+%D \NC \type{123,456.78e9}           \NC \ruledhbox{\strut\digits{123,456.78e9}}           \NC \NR
+%D \NC \type{/123,456.78e-9}         \NC \ruledhbox{\strut\digits{/123,456.78e-9}}         \NC \NR
+%D \NC \type{-123,456.78e-9}         \NC \ruledhbox{\strut\digits{-123,456.78e-9}}         \NC \NR
+%D \NC \type{+123,456.78e-9}         \NC \ruledhbox{\strut\digits{+123,456.78e-9}}         \NC \NR
+%D \NC \type{//123,456.78e-9}        \NC \ruledhbox{\strut\digits{//123,456.78e-9}}        \NC \NR
+%D \NC \type{--123,456.78e-9}        \NC \ruledhbox{\strut\digits{--123,456.78e-9}}        \NC \NR
+%D \NC \type{++123,456.78e-9}        \NC \ruledhbox{\strut\digits{++123,456.78e-9}}        \NC \NR
+%D \NC \type{___,___,123,456,789.00} \NC \ruledhbox{\strut\digits{___,___,123,456,789.00}} \NC \NR
+%D \NC \type{___,___,_12,345,678.==} \NC \ruledhbox{\strut\digits{___,___,_12,345,678.==}} \NC \NR
+%D \stoptabulate
 
 \newconstant\c_digits_order
 \newconstant\c_digits_method
@@ -163,7 +159,7 @@
      \expandafter\high
    \fi}
 
-\unexpanded\def\digitszeropadding   {\zeroamount}
+\unexpanded\def\digitszeropadding   {\hphantom{0}}
 \unexpanded\def\digitsnegative      {\digits_normalized{0}{\digits_raised{\textminus}}}
 \unexpanded\def\digitspositive      {\digits_normalized{0}{\digits_raised{\textplus}}}
 \unexpanded\def\digitsnegative      {\digits_normalized{0}{\mathematics{\negative}}}
@@ -332,20 +328,22 @@
 
 % only a space when a number is part of the unit
 
-\installcommandhandler \??un {units} \??un
+\installcommandhandler \??un {unit} \??un
 
-\setupunits
-  [\c!alternative=,        % done: text
-   \c!separator=\v!normal, % done: cdot|big|medium|space
-   \c!label=,              % done: (no interface yet)
-   \c!order=\v!normal,     % ,. (reverse: .,)
+\setupunit
+  [\c!alternative=,              % done: text
+   \c!separator=\v!normal,       % done: cdot|big|medium|space
+   \s!language=\currentlanguage, % done: (no interface yet)
+   \c!order=\v!normal,           % ,. (reverse: .,)
    \c!method=0,
-  %\c!grid=\v!yes,         % (maybe)
-  %\c!style=...,           % done
-  %\c!color=...,           % done
-  %\c!space=...,           % (maybe) small medium big
+  %\c!grid=\v!yes,               % (maybe)
+  %\c!style=...,                 % done
+  %\c!color=...,                 % done
+  %\c!space=...,                 % (maybe) small medium big
   ]
 
+\let\setupunits\setupunit
+
 \newconstant   \c_units_mode   % 0=text 1=math 2=textinmath 3=mathintext
 \newconstant   \c_units_state  % 0=start 1=suffix 2=operator 3=unit 4=prefix 5=number
 \newconditional\c_units_quantity
@@ -367,7 +365,7 @@
   {\setvalue{\??un:1:#1}{#2}}
 
 \unexpanded\def\dounitsseparator
-  {\edef\currentunitsseparator{\unitsparameter\c!separator}%
+  {\edef\currentunitsseparator{\unitparameter\c!separator}%
    \csname\??un:1:%
      \ifcsname\??un:1:\currentunitsseparator\endcsname\currentunitsseparator\else\v!normal\fi
    \endcsname}
@@ -382,7 +380,7 @@
   {\setvalue{\??un:2:#1}{#2}}
 
 \unexpanded\def\dounitsspace
-  {\edef\currentunitsspace{\unitsparameter\c!space}%
+  {\edef\currentunitsspace{\unitparameter\c!space}%
    \csname\??un:2:%
      \ifcsname\??un:2:\currentunitsspace\endcsname\currentunitsspace\else\v!normal\fi
    \endcsname}
@@ -396,8 +394,8 @@
 \newtoks \everyunits % we keep the old \units command so we need a longer one
 
 \appendtoks
-    \setuevalue\currentunits{\units_direct{\currentunits}}
-\to \everydefineunits
+    \setuevalue\currentunit{\units_direct{\currentunit}}
+\to \everydefineunit
 
 \unexpanded\def\units_direct#1%
   {\begingroup
@@ -405,13 +403,16 @@
      \settrue\c_units_dospace
      \removelastskip
    \fi
-   \c_digits_method\unitsparameter\c!method\relax
+   \c_digits_method\unitparameter\c!method\relax
    \ifmmode\else\dontleavehmode\fi
-   \edef\currentunits{#1}%
+   \edef\currentunit{#1}%
+   \edef\unitlanguage{\unitparameter\s!language}%
+   \let\prefixlanguage\unitlanguage
+   \let\operatorlanguage\unitlanguage
    \the\everyunits
-  %\removeunwantedspaces % now ok yet
-   \dosetunitsattributes\c!style\c!color
-   \edef\currentunitsalternative{\unitsparameter\c!alternative}%
+  %\removeunwantedspaces % not ok yet
+   \dosetunitattributes\c!style\c!color
+   \edef\currentunitsalternative{\unitparameter\c!alternative}%
    \ifmmode
      \ifx\currentunitsalternative\v!text
        \expandafter\expandafter\expandafter\units_direct_text_in_math
@@ -436,7 +437,7 @@
 
 \unexpanded\def\units_direct_math#1%
   {\c_units_mode\plusone
-   \rm\tf
+   \rm\tf % slow
    \mathtf
    \units_indeed{#1}%
    \units_finish
@@ -465,21 +466,26 @@
     \let\units_direct\units_direct_nested
 \to \everyunits
 
-\unexpanded\def\units_indeed#1{\ctxcommand{unit(\!!bs\detokenize{#1}\!!es,"\unitsparameter\c!label","\unitsparameter\c!order")}}
+\unexpanded\def\units_indeed#1%
+  {\ctxcommand{unit(\!!bs\detokenize{#1}\!!es,"\unitparameter\c!order")}}
+
+\unexpanded\def\unitsPUS#1#2#3{\units_next\prefixtext{#1}\unittext{#2}\unitsraise{\suffixtext{#3}}\c_units_state\plusone} % suffix
+\unexpanded\def\unitsPU   #1#2{\units_next\prefixtext{#1}\unittext{#2}\c_units_state\plusthree}              % unit
+\unexpanded\def\unitsPS   #1#2{\units_next\prefixtext{#1}\unitsraise{\suffixtext{#2}}\c_units_state\plusone}              % suffix
+\unexpanded\def\unitsUS   #1#2{\units_next\unittext{#1}\unitsraise{\suffixtext{#2}}\c_units_state\plusone}                % suffix
+\unexpanded\def\unitsP      #1{\units_next\prefixtext{#1}1\c_units_state\plusfour}                           % prefix
+\unexpanded\def\unitsU      #1{\units_next\unittext{#1}\c_units_state\plusthree}                             % unit
+\unexpanded\def\unitsS      #1{\units_start{}\unitsraise{\suffixtext{#1}}\c_units_state\plusone}                          % suffix
+\unexpanded\def\unitsO      #1{\units_start\operatortext{#1}\c_units_state\plustwo}                          % operator
+\unexpanded\def\unitsN      #1{\units_start#1\c_units_state\plusfive}                                        % number
+\unexpanded\def\unitsC      #1{\removeunwantedspaces\unittext{#1}\c_units_state\plussix}                     % connected
 
-\unexpanded\def\unitsPUS#1#2#3{\units_next#1#2\unitsraise{#3}\c_units_state\plusone}   % suffix
-\unexpanded\def\unitsPU   #1#2{\units_next#1#2\c_units_state               \plusthree} % unit
-\unexpanded\def\unitsPS   #1#2{\units_next#1\unitsraise{#2}\c_units_state  \plusone}   % suffix
-\unexpanded\def\unitsUS   #1#2{\units_next#1\unitsraise{#2}\c_units_state  \plusone}   % suffix
-\unexpanded\def\unitsP      #1{\units_next#1\c_units_state                 \plusfour}  % prefix
-\unexpanded\def\unitsU      #1{\units_next#1\c_units_state                 \plusthree} % unit
-\unexpanded\def\unitsS      #1{\units_start{}\unitsraise{#1}\c_units_state \plusone}   % suffix
-\unexpanded\def\unitsO      #1{\units_start#1\c_units_state                \plustwo}   % operator
-\unexpanded\def\unitsN      #1{\units_start#1\c_units_state                \plusfive}  % number
-\unexpanded\def\unitsC      #1{\removeunwantedspaces#1\c_units_state       \plussix}   % connected
+% hm, textacute also not present in some fonts
 
 \unexpanded\def\checkedtextprime      {\iffontchar\font"2032′\else\textacute\fi}
 \unexpanded\def\checkedtextdoubleprime{\iffontchar\font"2033″\else\textacute\kern-.25em\textacute\fi}
+\unexpanded\def\checkedtextcelsius    {\iffontchar\font"2103℃\else °C\fi}
+\unexpanded\def\checkedtextfahrenheit {\iffontchar\font"2109℉\else °F\fi}
 
 \setelementnature[unit]    [mixed]
 \setelementnature[quantity][mixed]
@@ -593,20 +599,42 @@
    {/}%
    }%\unitsbackspace}
 
+\definelabelclass [unit]     [2]
+\definelabelclass [operator] [2]
+\definelabelclass [prefix]   [2]
+\definelabelclass [suffix]   [2] % This is only a label because we want to show them in a table.
+
+\ctxlua{
+    languages.labels.define("setupprefixtext","prefixes")%
+    languages.labels.define("setupunittext","units")%
+    languages.labels.define("setupoperatortext","operators")%
+    languages.labels.define("setupsuffixtext","suffixes")%
+}
+
 %D You can define additional units:
 %D
 %D \starttyping
 %D \registerunit
-%D   [units]
+%D   [unit]
+%D   [point=point,
+%D    basepoint=basepoint,
+%D    scaledpoint=scaledpoint,
+%D    didot=didot,
+%D    cicero=cicero]
+%D \stoptyping
+%D
+%D Possible categories are: \type {prefix}, \type {unit}, \type {operator},
+%D \type {suffix}, \type {symbol},\type {packaged}. You also need to define
+%D labels:
+%D
+%D \starttyping
+%D \setupunittext
 %D   [point=pt,
 %D    basepoint=bp,
 %D    scaledpoint=sp,
 %D    didot=dd,
 %D    cicero=cc]
 %D \stoptyping
-%D
-%D Possible categories are: \type {prefixes}, \type {units}, \type {operators},
-%D \type {suffixes}, \type {symbols},\type {packaged}.
 
 \unexpanded\def\registerunit
   {\dodoubleempty\register_unit}
@@ -624,7 +652,7 @@
 
 %D Now we define the standard units command:
 
-\defineunits
+\defineunit
   [unit]
 
 %D Example:
diff --git a/tex/context/base/s-phy-01.mkiv b/tex/context/base/s-phy-01.mkiv
index 789aeb187..dde3f9bbb 100644
--- a/tex/context/base/s-phy-01.mkiv
+++ b/tex/context/base/s-phy-01.mkiv
@@ -18,64 +18,74 @@
 \startluacode
 moduledata.units = moduledata.units or { }
 
-local tables = physics.units.tables
+local tables    = physics.units.tables
+local units     = tables.units
+local shortcuts = tables.shortcuts
 
 local HL = context.HL
 local NC = context.NC
 local NR = context.NR
 
-local function typeset(category,name,list,followup)
-    if followup then
-        context.TB()
-    end
-    HL()
-    NC()
-    context.rlap(category .. ":" .. name)
-    NC()
-    NC()
-    NR()
-    HL()
-    for k, v in table.sortedhash(list) do
-        NC()
-        context(k)
-        NC()
-        if isunit then
-            context(v)
-        else
-            context.type(v)
+local function typeset(list,followup,name,category)
+    if list then
+        if followup then
+            context.TB()
+        end
+        if category then
+            HL()
+            NC()
+            context.rlap(category .. ":" .. name)
+            NC()
+            NC()
+            NR()
+            HL()
+        end
+        for k, v in table.sortedhash(list) do
+            NC()
+            context(k)
+            NC()
+            if isunit then
+                context(v)
+            else
+                context.type(v)
+            end
+            NC()
+            if name == "units" or name == "symbols" or name == "packaged" then
+                context.unittext(v)
+            elseif name == "prefixes" then
+                context.prefixtext(v)
+            elseif name == "operators" then
+                context.operatortext(v)
+            elseif name == "suffixes" then
+                context.suffixtext(v)
+            end
+            NC()
+            NR()
+        end
+        if category and name then
+            HL()
         end
-        NC()
-        NR()
     end
-    HL()
 end
 
 function moduledata.units.show_table(name)
-    context.starttabulate { "|lT|l|" }
+    context.starttabulate { "|lT|l|c|" }
     if name and name ~= "" then
-        local first, second = string.match("(.-):(.-)")
+        local first, second = string.match(name,"(.-):(.-)") -- [units|shortcuts]:[units|...]
         if first then
-            local t = tables[first]
-            if t then
-                t = t[second]
-            end
-            if t then
-                typeset(first,second,t,false)
-            end
+            typeset(tables[first] and tables[first][second],false)
         else
-            local t = tables.entries[name]
-            if t then
-                typeset("entries",name,t,false)
-            end
+            typeset(units[name],false)
+            typeset(shortcuts[name],true)
         end
     else
         local done = false
-        for what, list in table.sortedhash(tables.units) do
-            typeset("units",what,list,done)
+        for what, list in table.sortedhash(units) do
+            typeset(list,done,what,"units")
             done = true
         end
-        for what, list in table.sortedhash(tables.shortcuts) do
-            typeset("shortcuts",what,list,done)
+        for what, list in table.sortedhash(shortcuts) do
+            typeset(list,done,what,"shortcuts")
             done = true
         end
     end
diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf
index 329a70948..a4cfc9fe9 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 68547675c..9f4eb79ff 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 22585b465..34bcf0538 100644
--- a/tex/context/base/strc-flt.mkvi
+++ b/tex/context/base/strc-flt.mkvi
@@ -336,6 +336,7 @@
          \global\nofloatcaptiontrue
        \fi
      \else
+       \global\emptyfloatcaptionfalse
        \setbox\float_caption_box\hbox{\hskip\leftskip\box\float_caption_box}%
      \fi
    \fi}
@@ -709,9 +710,9 @@
       \globallet\currentfloatattribute  \empty
       \globallet\currentfloatsynchronize\relax
    \else
-     \ifnofloatnumber \else
-       \doincrementsubstructurecounter[\@@thestructurecounter\currentfloat][1]%
-     \fi
+      \ifnofloatnumber \else \ifnofloatcaption \else
+        \doincrementsubstructurecounter[\@@thestructurecounter\currentfloat][1]%
+      \fi \fi
      \dostructurecountercomponent
        {float}%
        \setupcurrentfloatcaption
diff --git a/tex/context/base/type-otf.mkiv b/tex/context/base/type-otf.mkiv
index 141d860c8..e7a473cfb 100644
--- a/tex/context/base/type-otf.mkiv
+++ b/tex/context/base/type-otf.mkiv
@@ -662,7 +662,7 @@
         \definetypeface [dejavu] [rm] [serif] [dejavu] [default]
         \definetypeface [dejavu] [ss] [sans]  [dejavu] [default]
         \definetypeface [dejavu] [tt] [mono]  [dejavu] [default]
-        \definetypeface [dejavu] [mm] [math]  [xits]   [default] [rscale=auto]
+        \definetypeface [dejavu] [mm] [math]  [xits]   [default] [rscale=1.2]
     \stoptypescript
 
     \starttypescript [serif] [dejavu-condensed] [name]
@@ -707,7 +707,7 @@
         \definetypeface [dejavu-condensed] [rm] [serif] [dejavu-condensed] [default]
         \definetypeface [dejavu-condensed] [ss] [sans]  [dejavu-condensed] [default]
         \definetypeface [dejavu-condensed] [tt] [mono]  [dejavu-condensed] [default]
-        \definetypeface [dejavu-condensed] [mm] [math]  [xits]             [default] [rscale=auto]
+        \definetypeface [dejavu-condensed] [mm] [math]  [xits]             [default] [rscale=1.2]
     \stoptypescript
 
 \stoptypescriptcollection
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index c09168701..907b4fd81 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/25/11 21:29:42
+-- merge date  : 11/29/11 18:47:56
 
 do -- begin closure to overcome local limits and interference
 
@@ -1695,32 +1695,72 @@ function lpeg.is_lpeg(p)
     return p and lpegtype(p) == "pattern"
 end
 
--- For the moment here, but it might move to utilities:
+-- For the moment here, but it might move to utilities. Beware, we need to
+-- have the longest keyword first, so 'aaa' comes beforte 'aa' which is why we
+-- loop back from the end.
 
-local sort, fastcopy, sortedpairs = table.sort, table.fastcopy, table.sortedpairs -- dependency!
+local sort, fastcopy, sortedkeys = table.sort, table.fastcopy, table.sortedkeys -- dependency!
 
-function lpeg.append(list,pp,delayed)
+function lpeg.append(list,pp,delayed,checked)
     local p = pp
     if #list > 0 then
-        list = fastcopy(list)
-        sort(list)
-        for l=1,#list do
+        local keys = fastcopy(list)
+        sort(keys)
+        for i=#keys,1,-1 do
+            local k = keys[i]
             if p then
-                p = P(list[l]) + p
+                p = P(k) + p
             else
-                p = P(list[l])
+                p = P(k)
             end
         end
-    elseif delayed then
-        for k, v in sortedpairs(list) do
-            if p then
+    elseif delayed then -- hm, it looks like the lpeg parser resolves anyway
+        local keys = sortedkeys(list)
+        if p then
+            for i=#keys,1,-1 do
+                local k = keys[i]
+                local v = list[k]
                 p = P(k)/list + p
+            end
+        else
+            for i=#keys,1,-1 do
+                local k = keys[i]
+                local v = list[k]
+                if p then
+                    p = P(k) + p
+                else
+                    p = P(k)
+                end
+            end
+            if p then
+                p = p / list
+            end
+        end
+    elseif checked then
+        -- problem: substitution gives a capture
+        local keys = sortedkeys(list)
+        for i=#keys,1,-1 do
+            local k = keys[i]
+            local v = list[k]
+            if p then
+                if k == v then
+                    p = P(k) + p
+                else
+                    p = P(k)/v + p
+                end
             else
-                p = P(k)/list
+                if k == v then
+                    p = P(k)
+                else
+                    p = P(k)/v
+                end
             end
         end
     else
-        for k, v in sortedpairs(list) do
+        local keys = sortedkeys(list)
+        for i=#keys,1,-1 do
+            local k = keys[i]
+            local v = list[k]
             if p then
                 p = P(k)/v + p
             else
-- 
cgit v1.2.3