From 5644affdd299c0567ee215dfefcb58f8e813330d Mon Sep 17 00:00:00 2001
From: Marius <mariausol@gmail.com>
Date: Wed, 11 Sep 2013 02:40:24 +0300
Subject: beta 2013.09.11 01:32

---
 tex/context/base/cont-new.mkiv                     |   2 +-
 tex/context/base/context-version.pdf               | Bin 4108 -> 4104 bytes
 tex/context/base/context.mkiv                      |   2 +-
 tex/context/base/font-pre.mkiv                     |   6 +
 tex/context/base/phys-dim.lua                      |   2 +-
 tex/context/base/status-files.pdf                  | Bin 24764 -> 24791 bytes
 tex/context/base/status-lua.log                    |   2 +-
 tex/context/base/typo-dha.lua                      | 388 ++++++++-------------
 tex/context/base/typo-dir.lua                      |  34 +-
 tex/context/base/typo-dua.lua                      |  39 +--
 tex/context/base/typo-dub.lua                      | 103 +++---
 tex/generic/context/luatex/luatex-fonts-merged.lua |   2 +-
 12 files changed, 245 insertions(+), 335 deletions(-)

diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv
index 1cd7ef578..d0472ac24 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{2013.09.10 18:06}
+\newcontextversion{2013.09.11 01:32}
 
 %D This file is loaded at runtime, thereby providing an excellent place for
 %D hacks, patches, extensions and new features.
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf
index dfd432aed..21b7ddaa1 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.mkiv b/tex/context/base/context.mkiv
index 7a6459fbe..5ec23b41c 100644
--- a/tex/context/base/context.mkiv
+++ b/tex/context/base/context.mkiv
@@ -25,7 +25,7 @@
 %D up and the dependencies are more consistent.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2013.09.10 18:06}
+\edef\contextversion{2013.09.11 01:32}
 \edef\contextkind   {beta}
 
 %D For those who want to use this:
diff --git a/tex/context/base/font-pre.mkiv b/tex/context/base/font-pre.mkiv
index 659c4840e..d8ef47e41 100644
--- a/tex/context/base/font-pre.mkiv
+++ b/tex/context/base/font-pre.mkiv
@@ -273,6 +273,12 @@
 \definecolor[font:8] [g=.75]
 \definecolor[font:9] [b=.75]
 
+\definecolor[bidi:left:original] [r=.6]
+\definecolor[bidi:left:reversed] [g=.6]
+\definecolor[bidi:right:original][b=.6]
+\definecolor[bidi:right:reversed][r=.6,g=.6]
+\definecolor[bidi:mirrored]      [r=.6,b=.6]
+
 %D Now we're up to some definitions.
 
 \definebodyfontenvironment
