summaryrefslogtreecommitdiff
path: root/tex/context/base/page-lin.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/page-lin.lua')
-rw-r--r--tex/context/base/page-lin.lua226
1 files changed, 123 insertions, 103 deletions
diff --git a/tex/context/base/page-lin.lua b/tex/context/base/page-lin.lua
index 73dba30b6..359aed877 100644
--- a/tex/context/base/page-lin.lua
+++ b/tex/context/base/page-lin.lua
@@ -43,12 +43,14 @@ local v_no = variables.no
local nodecodes = nodes.nodecodes
local skipcodes = nodes.skipcodes
local whatcodes = nodes.whatcodes
+local listcodes = nodes.listcodes
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
local whatsit_code = nodecodes.whatsit
local glue_code = nodecodes.glue
local glyph_code = nodecodes.glyph
+local line_code = listcodes.line
local leftskip_code = skipcodes.leftskip
local textdir_code = whatcodes.dir
@@ -72,6 +74,9 @@ local getlist = nuts.getlist
local getbox = nuts.getbox
local getfield = nuts.getfield
+local setprop = nuts.setprop
+local getprop = nuts.getprop
+
local setfield = nuts.setfield
local traverse_id = nuts.traverse_id
@@ -92,6 +97,8 @@ local new_kern = nodepool.kern
local ctx_convertnumber = context.convertnumber
local ctx_makelinenumber = context.makelinenumber
+local addtoline = typesetters.paragraphs.addtoline
+
-- cross referencing
function lines.number(n)
@@ -237,38 +244,96 @@ local function check_number(n,a,skip,sameline)
report_lines("skipping line number %s for setup %a: %s (%s)",#current_list,a,s,d.continue or v_no)
end
end
- ctx_makelinenumber(tag,skipflag,s,getfield(n,"width"),getfield(n,"dir"))
+ local p = getprop(n,"line")
+ ctx_makelinenumber(tag,skipflag,s,p.hsize,p.reverse and "TRT" or "TLT") -- getfield(n,"dir"))
end
end
--- xlist
--- xlist
--- hlist
+-- print(nodes.idstostring(list))
-local function identify(list)
- if list then
- for n in traverse_id(hlist_code,list) do
+-- hlists of type line will only have an attribute when the line number attribute
+-- still set at par building time which is not always the case unless we explicitly
+-- do a par before we end the line
+
+-- todo: check for a: when <= 0 then false
+
+local function lineisnumbered(n)
+ local n = getlist(n)
+ while n do
+ local id = getid(n)
+ if id == hlist_code or id == vlist_code then
+ -- this can hit fast as we inherit anchor attributes from parent
local a = getattr(n,a_linenumber)
- if a then
- return list, a
+ if a and a > 0 then
+ return a
+ end
+ elseif id == glyph_code then
+ local a = getattr(n,a_linenumber)
+ if a and a > 0 then
+ return a
+ else
+ return false
end
end
- local n = list
- while n do
- local id = getid(n)
- if id == hlist_code or id == vlist_code then
- local ok, a = identify(getlist(n))
- if ok then
- return ok, a
+ n = getnext(n)
+ end
+end
+
+local function listisnumbered(list)
+ if list then
+ for n in traverse_id(hlist_code,list) do
+ if getsubtype(n) == line_code then
+ local a = getattr(n,a_linenumber)
+ if a then
+ -- a quick test for lines (only valid when \par before \stoplinenumbering)
+ return a > 0 and list or false
+ else
+ -- a bit slower one, assuming that we have normalized and anchored
+ if lineisnumbered(n) then
+ return list
+ end
end
end
- n = getnext(n)
end
end
end
-function boxed.stage_zero(n) -- not used
- return identify(getlist(getbox(n)))
+local function findnumberedlist(list)
+ -- we assume wrapped boxes, only one with numbers
+ local n = list
+ while n do
+ local id = getid(n)
+ if id == hlist_code then
+ if getsubtype(n) == line_code then
+ local a = getattr(n,a_linenumber)
+ if a then
+ return a > 0 and list
+ end
+ return
+ else
+ local list = getlist(n)
+ if lineisnumbered(list) then
+ return n
+ end
+ local okay = findnumberedlist(list)
+ if okay then
+ return okay
+ end
+ end
+ elseif id == vlist_code then
+ local list = getlist(n)
+ if listisnumbered(list) then
+ return list
+ end
+ local okay = findnumberedlist(list)
+ if okay then
+ return okay
+ end
+ elseif id == glyph_code then
+ return
+ end
+ n = getnext(n)
+ end
end
-- reset ranges per page
@@ -279,40 +344,36 @@ function boxed.stage_one(n,nested)
current_list = { }
local box = getbox(n)
if box then
- local found = nil
- local list = getlist(box)
- if list and nested then
- list, found = identify(list)
+ local list = getlist(box)
+ if not list then
+ return
+ end
+ if nested then
+ local id = getid(box)
+ if id == vlist_code then
+ if listisnumbered(list) then
+ -- ok
+ else
+ list = findnumberedlist(list)
+ end
+ else -- hlist
+ list = findnumberedlist(list)
+ end
end
+ -- we assume we have a vlist
if list then
- local last_a, last_v, skip = nil, -1, false
+ local last_a = nil
+ local last_v = -1
+ local skip = false
for n in traverse_id(hlist_code,list) do -- attr test here and quit as soon as zero found
- if getfield(n,"height") == 0 and getfield(n,"depth") == 0 then
+ local subtype = getsubtype(n)
+ if subtype ~= line_code then
+ -- go on
+ elseif getfield(n,"height") == 0 and getfield(n,"depth") == 0 then
-- skip funny hlists -- todo: check line subtype
else
- local list = getlist(n)
- local a = getattr(list,a_linenumber)
--- if a and a < 0 then
--- break
--- end
- if not a or a == 0 then
- local n = getnext(list)
- while n do
- local id = getid(n)
- if id == glyph_code then
- break
- elseif id == whatsit_code and getsubtype(n) == textdir_code then
- n = getnext(n)
- elseif id == glue_code and getsubtype(n) == leftskip_code then -- first in list
- n = getnext(n)
- else
- -- can be hlist or skip (e.g. footnote line)
- n = getnext(n)
- end
- end
- a = n and getattr(n,a_linenumber)
- end
- if a and a > 0 then
+ local a = lineisnumbered(n)
+ if a then
if last_a ~= a then
local da = data[a]
local ma = da.method
@@ -341,54 +402,12 @@ function boxed.stage_one(n,nested)
end
skip = false
end
--- setattr(list,a_linenumber,-1)
end
end
end
end
end
--- todo: a general model for attaching stuff l/r
-
--- setfield(ti,"next",l)
--- setfield(l,"prev",ti)
--- local h = copy_node(n)
--- -- setfield(h,"dir","TLT")
--- setfield(h,"list",ti) -- the number
--- setfield(n,"list",h)
-
--- function boxed.stage_two(n,m)
--- if #current_list > 0 then
--- m = m or lines.scratchbox
--- local t, tn = { }, 0
--- for l in traverse_id(hlist_code,getlist(getbox(m))) do
--- tn = tn + 1
--- t[tn] = copy_node(l) -- use take_box instead
--- end
--- for i=1,#current_list do
--- local li = current_list[i]
--- local n, m, ti = li[1], li[2], t[i]
--- if ti then
--- local d = getfield(n,"dir")
--- local l = getlist(n)
--- if d == "TRT" then
--- local w = getfield(n,"width")
--- ti = hpack_nodes(linked_nodes(new_kern(-w),ti,new_kern(w)))
--- end
--- setfield(ti,"next",l)
--- setfield(l,"prev",ti)
--- setfield(n,"list",ti)
--- resolve(n,m)
--- else
--- report_lines("error in linenumbering (1)")
--- return
--- end
--- end
--- end
--- end
-
-local addtoline = typesetters.paragraphs and typesetters.paragraphs.addtoline
-
function boxed.stage_two(n,m)
if #current_list > 0 then
m = m or lines.scratchbox
@@ -401,19 +420,16 @@ function boxed.stage_two(n,m)
local li = current_list[i]
local n, m, ti = li[1], li[2], t[i]
if ti then
- if addtoline then
- addtoline(n,ti)
- else
- local d = getfield(n,"dir")
- local l = getlist(n)
- if d == "TRT" then
- local w = getfield(n,"width")
- ti = hpack_nodes(linked_nodes(new_kern(-w),ti,new_kern(w)))
- end
- setfield(ti,"next",l)
- setfield(l,"prev",ti)
- setfield(n,"list",ti)
- end
+ -- local d = getfield(n,"dir")
+ -- local l = getlist(n)
+ -- if d == "TRT" then
+ -- local w = getfield(n,"width")
+ -- ti = hpack_nodes(linked_nodes(new_kern(-w),ti,new_kern(w)))
+ -- end
+ -- setfield(ti,"next",l)
+ -- setfield(l,"prev",ti)
+ -- setfield(n,"list",ti)
+ addtoline(n,ti)
resolve(n,m)
else
report_lines("error in linenumbering (1)")
@@ -423,6 +439,10 @@ function boxed.stage_two(n,m)
end
end
+-- function boxed.stage_zero(n) -- not used
+-- return identify(getlist(getbox(n)))
+-- end
+
implement {
name = "linenumbersstageone",
actions = boxed.stage_one,