summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/page-lin.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/page-lin.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/page-lin.lua196
1 files changed, 129 insertions, 67 deletions
diff --git a/Master/texmf-dist/tex/context/base/page-lin.lua b/Master/texmf-dist/tex/context/base/page-lin.lua
index 1f2c9625116..676a4c7f656 100644
--- a/Master/texmf-dist/tex/context/base/page-lin.lua
+++ b/Master/texmf-dist/tex/context/base/page-lin.lua
@@ -6,34 +6,48 @@ if not modules then modules = { } end modules ['page-lin'] = {
license = "see context related readme files"
}
--- experimental
+-- experimental -> will become builders
local trace_numbers = false trackers.register("lines.numbers", function(v) trace_numbers = v end)
-local format = string.format
-local texsprint, texwrite, texbox = tex.sprint, tex.write, tex.box
+local report_lines = logs.reporter("lines")
-local ctxcatcodes = tex.ctxcatcodes
-local variables = interfaces.variables
+local texbox = tex.box
-nodes = nodes or { }
-nodes.lines = nodes.lines or { }
-nodes.lines.data = nodes.lines.data or { } -- start step tag
+local attributes, nodes, node, context = attributes, nodes, node, context
-storage.register("lines/data", nodes.lines.data, "nodes.lines.data")
+nodes.lines = nodes.lines or { }
+local lines = nodes.lines
+
+lines.data = lines.data or { } -- start step tag
+local data = lines.data
+local last = #data
+
+lines.scratchbox = lines.scratchbox or 0
+
+local leftmarginwidth = nodes.leftmarginwidth
+
+storage.register("lines/data", lines.data, "nodes.lines.data")
-- if there is demand for it, we can support multiple numbering streams
-- and use more than one attibute
-local hlist, vlist, whatsit = node.id('hlist'), node.id('vlist'), node.id('whatsit')
+local variables = interfaces.variables
-local display_math = attributes.private('display-math')
-local line_number = attributes.private('line-number')
-local line_reference = attributes.private('line-reference')
+local nodecodes = nodes.nodecodes
-local current_list = { }
-local cross_references = { }
-local chunksize = 250 -- not used in boxed
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local whatsit_code = nodecodes.whatsit
+
+local a_displaymath = attributes.private('displaymath')
+local a_linenumber = attributes.private('linenumber')
+local a_linereference = attributes.private('linereference')
+local a_verbatimline = attributes.private('verbatimline')
+
+local current_list = { }
+local cross_references = { }
+local chunksize = 250 -- not used in boxed
local has_attribute = node.has_attribute
local traverse_id = node.traverse_id
@@ -43,16 +57,9 @@ local hpack_node = node.hpack
local insert_node_after = node.insert_after
local insert_node_before = node.insert_before
-local whatsit = node.id("whatsit")
-
-local data = nodes.lines.data
-local last = #data
-
-nodes.lines.scratchbox = nodes.lines.scratchbox or 0
-
-- cross referencing
-function nodes.lines.number(n)
+function lines.number(n)
n = tonumber(n)
local cr = cross_references[n] or 0
cross_references[n] = nil
@@ -62,20 +69,20 @@ end
local function resolve(n,m) -- we can now check the 'line' flag (todo)
while n do
local id = n.id
- if id == whatsit then -- why whatsit
- local a = has_attribute(n,line_reference)
+ if id == whatsit_code then -- why whatsit
+ local a = has_attribute(n,a_linereference)
if a then
cross_references[a] = m
end
- elseif id == hlist or id == vlist then
+ elseif id == hlist_code or id == vlist_code then
resolve(n.list,m)
end
n = n.next
end
end
-function nodes.lines.finalize(t)
- local getnumber = nodes.lines.number
+function lines.finalize(t)
+ local getnumber = lines.number
for _,p in next, t do
for _,r in next, p do
if r.metadata.kind == "line" then
@@ -89,16 +96,16 @@ function nodes.lines.finalize(t)
end
end
-local filters = jobreferences.filters
-local helpers = structure.helpers
+local filters = structures.references.filters
+local helpers = structures.helpers
-jobreferences.registerfinalizer(nodes.lines.finalize)
+structures.references.registerfinalizer(lines.finalize)
filters.line = filters.line or { }
function filters.line.default(data)
-- helpers.title(data.entries.linenumber or "?",data.metadata)
- texsprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",data.entries.conversion or "numbers",data.entries.linenumber or "0"))
+ context.convertnumber(data.entries.conversion or "numbers",data.entries.linenumber or "0")
end
function filters.line.page(data,prefixspec,pagespec) -- redundant
@@ -106,90 +113,139 @@ function filters.line.page(data,prefixspec,pagespec) -- redundant
end
function filters.line.linenumber(data) -- raw
- texwrite(data.entries.linenumber or "0")
+ context(data.entries.linenumber or "0")
end
-- boxed variant, todo: use number mechanism
-nodes.lines.boxed = { }
+lines.boxed = { }
+local boxed = lines.boxed
-- todo: cache setups, and free id no longer used
-- use interfaces.cachesetup(t)
-function nodes.lines.boxed.register(configuration)
+function boxed.register(configuration)
last = last + 1
data[last] = configuration
if trace_numbers then
- logs.report("lines","registering setup %s",last)
+ report_lines("registering setup %s",last)
end
return last
end
-function nodes.lines.boxed.setup(n,configuration)
+function boxed.setup(n,configuration)
local d = data[n]
if d then
if trace_numbers then
- logs.report("lines","updating setup %s",n)
+ report_lines("updating setup %s",n)
end
for k,v in next, configuration do
d[k] = v
end
else
if trace_numbers then
- logs.report("lines","registering setup %s (br)",n)
+ report_lines("registering setup %s (br)",n)
end
data[n] = configuration
end
return n
end
-local the_left_margin = nodes.the_left_margin
-
-local function check_number(n,a,skip) -- move inline
+local function check_number(n,a,skip,sameline)
local d = data[a]
if d then
- local s = d.start or 1
+ local tag, skipflag, s = d.tag or "", 0, d.start or 1
current_list[#current_list+1] = { n, s }
- if not skip and s % d.step == 0 then
- local tag = d.tag or ""
- texsprint(ctxcatcodes, format("\\makenumber{%s}{%s}{%s}{%s}{%s}{%s}\\endgraf",tag,s,n.shift,n.width,the_left_margin(n.list),n.dir))
+ if sameline then
+ skipflag = 0
+ if trace_numbers then
+ report_lines("skipping broken line number %s for setup %s: %s (%s)",#current_list,a,s,d.continue or "no")
+ end
+ elseif not skip and s % d.step == 0 then
+ skipflag, d.start = 1, s + 1 -- (d.step or 1)
if trace_numbers then
- logs.report("numbers","making number %s for setup %s: %s (%s)",#current_list,a,s,d.continue or "no")
+ report_lines("making number %s for setup %s: %s (%s)",#current_list,a,s,d.continue or "no")
end
else
- texsprint(ctxcatcodes, "\\skipnumber\\endgraf")
+ skipflag, d.start = 0, s + 1 -- (d.step or 1)
+ if trace_numbers then
+ report_lines("skipping line number %s for setup %s: %s (%s)",#current_list,a,s,d.continue or "no")
+ end
+ end
+ context.makelinenumber(tag,skipflag,s,n.shift,n.width,leftmarginwidth(n.list),n.dir)
+ end
+end
+
+-- xlist
+-- xlist
+-- hlist
+
+local function identify(list)
+ if list then
+ for n in traverse_id(hlist_code,list) do
+ if has_attribute(n,a_linenumber) then
+ return list
+ end
+ end
+ local n = list
+ while n do
+ local id = n.id
+ if id == hlist_code or id == vlist_code then
+ local ok = identify(n.list)
+ if ok then
+ return ok
+ end
+ end
+ n = n.next
end
- d.start = s + 1 -- (d.step or 1)
end
end
-function nodes.lines.boxed.stage_one(n)
+function boxed.stage_zero(n)
+ return identify(texbox[n].list)
+end
+
+function boxed.stage_one(n,nested)
current_list = { }
local head = texbox[n]
if head then
local list = head.list
- local last_a, skip = nil, false
- for n in traverse_id(hlist,list) do -- attr test here and quit as soon as zero found
+ if nested then
+ list = identify(list)
+ end
+ local last_a, last_v, skip = nil, -1, false
+ for n in traverse_id(hlist_code,list) do -- attr test here and quit as soon as zero found
if n.height == 0 and n.depth == 0 then
- -- skip funny hlists
+ -- skip funny hlists -- todo: check line subtype
else
- local a = has_attribute(n.list,line_number)
+ local list = n.list
+ local a = has_attribute(list,a_linenumber)
if a and a > 0 then
if last_a ~= a then
- if data[a].method == variables.next then
+ local da = data[a]
+ local ma = da.method
+ if ma == variables.next then
skip = true
+ elseif ma == variables.page then
+ da.start = 1 -- eventually we will have a normal counter
end
last_a = a
+ if trace_numbers then
+ report_lines("starting line number range %s: start %s, continue",a,da.start,da.continue or "no")
+ end
end
- if has_attribute(n,display_math) then
+ if has_attribute(n,a_displaymath) then
if nodes.is_display_math(n) then
check_number(n,a,skip)
end
else
- -- the following test fails somehow (change in luatex?)
- -- if node.first_character(n.list) then
+ local v = has_attribute(list,a_verbatimline)
+ if not v or v ~= last_v then
+ last_v = v
check_number(n,a,skip)
- -- end
+ else
+ check_number(n,a,skip,true)
+ end
end
skip = false
end
@@ -198,18 +254,24 @@ function nodes.lines.boxed.stage_one(n)
end
end
-function nodes.lines.boxed.stage_two(n,m)
+function boxed.stage_two(n,m)
if #current_list > 0 then
- m = m or nodes.lines.scratchbox
- local t, i = { }, 0
- for l in traverse_id(hlist,texbox[m].list) do
- t[#t+1] = copy_node(l)
+ m = m or lines.scratchbox
+ local t, tn = { }, 0
+ for l in traverse_id(hlist_code,texbox[m].list) do
+ tn = tn + 1
+ t[tn] = copy_node(l)
end
for i=1,#current_list do
local li = current_list[i]
local n, m, ti = li[1], li[2], t[i]
- ti.next, n.list = n.list, ti
- resolve(n,m)
+ if ti then
+ ti.next, n.list = n.list, ti
+ resolve(n,m)
+ else
+ report_lines("error in linenumbering (1)")
+ return
+ end
end
end
end