summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/typo-duc.lua
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2019-01-28 13:43:45 +0100
committerContext Git Mirror Bot <phg@phi-gamma.net>2019-01-28 13:43:45 +0100
commit8bbd1dc6d3db576e4313277ac558f8fe7e0595ef (patch)
treefe409ac17c124c50163b1af03809554b9f80b4b5 /tex/context/base/mkiv/typo-duc.lua
parent55575b7cad42dac55b4a5f699c33363489cb502d (diff)
downloadcontext-8bbd1dc6d3db576e4313277ac558f8fe7e0595ef.tar.gz
2019-01-28 12:34:00
Diffstat (limited to 'tex/context/base/mkiv/typo-duc.lua')
-rw-r--r--tex/context/base/mkiv/typo-duc.lua84
1 files changed, 50 insertions, 34 deletions
diff --git a/tex/context/base/mkiv/typo-duc.lua b/tex/context/base/mkiv/typo-duc.lua
index 597042b37..c1338d0d1 100644
--- a/tex/context/base/mkiv/typo-duc.lua
+++ b/tex/context/base/mkiv/typo-duc.lua
@@ -66,6 +66,7 @@ local getchar = nuts.getchar
local getattr = nuts.getattr
local getprop = nuts.getprop
local getdirection = nuts.getdirection
+local isglyph = nuts.isglyph
local setprop = nuts.setprop
local setchar = nuts.setchar
@@ -247,16 +248,16 @@ end
-- tracking what direction is used and skipping tests is not faster (extra kind of
-- compensates gain)
-local mt_space = { __index = { char = 0x0020, direction = "ws", original = "ws", level = 0 } }
-local mt_lre = { __index = { char = 0x202A, direction = "lre", original = "lre", level = 0 } }
-local mt_rle = { __index = { char = 0x202B, direction = "rle", original = "rle", level = 0 } }
-local mt_pdf = { __index = { char = 0x202C, direction = "pdf", original = "pdf", level = 0 } }
-local mt_object = { __index = { char = 0xFFFC, direction = "on", original = "on", level = 0 } }
+local mt_space = { __index = { char = 0x0020, direction = "ws", original = "ws", level = 0, skip = 0 } }
+local mt_lre = { __index = { char = 0x202A, direction = "lre", original = "lre", level = 0, skip = 0 } }
+local mt_rle = { __index = { char = 0x202B, direction = "rle", original = "rle", level = 0, skip = 0 } }
+local mt_pdf = { __index = { char = 0x202C, direction = "pdf", original = "pdf", level = 0, skip = 0 } }
+local mt_object = { __index = { char = 0xFFFC, direction = "on", original = "on", level = 0, skip = 0 } }
local stack = table.setmetatableindex("table") -- shared
local list = { } -- shared
-local function build_list(head) -- todo: store node pointer ... saves loop
+local function build_list(head,where) -- todo: store node pointer ... saves loop
-- P1
local current = head
local size = 0
@@ -265,6 +266,7 @@ local function build_list(head) -- todo: store node pointer ... saves loop
local id = getid(current)
local p = properties[current]
if p and p.directions then
+ -- tricky as dirs can be injected in between
local skip = 0
local last = id
current = getnext(current)
@@ -287,6 +289,7 @@ local function build_list(head) -- todo: store node pointer ... saves loop
elseif id == glyph_code then
local chr = getchar(current)
local dir = directiondata[chr]
+ -- could also be a metatable
list[size] = { char = chr, direction = dir, original = dir, level = 0 }
current = getnext(current)
-- if not list[dir] then list[dir] = true end -- not faster when we check for usage
@@ -296,9 +299,9 @@ local function build_list(head) -- todo: store node pointer ... saves loop
elseif id == dir_code then
local dir, pop = getdirection(current)
if dir == lefttoright_code then
- list[size] = setmetatable({ },swap and mt_pdf or mt_lre)
+ list[size] = setmetatable({ },pop and mt_pdf or mt_lre)
elseif dir == righttoleft_code then
- list[size] = setmetatable({ },swap and mt_pdf or mt_rle)
+ list[size] = setmetatable({ },pop and mt_pdf or mt_rle)
else
list[size] = setmetatable({ id = id },mt_object)
end
@@ -353,6 +356,7 @@ end
local function resolve_fences(list,size,start,limit)
-- N0: funny effects, not always better, so it's an option
+ local stack = { }
local nofstack = 0
for i=start,limit do
local entry = list[i]
@@ -368,7 +372,6 @@ local function resolve_fences(list,size,start,limit)
local stacktop = stack[nofstack]
stacktop[1] = mirror
stacktop[2] = i
- stacktop[3] = false -- not used
elseif nofstack == 0 then
-- skip
elseif class == "close" then
@@ -411,15 +414,15 @@ local function get_baselevel(head,list,size,direction)
return direction, true
elseif getid(head) == localpar_code and getsubtype(head) == 0 then
direction = getdirection(head)
- if direction == righttoleft_code or direction == lefttoright_code then
+ if direction == lefttoright_code or direction == righttoleft_code then
return direction, true
end
end
-- for old times sake we we handle strings too
if direction == "TLT" then
- return righttoleft_code, true
- elseif direction == "TRT" then
return lefttoright_code, true
+ elseif direction == "TRT" then
+ return righttoleft_code, true
end
-- P2, P3:
for i=1,size do
@@ -505,7 +508,7 @@ local function resolve_explicit(list,size,baselevel)
end
-- X7
elseif direction == "pdf" then
- if nofstack < maximum_stack then
+ if nofstack > 0 then
local stacktop = stack[nofstack]
level = stacktop[1]
override = stacktop[2]
@@ -514,7 +517,11 @@ local function resolve_explicit(list,size,baselevel)
entry.direction = "bn"
entry.remove = true
elseif trace_directions then
- report_directions("stack overflow at position %a with direction %a",i,direction)
+ report_directions("stack underflow at position %a with direction %a",
+ i, direction)
+ else
+ report_directions("stack underflow at position %a with direction %a: %s",
+ i, direction, show_list(list,size))
end
-- X6
else
@@ -899,6 +906,10 @@ local function insert_dir_points(list,size)
end
end
+-- We flag nodes that can be skipped when we see them again but because whatever
+-- mechanism can injetc dir nodes that then are not flagged, we don't flag dir
+-- nodes that we inject here.
+
local function apply_to_list(list,size,head,pardir)
local index = 1
local current = head
@@ -914,7 +925,12 @@ local function apply_to_list(list,size,head,pardir)
local entry = list[index]
local begindir = entry.begindir
local enddir = entry.enddir
- local p = properties[current] if p then p.directions = true else properties[current] = { directions = true } end
+ local p = properties[current]
+ if p then
+ p.directions = true
+ else
+ properties[current] = { directions = true }
+ end
if id == glyph_code then
local mirror = entry.mirror
if mirror then
@@ -939,40 +955,33 @@ local function apply_to_list(list,size,head,pardir)
elseif id == glue_code then
if enddir and getsubtype(current) == parfillskip_code then
-- insert the last enddir before \parfillskip glue
- local d = new_direction(enddir,true)
- local p = properties[d] if p then p.directions = true else properties[d] = { directions = true } end
- -- setattrlist(d,current)
- head = insert_node_before(head,current,d)
+ head = insert_node_before(head,current,new_direction(enddir,true))
enddir = false
end
elseif begindir then
if id == localpar_code and getsubtype(current) == 0 then
-- localpar should always be the 1st node
- local d = new_direction(begindir)
- local p = properties[d] if p then p.directions = true else properties[d] = { directions = true } end
- -- setattrlist(d,current)
- head, current = insert_node_after(head,current,d)
+ head, current = insert_node_after(head,current,new_direction(begindir))
begindir = nil
end
end
if begindir then
- local d = new_direction(begindir)
- local p = properties[d] if p then p.directions = true else properties[d] = { directions = true } end
- -- setattrlist(d,current)
- head = insert_node_before(head,current,d)
+ head = insert_node_before(head,current,new_direction(begindir))
end
local skip = entry.skip
if skip and skip > 0 then
for i=1,skip do
current = getnext(current)
- local p = properties[current] if p then p.directions = true else properties[current] = { directions = true } end
+ local p = properties[current]
+ if p then
+ p.directions = true
+ else
+ properties[current] = { directions = true }
+ end
end
end
if enddir then
- local d = new_direction(enddir,true)
- local p = properties[d] if p then p.directions = true else properties[d] = { directions = true } end
- -- setattrlist(d,current)
- head, current = insert_node_after(head,current,d)
+ head, current = insert_node_after(head,current,new_direction(enddir,true))
end
if not entry.remove then
current = getnext(current)
@@ -996,12 +1005,19 @@ end
-- have more than one node. Actually, we only enter this function when we
-- do have a glyph!
-local function process(head,direction,only_one)
+local function process(head,direction,only_one,where)
+
+-- print("START")
+-- for n in nodes.traverse(nodes.tonode(head)) do
+-- print(" "..tostring(n))
+-- end
+-- print("STOP")
+
-- for the moment a whole paragraph property
local attr = getattr(head,a_directions)
local analyze_fences = getfences(attr)
--
- local list, size = build_list(head)
+ local list, size = build_list(head,where)
local baselevel, dirfound = get_baselevel(head,list,size,direction) -- we always have an inline dir node in context
if trace_details then
report_directions("analyze: baselevel %a",baselevel == righttoleft_code and "r2l" or "l2r")