寻找所有寡妇和孤儿

寻找所有寡妇和孤儿

关于如何避免出现孤行和寡行的问题已经有很多,所以我首先要声明这不是这里的问题。我知道我可以尝试调整设置,但仍然有可能出现孤行和寡行。

我确实想问的是,是否有一些简单的方法(包)来获取文档中所有孤儿和寡妇的列表。写入单独的文件或仅在文件处理完成后输出。

答案1

是的,如果您准备接受一定程度的误报,这是可能的。基本上,对于这两种情况,TeX 都使用特殊惩罚,这些惩罚可以在输出例程中识别。因此,下面的代码将 的值设置为\widowpenalty151, \clubpenalty将 (orphans) 的值设置为 152(LaTeX 默认值为 150)。我们使用以下代码:

\documentclass %[twocolumn]
    {article}

\clubpenalty=152
\widowpenalty=153

% we want to know if we are on first or second column in a 2 column document
\makeatletter
  \def\oncol{\if@twocolumn \space \if@firstcolumn  (first \else (second \fi column)\fi}
\makeatletter

% check if the output penalty was due to orphan or widow or both
\def\testforwidowsandorphans{%
   \ifnum\outputpenalty=153
        \typeout{*** Widow on page  \thepage \oncol}%
  \else
       \ifnum\outputpenalty=152
          \typeout{*** Orphan on page \thepage \oncol}%
      \else
         \ifnum\outputpenalty=305
            \typeout{*** Orphan and Widow on page \thepage \oncol}%
        \fi
      \fi
 \fi
}

% execute this code at the very beginning of the OR
\toks0=\output
\output\expandafter{\expandafter\testforwidowsandorphans
                                   \the\toks0}


\newcommand\stupidpara{First line\\second line\\and final line\par}
\newcommand\verystupidpara{First line\\and final one\par}

\setlength\textheight{5\baselineskip}

\begin{document}
  \stupidpara\stupidpara\stupidpara\stupidpara
   \verystupidpara\verystupidpara\verystupidpara\verystupidpara
\end{document}

基本上,我们测试\outputpenalty触发该页面的页面是 152 还是 153 或 305,即它们的总和(如果两行段落断开,就会出现这种情况)。这将为我们提供输出:

*** Widow on page 1
[1]
*** Orphan on page 2
[2]
*** Orphan and Widow on page 3

如果我们以双列模式排版同一篇文档,我们会得到

*** Widow on page 1 (first column)
*** Orphan on page 1 (second column)
[1]
*** Orphan and Widow on page 2 (first column)

您可能会发现其他分页符会产生相同的惩罚(这会导致误报),因此正确选择初始值至关重要。当然,您可以使用 150,而不区分寡妇和孤儿。

最后说明:可能还应该添加\displaywidowpenalty到测试中(这里的默认值在 LaTeX 中是 50,而不是简单的,\typeout人们可以想到更复杂的输出,但这只是语法糖。

小更新

正如 David Carlisle 在其他地方所言,最好不要使用 151(我最初对 就是这么做的\clubpenalty),因为标准 LaTeX 使用 151,\pagebreak[2]因此我们会得到一些不必要的误报。当然,如果任何此类默认值发生更改,上述代码也需要更改。

还值得注意的是:即使只改变很小的惩罚量,也意味着文档的中断行为可能会改变,即,在添加该代码后,文档的中断行为可能会有所不同。由于此版本仅添加警告,因此最好一直使用它,不要犯在纠正了报告的所有问题后在“最终”运行之前将其删除的错误。这可能只是意味着您之后会看到新的中断 --- 不太可能,但并非不可能!

现已作为套装提供

上述代码的扩展版本现已在 CTAN 上作为包提供widows-and-orphans。它会自动计算惩罚值以使所有内容唯一且可检测,除了孤行和孤行之外,它还会检测跨列或页面边界的连字以及与前面的文本分离的数学显示(如果文档允许的话)。

下一篇 Tugboat 将包含一篇文章,讨论解决此类问题的各种方法。我很快也会将其发布在https://latex-project.org/publications

相关内容