我正在尝试定义一个要使用的宏,如下所示:
\usepackage[normalem]{ulem}
\newcommand{\thesis}[1]{\uline{\ignorespaces #1\unskip}}
% underlining required by school - I know, I know
% later...
\thesis{
This is the beginning of a multi-line thesis statement.
I use one sentence on each line throughout my document.
Thus, the thesis is broken as in XKCD 1285.
}
问题是 不会\unskip
吞掉最后的换行符。如果我添加注释(如as in XKCD 1285.%
),那么它会按预期工作,但这不是\unskip
应该做的吗?
初始空格被正确吞掉。\ignorespaces
开头没有下划线空格,但\ignorespaces
删除了它。\unskip
应该删除末尾的下划线语句,但没有。
我的理解是\unskip
有点像\ignorepreviousspace
。这是正确的吗?
梅威瑟:
\documentclass{article}
\usepackage[normalem]{ulem}
\newcommand{\thesis}[1]{\uline{\ignorespaces #1\unskip}}
\begin{document}
\thesis{
Foo.
Bar.
Baz.
} % comment at end of previous line gives desired output
\end{document}
答案1
\uline
解析其参数以将文本划分为单词。解析后的单词被放入一个框中以测量其宽度并用标记(线、双线、波浪线等)覆盖。因此,\unskip
从新单词的开头到框的开头。没有要删除的空间。因此它没有效果。
推杆\unskip
后 \uline{...}
更好,因为它可以去除胶水。但\uline
插入二在空格处添加它们。第一个是下划线空格(\leaders
),第二个是小负空格(-1/300 英寸),可能是为了使下划线段更好地重叠而添加的。
在后面\unskip
只添加一个\uline
其他,现已删除的答案(仅对 10K+ 用户可见),如果行尾\thesis
被注释删除,则意外起作用。在段落末尾,TeX 通过隐式删除最后一个空格\unskip
。
解决方案有两个\unskip
\documentclass{article}
\usepackage[normalem]{ulem}
\newcommand*{\thesis}[1]{%
\uline{\ignorespaces #1}%
\unskip\unskip
}
\begin{document}
Before. \thesis{
Foo.
Bar.
Baz.
} After.
\end{document}
解决方案与包trimspaces
下一个示例使用包trimspaces
在将文本传递给 之前删除空格\uline
。这使解决方案更加独立于 的实现\uline
。
\documentclass{article}
\usepackage[normalem]{ulem}
\usepackage{trimspaces}
\makeatletter
\newcommand*{\thesis}[1]{%
\def\thesis@text{#1}%
\trim@spaces@in\thesis@text
\expandafter\uline\expandafter{\thesis@text}%
}
\makeatother
\begin{document}
Before. \thesis{
Foo.
Bar.
Baz.
} After.
\end{document}
答案2
Heiko 已经完整描述了如何解决这个问题,所以我只对子问题进行评论
我的理解是
\unskip
有点像\ignorepreviousspace
。这是正确的吗?
基本上不是,这种理解是不正确的。\unskip
并且\ignorespaces
在完全不同的级别上工作(并且%
在换行符再次在另一个级别上工作之前)。
稍微简化一下,TeX 读取一系列人物从文件中,然后变成代币(通过将一组字符读取为命令名称,或将 catcode 值分配给字符标记)然后处理这些标记列表,并最终产生水平或垂直列表排版盒和胶水。
%
在人物。如果看到 a,则%
该行上其余的字符以及行末的换行符将被跳过,并且根本不会变成标记。
\ignorespaces
在代币.\ignorespaces
在命令影响结束时,所有空格标记(通常在垂直模式下被忽略,或在水平模式下添加单词间粘合)都被忽略,直到看到第一个非空格标记。
\unskip
在列表。如果前一个项目添加到当前水平列表(无论来自空格还是来自显式或隐式\vskip
或\hskip
从当前列表中删除并丢弃。(除了在页面上的主垂直列表中,您不能删除已添加的项目,并且\unskip
是无操作)。
除了它们在不同的结构上操作之外,请注意(这与本问题段落末尾的处理有关),它\ignorespaces
会忽略任何数量的连续空格,但\unskip
只会删除一个粘合节点。通常当然\ignorespaces
只会看到一个要忽略的空格标记,因为您必须努力将两个连续的标记作为连续的空格人物被标记为单个空格标记。但是例如\ignorespaces\space\space
会忽略两者。