diff options
Diffstat (limited to 'tex/context/base/node-rul.lua')
-rw-r--r-- | tex/context/base/node-rul.lua | 172 |
1 files changed, 115 insertions, 57 deletions
diff --git a/tex/context/base/node-rul.lua b/tex/context/base/node-rul.lua index 242ea7ace..60c6e77f3 100644 --- a/tex/context/base/node-rul.lua +++ b/tex/context/base/node-rul.lua @@ -38,6 +38,75 @@ local texwrite = tex.write local fontdata = fonts.ids local variables = interfaces.variables +-- we can use this one elsewhere too +-- +-- todo: functions: word, sentence +-- +-- glyph rule unset whatsit glue margin_kern kern math disc + +local function process_words(attribute,data,flush,head,parent) + local n = head + if n then + local f, l, a, d, i, level + local continue, done = false, false + while n do + local id = n.id + if id == glyph then + local aa = has_attribute(n,attribute) + if aa then + if aa == a then + if not f then + f = n + end + l = n + else + -- possible extensions: when in same class then keep spanning + if f then + head, done = flush(head,f,l,d,level,parent), true + end + f, l, a = n, n, aa + level, i = floor(a/1000), a%1000 + d = data[i] + continue = d.continue == variables.yes + end + else + if f then + head, done = flush(head,f,l,d,level,parent), true + end + f, l, a = nil, nil, nil + end + elseif f and id == disc then + l = n + elseif f and id == kern and n.subtype == 0 then + l = n + elseif id == hlist or id == vlist then + if f then + head, done = flush(head,f,l,d,level,parent), true + f, l, a = nil, nil, nil + end + local list = n.list + if list then + n.list = process_words(attribute,data,flush,list,n) + end + elseif f and not continue then + head, done = flush(head,f,l,d,level,parent), true + f, l, a = nil, nil, nil + end + n = n.next + end + if f then + head, done = flush(head,f,l,d,level,parent), true + end + return head, true -- todo: done + else + return head, false + end +end + +nodes.process_words = process_words + +-- + nodes.rules = nodes.rules or { } nodes.rules.data = nodes.rules.data or { } @@ -50,7 +119,7 @@ function nodes.rules.define(settings) texwrite(#data) end -local function flush(head,f,l,d,level,parent) -- not that fast but acceptable for this purpose +local function flush_ruled(head,f,l,d,level,parent) -- not that fast but acceptable for this purpose local r, m 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 = @@ -97,67 +166,56 @@ local function flush(head,f,l,d,level,parent) -- not that fast but acceptable fo return head end --- todo: functions: word, sentence +local process = nodes.process_words --- glyph rule unset whatsit glue margin_kern kern math disc +nodes.rules.process = function(head) return process(a_ruled,data,flush_ruled,head) end -local function process(head,parent) - local n = head - local f, l, a, d, i, level - local continue = false - while n do - local id = n.id - if id == glyph then - local aa = has_attribute(n,a_ruled) - if aa then - if aa == a then - if not f then - f = n - end - l = n - else - -- possible extensions: when in same class then keep spanning - if f then - head = flush(head,f,l,d,level,parent) - end - f, l, a = n, n, aa - level, i = floor(a/1000), a%1000 - d = data[i] - continue = d.continue == variables.yes - end - else - if f then - head = flush(head,f,l,d,level,parent) - end - f, l, a = nil, nil, nil - end - elseif f and id == disc then - l = n - elseif f and id == kern and n.subtype == 0 then - l = n - elseif id == hlist or id == vlist then - if f then - head = flush(head,f,l,d,level,parent) - f, l, a = nil, nil, nil - end - n.list = process(n.list,n) - elseif f and not continue then - head = flush(head,f,l,d,level,parent) - f, l, a = nil, nil, nil - end - n = n.next +function nodes.rules.enable() + tasks.enableaction("shipouts","nodes.rules.process") +end + +-- elsewhere: +-- +-- tasks.appendaction ("shipouts", "normalizers", "nodes.rules.process") +-- tasks.disableaction("shipouts", "nodes.rules.process") -- only kick in when used + +local a_shifted = attributes.private('shifted') + +nodes.shifts = nodes.shifts or { } +nodes.shifts.data = nodes.shifts.data or { } + +storage.register("nodes/shifts/data", nodes.shifts.data, "nodes.shifts.data") + +local data = nodes.shifts.data + +function nodes.shifts.define(settings) + data[#data+1] = settings + texwrite(#data) +end + +local function flush_shifted(head,first,last,data,level,parent) -- not that fast but acceptable for this purpose + local prev, next = first.prev, last.next + first.prev, last.next = nil, nil + local width, height, depth = list_dimensions(parent.glue_set,parent.glue_sign,parent.glue_order,first,next) + local list = node.hpack(first,width,"exactly") + if first == head then + head = list + end + if prev then + prev.next, list.prev = list, prev end - if f then - head = flush(head,f,l,d,level,parent) + if next then + next.prev, list.next = list, next end - return head, true -- todo: done + local raise = data.dy * dimenfactor(data.unit,fontdata[first.font]) + list.shift, list.height, list.depth = raise, height, depth + return head end -nodes.rules.process = function(head) return process(head) end +local process = nodes.process_words -function nodes.rules.enable() - tasks.enableaction("shipouts","nodes.rules.process") -end +nodes.shifts.process = function(head) return process(a_shifted,data,flush_shifted,head) end ---~ tasks.appendaction ("shipouts", "normalizers", "nodes.rules.process") ---~ tasks.disableaction("shipouts", "nodes.rules.process") -- only kick in when used +function nodes.shifts.enable() + tasks.enableaction("shipouts","nodes.shifts.process") +end |