diff options
author | Hans Hagen <pragma@wxs.nl> | 2013-09-11 01:32:00 +0200 |
---|---|---|
committer | Hans Hagen <pragma@wxs.nl> | 2013-09-11 01:32:00 +0200 |
commit | 22352fedfedda2f3a89bedcdfcf715aa944ce227 (patch) | |
tree | 91d1fb817acfd89c0400c375a70586c4a939897c | |
parent | c43315bbcee9c1216def83861317eae1729a16d2 (diff) | |
download | context-22352fedfedda2f3a89bedcdfcf715aa944ce227.tar.gz |
beta 2013.09.11 01:32
-rw-r--r-- | tex/context/base/context-version.pdf | bin | 4108 -> 4104 bytes | |||
-rw-r--r-- | tex/context/base/font-pre.mkiv | 6 | ||||
-rw-r--r-- | tex/context/base/phys-dim.lua | 2 | ||||
-rw-r--r-- | tex/context/base/status-files.pdf | bin | 24764 -> 24791 bytes | |||
-rw-r--r-- | tex/context/base/typo-dha.lua | 388 | ||||
-rw-r--r-- | tex/context/base/typo-dir.lua | 34 | ||||
-rw-r--r-- | tex/context/base/typo-dua.lua | 39 | ||||
-rw-r--r-- | tex/context/base/typo-dub.lua | 103 |
8 files changed, 241 insertions, 331 deletions
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf Binary files differindex dfd432aed..21b7ddaa1 100644 --- a/tex/context/base/context-version.pdf +++ b/tex/context/base/context-version.pdf 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 Binary files differindex 229f9506b..1d72a62ec 100644 --- a/tex/context/base/status-files.pdf +++ b/tex/context/base/status-files.pdf 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 |