summaryrefslogtreecommitdiff
path: root/macros/luatex/generic/lua-widow-control/lua-widow-control.lua
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/generic/lua-widow-control/lua-widow-control.lua')
-rw-r--r--macros/luatex/generic/lua-widow-control/lua-widow-control.lua92
1 files changed, 61 insertions, 31 deletions
diff --git a/macros/luatex/generic/lua-widow-control/lua-widow-control.lua b/macros/luatex/generic/lua-widow-control/lua-widow-control.lua
index 0f23f42592..1ef86174c4 100644
--- a/macros/luatex/generic/lua-widow-control/lua-widow-control.lua
+++ b/macros/luatex/generic/lua-widow-control/lua-widow-control.lua
@@ -102,6 +102,7 @@ local insert_token = token.put_next or token.putnext
local last = node.slide
local linebreak = tex.linebreak
local new_node = node.new
+local remove = node.remove
local set_attribute = node.set_attribute or node.setattribute
local string_char = string.char
local tex_box = tex.box
@@ -137,6 +138,7 @@ lwc.colours = {
]]
local contrib_head,
emergencystretch,
+ hold_head,
info,
insert_attribute,
max_cost,
@@ -152,10 +154,12 @@ if lmtx then
contrib_head = "contributehead"
shrink_order = "shrinkorder"
stretch_order = "stretchorder"
+ hold_head = "holdhead"
else
contrib_head = "contrib_head"
shrink_order = "shrink_order"
stretch_order = "stretch_order"
+ hold_head = "hold_head"
end
if context then
@@ -194,8 +198,8 @@ elseif plain or latex or optex then
debug("Plain/LaTeX")
luatexbase.provides_module {
name = lwc.name,
- date = "2022/07/28", --%%slashdate
- version = "2.2.1", --%%version
+ date = "2022/08/23", --%%slashdate
+ version = "2.2.2", --%%version
description = [[
This module provides a LuaTeX-based solution to prevent
@@ -309,7 +313,7 @@ end
--- @param args table?
--- subtype: number = The node subtype
--- reverse: bool = Whether we should iterate backwards
---- @return node
+--- @return node?
local function next_of_type(head, id, args)
args = args or {}
@@ -332,6 +336,13 @@ local function next_of_type(head, id, args)
head = head.prev
end
end
+
+ -- Needed for the special `tex.lists` nodes
+ if head and head.id == id and
+ (head.subtype == args.subtype or args.subtype == nil)
+ then
+ return head
+ end
end
@@ -629,6 +640,14 @@ local function mark_inserts(head)
then
local hlist_before = next_of_type(insert, hlist_id, { reverse = true} )
+ local insert_class
+ if lmtx then
+ -- FIXME: temporarily hardcode the main "footnote" class
+ insert_class = 4 -- insert.index
+ else
+ insert_class = insert.subtype
+ end
+
--[[ We tag the first element of the hlist/line with an integer
that holds the insert class and the first and last indices
of the inserts contained in the line. This won't work if
@@ -638,7 +657,7 @@ local function mark_inserts(head)
set_attribute(
hlist_before.list,
insert_attribute,
- insert.subtype * INSERT_CLASS_MULTIPLE +
+ insert_class * INSERT_CLASS_MULTIPLE +
insert_indices[1] * INSERT_FIRST_MULTIPLE +
insert_indices[#insert_indices]
)
@@ -837,45 +856,52 @@ local function get_inserts(last_line)
break
end
- --[[ With LuaMetaTeX, the subtype of `insert` nodes is always zero,
- so we cannot detect their class therefore we can't fix any moved
- footnotes.
- ]]
- if lmtx then
- warning("!!!Incorrect footnotes on page " .. pagenum() .. "!!!")
- return {}
- end
-
-- Demux the insert values
local class = line_value // INSERT_CLASS_MULTIPLE
local first_index = (line_value % INSERT_CLASS_MULTIPLE) // INSERT_FIRST_MULTIPLE
local last_index = line_value % INSERT_FIRST_MULTIPLE
-- Get the output box containing the insert boxes
- local insert_box = tex_box[class]
+ local insert_box
- local m = insert_box.list
- while m do -- Iterate through the insert box
- local box_value
- box_value, m = find_attribute(m, insert_attribute)
+ if lmtx then
+ insert_box = tex.getinsertcontent(class)
+ else
+ insert_box = tex_box[class]
+ end
- if not m then
- break
- end
+ -- Get any portions of the insert held over until the next page
+ local split_insert = next_of_type(
+ tex_lists[hold_head],
+ insert_id,
+ { subtype = class }
+ )
- if abs(box_value) >= first_index and
- abs(box_value) <= last_index
- then
- -- Remove the respective contents from the insert box
- insert_box.list = node.remove(insert_box.list, m)
+ for i, insert in ipairs { insert_box, split_insert } do
+ local m = insert and insert.list
+
+ while m do -- Iterate through the insert box
+ local box_value
+ box_value, m = find_attribute(m, insert_attribute)
- if box_value > 0 then
- selected_inserts[#selected_inserts + 1] = copy(inserts[box_value])
+ if not m then
+ break
end
- m = free(m)
- else
- m = m.next
+ if abs(box_value) >= first_index and
+ abs(box_value) <= last_index
+ then
+ -- Remove the respective contents from the insert box
+ insert.list = remove(insert.list, m)
+
+ if box_value > 0 and i == 1 then
+ table.insert(selected_inserts, copy(inserts[box_value]))
+ end
+
+ m = free(m)
+ else
+ m = m.next
+ end
end
end
@@ -883,6 +909,10 @@ local function get_inserts(last_line)
tex_box[class] = nil
end
+ if split_insert and not split_insert.list then
+ remove(tex_lists[hold_head], split_insert)
+ end
+
n = n.next
end