(La)TeX — '%' 字符起什么作用?

(La)TeX — '%' 字符起什么作用?

这个%字符似乎有很多用途。到目前为止,我在以下地方遇到过它:

  1. 用于撰写评论
% Schrodinger wave equation
$$\nabla^2\psi + \frac{8\pi^2m}{h^2}(E-V) = 0$$
  1. (这里我可能说错了)对于将命令拆分为多行(参考这里
\newcounter{bull}
\newcommand{\showbullcntr}[1]{%
\setcounter{bull}{#1}%
\bullcntr{bull}%
}
  1. 与 结合使用minipage,删除插入的前导空格(改编自问题)
\noindent
\begin{minipage}{0.5\linewidth}
   ...
\end{minipage}%
\begin{minipage}{0.5\linewidth}
   ...
\end{minipage}

有人可以详细解释一下%LaTeX 中该字符的各种用途吗?特别是,为什么在第一次出现之后使用它\end{minipage}

答案1

您列出的角色的三个用例%可以统一为一个总体用例:将当前输入行剩余部分的所有内容排除在进一步处理之外

一切不仅包括注释(您提到的第一个用例),还包括输入行末尾不可见的行尾字符。事实上,在遇到一个%字符后,TeX 还会忽略下一行开头可能存在的任何空格。实际上,输入行开头的空格总是被忽略,无论前一行是否以 结尾%。好吧,逐字模式是一个例外,但这是另一个讨论的主题。

因此,

Hello %
World

Hello % 
    World

最终的处理方式相同:TeXHello从第一行(包括“Hello”后面的空格)读取,然后World从第二行读取,并输出“Hello World”。请注意,第一行末尾的行尾字符第二行开头的四个空格字符已被丢弃。

如果输入是

Hello% 
    World

现在输出将为“HelloWorld”。为什么?因为和以前一样,第一行末尾的行尾字符和第二行开头的四个空格字符被丢弃,剩下的是第一行的“Hello”和第二行的“World”。


还有一条信息:单身的行尾字符在 TeX 的第一个处理阶段被转换为空格。(相反,两个或多个连续的行尾字符被转换为一个\par标记。)因此,

Hello 
World

Hello World

创建相同的输出。


有了这些信息,我们就能弄清楚%以下代码块中字符的用途:

\noindent
\begin{minipage}{0.5\textwidth}
...
\end{minipage}%
\begin{minipage}{0.5\textwidth}
...
\end{minipage}

此构造的总宽度为0.5\textwidth+0.5\textwidth=1\textwidth。如果%省略该字符,则第一个 之后的行尾字符\end{minipage}将转换为空格,总宽度将为1\textwidth 加上空格字符的宽度。这几乎肯定不是我们想要的。还要注意,将字符放在%后面很重要\end{minipage};书写\end{minipage} %不会达到预期目的。


接下来,考虑以下两个宏定义:

\newcommand\cmdA[1]{
        #1}
\newcommand\cmdB[1]{%
        #1}

这两个定义都是合法的。特别是,从纯粹的语法角度来看,%在后面提供一个字符\newcommand\cmdA[1]{来编译宏并不是绝对必要的。但这并不意味着这两个宏会产生相同的输出。你能猜出\cmdA{abc}\cmdA{abc}\cmdB{abc}\cmdB{abc}会输出什么吗?为简单起见,请假设两个命令序列都出现在输入行的开头。

果然,\cmdB{abc}\cmdB{abc}输出“abcabc”,“abc”子字符串之间没有空格。

相反,输出“abc abc”。为什么?每个输出\cmdA{abc}\cmdA{abc}的两个实例;之前的空格存在,因为之后的单个行尾字符被转换为空格。TeX会忽略第一个实例贡献的空格,因为根据假设,它出现在行的开头;但是,第二个实例贡献的空格不是。这就是你最终得到的结果。\cmdA{abc}abcabc\newcommand\cmdA[1]{\cmdA{abc}\cmdA{abc}abc abc


附录,由@PhelypeOleinik 的评论提示:一些读者可能会从前面的讨论中得到这样的印象:虽然未能终止位于宏定义中的某些行,但使用%可能是错误的,但肯定会终止每一行在该宏定义中使用%不会造成任何损害。不幸的是,这也是一个错误。

请考虑以下这个有些牵强的例子。它有 5 个实例%,但其中只有一个很重要:

\ifnum1=0%
   1%
   a%
\else%
   b%
\fi

这里,\ifnum<u>=<v>是一个条件,检查<u>和是否<v>在数值上相等。(如果<u><v>为非数字,则发出错误消息。并且,只是为了修正想法:101在数值上相等。)

你猜 (La)TeX 会输出什么:11aab?如果你猜b——毕竟,1 是当然不等于 0!——你猜错了。正确答案是a。为什么?

%紧接着出现的角色\ifnum1=0字符会吞噬不可见的行尾字符;因此,TeX 会继续向前扫描,直到遇到第一个非数字字符,以便设置条件测试。因此,条件实际上由 TeX 评估的是\ifnum1=01——记住:开始一行被忽略——真的。这就是为什么a要进行排版。

然而,如果有人写

\ifnum1=0
   1%
   a%
\else%
   b%
\fi

或者更好的是,

\ifnum1=0
   1
   a
\else
   b
\fi

正确的答案是b,因为 TeX 会在之后“看到”行尾字符\ifnum1=0,将其转换为空格字符,意识到它应该开始评估是否\ifnum1=0为真,并选择条件“树”结构中的适当分支。

相关内容