我的问题描述
因此,我正在做一些黑客攻击,这需要我使用ulem
软件包。我在这个软件包的文档第 5 页(日期为 2019/11/18)上找到了以下内容:
括号和宏替换的一个重要不兼容性:括号内或来自宏的所有文本都排版在一个框中(就像在 \mbox 中一样)。因此,括号将抑制其所包含的文本的拉伸和换行
我对这个功能非常不满意,因此有以下问题
他们为什么必须引入这种功能?
他们是如何实现这种功能的?更具体地说,我想知道他们的源代码中的哪些代码
ulem.sty
引入了这种功能。稍稍离题一下。我发现,在 中,下划线和突出显示等功能都很难使用
LaTeX
。我说的难,是指现有的解决方案要么存在许多缺陷,要么我们必须进行一些艰难的黑客攻击才能实现它。例如,这里描述的这个令人不快的功能。或者使用 时的ulem
恶名。但是,在其他标记语言中,它会非常容易使用。例如,在和中,人们只需使用标签。在 中,人们可以使用Reconstruction failed
soul
HTML
Markdown
<u>
ConTeXt
\definetextbackground
。两者都易于使用。那么,是什么使得 中的下划线功能如此难以实现呢LaTeX
?注意,我这里不是问为什么人们应该从印刷方面避免使用下划线。我是问哪种底层编码机制使得下划线如此难以实现。
MWE 如果有帮助的话
\documentclass{book}
\usepackage{soul}
\usepackage{ulem}
\usepackage{lipsum}
\usepackage[colorlinks=true]{hyperref}
\begin{document}
% \ul{\lipsum[1]} % the infamous Reconstruction failed error
% \ul{\href{www.google.com}{Google}} % also some other error
% \ul{\url{www.google.com}} % also some other error
\ul{Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque dictum enim neque, non interdum diam vulputate et. Maecenas rhoncus vel libero vitae auctor. Pellentesque nec nisl sed nisi egestas tristique. Donec in semper tellus, sit amet pellentesque est. Sed scelerisque risus ut orci interdum convallis. Quisque placerat vehicula malesuada. Vestibulum est libero, pretium sit amet turpis vel, vulputate rhoncus nibh. Proin dictum lacus ut enim finibus tempus. Praesent malesuada viverra faucibus. Aliquam nisi risus, eleifend vel lorem a, porttitor molestie nunc. Phasellus porta urna sit amet tellus euismod, vitae aliquet augue commodo. Etiam congue bibendum enim. Donec congue dignissim massa, eget sodales erat tristique eu. Donec a diam vel eros vestibulum eleifend. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis id gravida nulla.} % normal
\uline{\lipsum[1]} % by macro replacement, no line break
\uline{{Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque dictum enim neque, non interdum diam vulputate et. Maecenas rhoncus vel libero vitae auctor. Pellentesque nec nisl sed nisi egestas tristique. Donec in semper tellus, sit amet pellentesque est. Sed scelerisque risus ut orci interdum convallis. Quisque placerat vehicula malesuada. Vestibulum est libero, pretium sit amet turpis vel, vulputate rhoncus nibh. Proin dictum lacus ut enim finibus tempus. Praesent malesuada viverra faucibus. Aliquam nisi risus, eleifend vel lorem a, porttitor molestie nunc. Phasellus porta urna sit amet tellus euismod, vitae aliquet augue commodo. Etiam congue bibendum enim. Donec congue dignissim massa, eget sodales erat tristique eu. Donec a diam vel eros vestibulum eleifend. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis id gravida nulla.}} % extra brace, also no line break
\uline{Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque dictum enim neque, non interdum diam vulputate et. Maecenas rhoncus vel libero vitae auctor. Pellentesque nec nisl sed nisi egestas tristique. Donec in semper tellus, sit amet pellentesque est. Sed scelerisque risus ut orci interdum convallis. Quisque placerat vehicula malesuada. Vestibulum est libero, pretium sit amet turpis vel, vulputate rhoncus nibh. Proin dictum lacus ut enim finibus tempus. Praesent malesuada viverra faucibus. Aliquam nisi risus, eleifend vel lorem a, porttitor molestie nunc. Phasellus porta urna sit amet tellus euismod, vitae aliquet augue commodo. Etiam congue bibendum enim. Donec congue dignissim massa, eget sodales erat tristique eu. Donec a diam vel eros vestibulum eleifend. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis id gravida nulla.} %normal
\uline{\href{www.google.com}{Google}} % work fine
\uline{\url{www.google.com}} % work fine
\end{document}
答案1
任何用于绘制规则或下划线的 tex 基元都将形成一个牢不可破的框,因此ulem
必须soul
进行大量工作在输入的每个部分周围添加多个框以尝试在不丢失断点的情况下进行下划线,在考虑连字符和任意嵌套的 tex 命令的同时执行此操作很困难,而且存在限制也就不足为奇了。
上下文当然是 luatex 独有的,使用 lualatex 时您可能更喜欢lua-ul
使用 Lua 来访问较低级别内容的包,因此可以使用经典 tex 中不可用的功能。
答案2
我对 David 的评论很感兴趣,他指出上下文的处理在多大程度上取决于引擎。因此,我尝试了这个简单的例子:
\setuppapersize[A6]
\define\lipsum%
{\dosingleargument\dolipsum}
\def\dolipsum[#1]%
{Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque dictum enim neque, non interdum diam vulputate et. Maecenas rhoncus vel libero vitae auctor. Pellentesque nec nisl sed nisi egestas tristique. Donec in semper tellus, sit amet pellentesque est. Sed scelerisque risus ut orci interdum convallis. Quisque placerat vehicula malesuada. Vestibulum est libero, pretium sit amet turpis vel, vulputate rhoncus nibh. Proin dictum lacus ut enim finibus tempus. Praesent malesuada viverra faucibus. Aliquam nisi risus, eleifend vel lorem a, porttitor molestie nunc. Phasellus porta urna sit amet tellus euismod, vitae aliquet augue commodo. Etiam congue bibendum enim. Donec congue dignissim massa, eget sodales erat tristique eu. Donec a diam vel eros vestibulum eleifend. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis id gravida nulla.}
\showframe
\starttext
\underbar{\input knuth\relax}
\underbar{\lipsum[1]}
\stoptext
我正在创建一个\lipsum
不可扩展的虚假命令来模仿 LaTeX 中发生的情况。
使用 ConTeXt MkII(即 pdftex 引擎),我得到以下输出(仅粘贴第 1 页)。请注意,下划线有效,但没有连字符。
使用 ConTeXt MkIV(即 luatex 引擎)和 ConTeXt LMTX(即 luametatex 引擎),我得到以下输出(下划线有效并且有连字符:
我不记得 MkII 中的下划线是如何实现的(MkII 已被弃用十多年了),但在 pdftex 中带下划线的文本可以换行(以连字符为代价)。