![使用 soul 包时页码出现错误](https://linux22.com/image/239594/%E4%BD%BF%E7%94%A8%20soul%20%E5%8C%85%E6%97%B6%E9%A1%B5%E7%A0%81%E5%87%BA%E7%8E%B0%E9%94%99%E8%AF%AF.png)
我最近在使用该软件包时遇到了一个奇怪的错误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
,注册一个新的寄存器可能也更合适。(例如参见这个问题。
我已经创建一个问题在soul
github 页面上,但它似乎处于非活动状态。
示范
经过上述修复后,以下文档中的页码是正确的。但是,如果您删除它们,页码将重置为 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
不是soul
andsl
会在 的范围内产生关于段落结尾的错误\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}