diff --git a/tex/context/base/phys-dim.lua b/tex/context/base/phys-dim.lua
index 123593ca8..24d0b9231 100644
--- a/tex/context/base/phys-dim.lua
+++ b/tex/context/base/phys-dim.lua
@@ -578,7 +578,7 @@ labels.units = allocate {
     lumen                       = { labels = { en = [[lm]]                       } },
     lux                         = { labels = { en = [[lx]]                       } },
     bequerel                    = { labels = { en = [[Bq]]                       } },
-    gray                        = { labels = { en = [[Gr]]                       } },
+    gray                        = { labels = { en = [[Gy]]                       } },
     sievert                     = { labels = { en = [[Sv]]                       } },
     katal                       = { labels = { en = [[kat]]                      } },
     minute                      = { labels = { en = [[min]]                      } },
diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf
index 229f9506b..1d72a62ec 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.log b/tex/context/base/status-lua.log
index c10777f85..55ea9f960 100644
--- a/tex/context/base/status-lua.log
+++ b/tex/context/base/status-lua.log
@@ -1,6 +1,6 @@
 (cont-yes.mkiv
 
-ConTeXt  ver: 2013.09.10 18:06 MKIV beta  fmt: 2013.9.10  int: english/english
+ConTeXt  ver: 2013.09.11 01:32 MKIV beta  fmt: 2013.9.11  int: english/english
 
 system          > 'cont-new.mkiv' loaded
 (cont-new.mkiv)
diff --git a/tex/context/base/typo-dha.lua b/tex/context/base/typo-dha.lua
index 131db28df..06a1cb957 100644
--- a/tex/context/base/typo-dha.lua
+++ b/tex/context/base/typo-dha.lua
@@ -40,21 +40,23 @@ if not modules then modules = { } end modules ['typo-dha'] = {
 -- todo  : swappable tables and floats i.e. start-end overloads (probably loop in builders)
 -- todo  : check if we still have crashes in luatex when non-matched (used to be the case)
 
+-- I removed the original tracing code and now use the colorful one. If I ever want to change
+-- something I will just inject prints for tracing.
+
 local nodes, node = nodes, node
 
 local trace_directions   = false  trackers.register("typesetters.directions.default", function(v) trace_directions = v end)
 
 local report_directions  = logs.reporter("typesetting","text directions")
 
-local hasbit             = number.hasbit
-local formatters         = string.formatters
-local insert             = table.insert
 
 local insert_node_before = nodes.insert_before
 local insert_node_after  = nodes.insert_after
 local remove_node        = nodes.remove
 local end_of_math        = nodes.end_of_math
 
+local nodepool           = nodes.pool
+
 local nodecodes          = nodes.nodecodes
 local whatcodes          = nodes.whatcodes
 local mathcodes          = nodes.mathcodes
@@ -71,10 +73,12 @@ local vlist_code         = nodecodes.vlist
 local localpar_code      = whatcodes.localpar
 local dir_code           = whatcodes.dir
 
-local nodepool           = nodes.pool
-
 local new_textdir        = nodepool.textdir
 
+local hasbit             = number.hasbit
+local formatters         = string.formatters
+local insert             = table.insert
+
 local fonthashes         = fonts.hashes
 local fontdata           = fonthashes.identifiers
 local fontchar           = fonthashes.characters
@@ -84,6 +88,7 @@ local charmirrors        = characters.mirrors
 local charclasses        = characters.textclasses
 
 local directions         = typesetters.directions
+local setcolor           = directions.setcolor
 local getglobal          = directions.getglobal
 
 local a_state            = attributes.private('state')
@@ -93,43 +98,54 @@ local strip              = false
 
 local s_isol             = fonts.analyzers.states.isol
 
-local function process(namespace,attribute,start)
+local function stopdir(finish)
+    return new_textdir(finish == "TRT" and "-TRT" or "-TLT")
+end
+
+local function startdir(finish)
+    return new_textdir(finish == "TRT" and "+TRT" or "+TLT")
+end
 
-    local head = start
+local function process(namespace,attribute,start)
 
-    local current, inserted = head, nil
-    local finish, autodir, embedded, override, done = nil, 0, 0, 0, false
-    local list, glyphs = trace_directions and { }, false
-    local finished, finidir, finipos = nil, nil, 1
-    local stack, top, obsolete = { }, 0, { }
-    local lro, rlo, prevattr = false, false, 0
-    local fences = { }
+    local head     = start
+
+    local current  = head
+    local inserted = nil
+    local finish   = nil
+    local autodir  = 0
+    local embedded = 0
+    local override = 0
+    local pardir   = 1
+    local textdir  = 1
+    local done     = false
+    local finished = nil
+    local finidir  = nil
+    local stack    = { }
+    local top      = 0
+    local obsolete = { }
+    local lro      = false
+    local lro      = false
+    local prevattr = false
+    local fences   = { }
 
     local function finish_auto_before()
-        local fdir = finish == "TRT" and "-TRT" or "-TLT"
-        head, inserted = insert_node_before(head,current,new_textdir(fdir))
+        head, inserted = insert_node_before(head,current,stopdir(finish))
         finished, finidir, autodir = inserted, finish, 0
-        if trace_directions then
-            insert(list,#list,formatters["auto %a inserted before, autodir %a, embedded %a"](fdir,autodir,embedded))
-            finipos = #list - 1
-        end
         finish, done = nil, true
     end
 
     local function finish_auto_after()
-        local fdir = finish == "TRT" and "-TRT" or "-TLT"
-        head, current = insert_node_after(head,current,new_textdir(fdir))
+        head, current = insert_node_after(head,current,stopdir(finish))
         finished, finidir, autodir = current, finish, 0
-        if trace_directions then
-            list[#list+1] = formatters["auto %a inserted after, autodir %a, embedded %a"](fdir,autodir,embedded)
-            finipos = #list
-        end
         finish, done = nil, true
     end
 
-    local function force_auto_left_before(d)
+    local function force_auto_left_before(direction)
         if finish then
-            finish_auto_before()
+            head, inserted = insert_node_before(head,current,stopdir(finish))
+            finished = inserted
+            finidir  = finish
         end
         if embedded >= 0 then
             finish, autodir = "TLT",  1
@@ -139,21 +155,16 @@ local function process(namespace,attribute,start)
         done = true
         if finidir == finish then
             head = remove_node(head,finished,true)
-            if trace_directions then
-                list[finipos] = list[finipos] .. ", deleted afterwards"
-                insert(list,#list,formatters["start text dir %a, auto left before, embedded %a, autodir %a, triggered by class %a"](finish,embedded,autodir,d))
-            end
         else
-            head, inserted = insert_node_before(head,current,new_textdir("+"..finish))
-            if trace_directions then
-                insert(list,#list,formatters["start text dir %a, auto left before, embedded %a, autodir %a, triggered by class %a"](finish,embedded,autodir,d))
-            end
+            head, inserted = insert_node_before(head,current,startdir(finish))
         end
     end
 
-    local function force_auto_right_before(d)
+    local function force_auto_right_before(direction)
         if finish then
-            finish_auto_before()
+            head, inserted = insert_node_before(head,current,stopdir(finish))
+            finished = inserted
+            finidir  = finish
         end
         if embedded <= 0 then
             finish, autodir, done = "TRT", -1
@@ -163,267 +174,183 @@ local function process(namespace,attribute,start)
         done = true
         if finidir == finish then
             head = remove_node(head,finished,true)
-            if trace_directions then
-                list[finipos] = list[finipos] .. ", deleted afterwards"
-                insert(list,#list,formatters["start text dir %a, auto right before, embedded %a, autodir %a, triggered by class %a"](finish,embedded,autodir,d))
-            end
         else
-            head, inserted = insert_node_before(head,current,new_textdir("+"..finish))
-            if trace_directions then
-                insert(list,#list,formatters["start text dir %a, auto right before, embedded %a, autodir %a, triggered by class %a"](finish,embedded,autodir,d))
-            end
+            head, inserted = insert_node_before(head,current,startdir(finish))
         end
     end
 
     local function nextisright(current)
-     -- repeat
-            current = current.next
-            local id = current.id
-            if id == glyph_code then
-                local char = current.char
-                local d = chardirections[char]
-                return d == "r" or d == "al" or d == "an"
-         -- elseif id == glue_code or id == kern_code or id == penalty_code then
-         --   -- too complex and doesn't cover bounds anyway
-     --     else
-     --         return
-            end
-     -- until not current
+        current = current.next
+        local id = current.id
+        if id == glyph_code then
+            local character = current.char
+            local direction = chardirections[character]
+            return direction == "r" or direction == "al" or direction == "an"
+        end
     end
 
     local function previsright(current)
-     -- repeat
-            current = current.prev
-            local id = current.id
-            if id == glyph_code then
-                local char = current.char
-                local d = chardirections[char]
-                return d == "r" or d == "al" or d == "an"
-         -- elseif id == glue_code or id == kern_code or id == penalty_code then
-         --   -- too complex and doesn't cover bounds anyway
-     --     else
-     --         return
-            end
-     -- until not current
+        current = current.prev
+        local id = current.id
+        if id == glyph_code then
+            local char = current.char
+            local direction = chardirections[character]
+            return direction == "r" or direction == "al" or direction == "an"
+        end
     end
 
     while current do
         local id = current.id
-     -- list[#list+1] = formatters["state: node %a, finish %a, autodir %a, embedded %a"](nutstring(current),finish or "unset",autodir,embedded)
         if id == math_code then
             current = end_of_math(current.next).next
         else
             local attr = current[attribute]
             if attr and attr > 0 and attr ~= prevattr then
-                if getglobal(a) then
-                    -- bidi parsing mode
-                else
-                    -- local
-                    if trace_directions and
-                        current ~= head then list[#list+1] = formatters["override reset, bidi %a"](attr)
-                    end
+                if not getglobal(a) then
                     lro, rlo = false, false
                 end
                 prevattr = attr
             end
-         -- if attr and attr > 0 then
-         --     if attr == 1 then
-         --         -- bidi parsing mode
-         --     elseif attr ~= prevattr then
-         --         -- no pop, grouped driven (2=normal,3=lro,4=rlo)
-         --         if attr == 3 then
-         --             if trace_directions then
-         --                 list[#list+1] = formatters["override right -> left (lro), bidi %a"](attr)
-         --             end
-         --             lro, rlo = true, false
-         --         elseif attr == 4 then
-         --             if trace_directions then
-         --                 list[#list+1] = formatters["override left -> right (rlo), bidi %a"](attr)
-         --             end
-         --             lro, rlo = false, true
-         --         else
-         --             if trace_directions and
-         --                 current ~= head then list[#list+1] = formatters["override reset, bidi %a"](attr)
-         --             end
-         --             lro, rlo = false, false
-         --         end
-         --         prevattr = attr
-         --     end
-         -- end
             if id == glyph_code then
-                glyphs = true
                 if attr and attr > 0 then
-                    local char = current.char
-                    local d = chardirections[char]
+                    local character = current.char
+                    local direction = chardirections[character]
+                    local reversed  = false
                     if rlo or override > 0 then
-                        if d == "l" then
-                            if trace_directions then
-                                list[#list+1] = formatters["char %C of class %a overridden to r, bidi %a)"](char,d,attr)
-                            end
-                            d = "r"
-                        elseif trace_directions then
-                            if d == "lro" or d == "rlo" or d == "pdf" then -- else side effects on terminal
-                                list[#list+1] = formatters["override char of class %a, bidi %a"](d,attr)
-                            else -- todo: rle lre
-                                list[#list+1] = formatters["char %C of class %a, bidi %a"](char,d,attr)
-                            end
+                        if direction == "l" then
+                            direction = "r"
+                            reversed = true
                         end
                     elseif lro or override < 0 then
-                        if d == "r" or d == "al" then
-                            current[a_state] = s_isol -- maybe better have a special bidi attr value -> override (9) -> todo
-                            if trace_directions then
-                                list[#list+1] = formatters["char %C of class %a overridden to l, bidi %a, state 'isol'"](char,d,attr)
-                            end
-                            d = "l"
-                        elseif trace_directions then
-                            if d == "lro" or d == "rlo" or d == "pdf" then -- else side effects on terminal
-                                list[#list+1] = formatters["override char of class %a, bidi %a"](d,attr)
-                            else -- todo: rle lre
-                                list[#list+1] = formatters["char %C of class %a, bidi %a"](char,d,attr)
-                            end
-                        end
-                    elseif trace_directions then
-                        if d == "lro" or d == "rlo" or d == "pdf" then -- else side effects on terminal
-                            list[#list+1] = formatters["override char of class %a, bidi %a"](d,attr)
-                        else -- todo: rle lre
-                            list[#list+1] = formatters["char %C of class %a, bidi %a"](char,d,attr)
+                        if direction == "r" or direction == "al" then
+                            current[a_state] = s_isol
+                            direction = "l"
+                            reversed = true
                         end
                     end
-                    if d == "on" then
-                        local mirror = charmirrors[char]
+                    if direction == "on" then
+                        local mirror = charmirrors[character]
                         if mirror and fontchar[current.font][mirror] then
-                            -- for the moment simple stacking
-                            local class = charclasses[char]
+                            local class = charclasses[character]
                             if class == "open" then
-                                fences[#fences+1] = autodir
                                 if nextisright(current) then
                                     if autodir >= 0 then
-                                        force_auto_right_before(d)
+                                        force_auto_right_before(direction)
                                     end
                                     current.char = mirror
                                     done = true
+                                elseif autodir < 0 then
+                                    current.char = mirror
+                                    done = true
                                 else
-                                    mirror = nil
-                                    if autodir <= 0 then
-                                        force_auto_left_before(d)
-                                    end
+                                    mirror = false
                                 end
+                                local fencedir = autodir == 0 and textdir or autodir
+                                fences[#fences+1] = fencedir
                             elseif class == "close" and #fences > 0 then
-                                local prevdir = fences[#fences]
+                                local fencedir = fences[#fences]
                                 fences[#fences] = nil
-                                if prevdir < 0 then
+                                if fencedir < 0 then
                                     current.char = mirror
                                     done = true
-                                    if autodir >= 0 then
-                                        -- a bit tricky but ok for simple cases
-                                        force_auto_right_before(d)
-                                    end
+                                    force_auto_right_before(direction)
                                 else
-                                    mirror = nil
+                                    mirror = false
                                 end
                             elseif autodir < 0 then
                                 current.char = mirror
                                 done = true
                             else
-                                mirror = nil
-                            end
-                            if trace_directions then
-                                if mirror then
-                                    list[#list+1] = formatters["mirroring char %C of class %a to %C, autodir %a, bidi %a"](char,d,mirror,autodir,attr)
-                                else
-                                    list[#list+1] = formatters["not mirroring char %C of class %a, autodir %a, bidi %a"](char,d,autodir,attr)
-                                end
+                                mirror = false
                             end
                         end
-                    elseif d == "l" or d == "en" then -- european number
+                        if trace_directions then
+                            setcolor(current,direction,false,mirror)
+                        end
+                    elseif direction == "l" then
+                        if trace_directions then
+                            setcolor(current,"l",reversed)
+                        end
                         if autodir <= 0 then -- could be option
-                            force_auto_left_before(d)
+                            force_auto_left_before(direction)
+                        end
+                    elseif direction == "r" then
+                        if trace_directions then
+                            setcolor(current,"r",reversed)
                         end
-                    elseif d == "r" or d == "al" then -- arabic number
                         if autodir >= 0 then
-                            force_auto_right_before(d)
+                            force_auto_right_before(direction)
+                        end
+                    elseif direction == "en" then -- european number
+                        if trace_directions then
+                            setcolor(current,"l")
+                        end
+                        if autodir <= 0 then -- could be option
+                            force_auto_left_before(direction)
+                        end
+                    elseif direction == "al" then -- arabic number
+                        if trace_directions then
+                            setcolor(current,"r")
                         end
-                    elseif d == "an" then -- arabic number
-                        -- actually this is language dependent ...
-                     -- if autodir <= 0 then
-                     --     force_auto_left_before(d)
-                     -- end
                         if autodir >= 0 then
-                            force_auto_right_before(d)
+                            force_auto_right_before(direction)
                         end
-                    elseif d == "lro" then -- Left-to-Right Override -> right becomes left
+                    elseif direction == "an" then -- arabic number
                         if trace_directions then
-                            list[#list+1] = "override right -> left"
+                            setcolor(current,"r")
                         end
+                        if autodir >= 0 then
+                            force_auto_right_before(direction)
+                        end
+                    elseif direction == "lro" then -- Left-to-Right Override -> right becomes left
                         top = top + 1
                         stack[top] = { override, embedded }
                         override = -1
                         obsolete[#obsolete+1] = current
-                    elseif d == "rlo" then -- Right-to-Left Override -> left becomes right
-                        if trace_directions then
-                            list[#list+1] = "override left -> right"
-                        end
+                    elseif direction == "rlo" then -- Right-to-Left Override -> left becomes right
                         top = top + 1
                         stack[top] = { override, embedded }
                         override = 1
                         obsolete[#obsolete+1] = current
-                    elseif d == "lre" then -- Left-to-Right Embedding -> TLT
-                        if trace_directions then
-                            list[#list+1] = "embedding left -> right"
-                        end
+                    elseif direction == "lre" then -- Left-to-Right Embedding -> TLT
                         top = top + 1
                         stack[top] = { override, embedded }
                         embedded = 1
                         obsolete[#obsolete+1] = current
-                    elseif d == "rle" then -- Right-to-Left Embedding -> TRT
-                        if trace_directions then
-                            list[#list+1] = "embedding right -> left"
-                        end
+                    elseif direction == "rle" then -- Right-to-Left Embedding -> TRT
                         top = top + 1
                         stack[top] = { override, embedded }
-                        embedded = -1 -- was 1
+                        embedded = -1
                         obsolete[#obsolete+1] = current
-                    elseif d == "pdf" then -- Pop Directional Format
-                     -- override = 0
+                    elseif direction == "pdf" then -- Pop Directional Format
                         if top > 0 then
                             local s = stack[top]
                             override, embedded = s[1], s[2]
                             top = top - 1
-                            if trace_directions then
-                                list[#list+1] = formatters["state: override %a, embedded %a, autodir %a"](override,embedded,autodir)
-                            end
-                        else
-                            if trace_directions then
-                                list[#list+1] = "pop error: too many pops"
-                            end
                         end
                         obsolete[#obsolete+1] = current
+                    else
+                        setcolor(current)
                     end
-                elseif trace_directions then
-                    local char = current.char
-                    local d = chardirections[char]
-                    list[#list+1] = formatters["char %C of class %a, bidi %a"](char,d or "?")
+                else
+                    -- we do nothing
                 end
             elseif id == whatsit_code then
-                -- we have less directions now so we can do hard checks for strings instead of splitting into pieces
-                if finish then
-                    finish_auto_before()
-                end
                 local subtype = current.subtype
                 if subtype == localpar_code then
-                 -- if false then
-                        local dir = current.dir
-                        if dir == 'TRT' then
-                            autodir = -1
-                        elseif dir == 'TLT' then
-                            autodir = 1
-                        end
-                    -- embedded = autodir
-                        if trace_directions then
-                            list[#list+1] = formatters["pardir %a"](dir)
-                        end
-                 -- end
+                    local dir = current.dir
+                    if dir == 'TRT' then
+                        autodir = -1
+                    elseif dir == 'TLT' then
+                        autodir = 1
+                    end
+                    pardir = autodir
+                    textdir = pardir
                 elseif subtype == dir_code then
+                    -- todo: also treat as lro|rlo and stack
+                    if finish then
+                        finish_auto_before()
+                    end
                     local dir = current.dir
                     if dir == "+TRT" then
                         finish, autodir = "TRT", -1
@@ -434,36 +361,25 @@ local function process(namespace,attribute,start)
                     elseif dir == "-TLT" then
                         finish, autodir = nil, 0
                     end
-                    if trace_directions then
-                        list[#list+1] = formatters["textdir %a, autodir %a"](dir,autodir)
+                    textdir = autodir
+                else
+                    if finish then
+                        finish_auto_before()
                     end
                 end
-            else
-                if trace_directions then
-                    list[#list+1] = formatters["node %a, subtype %a"](nodecodes[id],current.subtype)
-                end
-                if finish then
-                    finish_auto_before()
-                end
+            elseif finish then
+                finish_auto_before()
             end
             local cn = current.next
-            if not cn then
-                if finish then
-                    finish_auto_after()
-                end
+            if cn then
+                -- we're okay
+            elseif finish then
+                finish_auto_after()
             end
             current = cn
         end
     end
 
-    if trace_directions and glyphs then
-        report_directions("start log")
-        for i=1,#list do
-            report_directions("%02i: %s",i,list[i])
-        end
-        report_directions("stop log")
-    end
-
     if done and strip then
         local n = #obsolete
         if n > 0 then
diff --git a/tex/context/base/typo-dir.lua b/tex/context/base/typo-dir.lua
index aa6eb2eeb..312342348 100644
--- a/tex/context/base/typo-dir.lua
+++ b/tex/context/base/typo-dir.lua
@@ -26,7 +26,6 @@ if not modules then modules = { } end modules ['typo-dir'] = {
 -- = half tagging (the current implementation)
 -- = unicode version x interpretation (several depending on the evolution)
 
-
 local next, type = next, type
 local format, insert, sub, find, match = string.format, table.insert, string.sub, string.find, string.match
 local utfchar = utf.char
@@ -42,6 +41,8 @@ local report_textdirections = logs.reporter("typesetting","text directions")
 local report_mathdirections = logs.reporter("typesetting","math directions")
 
 
+
+
 local traverse_id        = node.traverse_id
 local insert_node_before = node.insert_before
 local insert_node_after  = node.insert_after
@@ -59,6 +60,9 @@ local whatcodes          = nodes.whatcodes
 local mathcodes          = nodes.mathcodes
 
 local tasks              = nodes.tasks
+local tracers            = nodes.tracers
+local setcolor           = tracers.colors.set
+local resetcolor         = tracers.colors.reset
 
 local glyph_code         = nodecodes.glyph
 local whatsit_code       = nodecodes.whatsit
@@ -163,6 +167,28 @@ directions.getfences      = getfences
 directions.getmethod      = getmethod
 directions.installhandler = installhandler
 
+-- beware: in dha we have character properties and in dua|b we have direction properties
+
+function directions.setcolor(current,direction,reversed,mirror)
+    if mirror then
+        setcolor(current,"bidi:mirrored")
+    elseif direction == "l" then
+        if reversed then
+            setcolor(current,"bidi:left:reversed")
+        else
+            setcolor(current,"bidi:left:original")
+        end
+    elseif direction == "r" then
+        if reversed then
+            setcolor(current,"bidi:right:reversed")
+        else
+            setcolor(current,"bidi:right:original")
+        end
+    else
+        resetcolor(current)
+    end
+end
+
 function commands.getbidimode(specification)
     context(tomode(specification)) -- hash at tex end
 end
@@ -191,6 +217,12 @@ function directions.process(namespace,attribute,head) -- for the moment nodes an
     return head, done
 end
 
+statistics.register("text directions", function()
+    if enabled then
+        return statistics.elapsedseconds(directions)
+    end
+end)
+
 -- function directions.enable()
 --     tasks.enableaction("processors","directions.handler")
 -- end
diff --git a/tex/context/base/typo-dua.lua b/tex/context/base/typo-dua.lua
index 8eb0a7859..73ed9f886 100644
--- a/tex/context/base/typo-dua.lua
+++ b/tex/context/base/typo-dua.lua
@@ -90,10 +90,8 @@ local parfillskip_code    = skipcodes.skipcodes
 ----- object_replacement  = 0xFFFC -- object replacement character
 local maximum_stack       = 60     -- probably spec but not needed
 
-local setcolor            = nodes.tracers.colors.set
-local resetcolor          = nodes.tracers.colors.reset
-
 local directions          = typesetters.directions
+local setcolor            = directions.setcolor
 
 local a_directions        = attributes.private('directions')
 
@@ -214,12 +212,12 @@ local function build_list(head) -- todo: store node pointer ... saves loop
             current = current.next
         elseif id == math_code then
             local skip = 0
-            current = current.next
+            current    = current.next
             while current.id ~= math_code do
-                skip = skip + 1
+                skip    = skip + 1
                 current = current.next
             end
-            skip = skip + 1
+            skip    = skip + 1
             current = current.next
             list[size] = { char = 0xFFFC, direction = "on", original = "on", level = 0, skip = skip, id = id }
         else
@@ -290,15 +288,8 @@ local function find_run_limit_b_s_ws_on(list,start,limit)
     return start
 end
 
--- directions.maindir = "r2l"
-
 local function get_baselevel(head,list,size) -- todo: skip if first is object (or pass head and test for local_par)
-    local maindir = directions.maindir
-    if maindir == "r2l" then
-        return 1, "TRT", false
-    elseif maindir == "l2r" then
-        return 0, "TLT", false
-    elseif head.id == whatsit_code and head.subtype == localpar_code then
+    if head.id == whatsit_code and head.subtype == localpar_code then
         if head.dir == "TRT" then
             return 1, "TRT", true
         else
@@ -696,28 +687,10 @@ local function apply_to_list(list,size,head,pardir)
                 current.char = mirror
             end
             if trace_directions then
-                local original  = entry.original
                 local direction = entry.direction
-                if mirror then
-                    setcolor(current,"trace:dc")
-                elseif direction == "l" then
-                    if original == direction then
-                        setcolor(current,"trace:dr")
-                    else
-                        setcolor(current,"trace:dm")
-                    end
-                elseif direction == "r" then
-                    if original == direction then
-                        setcolor(current,"trace:db")
-                    else
-                        setcolor(current,"trace:dg")
-                    end
-                else
-                    resetcolor(current)
-                end
+                setcolor(current,direction,direction ~= entry.original,mirror)
             end
         elseif id == hlist_code or id == vlist_code then
-         -- current.list = process(current.list) -- not needed
             current.dir = pardir -- is this really needed?
         elseif id == glue_code then
             if enddir and current.subtype == parfillskip_code then
diff --git a/tex/context/base/typo-dub.lua b/tex/context/base/typo-dub.lua
index 19f109470..b78694173 100644
--- a/tex/context/base/typo-dub.lua
+++ b/tex/context/base/typo-dub.lua
@@ -30,7 +30,6 @@ if not modules then modules = { } end modules ['typo-dub'] = {
 -- todo: no need for a max check
 -- todo: collapse bound similar ranges (not ok yet)
 -- todo: combine some sweeps
--- todo: add fence parser
 -- todo: removing is not needed when we inject at the same spot (only chnage the dir property)
 -- todo: isolated runs (isolating runs are similar to bidi=local in the basic analyzer)
 
@@ -45,10 +44,10 @@ if not modules then modules = { } end modules ['typo-dub'] = {
 -- Modifies Rule X10 to make the isolating run sequence the unit to which subsequent rules are applied.
 -- Modifies Rule W1 to change an NSM preceded by an isolate initiator or PDI into ON.
 -- Adds Rule N0 and makes other changes to Section 3.3.5, Resolving Neutral and Isolate Formatting Types to resolve bracket pairs to the same level.
--- Adds the new ARABIC LETTER MARK (U+061C) character to Section 2.6, Implicit Directional Marks and Table 4 Bidirectional Character Types.
 
 local insert, remove, unpack, concat = table.insert, table.remove, table.unpack, table.concat
 local utfchar = utf.char
+local setmetatable = setmetatable
 local formatters = string.formatters
 
 local directiondata       = characters.directions
@@ -78,12 +77,8 @@ local parfillskip_code    = skipcodes.skipcodes
 
 local maximum_stack       = 0xFF -- unicode: 60, will be jumped to 125, we don't care too much
 
-local setcolor            = nodes.tracers.colors.set
-local resetcolor          = nodes.tracers.colors.reset
-
 local directions          = typesetters.directions
-directions.maindir        = nil -- not used
-
+local setcolor            = directions.setcolor
 local getfences           = directions.getfences
 
 local a_directions        = attributes.private('directions')
@@ -230,6 +225,16 @@ end
 -- char is only used for mirror, so in fact we can as well only store it for
 -- glyphs only
 
+-- using metatable is slightly faster so maybe some day ...
+
+-- local space  = { char = 0x0020, direction = "ws",  original = "ws"  }
+-- local lre    = { char = 0x202A, direction = "lre", original = "lre" }
+-- local lre    = { char = 0x202B, direction = "rle", original = "rle" }
+-- local pdf    = { char = 0x202C, direction = "pdf", original = "pdf" }
+-- local object = { char = 0xFFFC, direction = "on",  original = "on"  }
+--
+-- local t = { level = 0 } setmetatable(t,space) list[size] = t
+
 local function build_list(head) -- todo: store node pointer ... saves loop
     -- P1
     local current = head
@@ -262,11 +267,11 @@ local function build_list(head) -- todo: store node pointer ... saves loop
             local skip = 0
             current = current.next
             while current.id ~= math_code do
-                skip = skip + 1
+                skip    = skip + 1
                 current = current.next
             end
-            skip = skip + 1
-            current = current.next
+            skip       = skip + 1
+            current    = current.next
             list[size] = { char = 0xFFFC, direction = "on", original = "on", level = 0, skip = skip, id = id }
         else
             local skip = 0
@@ -307,7 +312,7 @@ end
 -- ש ( ל [ א ] כ ) 2-8,4-6
 
 function resolve_fences(list,size,start,limit)
-    -- N0
+    -- N0: funny effects, not always better, so it's an options
     local stack = { }
     local top   = 0
     for i=start,limit do
@@ -325,40 +330,42 @@ function resolve_fences(list,size,start,limit)
                 elseif top == 0 then
                     -- skip
                 elseif class == "close" then
-                    for j=top,1,-1 do
-                        top = j
-                        local s = stack[j]
-                        if s[1] == char and not s[3] then
-                            s[3] = i
+                    while top > 0 do
+                        local s = stack[top]
+                        if s[1] == char then
+                            local open  = s[2]
+                            local close = i
+                            list[open ].paired = close
+                            list[close].paired = open
                             break
+                        else
+                            -- do we mirror or not
                         end
+                        top = top - 1
                     end
                 end
             end
         end
     end
-    for i=1,#stack do
-        local s = stack[i]
-        if s[3] then
-            local open  = s[2]
-            local close = s[3]
-            list[open ].paired = close
-            list[close].paired = open
-        end
-    end
---  inspect(stack)
---  inspect(list)
 end
 
+-- local function test_fences(str)
+--     local list  = { }
+--     for s in string.gmatch(str,".") do
+--         local b = utf.byte(s)
+--         list[#list+1] = { c = s, char = b, direction = directiondata[b] }
+--     end
+--     resolve_fences(list,#list,1,#size)
+--     inspect(list)
+-- end
+--
+-- test_fences("a(b)c(d)e(f(g)h)i")
+-- test_fences("a(b[c)d]")
+
 -- the action
 
 local function get_baselevel(head,list,size) -- todo: skip if first is object (or pass head and test for local_par)
-    local maindir = directions.maindir
-    if maindir == "r2l" then
-        return 1, "TRT", false
-    elseif maindir == "l2r" then
-        return 0, "TLT", false
-    elseif head.id == whatsit_code and head.subtype == localpar_code then
+	if head.id == whatsit_code and head.subtype == localpar_code then
         if head.dir == "TRT" then
             return 1, "TRT", true
         else
@@ -522,10 +529,8 @@ local function resolve_weak(list,size,start,limit,orderbefore,orderafter)
     local i = start
     while i <= limit do
         if list[i].direction == "et" then
-            local runstart     = i
-         -- local runlimit     = find_run_limit_et(list,runstart,limit) -- when moved inline we can probably collapse a lot
-
-            local runlimit     = runstart
+            local runstart = i
+            local runlimit = runstart
             for i=runstart,limit do
                 if list[i].direction == "et" then
                     runlimit = i
@@ -533,7 +538,6 @@ local function resolve_weak(list,size,start,limit,orderbefore,orderafter)
                     break
                 end
             end
-
             local rundirection = runstart == start and sor or list[runstart-1].direction
             if rundirection ~= "en" then
                 rundirection = runlimit == limit and orderafter or list[runlimit+1].direction
@@ -581,8 +585,6 @@ local function resolve_neutral(list,size,start,limit,orderbefore,orderafter)
         if b_s_ws_on[entry.direction] then
             local leading_direction, trailing_direction, resolved_direction
             local runstart = i
-         -- local runlimit = find_run_limit_b_s_ws_on(list,runstart,limit)
-
             local runlimit = runstart
             for i=runstart,limit do
                 if b_s_ws_on[list[i].direction] then
@@ -591,7 +593,6 @@ local function resolve_neutral(list,size,start,limit,orderbefore,orderafter)
                     break
                 end
             end
-
             if runstart == start then
                 leading_direction = sor
             else
@@ -794,28 +795,10 @@ local function apply_to_list(list,size,head,pardir)
                 current.char = mirror
             end
             if trace_directions then
-                local original  = entry.original
                 local direction = entry.direction
-                if mirror then
-                    setcolor(current,"trace:dc")
-                elseif direction == "l" then
-                    if original == direction then
-                        setcolor(current,"trace:dr")
-                    else
-                        setcolor(current,"trace:dm")
-                    end
-                elseif direction == "r" then
-                    if original == direction then
-                        setcolor(current,"trace:db")
-                    else
-                        setcolor(current,"trace:dg")
-                    end
-                else
-                    resetcolor(current)
-                end
+                setcolor(current,direction,direction ~= entry.original,mirror)
             end
         elseif id == hlist_code or id == vlist_code then
-         -- current.list = process(current.list) -- not needed
             current.dir = pardir -- is this really needed?
         elseif id == glue_code then
             if enddir and current.subtype == parfillskip_code then
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 4b07240c1..7cbb28798 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  : 09/10/13 18:06:22
+-- merge date  : 09/11/13 01:32:13
 
 do -- begin closure to overcome local limits and interference
 
-- 
cgit v1.2.3