% lua-widow-control
% https://github.com/gucci-on-fleek/lua-widow-control
% SPDX-License-Identifier: MPL-2.0+ OR CC-BY-SA-4.0+
% SPDX-FileCopyrightText: 2022 Max Chernoff

\doifnot{\contextmark}{LMTX}{
    \errhelp{LMTX/MkXL is required to compile this file.}
    \errmessage{Fatal error, exiting.}
}

\environment lwc-manual

\usemodule[lua-widow-control]
\usebtxdataset[\jobname.bib]

\useURL[projecturl][https://github.com/gucci-on-fleek/lua-widow-control]
\useURL[download][https://github.com/gucci-on-fleek/lua-widow-control/releases/latest]
\useURL[ctan][https://www.ctan.org/pkg/lua-widow-control]

% Abbreviations
\def\lwc/{\sans{lua-\allowbreak widow-\allowbreak control}}
\def\Lwc/{\sans{Lua-\allowbreak widow-\allowbreak control}}
\def\estretch/{\tex{emergency\allowbreak stretch}}
\def\openalty/{\tex{output\allowbreak penalty}}
\def\waos/{widows and orphans}
\def\wao/{widow and orphan}
\def\woo/{widow or orphan}
\def\mkxl/{\ConTeXt~Mk\acronym{XL}}
\def\mkiv/{\ConTeXt~Mk\acronym{IV}}
\define\OpTeX{Op\kern-.05em\TeX}
\def\LuaMeta{Lua\-Meta\-}
\def\LuaMetaTeX{\LuaMeta\TeX}
\def\plainop/{Plain~\TeX{}/\OpTeX{}}
\let\q=\quotation

\def\titlecite[#1]{\cite[title][#1]\cite[#1]}

\definetype[inlineTEX][option=tex, escape={$,$}, lines=hyphenated]
\definetype[inlineLUA][option=lua, escape={$,$}, lines=hyphenated]

\input lwc-manual-samples

\definecolor[expanded][r=0.00, g=0.70, b=0.25]
\definecolor[failure] [r=0.90, g=0.00, b=0.25]
\definecolor[moved]   [r=0.25, g=0.25, b=1.00]
\definecolor[cost]    [r=0.50, g=0.50, b=0.50]

\usemodule[markdown]
\define[4]\markdownRendererLinkPrototype{\goto{#1}[url(#3)]}
\def\markdownOptionHtml{true}
\def\markdownOptionShiftHeadings{1}
\startluacode
    interfaces.implement {
        name = "markdownRendererHeadingThreePrototype",
        public = true,
        arguments = { "string" },
        actions = function (str)
            context.subsection {
                title = str,
                list = str:match "v%d+%.%d+%.%d+"
            }
        end
    }
\stopluacode

\startdocument[
    title=lua-widow-control,
    author=Max Chernoff,
    version=3.0.0, %%version
    github=https://github.com/gucci-on-fleek/lua-widow-control,
    ctan=https://www.ctan.org/pkg/lua-widow-control,
]

\Lwc/ is a Plain~\TeX/\LaTeX/\ConTeXt{}/\OpTeX{} package that removes \waos/ without any user intervention. Using the power of \LuaTeX{}, it does so \emph{without} stretching any glue or shortening any pages or columns. Instead, \lwc/ automatically lengthens a paragraph on a page or column where a \woo/ would otherwise occur.

\section{Quick Start}
Ensure that your \TeX~Live/Mik\TeX{} distribution is up-to-date. Then, \LaTeX{} users just need to place \inlineTEX{\usepackage{lua-widow-control}} in the preamble of their document. For more details, see the \goto{Usage sections}[sec:usage].

\subject{Contents}
\placecontent[criterium=all]

\section{Preliminaries}

This manual begins with a brief introduction to widows, orphans, and \lwc/. For an extended introduction and discussion of these topics, please see the \emph{Zpravodaj} article\cite[zpravodaj] distributed with this manual (Links: \goto{local}[lwc-zpravodaj::], \goto{\acronym{CTAN}}[url(http://mirrors.ctan.org/macros/luatex/generic/lua-widow-control/lwc-zpravodaj.pdf)], \goto{GitHub}[url(https://github.com/gucci-on-fleek/lua-widow-control/releases/latest/download/lwc-zpravodaj.pdf)]). This same material is also available in two \emph{TUGboat} articles\cite[tugboat1, tugboat2] (Links: \goto{local}[tb133chernoff-widows::], \goto{\acronym{CTAN}}[url(http://mirrors.ctan.org/macros/luatex/generic/lua-widow-control/tb133chernoff-widows.pdf)], \goto{GitHub}[url(https://github.com/gucci-on-fleek/lua-widow-control/releases/latest/download/tb133chernoff-widows.pdf)]) if you prefer. You can also skip ahead to the \goto{installation instructions on \at{page}[sec:install]}[sec:install] or the \goto{usage section starting at \at{page}[sec:usage]}[sec:usage].

\section[sec:motivation]{Motivation}

Unmodified \TeX{} has only two familiar ways of dealing with \waos/: it can
either shorten a page by one line, or it can stretch vertical
whitespace. \TeX{} was designed for mathematical and scientific typesetting,
where a typical page has multiple section headings, tables, figures, and
equations. For this style of document, \TeX's default behaviour works quite
well, since the slight stretching of whitespace between the various document
elements is nearly imperceptible; however, for prose or other documents
composed almost entirely of paragraphs, there is little vertical whitespace
to stretch.

\Lwc/ offers an alternative method of removing \waos/: instead of shortening a page or stretching vertical whitespace, \lwc/ simply chooses a paragraph to lengthen by one~line such that the \woo/ is eliminated.

\section{Widows and Orphans}
\subsection{Widows}
A \q{widow} occurs when the majority of a paragraph is on one page or column,
but the last line is on the following page or column. It not only looks
quite odd for a lone line to be at the start of the page, but it makes a
paragraph harder to read since the separation of a paragraph and
its last line disconnects the two, causing the reader to lose context for
the widowed line.

\subsection{Orphans}
An \q{orphan} occurs when the first line of a paragraph is at the end
of the page or column preceding the remainder of the paragraph. They are not
as distracting for the reader, but they are still not ideal.
Visually, \waos/ are about equally disruptive; however, orphans tend not to
decrease the legibility of a text as much as widows, so some authors choose
to ignore them.

\subsection{Broken Hyphens}
\q{Broken} hyphens occur whenever a page break occurs in a
hyphenated word. These are not related to \waos/; however,
breaking a word across two pages is at least as disruptive for the reader
as \waos/. \TeX{} identifies broken hyphens in the same ways as \waos/, so
\lwc/ treats broken hyphens in the same way.

\startplacefigure[location={here, top, bottom}, title={A visual comparison of \waos/.}, reference=tab:widow]
    \getbuffer[widow-orphan]
\stopplacefigure

\section{\TeX's Pagination}
\subsection{Algorithm}
It is tricky to understand how \lwc/ works if you aren't familiar with how
\TeX{} breaks pages and columns. For a full description, you should
consult Chapter~15 of \titlecite[texbook] (\q{How \TeX{} Makes Lines
into Pages}); however, this goes into much more detail than most users
require, so here is a \emph{very} simplified summary of \TeX{}'s page
breaking algorithm:

\TeX{} fills the page with lines and other objects until the next object
will no longer fit. Once no more objects will fit, \TeX{} will align the
bottom of the last line with the bottom of the page by stretching any
available vertical spaces if (in \LaTeX) \tex{flushbottom} is set;
otherwise, it will
break the page and leave the bottom empty.

However, some objects have \q{penalties} attached. Penalties encourage or
discourage page breaks from occurring at specific places. For example,
\LaTeX{} sets a negative penalty before section headings to encourage a
page break there; conversely, it sets a positive penalty after section
headings to discourage breaking.

To reduce \waos/, \TeX{} sets weakly-positive penalties between the
first and second lines of a paragraph to prevent orphans, and between the
penultimate and final lines to prevent widows.

\subsection{Behaviour}

Due to these \q{penalties} attached to \waos/, \TeX{} tries to avoid
creating them. Widows and orphans with small penalties attached---like
\LaTeX's default values of 150---are only lightly coupled to the rest
of the paragraph, while \waos/ with large penalties---values of
10\,000 or more---are treated as infinitely bad and are thus
unbreakable. Intermediate values behave just as you would expect,
discouraging page breaks proportional to their value.

However, when these lines are moved as a group, \TeX{} will have to make a page or column with less lines. \about[sec:demo] goes into further detail about how \TeX{} deals with these too-short pages or columns.

\startpostponing
\startTEXpage[
    align=normal,
    width=100cm,
    autowidth=force,
    offset=5pt,
    pagestate=start,
]
    \veryraggedcenter
    \setupTABLE[row][first][style=\ssbf, align=middle]
    \setupTABLE[frame=off, offset=5pt]
    \startTABLE
        \NC Ignore
        \NC Shorten
        \NC Stretch
        \NC \Lwc/ \NC\NR

        \NC \typesetbuffer[ignore][frame=on,page=1]
        \NC \typesetbuffer[shorten][frame=on,page=1]
        \NC \typesetbuffer[stretch][frame=on,page=1]
        \NC \typesetbuffer[lwc][frame=on,page=1]
        \NC\NR

        \NC \typesetbuffer[ignore][frame=on,page=2]
        \NC \typesetbuffer[shorten][frame=on,page=2]
        \NC \typesetbuffer[stretch][frame=on,page=2]
        \NC \typesetbuffer[lwc][frame=on,page=2]
        \NC\NR

        \NC \typebuffer[ignore-code][option=TEX]
        \NC \typebuffer[shorten-code][option=TEX]
        \NC \typebuffer[stretch-code][option=TEX]
        \NC \typebuffer[lwc-code][option=TEX]
        \NC\NR
    \stopTABLE

    \placefloatcaption[table][reference=tab:demo, title={A visual comparison of various automated widow handling techniques.}]
\stopTEXpage
\stoppostponing

\section[sec:demo]{Demonstration}

Although \TeX{}'s page breaking algorithm is reasonably
straightforward, it can lead to
complex behaviour when \waos/ are involved. The usual
choices, when rewriting is not possible, are to ignore them,
stretch some glue, or shorten the
page. \in{Table}[tab:demo] has a visual comparison of these
options, which we'll discuss in the following:

\subsection{\q{Ignore}}

As you can see, the last line of the page is on a separate page from the
rest of its paragraph, creating a widow. This is usually highly
distracting for the reader, so it is best avoided for the reasons previously
discussed.

\subsection{\q{Shorten}}

This page did not leave any widows, but it did shorten the previous page
by one line. Sometimes this is acceptable, but usually it looks bad because
pages will then have different text-block heights. This can make the pages
look quite uneven, especially when typesetting with columns or in a book
with facing pages.

\subsection{\q{Stretch}}

This page also has no widows and it has a flush bottom margin. However,
the space between each pair of paragraphs had to be stretched.

If this page had many equations, headings, and other elements with
natural space between them, the stretched out space would be much less
noticeable. \TeX{} was designed for mathematical typesetting, so it makes
sense that this is its default behaviour. However, in a page with mostly
text, these paragraph gaps look unsightly.

Also, this method is incompatible with grid typesetting, where
all glue stretching must be quantised to the height of a line.

\subsection{\q{\lwc/}}

\Lwc/ has none of these issues: it eliminates the widows in a document
while keeping a flush bottom margin and constant paragraph spacing.

To do so, \lwc/ lengthened the second paragraph by one line. If you look
closely, you can see that this stretched the interword spaces. This
stretching is noticeable when typesetting in a narrow text block, but
is mostly imperceptible with larger widths.

\Lwc/ automatically finds the \q{best} paragraph to stretch, so the
increase in interword spaces should almost always be minimal.

\section[sec:install]{Installation}
Most up-to-date \TeX~Live and Mik\TeX{} systems should already have \lwc/ installed. However, a manual installation may occasionally be required.

\subsection{\TeX~Live}
Run \type{tlmgr install lua-widow-control} in a terminal, or install using the \q{\TeX~Live Manager} \acronym{GUI}.

\subsection{Mik\TeX}
Run \type{mpm --install=lua-widow-control} in a terminal, or install using the \q{Mik\TeX{} Maintenance} \acronym{GUI}.

\subsection{Manual}
Currently, \mkxl/ (\LuaMetaTeX{}) users must manually install the package. Most other users will be better served by using the \lwc/ supplied by \TeX~Live and Mik\TeX{}; however, all users may manually install the package if desired. The procedure should be fairly similar regardless of your \acronym{OS}, \TeX{}  distribution, or format.

\subsection{Steps}
\startitemize[N]
    \item Download \type{lua-widow-control.tds.zip} from \goto{\acronym{CTAN}}[url(ctan)], \goto{GitHub}[url(download)] or the \goto{\ConTeXt{}~Garden}[url(https://modules.contextgarden.net/cgi-bin/module.cgi/action=view/id=127)].
    \item Unzip the release into your \type{TEXMFLOCAL/} directory. (You can find its location by running \type{kpsewhich --var-value TEXMFHOME} in a terminal)
    \item Refresh the filename database: \startitemize[1]
        \item \ConTeXt: \type{mtxrun --generate}
        \item \TeX~Live: \type{mktexlsr}
        \item Mik\TeX: \type{initexmf --update-fndb}
    \stopitemize
\stopitemize

\section{Dependencies}
\Lwc/ does have a few dependencies; however, these will almost certainly be met by all but the most minimal of \TeX{} installations.

\subsection{Plain~\TeX{}}
\Lwc/ requires \LuaTeX{} ($\ge$ 0.85) and the most recent version of \sans{luatexbase} (2015/10/04). Any version of \TeX~Live $\ge$ 2016 will meet these requirements.

\subsection{\LaTeX{}}
\Lwc/ requires \LuaTeX{} ($\ge$ 0.85), \LaTeX{} ($\ge$ 2020/10/01), and \sans{microtype} (any version). Any version of \TeX~Live $\ge$ 2021 will meet these requirements.

\Lwc/ also supports a \q{legacy} mode for older \LaTeX{} kernels. This uses an older version of the \LaTeX{} code while still using the most recent Lua code. This mode requires \LuaTeX{} ($\ge$ 0.85), \LaTeX{} ($\ge$ 2015/01/01), \sans{microtype} (any version), and \sans{etoolbox} (any version). Any version of \TeX~Live $\ge$ 2016 will meet these requirements.

Please note that when running in legacy mode, you cannot use the key--value interface. This legacy interface is undocumented, but mostly the same as the \q{Plain~\TeX{}} interface.

\subsection{\ConTeXt{}}
\Lwc/ supports both \mkxl/ (\LuaMetaTeX{}) and \mkiv/ (\LuaTeX{}).

\subsection{\OpTeX{}}
\Lwc/ works with any version of \OpTeX{} and has no dependencies.

\subsection{LuaMeta\TeX{}}

\Lwc/ has preliminary support for LuaMeta\LaTeX{} and LuaMetaPlain. All features should work identically to the \LuaTeX{}-based version, although there are a few minor bugs. You should always make sure to use the latest engine, format, and \lwc/ since these formats are under rapid development.


\section[sec:usage]{Loading the Package}

\startTABLE[setups=commandtable]
    \NC Plain~\TeX{}
    \NC\inlineTEX{\input  lua-widow-control}
    \NC\NR
    \NC \LaTeX{}
    \NC\inlineTEX{\usepackage{lua-widow-control}}
    \NC\NR
    \NC \ConTeXt{}
    \NC\inlineTEX{\usemodule[lua-widow-control]}
    \NC\NR
    \NC \OpTeX{}
    \NC\inlineTEX{\load[lua-widow-control]}
    \NC\NR
\stopTABLE

\section{Options}

\Lwc/ is automatically enabled with the default settings as soon as you load it. Most users should not need to configure \lwc/; however, the packages provides a few commands.

\subsection{Overview}

\LaTeX{} users can set the options either when loading the package (\inlineTEX{\usepackage[$\meta{options}$]{lua-widow-control}}) or at any point using \inlineTEX{\lwcsetup{$\meta{options}$}}.

\ConTeXt{} users should use the \inlineTEX{\setuplwc[$\meta{options}$]} command for setting options at any point.

Plain~\TeX{} and \OpTeX{} are a little different. Some options require you to set a register (i.e., \inlineTEX{\lwcemergencystretch = $\meta{dimension}$}), while others use macro arguments (i.e., \inlineTEX{\lwcnobreak{$\meta{option}$}}).

\subsection{Disabling}

You may want to disable \lwc/ for certain portions of your
document. You can do so with the following commands:

\startTABLE[setups=commandtable]
    \NC \plainop/
    \NC\inlineTEX{\lwcdisable}
    \NC\NR
    \NC \LaTeX{}
    \NC\inlineTEX{\lwcsetup{disable}}
    \NC\NR
    \NC \ConTeXt{}
    \NC\inlineTEX{\setuplwc[state = stop]}
    \NC\NR
\stopTABLE

This prevents \lwc/ from stretching any paragraphs that follow. If a page
has earlier paragraphs where \lwc/ was still enabled and a \woo/ is
detected, \lwc/ will still attempt to remove the \woo/.

\subsection{Enabling}

\Lwc/ is enabled as soon as the package is loaded. If you
have previously disabled it, you will need to re-enable it to save new paragraphs.

\startTABLE[setups=commandtable]
    \NC \plainop/
    \NC\inlineTEX{\lwcenable}
    \NC\NR
    \NC \LaTeX{}
    \NC\inlineTEX{\lwcsetup{enable}}
    \NC\NR
    \NC \ConTeXt{}
    \NC\inlineTEX{\setuplwc[state = start]}
    \NC\NR
\stopTABLE

\subsection{Automatically disabling}

You may want to disable \lwc/ for certain commands where
stretching is undesirable such as section headings. Of course, manually
disabling and
then enabling \lwc/ multiple times
throughout a document would quickly become tedious, so \lwc/ provides
some options to do this automatically for you.

\Lwc/ automatically patches the default \LaTeX{}, \ConTeXt{},
Plain~\TeX{}, \OpTeX{}, \sans{memoir}, \sans{\acronym{KOMA}-Script}, and
\sans{titlesec} section commands, so you don't need to patch these.
Any others, though, you'll need to patch yourself.

\startTABLE[setups=commandtable]
    \NC \plainop/
    \NC \inlineTEX{\lwcdisablecmd $\meta{\backslash macro}$}
    \NC\NR
    \NC \LaTeX{}
    \NC \inlineTEX{\lwcsetup{disablecmds = {$\meta{macronameone}$, $\meta{macronametwo}$}}}
    \NC\NR
    \NC \ConTeXt{}
    \NC \inlineTEX{\prependtoks\lwc$\hskip-0.5em\relax$@patch@pre\to\everybefore$\hskip-0.5em\relax\meta{hook}$}
    \NC\NR\NC\NC \inlineTEX{\prependtoks\lwc$\hskip-0.5em\relax$@patch@pre\to\everyafter$\hskip-0.5em\relax\meta{hook}$}
    \NC\NR
\stopTABLE

The Plain~\TeX{}, \OpTeX{}, and \ConTeXt{} commands \emph{append} to the list of patched commands: they simply patch the provided commands while leaving the original patches in place. The \LaTeX{} option \emph{sets} the list of patched commands: it replaces the default list with the provided list.

\subsection{\estretch/}

\Lwc/ defaults to an \estretch/ value of 3~em for stretched paragraphs,
but you can configure this.

\Lwc/ will only use the \estretch/ when it cannot lengthen a paragraph
in any other way, so it is fairly safe to set this to a large value.
\TeX{} accumulates badness when \estretch/ is
used, so it's pretty rare that a paragraph that
requires any \estretch/ will actually be used on the page.

\startTABLE[setups=commandtable]
    \NC \plainop/
    \NC\inlineTEX{\lwcemergencystretch = $\meta{dimension}$}
    \NC\NR
    \NC \LaTeX{}
    \NC\inlineTEX{\lwcsetup{emergencystretch = $\meta{dimension}$}}
    \NC\NR
    \NC \ConTeXt{}
    \NC\inlineTEX{\setuplwc[emergencystretch = $\meta{dimension}$]}
    \NC\NR
\stopTABLE

\subsection{Penalties}

You can also manually adjust the penalties that \TeX{} assigns to \waos/.
Usually, the defaults are fine, but there are a few circumstances where you
may want to change them.

\startTABLE[setups=commandtable]
    \NC \plainop/
    \NC\inlineTEX{\widowpenalty = $\meta{integer}$}
    \NC\NR\NC\NC\inlineTEX{\clubpenalty = $\meta{integer}$}
    \NC\NR\NC\NC\inlineTEX{\brokenpenalty = $\meta{integer}$}
    \NC\NR
    \NC \LaTeX{}
    \NC\inlineTEX{\lwcsetup{widowpenalty = $\meta{integer}$}}
    \NC\NR\NC\NC\inlineTEX{\lwcsetup{orphanpenalty = $\meta{integer}$}}
    \NC\NR\NC\NC\inlineTEX{\lwcsetup{brokenpenalty = $\meta{integer}$}}
    \NC\NR
    \NC \ConTeXt{}
    \NC\inlineTEX{\setuplwc[widowpenalty = $\meta{integer}$]}
    \NC\NR\NC\NC\inlineTEX{\setuplwc[orphanpenalty = $\meta{integer}$]}
    \NC\NR\NC\NC\inlineTEX{\setuplwc[brokenpenalty = $\meta{integer}$]}
    \NC\NR
\stopTABLE

The value of these penalties determines how much \TeX{} should attempt
to stretch glue before passing the \woo/ to \lwc/. If you set the values to~1
(default), \TeX{} will stretch nothing and immediately trigger \lwc/;
if you set the values to 10\,000, \TeX{} will stretch infinitely and
\lwc/ will never be triggered. If you set the value to some intermediate
number, \TeX{} will first attempt to stretch some glue to remove the \woo/;
only if it fails will \lwc/ come in and lengthen a paragraph. As a special
case, if you set the values to~0, both \TeX{} and \lwc/ will completely
ignore the \woo/.

\Lwc/ will pick up on the values of \tex{widowpenalty}, \tex{clubpenalty}, and
\tex{brokenpenalty} regardless of how you set them, so the use of these
dedicated keys is entirely optional.

\subsection{\tex{nobreak} Behaviour}

When \lwc/ encounters an orphan, it removes it by moving the orphaned
line to the next page. The majority of the time, this is an appropriate
solution. However, if the orphan is immediately preceded by a section
heading (or \tex{nobreak}\slash\tex{penalty 10000}), \lwc/ would na\"ively separate a section heading from
the paragraph that follows. This is almost always undesirable, so \lwc/
provides some options to configure this.

\startTABLE[setups=commandtable]
    \NC \plainop/
    \NC\inlineTEX{\lwcnobreak{$\meta{value}$}}
    \NC\NR
    \NC \LaTeX{}
    \NC\inlineTEX{\lwcsetup{nobreak = $\meta{value}$}}
    \NC\NR
    \NC \ConTeXt{}
    \NC\inlineTEX{\setuplwc[nobreak = $\meta{value}$]}
    \NC\NR
\stopTABLE

The default value, \type{keep}, \emph{keep}s the section heading with
the orphan by moving both to the next page. The advantage to this option
is that it removes the orphan and retains any \tex{nobreak}s; the
disadvantage is that moving the section heading can create a large blank
space at the end of the page.

The value \type{split} \emph{split}s up the section heading and the
orphan by moving the orphan to the next page while leaving the heading
behind. This is usually a bad idea, but exists for the sake of
flexibility.

The value \type{warn} causes \lwc/ to give up on the page and do nothing,
leaving an orphaned line. \Lwc/ \emph{warn}s the user so that they can
manually remove the orphan.

\startplacefigure[location={here, top, bottom}, title={A visual comparison of the various \type{nobreak} options, where each box represents a different page.}, reference=tab:nobreak]
    \getbuffer[nobreak]
\stopplacefigure

\subsection{Maximum Cost}

\Lwc/ ranks each paragraph on the page by how much it would \q{cost} to
lengthen that paragraph. By default, \lwc/ selects the paragraph on
the page with the lowest cost; however, you can configure it to only
select paragraphs below a selected cost.

If there aren't any paragraphs below the set threshold, then \lwc/ won't
remove the \woo/ and will instead issue a warning.

\startTABLE[setups=commandtable]
    \NC \plainop/
    \NC\inlineTEX{\lwcmaxcost = $\meta{integer}$}
    \NC\NR
    \NC \LaTeX{}
    \NC\inlineTEX{\lwcsetup{max-cost = $\meta{integer}$}}
    \NC\NR
    \NC \ConTeXt{}
    \NC\inlineTEX{\setuplwc[maxcost = $\meta{integer}$]}
    \NC\NR
\stopTABLE

Based on my testing, \type{max-cost} values less than 1\,000
cause completely imperceptible changes in interword spacing; values less
than 5\,000 are only noticeable if you are specifically trying to pick out the
expanded paragraph on the page; values less than 15\,000 are typically
acceptable; and larger values may become distracting. \Lwc/ defaults to an
infinite \type{max-cost}, although the \q{strict} and \q{balanced} modes
sets the values to~5\,000 and 10\,000 respectively.

\Lwc/ uses a \q{cost function} $C$ that is initially defined as \startformula
    C = \frac{d}{\sqrt{l}}
\stopformula where $d$ is the total demerits of the paragraph, and $l$ is the number of lines in the paragraph.

\subsection{Draft Mode}

\setuplwc[draft=start]
\definecolor[lwc_expanded][s=0]
\definecolor[lwc_failure][s=0]
\definecolor[lwc_moved][s=0]
You can use the draft mode to visualize how \lwc/ processes pages. Any \color[failure]{remaining widows and orphans will be coloured red}, any \color[expanded]{expanded paragraphs will be coloured green}, and any \color[moved]{lines moved to the next page will be coloured blue}. In addition, the \color[cost]{cost of each paragraph is shown in the right margin} as it is here.

\startTABLE[setups=commandtable]
    \NC \plainop/
    \NC\inlineTEX{\lwcdraft 1}
    \NC\NR
    \NC \LaTeX{}
    \NC\inlineTEX{\lwcsetup{draft}}
    \NC\NR
    \NC \ConTeXt{}
    \NC\inlineTEX{\setuplwc[draft = start]}
    \NC\NR
\stopTABLE

Advanced users may also customize the colours used by modifying the \inlineLUA{lwc.colours} table. The table keys are currently \type{expanded}, \type{failure}, \type{moved}, and \type{cost}. The table values are \acronym{RGB} 3-tuples, where each element is a float between zero and one.

You can also show or hide the costs and colours independently of each other.

\startTABLE[setups=commandtable]
    \NC \plainop/
    \NC\inlineTEX{\lwcshowcosts 1}
    \NC\NR\NC\NC\inlineTEX{\lwcshowcolours 1}
    \NC\NR
    \NC \LaTeX{}
    \NC\inlineTEX{\lwcsetup{showcosts = true}}
    \NC\NR\NC\NC\inlineTEX{\lwcsetup{showcolours = true}}
    \NC\NR
    \NC \ConTeXt{}
    \NC\inlineTEX{\setuplwc[showcosts = start]}
    \NC\NR\NC\NC\inlineTEX{\setuplwc[showcolours = start]}
    \NC\NR
\stopTABLE

Plain~\TeX{} users will need to modify their output routines to be able to see the costs. Before you ship out the page, you should call \inlineTEX{\lwcpreshipout} with a box number as its argument. For example, here is some sample code to correctly reproduce the standard Plain~\TeX{} output routine:

\startTEX
\newbox\tempshipoutbox
\output={
    \setbox\tempshipoutbox=\vbox{
        \makeheadline
        \pagebody
        \makefootline
    }
    \lwcpreshipout\the\tempshipoutbox
    \shipout\box\tempshipoutbox
    \advancepageno
}
\stopTEX

Setting the output routine like this is automatic in all other formats. \Lwc/ does not modify the output routine in Plain~\TeX{} since most of its users likely have their own output routines.

\subsection{Draft Offset}

In draft mode, the paragraph costs are printed in the margins, offset a certain distance from the page edge. By default, this offset is set to \unit{1 inch}; however, you can change this to any value that you want:

\startTABLE[setups=commandtable]
    \NC \plainop/
    \NC\inlineTEX{\lwcdraftoffset = $\meta{dimension}$}
    \NC\NR
    \NC \LaTeX{}
    \NC\inlineTEX{\lwcsetup{draftoffset = $\meta{dimension}$}}
    \NC\NR
    \NC \ConTeXt{}
    \NC\inlineTEX{\setuplwc[draftoffset = $\meta{dimension}$]}
    \NC\NR
\stopTABLE

\setuplwc[draft=stop]
\subsection{Debug Mode}

\Lwc/ offers a \q{debug} mode that prints extra information in the log files. This may be helpful to understand how \lwc/ is processing paragraphs and pages, although the information is likely inscrutable unless you are the package's author. If you are reporting an issue with \lwc/, make sure to compile your document with debug mode enabled!

\startTABLE[setups=commandtable]
    \NC \plainop/
    \NC\inlineTEX{\lwcdebug 1}
    \NC\NR\NC\NC\inlineTEX{\lwcdebug 0}
    \NC\NR
    \NC \LaTeX{}
    \NC\inlineTEX{\lwcsetup{debug = true}}
    \NC\NR\NC\NC\inlineTEX{\lwcsetup{debug = false}}
    \NC\NR
    \NC \ConTeXt{}
    \NC\inlineTEX{\setuplwc[debug = start]}
    \NC\NR\NC\NC\inlineTEX{\setuplwc[debug = stop]}
    \NC\NR
\stopTABLE

\section{Presets}

As you can see, \lwc/ provides quite a few options. Luckily, there are a few
presets that you can use to set multiple options at once. These presets are
a good starting point for most documents, and you can always manually
override individual options.

Presets are available only with \LaTeX{} and \ConTeXt{}.

\startTABLE[setups=commandtable]
    \NC \LaTeX{}
    \NC\inlineTEX{\lwcsetup{$\meta{preset}$}}\NC\NR
    \NC \ConTeXt{}
    \NC\inlineTEX{\setuplwc[$\meta{preset}$]}\NC\NR
\stopTABLE

\subsection{\type{default}}

If you use \lwc/ without any options, it defaults to this preset. In default
mode, \lwc/ takes all possible measures to remove \waos/ and will not
attempt to stretch any vertical glue. This usually
removes~$\mathord{>}\,95\%$ of all
possible \waos/. The catch here is that this mode is quite aggressive, so
it often leaves behind some fairly \q{spacey} paragraphs.

This mode is good if you want to remove (nearly) all \waos/ from your
document, without fine-tuning the results.

\subsection{\type{strict}}

\Lwc/ also offers a strict mode. This greatly restricts \lwc/'s tolerance
and makes it so that it will only lengthen paragraphs where the change will
be imperceptible.

The caveat with strict mode is that---depending on the document---
\lwc/ will be able to remove less than a third of the \waos/.
For the \waos/ that can't be automatically removed, a warning will be
printed to your terminal and log file so that a human can manually fix the
situation.

This mode is good if you want the best possible typesetting and are willing
to do some manual editing.

\subsection{\type{balanced}}

Balanced mode sits somewhere between default mode and strict mode. This mode
first lets \TeX{} stretch a little glue to remove the \woo/; only if that
fails will it then trigger \lwc/. Even then, the maximum paragraph cost is
capped. Here, \lwc/ can usually remove 90\% of a document's
potential \waos/, and it does so while making a minimal visual impact.

This mode is recommended for most users who care about their document's
typography. This mode is not the default since it doesn't remove all
\waos/: it
still requires a little manual intervention.

% %
\startplacetable[location={here, top, bottom}, title={\Lwc/ options set by each mode.}, reference=tab:modes]
    \startTABLE[setups=booktabs, style=tt, loffset=0.5em]
        \NC {\rm Option} \NC default \NC balanced \NC strict \NC\NR
        \NC max-cost \NC $\infty$ \NC 10000 \NC 5000 \NC\NR
        \NC emergencystretch \NC 3em \NC 1em \NC 0pt \NC\NR
        \NC nobreak \NC keep \NC keep \NC warn \NC\NR
        \NC widowpenalty \NC 1 \NC 500 \NC 1 \NC\NR
        \NC orphanpenalty \NC 1 \NC 500 \NC 1 \NC\NR
        \NC brokenpenalty \NC 1 \NC 500 \NC 1 \NC\NR
    \stopTABLE
\stopplacetable

\section{Lua Interface}

\Lwc/ provides a few public functions and tables that you can safely use or modify as documented. Any Lua interfaces that aren't documented below are subject to change at any time, but ff you do want to use an undocumented interface, please let me know and can easily document it.

\subsection{Costs}

\Lwc/ uses a \q{cost function} to select which paragraph to expand. Typically, this depends on the number of lines and demerits in the broken paragraph; however, you can redefine this function to do something else if you want. The default function is defined as:

\startLUA
--- The "cost function" to use.
---
--- @param demerits number The demerits of the broken paragraph
--- @param lines number The number of lines in the broken paragraph
--- @param nat_demerits number The demerits of the naturally-broken paragraph
--- @param nat_lines number The number of lines in the naturally-broken paragraph
--- @param head node The head of the broken paragraph
--- @return number cost The cost of the broken paragraph
function lwc.paragraph_cost(demerits, lines, nat_demerits, nat_lines, head)
    return demerits / math.sqrt(lines)
end
\stopLUA

\subsection{Activation}

Typically, \lwc/ determines if there are \waos/ at the end of a page by checking the \tex{outputpenalty} register. However, you can use a custom check if you want. The default check is defined as:

\startLUA
--- Determines if we should "activate" lwc for the current page/column.
---
--- @param penalty number The \outputpenalty for the current page/column
--- @param paragraphs table<table<string, node|number>> The `paragraphs` table
--- @param head node The head of the current page/column
--- @return boolean activate True if lwc should move the last line on this page
function lwc.should_remove_widows(penalty, paragraphs, head)
    return is_matching_penalty(penalty)
end
\stopLUA

By setting a custom activation and cost function, you can transform \lwc/ from a \wao/ remover into a custom layout customization tool.

\section{Compatibility}

The \lwc/ implementation is almost entirely in Lua, with only a minimal
\TeX{} footprint. It
doesn't modify the output routine, \tex{everypar}, and
it doesn't insert any whatsits. This means that it should be compatible with
nearly any \TeX{} package, class, and format. Most changes that \lwc/ makes
are not observable on the \TeX{} side.

However, on the Lua side, \lwc/ modifies much of a page's internal
structure.
This should not affect any \TeX{} code; however, it may surprise
Lua code that modifies or depends on the page's low-level structure. This
does not matter for Plain~\TeX{} or \LaTeX{}, where even most Lua-based
packages don't depend on the node list structure; nevertheless, there are
a few issues with \ConTeXt{}.

However, on the Lua side, \lwc/ modifies much of a page's internal
structure. This should not affect any \TeX{} code; however, it may surprise
Lua code that modifies or depends on the page's low-level structure. This
does not affect Plain~\TeX{} or \LaTeX{} where even most Lua-based packages
don't depend on the node list structure. \ConTeXt{} \emph{does} depend on
this internal node structure; however, I have carefully tested the package
to ensure that this causes no issues.

Finally, keep in mind that adding \lwc/ to a document will almost certainly
change its page break locations.

\subsection{Formats}

\Lwc/ runs on all known Lua\TeX{}-based formats: Plain~Lua\TeX{},
Lua\LaTeX{}, \ConTeXt{} Mk\acronym{IV}, and~\OpTeX{}. Unless otherwise
documented, all features should work equally well in all formats.

\Lwc/ is also fully-compatible with the \LuaMeta\TeX{}-based formats:
\ConTeXt{} Mk\acronym{XL}\slash\acronym{LMTX}, \LuaMeta\LaTeX{}, and
\LuaMeta{}Plain. \ConTeXt{} Mk\acronym{XL} works equally
well as \ConTeXt{} Mk\acronym{IV} and Lua\LaTeX{}; however, \LuaMeta\LaTeX{}
and \LuaMeta{}Plain support is still quite early. All features should work,
although there are still a few minor bugs.

All told, \lwc/ supports 7 different format\slash{}engine combinations.

\subsection{Columns}

Since \TeX{} and the formats implement column breaking and page
breaking through the
same internal mechanisms, \lwc/ removes \waos/ between columns just
as it does with \waos/ between pages.

\Lwc/ is known to work with the \LaTeX{} class option \type{twocolumn}
and the two-column output routine from Chapter~23 of \titlecite[texbook].

\subsection{Performance}

\Lwc/ runs entirely in a single pass, without depending on any
\type{.aux} files or the like. Thus, it shouldn't meaningfully
increase compile times. Although \lwc/ internally breaks each paragraph
twice, modern computers break paragraphs near-instantaneously, so you
are not likely to notice any slowdown.

\subsection{\eTeX{} penalties}

Knuth's original \TeX{} has three basic line penalties:
\tex{interlinepenalty}, which
is inserted between all lines; \tex{club\-penalty}, which is inserted after
the first line; and \tex{widow\-penalty}, which is inserted before the last
line. The \eTeX{} extensions generalize these commands with a
syntax similar to \tex{parshape}: with \tex{widow\-penalties} you can set the
penalty between the last, second last, and $n$th last lines of a paragraph;
\tex{inter\-line\-penalties} and \tex{club\-penalties} behave similarly.

\Lwc/ makes no explicit attempts to support these new -\type{penalties}
commands. Specifically, if you give a line a penalty that matches either
\tex{widowpenalty} or \tex{clubpenalty}, \lwc/ will treat the lines
exactly as it would a \woo/. So while these commands won't break \lwc/, they
are likely to lead to some unexpected behaviour.

\subsection{Grids}

\Lwc/ is fully compatible with the grid snapping features of \ConTeXt{} \mkiv/ and \mkxl/.

\subsection{Footnotes}

If there are footnotes (or any other type of inline \tex{insert}) present in the moved line, \lwc/ will move both the \q{footnote mark} and the \q{footnote text} such that both are on the same page. However, this may lead to an odd blank space at the bottom of the page since \lwc/ needs to move both the line and its footnotes. Footnotes cause the same page-breaking issues in unmodified Plain~\TeX{} and \LaTeX{}, so this is mostly unavoidable.

\section{Stability}

The documented interfaces of \lwc/ can be considered stable: I'm not planning on removing or modifying any existing options or commands in any way that would break documents.

However, \lwc/'s page breaking \emph{is} subject to change. I will attempt to keep page breaks the same whenever reasonable; however, I will \emph{rarely} make modifications to the algorithm when I can improve the output quality. Any such changes will be clearly noted in the release notes.

\section{Short last lines}

When lengthening a paragraph with \tex{looseness}, it is common advice to insert
ties (\type{~}) between the last few words of the paragraph to avoid
overly-short last lines\cite[texbook]. \Lwc/ does this automatically,
but instead of using ties or \tex{hbox}es, it uses the
\tex{par\allowbreak fill\allowbreak skip}
parameter. When lengthening a paragraph
(and only when lengthening a paragraph---remember, \lwc/ doesn't
interfere with \TeX{}'s output unless it detects a \woo/), \lwc/ sets
\tex{parfillskip} to \type{0.75\hsize plus 0.05\hsize minus 0.75\hsize}.
This normally makes the last line of a paragraph be at least
20\% of the overall paragraph's width, thus preventing
ultra-short~lines.

\section[sec:issues]{Known Issues}

\startitemize
    \item When a three-line paragraph is at the end of a page forming a
    widow, \lwc/ will remove the widow; however, it will leave an orphan.
    This issue is inherent to any process that removes widows through
    paragraph expansion and is thus unavoidable. Orphans are considered
    to be better than widows\cite[elements], so this is still an
    improvement.

    \item \Lwc/ only attempts to expand paragraphs; it never attempts to shrink them. See the \emph{TUGboat}~article\cite[article] §15.3 for further discussion. \githubissue{33}

    \item \Lwc/ can only expand paragraphs that fit completely on a page. This is unavoidable due to the one-page-at-a-time model: you can't modify the bottom half of a paragraph since its top half has already shipped out, and you can't expand the top half of a paragraph since that can't remove orphans. This only causes issues if your document has paragraphs so long that a page only has two half-paragraphs and zero whole paragraphs.

    \item Sometimes a \woo/ cannot be eliminated because no paragraph has
    enough stretch. Sometimes this can be remediated by
    increasing \lwc/'s \estretch/; however, some pages just don't have
    any suitable paragraph.

    Long paragraphs with short words tend to be stretchier than short
    paragraphs with long words since these long paragraphs have more
    interword glue. Narrow columns also stretch more easily than wide columns
    since you need to expand a paragraph by less to make a new line.

    \item \Lwc/ only attempts to expand paragraphs on a page with
    a \woo/. A global system like in \titlecite[global] would solve this;
    however, this is both \acronym{NP}-complete\cite[plass] and
    impossible to solve in a single pass. Very rarely would such a
    system remove widows or orphans that \lwc/ cannot.
\stopitemize

\section{Contributions}

If you have any issues with \lwc/, please create an issue at the \goto{project's GitHub page}[url(projecturl)]. Or, if you think that you can solve any of the \about[sec:issues] or add any new features, \goto{submit a \acronym{PR}}[url(projecturl)]. Thanks!

\section{License}

\Lwc/ is licensed under the \goto{\emph{Mozilla Public License}, version 2.0}[url(https://www.mozilla.org/en-US/MPL/2.0/)] or greater. The documentation is licensed under \goto{\acronym{CC-BY-SA}, version 4.0}[url(https://creativecommons.org/licenses/by-sa/4.0/legalcode)] or greater as well as the \acronym{MPL}.

Please note that a compiled document is \bold{not} considered to be an \q{Executable Form} as defined by the \acronym{MPL}. The \acronym{MPL} and \acronym{CC-BY-SA} licenses \bold{only} apply to you if you distribute the \lwc/ source code or documentation.

\section{References}

\placelistofpublications

\page

\setuphead[subsection][
    alternative=normal,
    style=\ssitb,
    after={\blank[disable, penalty:10000]}
]
\markdownInput{../../CHANGELOG.md}

\page

\setuplayout[
    width=middle,
    backspace=1in,
    height=9.25in,
]
\section[sec:implementation]{Implementation}

From here and until the end of this manual is the raw source code of \lwc/. This is primarily of interest to developers; most users need not read further.

This code vaguely resembles the typical \LaTeX{} literate programming style, although I use extensive inline comments instead of arcane \sans{docstrip} macros. Hopefully this is  useful as a reference for advanced \lwc/ users as well as anyone doing extensive node manipulation in \LuaTeX{}.

If want to offer any improvements to the code below, please open an issue or a \acronym{PR} on \goto{GitHub}[url(projecturl)].

\usemodule[scite]
\setupbodyfont[10pt]
\setuphead[subsection][
    page=yes,
    continue=yes,
]

\subsection{lua-widow-control.lua}

\typeLUAfile{../source/lua-widow-control.lua}

\subsection{lua-widow-control.tex}

\typeTEXfile{../source/lua-widow-control.tex}

\subsection{lua-widow-control.sty}

\typeTEXfile{../source/lua-widow-control.sty}

\subsection{lua-widow-control-2022-02-22.sty}

\typeTEXfile{../source/lua-widow-control-2022-02-22.sty}

\subsection{t-lua-widow-control.mkxl}

\typeTEXfile{../source/t-lua-widow-control.mkxl}

\subsection{lua-widow-control.opm}

\typeTEXfile{../source/lua-widow-control.opm}

\subsection{Demo from \in{Table}[tab:demo]}

\typeTEXfile{\jobname-demo-text.tmp}

\stopdocument
