diff options
Diffstat (limited to 'Master/texmf-dist/tex/luatex')
-rw-r--r-- | Master/texmf-dist/tex/luatex/lua-widow-control/lua-widow-control.lua | 59 | ||||
-rw-r--r-- | Master/texmf-dist/tex/luatex/lua-widow-control/lua-widow-control.tex | 34 |
2 files changed, 85 insertions, 8 deletions
diff --git a/Master/texmf-dist/tex/luatex/lua-widow-control/lua-widow-control.lua b/Master/texmf-dist/tex/luatex/lua-widow-control/lua-widow-control.lua index a85793d3a9e..62f1867b62d 100644 --- a/Master/texmf-dist/tex/luatex/lua-widow-control/lua-widow-control.lua +++ b/Master/texmf-dist/tex/luatex/lua-widow-control/lua-widow-control.lua @@ -2,7 +2,7 @@ lua-widow-control https://github.com/gucci-on-fleek/lua-widow-control SPDX-License-Identifier: MPL-2.0+ - SPDX-FileCopyrightText: 2021 gucci-on-fleek + SPDX-FileCopyrightText: 2021 Max Chernoff ]] lwc = {} @@ -34,6 +34,7 @@ local glue_id = node.id("glue") local set_attribute = node.set_attribute local has_attribute = node.has_attribute local flush_list = node.flush_list or node.flushlist +local free = node.free local min_col_width = tex.sp("25em") local maxdimen = 1073741823 -- \\maxdimen in sp @@ -63,8 +64,8 @@ if lwc.context then elseif lwc.plain or lwc.latex then luatexbase.provides_module { name = lwc.name, - date = "2021/10/09", --%%date - version = "1.0.0", --%%version + date = "2021/11/08", --%%date + version = "1.1.0", --%%version description = [[ This module provides a LuaTeX-based solution to prevent @@ -77,7 +78,11 @@ elseif lwc.plain or lwc.latex then lwc.attribute = luatexbase.new_attribute(lwc.name) lwc.contrib_head = 'contrib_head' -- For \LuaTeX{} else -- uh oh - error("Unsupported format. Please use (Lua)LaTeX, Plain (Lua)TeX, or ConTeXt (MKXL/LMTX)") + error [[ + Unsupported format. + + Please use (Lua)LaTeX, Plain (Lua)TeX, or ConTeXt (MKXL/LMTX) + ]] end lwc.paragraphs = {} -- List to hold the alternate paragraph versions @@ -163,7 +168,7 @@ function lwc.save_paragraphs(head) local parfillskip = last(new_head) if parfillskip.id == glue_id and tex.hsize > min_col_width then parfillskip.stretch_order = 0 - parfillskip.stretch = 0.9 * tex.hsize -- Last line must be at least 10% long + parfillskip.stretch = 0.8 * tex.hsize -- Last line must be at least 20% long end -- Break the paragraph 1 line longer than natural @@ -211,6 +216,31 @@ function lwc.mark_paragraphs(head) end +--- A "safe" version of the last/slide function. +--- +--- Sometimes the node list can form a loop. Since there is no last element +--- of a looped linked-list, the `last()` function will never terminate. This +--- function provides a "safe" version of the `last()` function that returns +--- `nil` if the list is circular. +local function safe_last(head) + local ids = {} + + while head.next do + local id = node.is_node(head) -- Returns the internal node id + + if ids[id] then + lwc.warning("Circular node list detected!") + return nil + end + + ids[id] = true + head = head.next + end + + return head +end + + --- Remove the widows and orphans from the page, just after the output routine. --- --- This function holds the "meat" of the module. It is called just after the @@ -264,7 +294,16 @@ function lwc.remove_widows(head) while head do -- Insert the start of the replacement paragraph if has_attribute(head, lwc.attribute, paragraph_index) then + local current = head head.prev.next = target_node + + -- Abort if we've created a loop + if not safe_last(target_node) then + head.prev.next = current + lwc.warning("Widow/Orphan NOT removed!") + break + end + clear_flag = true end @@ -286,7 +325,7 @@ function lwc.remove_widows(head) end if clear_flag then - head = node.free(head) + head = free(head) else head = head.next end @@ -359,5 +398,13 @@ function lwc.disable_callbacks() end end +function lwc.if_lwc_enabled() + if enabled then + tex.sprint("\\iftrue") + else + tex.sprint("\\iffalse") + end +end + return lwc diff --git a/Master/texmf-dist/tex/luatex/lua-widow-control/lua-widow-control.tex b/Master/texmf-dist/tex/luatex/lua-widow-control/lua-widow-control.tex index fc10ff0ebb6..904ee03c69f 100644 --- a/Master/texmf-dist/tex/luatex/lua-widow-control/lua-widow-control.tex +++ b/Master/texmf-dist/tex/luatex/lua-widow-control/lua-widow-control.tex @@ -1,9 +1,9 @@ % lua-widow-control % https://github.com/gucci-on-fleek/lua-widow-control % SPDX-License-Identifier: MPL-2.0+ -% SPDX-FileCopyrightText: 2021 gucci-on-fleek +% SPDX-FileCopyrightText: 2021 Max Chernoff -\wlog{lua-widow-control v1.0.0} %%version +\wlog{lua-widow-control v1.1.0} %%version \input ltluatex % \LuaTeX{}Base @@ -24,10 +24,40 @@ \expandglyphsinfont\the\font 20 20 5 \adjustspacing=2 +% Define \TeX{} wrappers for Lua functions \def\lwcenable{\directlua{lwc.enable_callbacks()}} \def\lwcdisable{\directlua{lwc.disable_callbacks()}} +\def\iflwc{\directlua{lwc.if_lwc_enabled()}} % Enable \lwc/ by default when the package is loaded. \lwcenable +% Expansion of some parts of the document, such as section headings, is quite +% undesirable, so we'll disable \lwc/ for certain commands. +\catcode`@=11 + +% We should only reenable \lwc/ at the end if it was already enabled. +\newif\iflwc@should@reenable + +\def\lwc@patch@pre{\iflwc% + \lwc@should@reenabletrue% + \lwcdisable% +\fi} + +\def\lwc@patch@post{\iflwc@should@reenable% + \lwcenable% +\fi} + +\def\lwcdisablecmd#1{% + \ifdefined#1 + \expandafter\def\expandafter#1\expandafter{\lwc@patch@pre #1\lwc@patch@post} + \fi +} +\catcode`@=12 + +\begingroup + \suppressoutererror=1 + \lwcdisablecmd{\beginsection} % Sectioning +\endgroup + \endinput |