使用 soul 包时页码出现错误

使用 soul 包时页码出现错误

我最近在使用该软件包时遇到了一个奇怪的错误soul。我设法将其归结为以下示例。问题是页码混乱了。在下面的例子中,它们应该是 1、2 和 3。实际上,它们是 1、0 和 1,按此顺序排列。看起来(在某些情况下)在环境中添加空白行\hl有时会导致此问题,而删除空白行可以解决问题。正如我们所看到的,删除环境中的空白行\hl{} 可以解决以下示例中的问题。也可以通过其他方式解决问题。

无论如何,既然我已经发现了这一点,我就可以在我的论文中解决这个问题。但是,我很好奇是什么原因造成的,所以我想我最好把这个问题发布出来。我没有尝试询问的创建者soul,我认为它可能无人维护。上次更新是很久以前。这是使用 Debian squeeze,使用 TeX Live 2009 和soul.sty版本 2.4。

我正在使用 LaTex 函数dummytext来生成虚拟数据,感谢本网站的好心人,请参阅使用 TeX/LaTeX 以编程方式生成虚拟文本 我使用的具体解决方案是马丁·沙雷尔

\documentclass[10pt]{article}
\usepackage{soul}
\usepackage{pgffor}
\usepackage{setspace}
\doublespacing
\newcommand\dummytext[3]{%
    \foreach \n in {1,...,#3} {%
        \foreach \k in {1,...,#2} {%
            #1%
        }%
        \\
    }%
}
\pagestyle{myheadings}
\begin{document}
\dummytext{HelloWorld}{5}{52}

\dummytext{HelloWorld}{5}{17}
\hl{

x
}
\end{document}

答案1

问题

问题似乎是soul用作\count0本地暂存寄存器。虽然一般来说,使用偶数\count在本地使用偶数是安全的(参见 .eg这个答案),\count0很特殊,因为它保存着页码。这样使用就可以了。仅有的如果在使用分页符的范围内触发分页符的可能性为零(如同样的答案)。

这正是您在此处看到的情况。虽然分页符不是在带下划线的文本本身中发生的,但它是由 参数中的段落分隔符触发的\hl。在此段落分隔符之前,TeX 仍在考虑将突出显示的文本的第一部分放在上一页。

使固定

通过在序言中添加以下几行可以修复该问题。

\makeatletter %% <- make @ usable in command sequences
\newcount\SOUL@minus
\makeatother  %% <- revert @

这将保留一个新的计数寄存器来soul代替默认使用的计数寄存器。

为了在包级别解决问题,以下行

\countdef\SOUL@minus\z@

soul.dtx需要替换为(例如)

\newcount\SOUL@minus

还有一些其他正在使用的寄存器soul,注册一个新的寄存器可能也更合适。(例如参见这个问题

我已经创建一个问题soulgithub 页面上,但它似乎处于非活动状态。

示范

经过上述修复后,以下文档中的页码是正确的。但是,如果您删除它们,页码将重置为 0,就像您的示例中一样。

\documentclass{article}
\usepackage{soul}
\usepackage{blindtext}

\makeatletter
\newcount\SOUL@minus %% <- without this line the page number would be reset to 0
\makeatother

\begin{document}

\Blindtext[4]

\blindtext
\hl{Closing words

New paragraph!}

\end{document}

这是输出第一页的底部:

输出

如果序言中没有这部分内容,那么情况将会是这样的:

本来可以

答案2

与其说是答案,不如说是问题的简化,希望能够集中于问题(长而格式化的评论?)并提出两种可能的方法来避免它。

\st使用而不是 时,OP 看到的行为与 OP 看到的相同\hl。使用ulem包 and 而\sout不是soulandsl会在 的范围内产生关于段落结尾的错误\sout!段落在 \UL@word 完成之前结束。)。删除括号内的段落结尾可ulem继续并产生具有正确页码的结果。但是,删除相同的段落分隔符后,使用soul也会产生正确的页码。那么,soul当正确或更好的操作是标记错误并停止时,是否继续进行,就像ulem看起来那样?

为了证明这一点,以下更简单的例子也产生了错误的页码:

\documentclass[10pt]{article}
\usepackage{soul}
\usepackage{blindtext}
\begin{document}
\blindtext[8]

\blindtext[8]
\hl{

x
}
\end{document}

然而

...

\blindtext[8]

\hl{
x
}
\end{document}

才不是。

这个问题似乎是soul允许在其参数内中断段落但无法安全地处理它或停止并引发错误。

解决方案似乎是

A) 进行修改soul以识别问题并停止并显示适当的错误消息。

或者

b)不要在命令参数内放置段落分隔符soul

编辑:补充观察

当包含格式化命令(带有包含段落分隔符的参数)的段落的开头soul与所请求格式化的开头位于不同的页面上时,似乎会发生页码编号中断。段落开始的页码设置为 0,并从那里开始计数。在上面的示例中,删除\blindtext上述示例中的其中一行及其附带的段落分隔符会使第一页显示数字 0,而后续页面的计数正确。

这也许符合soul的文档,其中指出“复杂的引擎必须读取并检查每个字符,然后才能将其交给 TEX 的段落生成器”(第 2.2 节)以及文档介绍中的提示“有几种可能性可以强调段落的某些部分”(第 1 节)。

\blindtext通过将第一个参数设置为 8(页码 1,2,3,4)、9(页码 1,0,1,2)以及 10(页码 1,2,3,4),可以在下面的示例中看到各种情况。

\documentclass[10pt, letterpaper]{article}
\usepackage{soul}
\usepackage{blindtext}
\begin{document}
\blindtext[9]

\blindtext
\hl{

x
}

\blindtext[6]
\end{document}

相关内容