summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex')
-rw-r--r--Master/texmf-dist/tex/context/third/lua-widow-control/t-lua-widow-control.mkiv77
-rw-r--r--Master/texmf-dist/tex/context/third/lua-widow-control/t-lua-widow-control.mkxl16
-rw-r--r--Master/texmf-dist/tex/lualatex/lua-widow-control/lua-widow-control.sty24
-rw-r--r--Master/texmf-dist/tex/luatex/lua-widow-control/lua-widow-control.lua225
-rw-r--r--Master/texmf-dist/tex/luatex/lua-widow-control/lua-widow-control.tex16
-rw-r--r--Master/texmf-dist/tex/optex/lua-widow-control/lua-widow-control.opm27
6 files changed, 264 insertions, 121 deletions
diff --git a/Master/texmf-dist/tex/context/third/lua-widow-control/t-lua-widow-control.mkiv b/Master/texmf-dist/tex/context/third/lua-widow-control/t-lua-widow-control.mkiv
new file mode 100644
index 00000000000..6eff5c9b00c
--- /dev/null
+++ b/Master/texmf-dist/tex/context/third/lua-widow-control/t-lua-widow-control.mkiv
@@ -0,0 +1,77 @@
+%D \module
+%D [ file=t-lua-widow-control,
+%D version=1.1.6, %%version
+%D title=lua-widow-control,
+%D subtitle=\ConTeXt module for lua-widow-control,
+%D author=Max Chernoff,
+%D date=2022-02-22, %%date
+%D copyright=Max Chernoff,
+%D license=MPL-2.0+,
+%D url=https://github.com/gucci-on-fleek/lua-widow-control]
+\startmodule[lua-widow-control]
+\unprotect
+
+\installnamespace{lwc}
+
+\installcommandhandler \????lwc {lwc} \????lwc
+
+\newdimen\lwcemergencystretch
+\appendtoks
+ \lwcemergencystretch=\lwcparameter{emergencystretch}
+\to\everysetuplwc
+
+\appendtoks
+ \doifelse{\lwcparameter{\c!state}}\v!start{
+ \ctxlua{lwc.enable_callbacks()}
+ }{
+ \ctxlua{lwc.disable_callbacks()}
+ }
+\to\everysetuplwc
+
+\define\iflwc{\ctxlua{lwc.if_lwc_enabled()}}
+
+\ctxloadluafile{lua-widow-control}
+
+\setuplwc[emergencystretch=3em, \c!state=\v!start]
+
+% We can't just set the penalties because they will be reset automatically
+% at \\starttext.
+\startsetups[*default]
+ \clubpenalty=1
+ \widowpenalty=1
+ \displaywidowpenalty=0
+ \interlinepenalty=0
+ \brokenpenalty=0
+\stopsetups
+
+\setups[*default]
+
+% Here, we enable font expansion/contraction. It isn't strictly necessary for
+% \lwc/'s functionality; however, it is required for the
+% lengthened paragraphs to not have terrible spacing.
+\definefontfeature[default][default][expansion=quality]
+\setupalign[hz]
+
+% Expansion of some parts of the document, such as section headings, is quite
+% undesirable, so we'll disable \lwc/ for certain commands.
+% We should only reenable \lwc/ at the end if it was already enabled.
+\newif\iflwc@should@reenable
+
+\define\lwc@patch@pre{%
+ \iflwc%
+ \lwc@should@reenabletrue%
+ \setuplwc[state=stop]%
+ \else%
+ \lwc@should@reenablefalse
+ \fi%
+}
+
+\define\lwc@patch@post{\iflwc@should@reenable%
+ \setuplwc[state=start]%
+\fi}
+
+\prependtoks\lwc@patch@pre\to\everybeforesectionheadhandle % Sectioning
+\prependtoks\lwc@patch@post\to\everyaftersectionheadhandle
+
+\protect
+\stopmodule
diff --git a/Master/texmf-dist/tex/context/third/lua-widow-control/t-lua-widow-control.mkxl b/Master/texmf-dist/tex/context/third/lua-widow-control/t-lua-widow-control.mkxl
index b38d6eda018..6eff5c9b00c 100644
--- a/Master/texmf-dist/tex/context/third/lua-widow-control/t-lua-widow-control.mkxl
+++ b/Master/texmf-dist/tex/context/third/lua-widow-control/t-lua-widow-control.mkxl
@@ -1,10 +1,10 @@
%D \module
%D [ file=t-lua-widow-control,
-%D version=1.1.5, %%version
+%D version=1.1.6, %%version
%D title=lua-widow-control,
%D subtitle=\ConTeXt module for lua-widow-control,
%D author=Max Chernoff,
-%D date=2022-02-15, %%date
+%D date=2022-02-22, %%date
%D copyright=Max Chernoff,
%D license=MPL-2.0+,
%D url=https://github.com/gucci-on-fleek/lua-widow-control]
@@ -57,10 +57,14 @@
% We should only reenable \lwc/ at the end if it was already enabled.
\newif\iflwc@should@reenable
-\define\lwc@patch@pre{\iflwc%
- \lwc@should@reenabletrue%
- \setuplwc[state=stop]%
-\fi}
+\define\lwc@patch@pre{%
+ \iflwc%
+ \lwc@should@reenabletrue%
+ \setuplwc[state=stop]%
+ \else%
+ \lwc@should@reenablefalse
+ \fi%
+}
\define\lwc@patch@post{\iflwc@should@reenable%
\setuplwc[state=start]%
diff --git a/Master/texmf-dist/tex/lualatex/lua-widow-control/lua-widow-control.sty b/Master/texmf-dist/tex/lualatex/lua-widow-control/lua-widow-control.sty
index 1be00709bc8..9ef5a76de56 100644
--- a/Master/texmf-dist/tex/lualatex/lua-widow-control/lua-widow-control.sty
+++ b/Master/texmf-dist/tex/lualatex/lua-widow-control/lua-widow-control.sty
@@ -1,11 +1,11 @@
% lua-widow-control
% https://github.com/gucci-on-fleek/lua-widow-control
% SPDX-License-Identifier: MPL-2.0+
-% SPDX-FileCopyrightText: 2021 Max Chernoff
+% SPDX-FileCopyrightText: 2022 Max Chernoff
\NeedsTeXFormat{LaTeX2e}[2015/01/01] % Formats built after 2015 include \LuaTeX{}Base
\ProvidesPackage{lua-widow-control}%
- [2022/02/15 v1.1.5] %%version %%date
+ [2022/02/22 v1.1.6] %%version %%date
\ifdefined\directlua\else
\PackageError{lua-widow-control}{%
@@ -56,14 +56,20 @@
% We should only reenable \lwc/ at the end if it was already enabled.
\newif\iflwc@should@reenable
-\newcommand{\lwc@patch@pre}{\iflwc%
- \lwc@should@reenabletrue%
- \lwcdisable%
-\fi}
+\newcommand{\lwc@patch@pre}{%
+ \iflwc%
+ \lwc@should@reenabletrue%
+ \lwcdisable%
+ \else%
+ \lwc@should@reenablefalse%
+ \fi%
+}
-\newcommand{\lwc@patch@post}{\iflwc@should@reenable%
- \lwcenable%
-\fi}
+\newcommand{\lwc@patch@post}{%
+ \iflwc@should@reenable%
+ \lwcenable%
+ \fi%
+}
\newcommand{\lwcdisablecmd}[1]{%
\ifdefined#1
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 9304bf9a4d1..f1ecb54c65f 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 Max Chernoff
+ SPDX-FileCopyrightText: 2022 Max Chernoff
]]
lwc = {}
@@ -14,13 +14,19 @@ lwc.name = "lua-widow-control"
detect the format name then set some flags for later processing.
]]
local format = tex.formatname
+local context, latex, plain, optex, lmtx
if format:find('cont') then -- cont-en, cont-fr, cont-nl, ...
- lwc.context = true
+ context = true
+ if status.luatex_engine == "luametatex" then
+ lmtx = true
+ end
elseif format:find('latex') then -- lualatex, lualatex-dev, ...
- lwc.latex = true
+ latex = true
elseif format == 'luatex' then -- Plain
- lwc.plain = true
+ plain = true
+elseif format == 'optex' then -- OpTeX
+ optex = true
end
--[[
@@ -29,7 +35,7 @@ end
]]
local last = node.slide
local copy = node.copy_list
-local par_id = node.id("par")
+local par_id = node.id("par") or node.id("local_par")
local glue_id = node.id("glue")
local set_attribute = node.set_attribute
local has_attribute = node.has_attribute
@@ -39,36 +45,29 @@ local min_col_width = tex.sp("25em")
local maxdimen = 1073741823 -- \\maxdimen in sp
--[[
- This error is raised in the following circumstances:
- - When the user manually loads the Lua module without loading Lua\TeX{}Base
- - When the package is used with an unsupported format
- Both of these are pretty unlikely, but it can't hurt to check.
- ]]
-assert(lwc.context or luatexbase, [[
-
- This module requires a supported callback library. Please
- follow the following format-dependant instructions:
- - LaTeX: Use a version built after 2015-01-01, or include
- `\usepackage{luatexbase}' before loading this module.
- - Plain: Include `\input ltluatex' before loading this module.
- - ConTeXt: Use the LMTX version.
-]])
-
---[[
Package/module initialization
]]
-if lwc.context then
- lwc.warning = logs.reporter("module", lwc.name)
- lwc.info = logs.reporter("module", lwc.name)
- lwc.attribute = attributes.public(lwc.name)
- lwc.contrib_head = 'contributehead' -- For \LuaMetaTeX{}
- lwc.stretch_order = "stretchorder"
- lwc.pagenum = function () return tex.count["realpageno"] end
-elseif lwc.plain or lwc.latex then
+local warning, info, attribute, contrib_head, stretch_order, pagenum
+
+if context and lmtx then
+ warning = logs.reporter("module", lwc.name)
+ info = logs.reporter("module", lwc.name)
+ attribute = attributes.public(lwc.name)
+ contrib_head = 'contributehead' -- For \LuaMetaTeX{}
+ stretch_order = "stretchorder"
+ pagenum = function() return tex.count["realpageno"] end
+elseif context and not lmtx then
+ warning = logs.reporter("module", lwc.name)
+ info = logs.reporter("module", lwc.name)
+ attribute = attributes.public(lwc.name)
+ contrib_head = 'contrib_head'
+ stretch_order = "stretch_order"
+ pagenum = function() return tex.count["realpageno"] end
+elseif plain or latex then
luatexbase.provides_module {
name = lwc.name,
- date = "2022/02/15", --%%date
- version = "1.1.5", --%%version
+ date = "2022/02/22", --%%date
+ version = "1.1.6", --%%version
description = [[
This module provides a LuaTeX-based solution to prevent
@@ -77,29 +76,30 @@ elseif lwc.plain or lwc.latex then
paragraphs.
]],
}
- lwc.warning = function(str) luatexbase.module_warning(lwc.name, str) end
- lwc.info = function(str) luatexbase.module_info(lwc.name, str) end
- lwc.attribute = luatexbase.new_attribute(lwc.name)
- lwc.contrib_head = 'contrib_head' -- For \LuaTeX{}
- lwc.stretch_order = "stretch_order"
- lwc.pagenum = function () return tex.count[0] end
+ warning = function(str) luatexbase.module_warning(lwc.name, str) end
+ info = function(str) luatexbase.module_info(lwc.name, str) end
+ attribute = luatexbase.new_attribute(lwc.name)
+ contrib_head = 'contrib_head' -- For \LuaTeX{}
+ stretch_order = "stretch_order"
+ pagenum = function() return tex.count[0] end
+elseif optex then
+ local write_nl = texio.write_nl
+ warning = function(str) write_nl(lwc.name .. " Warning: " .. str) end
+ info = function(str) write_nl("log", lwc.name .. " Info: " .. str) end
+ attribute = alloc.new_attribute(lwc.name)
+ contrib_head = 'contrib_head'
+ stretch_order = "stretch_order"
+ pagenum = function() return tex.count[0] end
else -- uh oh
error [[
Unsupported format.
- Please use (Lua)LaTeX, Plain (Lua)TeX, or ConTeXt (MKXL/LMTX)
+ Please use (Lua)LaTeX, Plain (Lua)TeX, ConTeXt (MKXL/LMTX),
+ or OpTeX.
]]
end
-lwc.paragraphs = {} -- List to hold the alternate paragraph versions
-
-if tex.interlinepenalty ~= 0 then
- lwc.warning [[
-\interlinepenalty is set to a non-zero value.
-This may prevent lua-widow-control from
-properly functioning.
-]]
-end
+local paragraphs = {} -- List to hold the alternate paragraph versions
--[[
@@ -118,8 +118,8 @@ end
--- @return table t Enablers/Disablers for the callback
--- enable: function = Enable the callback
--- disable: function = Disable the callback
-function lwc.register_callback(t)
- if lwc.plain or lwc.latex then -- Both use \LuaTeX{}Base for callbacks
+local function register_callback(t)
+ if plain or latex then -- Both use \LuaTeX{}Base for callbacks
return {
enable = function()
luatexbase.add_to_callback(t.callback, t.func, t.name)
@@ -128,19 +128,19 @@ function lwc.register_callback(t)
luatexbase.remove_from_callback(t.callback, t.name)
end,
}
- elseif lwc.context and not t.lowlevel then
+ elseif context and not t.lowlevel then
return {
-- Register the callback when the table is created,
-- but activate it when `enable()` is called.
enable = nodes.tasks.appendaction(t.category, t.position, "lwc." .. t.name)
- or function()
+ or function()
nodes.tasks.enableaction(t.category, "lwc." .. t.name)
- end,
+ end,
disable = function()
nodes.tasks.disableaction(t.category, "lwc." .. t.name)
end,
}
- elseif lwc.context and t.lowlevel then
+ elseif context and t.lowlevel then
--[[
Some of the callbacks in \ConTeXt{} have no associated "actions". Unlike
with \LuaTeX{}base, \ConTeXt{} leaves some \LuaTeX{} callbacks unregistered
@@ -153,17 +153,31 @@ function lwc.register_callback(t)
enable = function() callback.register(t.callback, t.func) end,
disable = function() callback.register(t.callback, nil) end,
}
+ elseif optex then
+ return {
+ enable = function()
+ callback.add_to_callback(t.callback, t.func, t.name)
+ end,
+ disable = function()
+ callback.remove_from_callback(t.callback, t.name)
+ end,
+ }
end
end
-
--- Saves each paragraph, but lengthened by 1 line
function lwc.save_paragraphs(head)
-- Prevent the "underfull hbox" warnings when we store a potential paragraph
- lwc.callbacks.disable_box_warnings.enable()
+ local renable_box_warnings
+ if (latex or plain) and
+ #luatexbase.callback_descriptions("hpack_quality") == 0
+ then -- See #18 and michal-h21/linebreaker#3
+ renable_box_warnings = true
+ lwc.callbacks.disable_box_warnings.enable()
+ end
-- Ensure that we were actually given a par (only under \ConTeXt{} for some reason)
- if head.id ~= par_id and lwc.context then
+ if head.id ~= par_id and context then
return head
end
@@ -173,8 +187,8 @@ function lwc.save_paragraphs(head)
-- Prevent ultra-short last lines (\TeX{}Book p. 104), except with narrow columns
local parfillskip = last(new_head)
if parfillskip.id == glue_id and tex.hsize > min_col_width then
- parfillskip[lwc.stretch_order] = 0
- parfillskip.stretch = 0.8 * tex.hsize -- Last line must be at least 20% long
+ parfillskip[stretch_order] = 0
+ parfillskip.stretch = 0.8 * tex.hsize -- Last line must be at least 20% long
end
-- Break the paragraph 1 line longer than natural
@@ -187,7 +201,9 @@ function lwc.save_paragraphs(head)
local natural_node, natural_info = tex.linebreak(copy(head))
flush_list(natural_node)
- lwc.callbacks.disable_box_warnings.disable()
+ if renable_box_warnings then
+ lwc.callbacks.disable_box_warnings.disable()
+ end
-- If we can't lengthen the paragraph, assign a \emph{very} large demerit value
local long_demerits
@@ -202,26 +218,24 @@ function lwc.save_paragraphs(head)
prevdepth.width = natural_info.prevdepth - long_info.prevdepth
last(long_node).next = prevdepth
- table.insert(lwc.paragraphs, {demerits = long_demerits, node = long_node})
+ table.insert(paragraphs, { demerits = long_demerits, node = long_node })
-- \LuaMetaTeX{} crashes if we return `true`
return head
end
-
--- Tags the beginning and the end of each paragraph as it is added to the page.
---
--- We add an attribute to the first and last node of each paragraph. The ID is
--- some arbitrary number for \lwc/, and the value corresponds to the
--- paragraphs index, which is negated for the end of the paragraph.
function lwc.mark_paragraphs(head)
- set_attribute(head, lwc.attribute, #lwc.paragraphs)
- set_attribute(last(head), lwc.attribute, -1 * #lwc.paragraphs)
+ set_attribute(head, attribute, #paragraphs)
+ set_attribute(last(head), attribute, -1 * #paragraphs)
return head
end
-
--- A "safe" version of the last/slide function.
---
--- Sometimes the node list can form a loop. Since there is no last element
@@ -236,7 +250,7 @@ local function safe_last(head)
local id = node.is_node(head) -- Returns the internal node id
if ids[id] then
- lwc.warning [[Circular node list detected!
+ warning [[Circular node list detected!
This should never happen. I'll try and recover, but your output may be
corrupted. As a workaround, disable lua-widow-control for the
affected paragraph or change the page breaks in your document.]]
@@ -254,7 +268,6 @@ affected paragraph or change the page breaks in your document.]]
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
@@ -263,21 +276,36 @@ end
--- replace one paragraph with the same paragraph, but lengthened by one line.
--- Then, we can push the bottom line of the page to the next page.
function lwc.remove_widows(head)
- local penalty = tex.outputpenalty
- local paragraphs = lwc.paragraphs
+ local penalty = tex.outputpenalty - tex.interlinepenalty
+ local widowpenalty = tex.widowpenalty
+ local clubpenalty = tex.clubpenalty
+ local displaywidowpenalty = tex.displaywidowpenalty
+ local brokenpenalty = tex.brokenpenalty
--[[
We only need to process pages that have orphans or widows. If `paragraphs`
is empty, then there is nothing that we can do.
+
+ The list of penalties is from:
+ https://tug.org/TUGboat/tb39-3/tb123mitt-widows-code.pdf#subsection.0.2.1
]]
- if penalty >= 10000 or
- penalty <= -10000 or
- penalty == 0 or
- #paragraphs == 0 then
- return head
+ if (penalty == widowpenalty or
+ penalty == displaywidowpenalty or
+ penalty == clubpenalty or
+ penalty == clubpenalty + widowpenalty or
+ penalty == clubpenalty + displaywidowpenalty or
+ penalty == brokenpenalty or
+ penalty == brokenpenalty + widowpenalty or
+ penalty == brokenpenalty + displaywidowpenalty or
+ penalty == brokenpenalty + clubpenalty or
+ penalty == brokenpenalty + clubpenalty + widowpenalty or
+ penalty == brokenpenalty + clubpenalty + displaywidowpenalty) and
+ #paragraphs >= 1 then
+ else
+ return head
end
- lwc.info("Widow/orphan detected. Attempting to remove.")
+ info("Widow/orphan detected. Attempting to remove.")
local head_save = head -- Save the start of the `head` linked-list
@@ -309,7 +337,7 @@ function lwc.remove_widows(head)
-- Loop through all of the nodes on the page
while head do
-- Insert the start of the replacement paragraph
- if has_attribute(head, lwc.attribute, paragraph_index) then
+ if has_attribute(head, attribute, paragraph_index) then
safe_last(target_node) -- Remove any loops
head.prev.next = target_node
@@ -317,25 +345,25 @@ function lwc.remove_widows(head)
end
-- Insert the end of the replacement paragraph
- if has_attribute(head, lwc.attribute, -1 * paragraph_index) then
+ if has_attribute(head, attribute, -1 * paragraph_index) then
safe_last(target_node).next = head.next
clear_flag = false
end
-- Start of final paragraph
- if has_attribute(head, lwc.attribute, #paragraphs) then
+ if has_attribute(head, attribute, #paragraphs) then
local last_line = copy(last(head))
- last(last_line).next = copy(tex.lists[lwc.contrib_head])
+ last(last_line).next = copy(tex.lists[contrib_head])
last(head).prev.prev.next = nil
-- Move the last line to the next page
- tex.lists[lwc.contrib_head] = last_line
- lwc.info(
- "Widow/orphan successfully removed at paragraph "
+ tex.lists[contrib_head] = last_line
+ info(
+ "Widow/orphan successfully removed at paragraph "
.. paragraph_index
.. " on page "
- .. lwc.pagenum()
+ .. pagenum()
.. "."
)
end
@@ -347,37 +375,36 @@ function lwc.remove_widows(head)
end
end
- lwc.paragraphs = {} -- Clear paragraphs array at the end of the page
+ paragraphs = {} -- Clear paragraphs array at the end of the page
return head_save
end
-
-- Add all of the callbacks
lwc.callbacks = {
- disable_box_warnings = lwc.register_callback({
+ disable_box_warnings = register_callback({
callback = "hpack_quality",
- func = function() end,
- name = "disable_box_warnings",
+ func = function() end,
+ name = "disable_box_warnings",
lowlevel = true,
}),
- remove_widows = lwc.register_callback({
+ remove_widows = register_callback({
callback = "pre_output_filter",
- func = lwc.remove_widows,
- name = "remove_widows",
+ func = lwc.remove_widows,
+ name = "remove_widows",
lowlevel = true,
}),
- save_paragraphs = lwc.register_callback({
+ save_paragraphs = register_callback({
callback = "pre_linebreak_filter",
- func = lwc.save_paragraphs,
- name = "save_paragraphs",
+ func = lwc.save_paragraphs,
+ name = "save_paragraphs",
category = "processors",
position = "after",
}),
- mark_paragraphs = lwc.register_callback({
+ mark_paragraphs = register_callback({
callback = "post_linebreak_filter",
- func = lwc.mark_paragraphs,
- name = "mark_paragraphs",
+ func = lwc.mark_paragraphs,
+ name = "mark_paragraphs",
category = "finalizers",
position = "after",
}),
@@ -393,11 +420,10 @@ function lwc.enable_callbacks()
enabled = true
else
- lwc.warning("Already enabled")
+ warning("Already enabled")
end
end
-
function lwc.disable_callbacks()
if enabled then
lwc.callbacks.save_paragraphs.disable()
@@ -410,7 +436,7 @@ function lwc.disable_callbacks()
enabled = false
else
- lwc.warning("Already disabled")
+ warning("Already disabled")
end
end
@@ -422,5 +448,4 @@ function lwc.if_lwc_enabled()
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 efab23b8b4b..d83e6114f4f 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 Max Chernoff
+% SPDX-FileCopyrightText: 2022 Max Chernoff
-\wlog{lua-widow-control v1.1.5} %%version
+\wlog{lua-widow-control v1.1.6} %%version
\ifx\directlua\undefined
\errmessage{%
@@ -46,10 +46,14 @@
% 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@pre{%
+ \iflwc%
+ \lwc@should@reenabletrue%
+ \lwcdisable%
+ \else%
+ \lwc@should@reenablefalse%
+ \fi%
+}
\def\lwc@patch@post{\iflwc@should@reenable%
\lwcenable%
diff --git a/Master/texmf-dist/tex/optex/lua-widow-control/lua-widow-control.opm b/Master/texmf-dist/tex/optex/lua-widow-control/lua-widow-control.opm
new file mode 100644
index 00000000000..4b8837cfec9
--- /dev/null
+++ b/Master/texmf-dist/tex/optex/lua-widow-control/lua-widow-control.opm
@@ -0,0 +1,27 @@
+% lua-widow-control
+% https://github.com/gucci-on-fleek/lua-widow-control
+% SPDX-License-Identifier: MPL-2.0+
+% SPDX-FileCopyrightText: 2022 Max Chernoff
+
+\_codedecl\lwcenable{lua-widow-control <v1.1.6>} %%version
+
+\_clubpenalty=1
+\_widowpenalty=1
+\_displaywidowpenalty=0
+\_interlinepenalty=0
+\_brokenpenalty=0
+
+\_newdimen\lwcemergencystretch
+\lwcemergencystretch=3em
+
+\_directlua{require "lua-widow-control"}
+
+% 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
+
+\_endcode