From e8be1d547a4b7dae051eb30aabd3fb75e754a1df Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sat, 19 Mar 2022 20:03:16 +0000 Subject: lua-widow-control (18mar22) git-svn-id: svn://tug.org/texlive/trunk@62811 c570f23f-e606-0410-a88d-b1316a301751 --- .../doc/luatex/lua-widow-control/README.md | 8 +- .../luatex/lua-widow-control/lua-widow-control.pdf | Bin 415431 -> 375961 bytes .../lua-widow-control/lwc-documentation.mkxl | 11 +- .../luatex/lua-widow-control/lwc-documentation.tex | 114 +++++++++++---------- .../source/luatex/lua-widow-control/lwc-sample.tex | 6 +- .../lua-widow-control/t-lua-widow-control.mkiv | 8 +- .../lua-widow-control/t-lua-widow-control.mkxl | 8 +- .../lua-widow-control-2022-02-22.sty | 2 +- .../lua-widow-control/lua-widow-control.sty | 30 +++--- .../luatex/lua-widow-control/lua-widow-control.lua | 31 +++--- .../luatex/lua-widow-control/lua-widow-control.tex | 5 +- .../optex/lua-widow-control/lua-widow-control.opm | 3 +- 12 files changed, 128 insertions(+), 98 deletions(-) diff --git a/Master/texmf-dist/doc/luatex/lua-widow-control/README.md b/Master/texmf-dist/doc/luatex/lua-widow-control/README.md index 920873c5b06..e6e9ce0b295 100644 --- a/Master/texmf-dist/doc/luatex/lua-widow-control/README.md +++ b/Master/texmf-dist/doc/luatex/lua-widow-control/README.md @@ -7,7 +7,7 @@ lua-widow-control ================= -Lua-widow-control is a Plain TeX/LaTeX/ConTeXt/OpTeX package that removes widows and orphans without any user intervention. Using the power of LuaTeX, it does so _without_ stretching any glue or shortening any pages or columns. Instead, lua-widow-control automatically lengthens a paragraph on a page or column where a widow or orphan would otherwise occur. +Lua-widow-control is a Plain TeX/LaTeX/ConTeXt/OpTeX package that removes widows and orphans without any user intervention. Using the power of LuaTeX, it does so _without_ stretching any glue or shortening any pages or columns. Instead, lua-widow-control automatically lengthens a paragraph on a page or column where a widow or orphan would otherwise occur. Please see the [**full documentation**](https://github.com/gucci-on-fleek/lua-widow-control/releases/latest/download/lua-widow-control.pdf) for more. @@ -38,14 +38,14 @@ To load the package, add the relevant line to your preamble: Contributing ------------ -Please see [`contributing.md`](https://github.com/gucci-on-fleek/lua-widow-control/blob/master/.github/contributing.md). +Please see [`CONTRIBUTING.md`](https://github.com/gucci-on-fleek/lua-widow-control/blob/master/CONTRIBUTING.md). Licence ------- Lua-widow-control is licensed under the [_Mozilla Public License_, version 2.0](https://www.mozilla.org/en-US/MPL/2.0/) or greater. The documentation is additionally licensed under [CC-BY-SA, version 4.0](https://creativecommons.org/licenses/by-sa/4.0/legalcode) or greater. -Please note that a compiled document is absolutely **not** considered to be an "Executable Form" as defined by the MPL. The use of lua-widow-control in a document does not place **any** obligations on the document's author or distributors. The MPL and CC-BY-SA licenses **only** apply to you if you distribute the lua-widow-control source code or documentation. +Please note that a compiled document is absolutely **not** considered to be an "Executable Form" as defined by the MPL. The use of lua-widow-control in a document does not place **any** obligations on the document's author or distributors. The MPL and CC-BY-SA licenses **only** apply to you if you distribute the lua-widow-control source code or documentation. --- -_v2.0.0 (2022-03-07)_ +_v2.0.1 (2022-03-18)_ diff --git a/Master/texmf-dist/doc/luatex/lua-widow-control/lua-widow-control.pdf b/Master/texmf-dist/doc/luatex/lua-widow-control/lua-widow-control.pdf index 9243a3a07c9..106f106a087 100644 Binary files a/Master/texmf-dist/doc/luatex/lua-widow-control/lua-widow-control.pdf and b/Master/texmf-dist/doc/luatex/lua-widow-control/lua-widow-control.pdf differ diff --git a/Master/texmf-dist/source/luatex/lua-widow-control/lwc-documentation.mkxl b/Master/texmf-dist/source/luatex/lua-widow-control/lwc-documentation.mkxl index 4edaa106941..8a0a0fe3822 100644 --- a/Master/texmf-dist/source/luatex/lua-widow-control/lwc-documentation.mkxl +++ b/Master/texmf-dist/source/luatex/lua-widow-control/lwc-documentation.mkxl @@ -117,7 +117,7 @@ setbounds currentpicture to boundingbox OverlayBox; align=flushleft, ]{% {\ssa\bf Warning} - + #1 }} \blank[line] @@ -139,6 +139,7 @@ setbounds currentpicture to boundingbox OverlayBox; ] \define[1]\meta{\m{\langle}\italic{#1}\m{\rangle}} +\define[1]\githubissue{\goto{(Issue~\##1)}[url(https://github.com/gucci-on-fleek/lua-widow-control/issues/#1)]} %%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%% Section Commands %%%%% @@ -146,6 +147,8 @@ setbounds currentpicture to boundingbox OverlayBox; \definecharacterkerning[titlekern][factor=0.2] +\protected\def\interwordspace{\scaledfontdimen2\font} + % Section \startsetups[style:section] \setcharacterkerning[titlekern] @@ -202,7 +205,7 @@ setbounds currentpicture to boundingbox OverlayBox; \else \box0 \fi - + \goodbreak \stoptexdefinition @@ -295,7 +298,7 @@ interfaces.implement { \dontleavehmode \blackrule[depth=-0.25\baselineskip, height=\dimexpr0.25\baselineskip + 0.4pt, width=8em] \par - + \doifdocumentvariable{ctan}{ \strippedurl{\documentvariable{ctan}} } @@ -306,7 +309,7 @@ interfaces.implement { \noindentation \stopalignment -\stopsetups +\stopsetups \startsetups[document:start] \setup[titleblock] diff --git a/Master/texmf-dist/source/luatex/lua-widow-control/lwc-documentation.tex b/Master/texmf-dist/source/luatex/lua-widow-control/lwc-documentation.tex index 1194acb44fa..6e9eaacc662 100644 --- a/Master/texmf-dist/source/luatex/lua-widow-control/lwc-documentation.tex +++ b/Master/texmf-dist/source/luatex/lua-widow-control/lwc-documentation.tex @@ -29,21 +29,20 @@ \def\titlecite[#1]{\cite[title][#1]\cite[#1]} -\usemodule[vim] -\definevimtyping[TEX][syntax=tex, lines=split, escape=comment, directory=tmp] -\definevimtyping[LUA][syntax=lua, lines=split, escape=comment, directory=tmp] +\definetype[inlineTEX][option=tex, escape={$,$}, lines=hyphenated] +\definetype[inlineLUA][option=lua, escape={$,$}, lines=hyphenated] \input lwc-sample \startdocument[ title=lua-widow-control, author=Max Chernoff, - version=2.0.0, %%version + version=2.0.1, %%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{}/Op\TeX{} 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. +\Lwc/ is a Plain~\TeX/\LaTeX/\ConTeXt{}/Op\TeX{} 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 your document. For more details, see the \goto{Usage sections}[sec:usage]. @@ -65,6 +64,9 @@ Widows occur when when the majority of a paragraph is on one page or column, but \subsection{Orphans} Orphans are when the first line of a paragraph occurs on the page or column before the remainder of they paragraph. They are not nearly 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 do, so they tend to be ignored more often. +\subsection{Broken Hyphens} +\q{Broken} hyphens occur whenever a page break occurs part way through a hyphenated word. These really have nothing to do with \waos/; however, \TeX{} treats broken hyphens exactly the same as it does \waos/. In addition, breaking a word across two pages is at almost as bad for the reader as \waos/; therefore, \lwc/ treats broken hyphens exactly the same way as it treats \waos/. + \startplacefigure[location={here, top, bottom}, title={A visual comparison of \waos/.}, reference=tab:widow] \getbuffer[widow-orphan] \stopplacefigure @@ -81,7 +83,7 @@ However, some objects have penalties attached. These penalties make \TeX{} treat One important note: once \TeX{} begins breaking a page, it never goes back and modifies any content on the page. Page breaking is a localized algorithm, without any backtracking. \subsection{Behavior} -Of course, this algorithm doesn't allow us to intuitively understand how \TeX{} deals with \waos/. +Of course, this algorithm doesn't allow us to intuitively understand how \TeX{} deals with \waos/. Due to the penalties attached to \waos/, \TeX{} treats them as if they are longer than they actually are. Widows and orphans with small penalties attached---like \LaTeX's default values of 150---are only treated as slightly taller than 1 line, while \waos/ with large penalties---values near 10\,000---are treated as if they are 2 lines tall. Because potential \wao/ lines are broken as if they are taller than they actually are, \TeX{} will tend to group them together on the same pages. @@ -92,16 +94,17 @@ There have been a few previous attempts to improve upon \TeX's previously-discus \titlecite[tugboat-strategies] and \titlecite[tugboat-widows] both begin with comprehensive discussions of the methods of preventing \waos/. They both agree that \waos/ are bad and ought to be avoided; however, they each differ in solutions. \italic{Strategies}\cite[tugboat-strategies] proposes an output routine that reduces the length of facing pages by 1~line when necessary to remove \waos/ while \italic{Managing}\cite[tugboat-widows] proposes that the author manually rewrites or adjusts the \tex{looseness} when needed. -\titlecite[widow-assist] contains a file \type{widow-assist.lua} that automatically detects which paragraphs can be safely shortened or lengthened by 1 line. \titlecite[widows-and-orphans] alerts the author to the pages that contain widows or orphans. Combined, these packages make it very simple for the author to quickly remove \waos/ by adjusting the \tex{looseness} values; however, it still requires the author to make manual source changes after each revision. +\titlecite[widow-assist] contains a file \type{widow-assist.lua} that automatically detects which paragraphs can be safely shortened or lengthened by 1 line. \titlecite[widows-and-orphans] alerts the author to the pages that contain widows or orphans. Combined, these packages make it very simple for the author to quickly remove \waos/ by adjusting the \tex{looseness} values; however, it still requires the author to make manual source changes after each revision. \Lwc/ is essentially just a combination of \type{widow-assist.lua}\cite[widow-assist] and \sans{widows-and-orphans}:\cite[widows-and-orphans] when the \openalty/ shows that a \woo/ occurred, Lua is used to find a stretchable paragraph. What \lwc/ adds on top of these packages is automation: \lwc/ eliminates the requirement for any manual adjustments. +\startpostponing \startTEXpage[ align=normal, width=100cm, autowidth=force, offset=5pt, - pagestate=start + pagestate=start, ] \veryraggedcenter \setupTABLE[row][first][style=\ssbf, align=middle] @@ -116,7 +119,7 @@ There have been a few previous attempts to improve upon \TeX's previously-discus \NC \typesetbuffer[shorten][frame=on,page=1] \NC \typesetbuffer[stretch][frame=on,page=1] \NC \typesetbuffer[lwc][frame=on,page=1] - \NC\NR + \NC\NR \NC \typesetbuffer[ignore][frame=on,page=2] \NC \typesetbuffer[shorten][frame=on,page=2] @@ -124,15 +127,16 @@ There have been a few previous attempts to improve upon \TeX's previously-discus \NC \typesetbuffer[lwc][frame=on,page=2] \NC\NR - \NC \processTEXbuffer[ignore-code] - \NC \processTEXbuffer[shorten-code] - \NC \processTEXbuffer[stretch-code] - \NC \processTEXbuffer[lwc-code] + \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} @@ -145,21 +149,21 @@ As you can see, the last line of the page is on a separate page from the rest of This page did not leave any widows, but it did shorten the previous page by 1~line. Sometimes this is acceptable, but usually it looks bad because each page will 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{Stretch} -This page also has no widows and it has a flushed bottom margin. However, the space between each paragraph had to be stretched. +This page also has no widows and it has a flushed bottom margin. However, the space between each paragraph 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 behavior. However, in a page with mostly text, these paragraph gaps can look unsightly. +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 behavior. However, in a page with mostly text, these paragraph gaps can look unsightly. In addition, this method is incompatible with typesetting on a grid since all glue stretch must be quantized to the height of a line. \subsection{\lwc/} -\Lwc/ has none of these issues: it eliminates the widows in a document while keeping a flushed bottom margin and constant paragraph spacing. +\Lwc/ has none of these issues: it eliminates the widows in a document while keeping a flushed 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 it becomes nearly 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{Installation} -Most up-to-date \TeX~Live and Mik\TeX{} systems should already have \lwc/ installed. However, a manual installation may occasionally be required. +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}. @@ -231,11 +235,11 @@ Please note that when running in legacy mode, you cannot use the key--value inte \subsection{Overview} -\LaTeX{} users can set the options either when loading the package (\tex{usepackage[\meta{options}]\{lua-widow-control\}}) or at any point using \tex{lwcsetup\{\meta{options}\}}. +\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 always use the \tex{setuplwc[\meta{options}]} command. +\ConTeXt{} users should always use the \inlineTEX{\setuplwc[$\meta{options}$]} command. -Plain~\TeX{} and Op\TeX{} are a little different. Some options have commands provided (i.e., \tex{lwcemergencystretch=\meta{dimension}}), while others must be set manually (i.e., \tex{directlua\{lwc.debug = true\}}). +Plain~\TeX{} and Op\TeX{} are a little different. Some options have commands provided (i.e., \inlineTEX{\lwcemergencystretch = $\meta{dimension}$}), while others must be set manually (i.e., \inlineTEX{\directlua{lwc.debug = true}}). Also, please note that not all commands are provided for all formats. @@ -271,7 +275,7 @@ Also, please note that not all commands are provided for all formats. \subsection{Strict Mode} -By default, \lwc/ takes all possible measures to remove \waos/. This normally works out pretty well; however, sometimes these measures may be a little more aggressive than certain users want. +By default, \lwc/ takes all possible measures to remove \waos/. This normally works out pretty well; however, sometimes these measures may be a little more aggressive than certain users want. \Lwc/ offers a \q{strict} mode that will only make modification to the page that are near-imperceptible to remove \waos/. @@ -281,28 +285,28 @@ By default, \lwc/ takes all possible measures to remove \waos/. This normally wo \NC\NR \stopTABLE -Internally, this sets {\tt emergencystretch = 0pt}, {\tt max-cost = 2500}, and {\tt nobreak = warn}. +Internally, this sets {\tt emergencystretch = 0pt}, {\tt max-cost = 5000}, and {\tt nobreak = warn}. \subsection{\estretch/} -You can configure the \estretch/ used when stretching a paragraph. The default value is 3~em. +You can configure the \estretch/ used when stretching a paragraph. The default value is 3~em. \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{} still 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 \NC \plainop/ - \NC\tex{lwcemergencystretch=\meta{dimension}} + \NC\inlineTEX{\lwcemergencystretch = $\meta{dimension}$} \NC\NR \NC \LaTeX{} - \NC\tex{lwcsetup\{emergencystretch = \meta{dimension}\}} + \NC\inlineTEX{\lwcsetup{emergencystretch = $\meta{dimension}$}} \NC\NR \NC \ConTeXt{} - \NC\tex{setuplwc[emergencystretch = \meta{dimension}]} + \NC\inlineTEX{\setuplwc[emergencystretch = $\meta{dimension}$]} \NC\NR \stopTABLE \subsection{Selectively Disabling} -Sometimes, you may want to disable \lwc/ for certain commands where stretching is undesirable. For example, you typically wouldn't want section headings to be stretched. +Sometimes, you may want to disable \lwc/ for certain commands where stretching is undesirable. For example, you typically wouldn't want section headings to be stretched. You could just disable then reenable \lwc/ every time that you use the command; however, \lwc/ provides a convenience macro that will do this automatically for you. @@ -310,33 +314,36 @@ You could just disable then reenable \lwc/ every time that you use the command; \startTABLE \NC Plain \TeX{} - \NC \tex{lwcdisablecmd\{\meta{\backslash macro}\}} + \NC \inlineTEX{\lwcdisablecmd{$\meta{\backslash macro}$}} \NC\NR \NC \LaTeX{} - \NC \tex{lwcsetup\{disablecmds = \{\meta{\backslash macroone}, \meta{\backslash macrotwo}\}\}} + \NC \inlineTEX{\lwcsetup{disablecmds = {$\meta{\backslash macroone}$, $\meta{\backslash macrotwo}$}}} \NC\NR \NC \ConTeXt{} - \NC \tex{prependtoks\backslash lwc@patch@pre\backslash to\backslash everybefore\meta{hook}} - \NC\NR\NC\NC \tex{prependtoks\backslash lwc@patch@post\backslash to\backslash everyafter\meta{hook}} + \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 \subsection{Widow and Orphan Penalties} -You can also manually adjust the penalties that \TeX{} assigns to \waos/. Usually, the defaults are fine, but advanced users may want to change them. +You can also manually adjust the penalties that \TeX{} assigns to widows, orphans, and broken hyphens. Usually, the defaults are fine, but advanced users may want to change them. \startTABLE \NC \plainop/ - \NC\tex{widowpenalty=\meta{integer}} - \NC\NR\NC\NC\tex{clubpenalty=\meta{integer}} + \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\tex{lwcsetup\{widowpenalty = \meta{integer}\}} - \NC\NR\NC\NC\tex{lwcsetup\{orphanpenalty = \meta{integer}\}} + \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\tex{setuplwc[widowpenalty = \meta{integer}]} - \NC\NR\NC\NC\tex{setuplwc[orphanpenalty = \meta{integer}]} + \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 @@ -354,13 +361,13 @@ When \lwc/ encounters an orphan, it removes it by removing the orphaned line to \startTABLE \NC \plainop/ - \NC\tex{directlua\{lwc.nobreak_behaviour = "\meta{value}"\}} + \NC\inlineTEX{\directlua{lwc.nobreak_behaviour = "$\meta{value}$"}} \NC\NR \NC \LaTeX{} - \NC\tex{lwcsetup\{nobreak = \meta{value}\}} + \NC\inlineTEX{\lwcsetup{nobreak = $\meta{value}$}} \NC\NR \NC \ConTeXt{} - \NC\tex{setuplwc[nobreak = \meta{value}]} + \NC\inlineTEX{\setuplwc[nobreak = $\meta{value}$]} \NC\NR \stopTABLE @@ -375,20 +382,20 @@ The value \type{warn} causes \lwc/ to give up on the page and do nothing, leavin When \TeX{} breaks a paragraph, it scores it by the number of \q{demerits}. The demerits for a paragraph is the sum of the squared badnesses for each line, plus any \q{additional demerits} added for any other reason. The badness for a line is proportional the cube of the glue stretch ratio, so demerits grow with the sixth power of glue stretch. To choose the \q{best} paragraph on the page, \lwc/ uses a \q{cost function} $C$ that is initially defined as \startformula - C = \frac{d}{2\sqrt{l}} -\stopformula where $d$ is the total demerits of the paragraph, and $l$ is the number of lines in the paragraph. + 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. By default, \lwc/ just 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 \NC \plainop/ - \NC\tex{lwcmaxcost=\meta{integer}} + \NC\inlineTEX{\lwcmaxcost = $\meta{integer}$} \NC\NR \NC \LaTeX{} - \NC\tex{lwcsetup\{max-cost = \meta{integer}\}} + \NC\inlineTEX{\lwcsetup{max-cost = $\meta{integer}$}} \NC\NR \NC \ConTeXt{} - \NC\tex{setuplwc[maxcost = \meta{integer}]} + \NC\inlineTEX{\setuplwc[maxcost = $\meta{integer}$]} \NC\NR \stopTABLE @@ -419,17 +426,19 @@ Since \TeX{} implements column breaking and page breaking through the same inter \section[sec:issues]{Known Issues} \startitemize - \item \Lwc/ will rarely fail to correctly move the last line on an expanded page to the next page in documents with \emph{very} small paper sizes. + \item \Lwc/ will rarely fail to correctly move the last line on an expanded page to the next page in documents with \emph{very} small paper sizes. \githubissue{19} \item When a 3-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 better than widows, so this is still an improvement. \item Sometimes a \woo/ cannot be eliminated because no paragraph has enough \q{stretch}. This can \emph{sometimes} be remediated by increasing \lwc/'s \estretch/; however, some pages just don't have enough \q{stretchy} paragraphs. Long paragraphs with short words tend to be \q{stretchier} than short paragraphs with long words since these long paragraphs will have more interword glue. Narrow columns also stretch easier than wide columns since you need to expand a paragraph by less to make a new line. - \item When running under \LuaMetaTeX, the log may be filled with lines like \q{\tt luatex warning > tex: left parfill skip is gone}. This is harmless and can be ignored. % I have no idea how to fix this. The LMTX manual has "\parfillleftskip" in the indices, but that's all that I can find about it. + \item When running under \LuaMetaTeX, the log may be filled with lines like \q{\tt luatex warning > tex: left parfill skip is gone}. This is harmless and can be ignored. \githubissue{7} % I have no idea how to fix this. The LMTX manual has "\parfillleftskip" in the indices, but that's all that I can find about it. + + \item \Lwc/ will rarely raise a \q{\tt Circular node list detected!} warning. This occurs when the replacement paragraph node list loops back on itself. This is usually harmless, but can rarely cause the entire compile to completely fail. \githubissue{9} - \item \Lwc/ will rarely raise a \q{\tt Circular node list detected!} warning. This occurs when the replacement paragraph node list loops back on itself. This is usually harmless, but can rarely cause the entire compile to completely fail. + \item \TeX{} may warn you about over or underfull vboxes on pages where \lwc/ removed a \woo/. This is a false alarm and can be ignored. \githubissue{8} - \item \TeX{} may warn you about over or underfull vboxes on pages where \lwc/ removed a \woo/. This is a false alarm and can be ignored. + \item If there is a footnote on the last line of the page with a \woo/, \lwc/ will sometimes move the \q{footnote mark} but not the \q{footnote text}, thus breaking up a footnote. \githubissue{26} \stopitemize \section{The Algorithm} @@ -473,11 +482,13 @@ Please note that a compiled document is \bold{not} considered to be an \q{Execut ] \section[sec:implementation]{Implementation} +\usemodule[scite] \setupbodyfont[10pt] \setuphead[subsection][ alternative=normal, style=\ssita, - before={\blank[big, preference]}, + page=yes, + continue=yes, ] \subsection{lua-widow-control.lua} @@ -492,7 +503,6 @@ Please note that a compiled document is \bold{not} considered to be an \q{Execut \typeTEXfile{../source/lua-widow-control.sty} -\def\module{\tex{module}} \subsection{t-lua-widow-control.mkxl/mkiv} \typeTEXfile{../source/t-lua-widow-control.mkxl} diff --git a/Master/texmf-dist/source/luatex/lua-widow-control/lwc-sample.tex b/Master/texmf-dist/source/luatex/lua-widow-control/lwc-sample.tex index 0ba9f17f76b..8df05999a52 100644 --- a/Master/texmf-dist/source/luatex/lua-widow-control/lwc-sample.tex +++ b/Master/texmf-dist/source/luatex/lua-widow-control/lwc-sample.tex @@ -37,10 +37,10 @@ \setuplanguage[en][spacing=packed] \starttext - \Lwc/ can remove most widows and orphans from a document, \emph{without} stretching any glue or shortening any pages. - + \Lwc/ can remove most widows and orphans from a document, \emph{without} stretching any glue or shortening any pages. + It does so by automatically lengthening a paragraph on a page where a widow or orphan would otherwise occur. While \TeX{} breaks paragraphs into their natural length, \lwc/ is breaking the paragraph 1~line longer than its natural length. \TeX{}'s paragraph is output to the page, but \lwc/'s paragraph is just stored for later. When a widow or orphan occurs, \lwc/ can take over. It selects the previously-saved paragraph with the least badness; then, it replaces \TeX{}'s paragraph with its saved paragraph. This increases the text block height of the page by 1~line. - + Now, the last line of the current page can be pushed to the top of the next page. This removes the widow or the orphan without creating any additional work. \stoptext \stopbuffer 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 index e24f972d577..716e45dcf5f 100644 --- 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 @@ -1,10 +1,10 @@ %D \module %D [ file=t-lua-widow-control, -%D version=2.0.0, %%version +%D version=2.0.1, %%version %D title=lua-widow-control, %D subtitle=\ConTeXt module for lua-widow-control, %D author=Max Chernoff, -%D date=2022-03-07, %%dashdate +%D date=2022-03-18, %%dashdate %D copyright=Max Chernoff, %D license=MPL-2.0+, %D url=https://github.com/gucci-on-fleek/lua-widow-control] @@ -52,6 +52,7 @@ \clubpenalty=\lwcparameter{orphanpenalty} \widowpenalty=\lwcparameter{widowpenalty} \displaywidowpenalty=\lwcparameter{widowpenalty} + \brokenpenalty=\lwcparameter{brokenpenalty} \stopsetups \setups[*default] @@ -67,6 +68,7 @@ debug=\v!stop, orphanpenalty=1, widowpenalty=1, + brokenpenalty=1, nobreak=keep, maxcost=2147483647, ] @@ -74,7 +76,7 @@ % 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. +% lengthened paragraphs to not have terrible spacing. \definefontfeature[default][default][expansion=quality] \setupalign[hz] 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 e24f972d577..716e45dcf5f 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=2.0.0, %%version +%D version=2.0.1, %%version %D title=lua-widow-control, %D subtitle=\ConTeXt module for lua-widow-control, %D author=Max Chernoff, -%D date=2022-03-07, %%dashdate +%D date=2022-03-18, %%dashdate %D copyright=Max Chernoff, %D license=MPL-2.0+, %D url=https://github.com/gucci-on-fleek/lua-widow-control] @@ -52,6 +52,7 @@ \clubpenalty=\lwcparameter{orphanpenalty} \widowpenalty=\lwcparameter{widowpenalty} \displaywidowpenalty=\lwcparameter{widowpenalty} + \brokenpenalty=\lwcparameter{brokenpenalty} \stopsetups \setups[*default] @@ -67,6 +68,7 @@ debug=\v!stop, orphanpenalty=1, widowpenalty=1, + brokenpenalty=1, nobreak=keep, maxcost=2147483647, ] @@ -74,7 +76,7 @@ % 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. +% lengthened paragraphs to not have terrible spacing. \definefontfeature[default][default][expansion=quality] \setupalign[hz] diff --git a/Master/texmf-dist/tex/lualatex/lua-widow-control/lua-widow-control-2022-02-22.sty b/Master/texmf-dist/tex/lualatex/lua-widow-control/lua-widow-control-2022-02-22.sty index 783db59ed22..e8b2eefb0a4 100644 --- a/Master/texmf-dist/tex/lualatex/lua-widow-control/lua-widow-control-2022-02-22.sty +++ b/Master/texmf-dist/tex/lualatex/lua-widow-control/lua-widow-control-2022-02-22.sty @@ -38,7 +38,7 @@ % 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. +% lengthened paragraphs to not have terrible spacing. \RequirePackage{etoolbox} \AtEndPreamble{ \@ifpackageloaded{microtype}{}{ % Only load if not already loaded 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 56462e40d87..fc80a58cfbb 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 @@ -5,7 +5,7 @@ % Formats built after 2015 include \LuaTeX{}Base, so this is the absolute % minimum version that we will run under. -\NeedsTeXFormat{LaTeX2e}[2015/01/01] +\NeedsTeXFormat{LaTeX2e}[2015/01/01] % For _really_ old formats \providecommand\DeclareRelease[3]{} @@ -13,7 +13,7 @@ \DeclareRelease{}{0000-00-00}{lua-widow-control-2022-02-22.sty} \DeclareRelease{v1.1.6}{2022-02-22}{lua-widow-control-2022-02-22.sty} -\DeclareCurrentRelease{v2.0.0}{2022-03-07} %%version %%dashdate +\DeclareCurrentRelease{v2.0.1}{2022-03-18} %%version %%dashdate % If this version of LaTeX doesn't support command hooks, then we load % the last v1.1.X version of the package. @@ -23,8 +23,8 @@ \ProvidesExplPackage {lua-widow-control} - {2022/03/07} %%slashdate - {v2.0.0} %%version + {2022/03/18} %%slashdate + {v2.0.1} %%version {Use Lua to remove widows and orphans} % Unconditional Package Loads @@ -44,15 +44,15 @@ \msg_new:nnn { \c__lwc_name_str } { patch-failed } - { + { Patching~ \c_backslash_str #1~ failed. \\ - Please~ ensure~ that~ \c_backslash_str #1~ exists. + Please~ ensure~ that~ \c_backslash_str #1~ exists. } \msg_new:nnn { \c__lwc_name_str } { old-format-patch } - { + { Patching~ not~ supported~ with~ old~ LaTeX. \\ Please~ use~ a~ LaTeX~ format~ >=~ 2021/06/01. } @@ -60,9 +60,9 @@ \msg_new:nnn { \c__lwc_name_str } { old-command } - { + { \c_backslash_str #1~ has~ been~ REMOVED! \\ - Please~ use~ \c_backslash_str setuplwc \c_left_brace_str #2 + Please~ use~ \c_backslash_str setuplwc \c_left_brace_str #2 \c_right_brace_str\ instead. } @@ -91,6 +91,10 @@ orphanpenalty .value_required:n = true, orphanpenalty .initial:n = 1, + brokenpenalty .int_gset:N = \tex_brokenpenalty:D, + brokenpenalty .value_required:n = true, + brokenpenalty .initial:x = 1, + microtype .bool_gset:N = \g__lwc_use_microtype_bool, microtype .value_required:n = true, microtype .initial:n = true, @@ -194,16 +198,16 @@ debug / false .code:n = \lua_now:n { lwc.debug = false }, strict .meta:n = { emergencystretch = 0pt, - max-cost = 2500, - nobreak = warn, + max-cost = 5000, + nobreak = warn, }, strict .value_forbidden:n = true, default .meta:n = { emergencystretch = 3em, max-cost = \c_max_int, - nobreak = keep, + nobreak = keep, }, - default .value_forbidden:n = true, + default .value_forbidden:n = true, } % Add the user interface for the keys 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 5801feef129..be9cab16cb9 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 @@ -107,8 +107,8 @@ elseif plain or latex or optex then debug_print("Plain/LaTeX") luatexbase.provides_module { name = lwc.name, - date = "2022/03/07", --%%slashdate - version = "2.0.0", --%%version + date = "2022/03/18", --%%slashdate + version = "2.0.1", --%%version description = [[ This module provides a LuaTeX-based solution to prevent @@ -182,7 +182,7 @@ local function register_callback(t) with \LuaTeX{}base, \ConTeXt{} leaves some \LuaTeX{} callbacks unregistered and unfrozen. Because of this, we need to register some callbacks at the engine level. This is fragile though, because a future \ConTeXt{} update - may decide to register one of these functions, in which case + may decide to register one of these functions, in which case \lwc/ will crash with a cryptic error message. ]] return { @@ -225,7 +225,7 @@ end function lwc.paragraph_cost(demerits, lines) - return demerits / (2 * math.sqrt(lines)) + return demerits / math.sqrt(lines) end @@ -299,14 +299,17 @@ function lwc.save_paragraphs(head) return head end + +local last_paragraph = 0 --- 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, attribute, #paragraphs) - set_attribute(last(head), attribute, -1 * #paragraphs) + set_attribute(head, attribute, #paragraphs + (100 * pagenum())) + set_attribute(last(head), attribute, -1 * (#paragraphs + (100 * pagenum()))) + last_paragraph = #paragraphs return head end @@ -326,7 +329,7 @@ local function safe_last(head) if ids[id] then warning [[Circular node list detected! -This should never happen. I'll try and +This should never happen. I'll try and recover, but your output may be corrupted. (Internal Error)]] prev.next = nil @@ -385,7 +388,7 @@ function lwc.remove_widows(head) #paragraphs >= 1 then else paragraphs = {} - return head + return head_save end info("Widow/orphan detected. Attempting to remove.") @@ -398,7 +401,9 @@ function lwc.remove_widows(head) -- We find the current "best" replacement, then free the unused ones for i, paragraph in pairs(paragraphs) do - if paragraph.cost < best_cost and i <= #paragraphs - 1 then + if paragraph.cost < best_cost and + i ~= last_paragraph + then -- Clear the old best paragraph flush_list(paragraphs[paragraph_index].node) paragraphs[paragraph_index].node = nil @@ -421,7 +426,9 @@ function lwc.remove_widows(head) ")" ) - if best_cost > tex.getcount(max_cost) then + if best_cost > tex.getcount(max_cost) or + paragraph_index == last_paragraph + then -- If the best replacement is too bad, we can't do anything warning("Widow/Orphan NOT removed on page " .. pagenum()) paragraphs = {} @@ -488,7 +495,7 @@ function lwc.remove_widows(head) debug_print("remove_widows", "found " .. value) -- Insert the start of the replacement paragraph - if value == paragraph_index then + if value == paragraph_index + (100 * pagenum()) then debug_print("remove_widows", "replacement start") safe_last(target_node) -- Remove any loops @@ -497,7 +504,7 @@ function lwc.remove_widows(head) end -- Insert the end of the replacement paragraph - if value == -1 * paragraph_index then + if value == -1 * (paragraph_index + (100 * pagenum())) then debug_print("remove_widows", "replacement end") safe_last(target_node).next = head.next break 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 7a75e52132f..6d4f0722e35 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 @@ -3,7 +3,7 @@ % SPDX-License-Identifier: MPL-2.0+ % SPDX-FileCopyrightText: 2022 Max Chernoff -\wlog{lua-widow-control v2.0.0} %%version +\wlog{lua-widow-control v2.0.1} %%version \ifx\directlua\undefined \errmessage{% @@ -17,6 +17,7 @@ \clubpenalty=1 \widowpenalty=1 \displaywidowpenalty=1 +\brokenpenalty=1 \newdimen\lwcemergencystretch \lwcemergencystretch=3em @@ -28,7 +29,7 @@ % 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. +% lengthened paragraphs to not have terrible spacing. \expandglyphsinfont\the\font 20 20 5 \adjustspacing=2 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 index 992d817a5c8..8980ca60076 100644 --- 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 @@ -3,11 +3,12 @@ % SPDX-License-Identifier: MPL-2.0+ % SPDX-FileCopyrightText: 2022 Max Chernoff -\_codedecl\lwcenable{lua-widow-control } %%version +\_codedecl\lwcenable{lua-widow-control } %%version \_clubpenalty=1 \_widowpenalty=1 \_displaywidowpenalty=1 +\_brokenpenalty=1 \_newdimen\lwcemergencystretch \lwcemergencystretch=3em -- cgit v1.2.3