summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/node-rul.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/node-rul.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/node-rul.lua247
1 files changed, 168 insertions, 79 deletions
diff --git a/Master/texmf-dist/tex/context/base/node-rul.lua b/Master/texmf-dist/tex/context/base/node-rul.lua
index 9dd89bcdae3..4cbd1ad0c5f 100644
--- a/Master/texmf-dist/tex/context/base/node-rul.lua
+++ b/Master/texmf-dist/tex/context/base/node-rul.lua
@@ -8,73 +8,115 @@ if not modules then modules = { } end modules ['node-rul'] = {
-- this will go to an auxiliary module
-- beware: rules now have a dir field
+--
+-- todo: make robust for layers ... order matters
+
+local attributes, nodes, node = attributes, nodes, node
+
+local nodecodes = nodes.nodecodes
+local tasks = nodes.tasks
-local glyph = node.id("glyph")
-local disc = node.id("disc")
-local rule = node.id("rule")
+local glyph_code = nodecodes.glyph
+local disc_code = nodecodes.disc
+local rule_code = nodecodes.rule
-function nodes.strip_range(first,last) -- todo: dir
+function nodes.striprange(first,last) -- todo: dir
if first and last then -- just to be sure
- local current = first
- while current and current ~= last do
- local id = current.id
- if id == glyph or id == disc then
- --~ if id == glyph or id == rule or id == disc then
- first = current
+ if first == last then
+ return first, last
+ end
+ while first and first ~= last do
+ local id = first.id
+ if id == glyph_code or id == disc_code then -- or id == rule_code
break
else
- current = current.next
+ first = first.next
end
end
- local current = last
- while current and current ~= first do
- local id = current.id
- --~ if id == glyph or id == rule or id == disc then
- if id == glyph or id == disc then
- last = current
+ if not first then
+ return nil, nil
+ elseif first == last then
+ return first, last
+ end
+ while last and last ~= first do
+ local id = last.id
+ if id == glyph_code or id == disc_code then -- or id == rule_code
break
else
- current = current.prev
+local prev = last.prev -- luatex < 0.70 has italic correction kern not prev'd
+if prev then
+ last = last.prev
+else
+ break
+end
end
end
+ if not last then
+ return nil, nil
+ end
end
return first, last
end
-- todo: order and maybe other dimensions
-local trace_ruled = false trackers.register("nodes.ruled", function(v) trace_ruled = v end)
-
local floor = math.floor
-local n_tostring, n_tosequence = nodes.ids_tostring, nodes.tosequence
-
-local a_ruled = attributes.private('ruled')
-local a_color = attributes.private('color')
-local a_transparency = attributes.private('transparency')
-local a_colorspace = attributes.private('colormodel')
-
-local glyph = node.id("glyph")
-local disc = node.id("disc")
-local glue = node.id("glue")
-local penalty = node.id("penalty")
-local kern = node.id("kern")
-local hlist = node.id("hlist")
-local vlist = node.id("vlist")
-local rule = node.id("rule")
-local whatsit = node.id("whatsit")
-
-local new_rule = nodes.rule
-local new_kern = nodes.kern
-local new_glue = nodes.glue
-
-local insert_before, insert_after, strip_range = node.insert_before, node.insert_after, nodes.strip_range
-local list_dimensions, has_attribute, set_attribute = node.dimensions, node.has_attribute, node.set_attribute
-local hpack_nodes = node.hpack
-local dimenfactor = fonts.dimenfactor
-local texwrite = tex.write
-
-local fontdata = fonts.ids
-local variables = interfaces.variables
+
+local trace_ruled = false trackers.register("nodes.rules", function(v) trace_ruled = v end)
+
+local report_ruled = logs.reporter("nodes","rules")
+
+local n_tostring = nodes.idstostring
+local n_tosequence = nodes.tosequence
+
+local a_ruled = attributes.private('ruled')
+local a_color = attributes.private('color')
+local a_transparency = attributes.private('transparency')
+local a_colorspace = attributes.private('colormodel')
+
+local texwrite = tex.write
+
+local insert_before = node.insert_before
+local insert_after = node.insert_after
+local striprange = nodes.striprange
+local list_dimensions = node.dimensions
+local has_attribute = node.has_attribute
+local set_attribute = node.set_attribute
+
+local hpack_nodes = node.hpack
+
+local fontdata = fonts.hashes.identifiers
+local variables = interfaces.variables
+local dimenfactor = fonts.helpers.dimenfactor
+
+local nodecodes = nodes.nodecodes
+local skipcodes = nodes.skipcodes
+local whatcodes = nodes.whatcodes
+local kerncodes = nodes.kerncodes
+
+local glyph_code = nodecodes.glyph
+local disc_code = nodecodes.disc
+local glue_code = nodecodes.glue
+local penalty_code = nodecodes.penalty
+local kern_code = nodecodes.kern
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local rule_code = nodecodes.rule
+local whatsit_code = nodecodes.whatsit
+
+local userskip_code = skipcodes.userskip
+local spaceskip_code = skipcodes.spaceskip
+local xspaceskip_code = skipcodes.xspaceskip
+
+local dir_code = whatcodes.dir
+
+local kerning_code = kerncodes.kern
+
+local nodepool = nodes.pool
+
+local new_rule = nodepool.rule
+local new_kern = nodepool.kern
+local new_glue = nodepool.glue
-- we can use this one elsewhere too
--
@@ -86,15 +128,22 @@ local checkdir = true
-- we assume {glyphruns} and no funny extra kerning, ok, maybe we need
-- a dummy character as start and end; anyway we only collect glyphs
+--
+-- this one needs to take layers into account (i.e. we need a list of
+-- critical attributes)
-local function process_words(attribute,data,flush,head,parent) -- we have hlistdir and local dir
+-- omkeren class en level -> scheelt functie call in analyze
+
+-- todo: switching inside math
+
+local function processwords(attribute,data,flush,head,parent) -- we have hlistdir and local dir
local n = head
if n then
- local f, l, a, d, i, level
- local continue, done, strip = false, false, false
+ local f, l, a, d, i, class
+ local continue, done, strip, level = false, false, true, -1
while n do
local id = n.id
- if id == glyph or id == rule then
+ if id == glyph_code or id == rule_code then
local aa = has_attribute(n,attribute)
if aa then
if aa == a then
@@ -104,12 +153,18 @@ local function process_words(attribute,data,flush,head,parent) -- we have hlistd
l = n
else
-- possible extensions: when in same class then keep spanning
+ local newlevel, newclass = floor(aa/1000), aa%1000
+--~ strip = not continue or level == 1 -- 0
if f then
- head, done = flush(head,f,l,d,level,parent,strip), true
+ if class == newclass then -- and newlevel > level then
+ head, done = flush(head,f,l,d,level,parent,false), true
+ else
+ head, done = flush(head,f,l,d,level,parent,strip), true
+ end
end
f, l, a = n, n, aa
- level, i = floor(a/1000), a%1000
- d = data[i]
+ level, class = newlevel, newclass
+ d = data[class]
continue = d.continue == variables.yes
end
else
@@ -118,27 +173,37 @@ local function process_words(attribute,data,flush,head,parent) -- we have hlistd
end
f, l, a = nil, nil, nil
end
- elseif f and (id == disc or (id == kern and n.subtype == 0)) then
+ elseif f and (id == disc_code or (id == kern_code and n.subtype == kerning_code)) then
l = n
- elseif id == hlist or id == vlist then
+ elseif id == hlist_code or id == vlist_code then
if f then
head, done = flush(head,f,l,d,level,parent,strip), true
f, l, a = nil, nil, nil
end
local list = n.list
if list then
- n.list = process_words(attribute,data,flush,list,n)
+ n.list = processwords(attribute,data,flush,list,n)
end
- elseif checkdir and id == whatsit and n.subtype == 7 then -- only changes in dir, we assume proper boundaries
+ elseif checkdir and id == whatsit_code and n.subtype == dir_code then -- only changes in dir, we assume proper boundaries
if f and a then
l = n
end
elseif f then
if continue then
- if id == penalty or id == kern then
+ if id == penalty_code then
l = n
- elseif id == glue then
+ elseif id == kern_code then
l = n
+ elseif id == glue_code then
+ -- catch \underbar{a} \underbar{a} (subtype test is needed)
+ local subtype = n.subtype
+ if continue and has_attribute(n,attribute) and
+ (subtype == userskip_code or subtype == spaceskip_code or subskip == xspaceskip_code) then
+ l = n
+ else
+ head, done = flush(head,f,l,d,level,parent,strip), true
+ f, l, a = nil, nil, nil
+ end
end
else
head, done = flush(head,f,l,d,level,parent,strip), true
@@ -156,7 +221,7 @@ local function process_words(attribute,data,flush,head,parent) -- we have hlistd
end
end
-nodes.process_words = process_words
+nodes.processwords = processwords
--
@@ -172,16 +237,32 @@ function nodes.rules.define(settings)
texwrite(#data)
end
+local a_viewerlayer = attributes.private("viewerlayer")
+
local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but acceptable for this purpose
-- check for f and l
+ if f.id ~= glyph_code then
+ -- saveguard ... we need to deal with rules and so (math)
+ return head
+ end
local r, m
- if true then
- f, l = strip_range(f,l)
+ if strip then
+ if trace_ruled then
+ local before = n_tosequence(f,l,true)
+ f, l = striprange(f,l)
+ local after = n_tosequence(f,l,true)
+ report_ruled("range stripper: %s -> %s",before,after)
+ else
+ f, l = striprange(f,l)
+ end
+ end
+ if not f then
+ return head
end
local w = list_dimensions(parent.glue_set,parent.glue_sign,parent.glue_order,f,l.next)
local method, offset, continue, dy, rulethickness, unit, order, max, ma, ca, ta =
d.method, d.offset, d.continue, d.dy, d.rulethickness, d.unit, d.order, d.max, d.ma, d.ca, d.ta
- local e = dimenfactor(unit,fontdata[f.font])
+ local e = dimenfactor(unit,fontdata[f.font]) -- what if no glyph node
local colorspace = (ma > 0 and ma) or has_attribute(f,a_colorspace) or 1
local color = (ca > 0 and ca) or has_attribute(f,a_color)
local transparency = (ta > 0 and ta) or has_attribute(f,a_transparency)
@@ -200,6 +281,12 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a
local ht = (offset+(i-1)*dy+rulethickness)*e - m
local dp = -(offset+(i-1)*dy-rulethickness)*e + m
local r = new_rule(w,ht,dp)
+ local v = has_attribute(f,a_viewerlayer)
+ -- quick hack
+ if v then
+ set_attribute(r,a_viewerlayer,v)
+ end
+ --
if color then
set_attribute(r,a_colorspace,colorspace)
set_attribute(r,a_color,color)
@@ -213,11 +300,11 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a
insert_after(head,k,r)
l = r
else
- head, _ = insert_before(head,f,r)
+ head = insert_before(head,f,r)
insert_after(head,r,k)
end
if trace_ruled then
- logs.report("ruled", "level: %s, width: %i, height: %i, depth: %i, nodes: %s, text: %s",
+ report_ruled("level: %s, width: %i, height: %i, depth: %i, nodes: %s, text: %s",
level,w,ht,dp,n_tostring(f,l),n_tosequence(f,l,true))
-- level,r.width,r.height,r.depth,n_tostring(f,l),n_tosequence(f,l,true))
end
@@ -225,20 +312,22 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a
return head
end
-local process = nodes.process_words
+local process = nodes.processwords
-nodes.rules.process = function(head) return process(a_ruled,data,flush_ruled,head) end
+nodes.rules.handler = function(head) return process(a_ruled,data,flush_ruled,head) end
function nodes.rules.enable()
- tasks.enableaction("shipouts","nodes.rules.process")
+ tasks.enableaction("shipouts","nodes.rules.handler")
end
-- elsewhere:
--
--- tasks.appendaction ("shipouts", "normalizers", "nodes.rules.process")
--- tasks.disableaction("shipouts", "nodes.rules.process") -- only kick in when used
+-- tasks.appendaction ("shipouts", "normalizers", "nodes.rules.handler")
+-- tasks.disableaction("shipouts", "nodes.rules.handler") -- only kick in when used
+
+local trace_shifted = false trackers.register("nodes.shifting", function(v) trace_shifted = v end)
-local trace_shifted = false trackers.register("nodes.shifted", function(v) trace_shifted = v end)
+local report_shifted = logs.reporter("nodes","shifting")
local a_shifted = attributes.private('shifted')
@@ -256,7 +345,7 @@ end
local function flush_shifted(head,first,last,data,level,parent,strip) -- not that fast but acceptable for this purpose
if true then
- first, last = strip_range(first,last)
+ first, last = striprange(first,last)
end
local prev, next = first.prev, last.next
first.prev, last.next = nil, nil
@@ -274,15 +363,15 @@ local function flush_shifted(head,first,last,data,level,parent,strip) -- not tha
local raise = data.dy * dimenfactor(data.unit,fontdata[first.font])
list.shift, list.height, list.depth = raise, height, depth
if trace_shifted then
- logs.report("shifted", "width: %s, nodes: %s, text: %s",width,n_tostring(first,last),n_tosequence(first,last,true))
+ report_shifted("width: %s, nodes: %s, text: %s",width,n_tostring(first,last),n_tosequence(first,last,true))
end
return head
end
-local process = nodes.process_words
+local process = nodes.processwords
-nodes.shifts.process = function(head) return process(a_shifted,data,flush_shifted,head) end
+nodes.shifts.handler = function(head) return process(a_shifted,data,flush_shifted,head) end
function nodes.shifts.enable()
- tasks.enableaction("shipouts","nodes.shifts.process")
+ tasks.enableaction("shipouts","nodes.shifts.handler")
end