长命令(即不接受段落分隔符的命令)如何处理空格和空行?除了“ ”和空行之外,还有其他空格标记吗?看来空行恰好算作一个空参数:
\documentclass{article}
\newcommand{\oneArg}[1]{}
\newcommand{\twoArgs}[2]{}
\newcommand{\threeArgs}[3]{}
\begin{document}
\indent
A \oneArg
B
% output:
% A B
A \twoArgs
B
C
% output:
% A
% C
A \threeArgs
B
C
% output:
% A C
\end{document}
在这方面,关于数学模式有什么特别需要了解的吗?
一个提示:一些相关信息这个问题, 尤其\somecommand *
这个关于合法 LaTeX 的讨论主题。
附录:关于短宏(例如用 定义的宏\newcommand*
)的一个有趣的细节:如果我添加\newcommand*{\noPar}[1]{#1}
到我的源代码并尝试编译一个额外的代码块
\noPar{
A \threeArgs
B
C
}
编译器会抛出错误。因为这是语义上不是段落分隔符,命令之间的长短区别可能应该用空行来描述,而不是段落分隔符。还是不?
答案1
标题问题的答案是技术上“它们没有被处理”但我不认为这是你想要的答案。
如果你将定义修改为
\newcommand{\oneArg}[1]{\long\def\a{[#1]}\typeout{\meaning\a}}
\newcommand{\twoArgs}[2]{\long\def\a{[#1][#2]}\typeout{\meaning\a}}
\newcommand{\threeArgs}[3]{\long\def\a{[#1][#2][#3]}\typeout{\meaning\a}}
你会看见
\long macro:->[\par ]
\long macro:->[\par ][B]
\long macro:->[\par ][B][\par ]
假设正常的 catcode 有效,TeX 会将空白行转换为标记\par
(实际上是命令名称标记,\par
而不是原始段落结束函数)。它在字符被标记化的早期阶段执行此操作,因此在任何标记列表传递给宏之前。因此,宏永远不会在其参数中看到空白行。行为总是像您在\par
输入文件中用 替换空白行一样。
在这个早期阶段,空格标记的处理方式类似。行尾和下一行开头的空格会被丢弃,并且根本不会被标记,因此宏没有它们的记录。(即使更改空格的 catcode,也无法阻止行尾空格被丢弃)并且空格字符的运行只会产生一个空格标记。传递给宏的是标记,而不是文件字符。
如果您有非分隔参数(如示例中所示),则在查找参数时会跳过任何空格标记,如果您希望使用空格是您需要的参数{ }
.\par
如果宏是,则可以是无分隔符参数\long
,否则可以是错误。
答案2
TeX 的标记化过程在这里很重要。当 (La)TeX 读取一新队
some text
some more text
它将换行符转换为空格(忽略第二行开头的任何空格):。some text some more text
但是,当 TeX 读取二连续的换行符会转换为一个\par
标记
some text
some more text
最终结果为some text \par some more text
。(我假设\endlinechar
这里的标准设置。)
参数的获取发生在这个过程发生之后,所以你不会看到“空行”被读为参数,而是被读为\par
标记。这是\par
代币在命令的参数中,区分“短”命令和“长”命令,并且这些命令必须出现直接地在参数中使用“短”命令引发错误。
答案3
<end-of-line>
(1)扫描参数时,不包含两个 s 的空格将被跳过。 (2)包含至少two<end-of-lines>
被转换为\par
并且可以作为参数传递。
另一方面,当 TeX 扫描不带\long
、 和的命令定义时\par
(如\par
或如上面的 (2) 所示),它会抛出错误。这样您就可以更轻松地调试错误分组。(记住:\newcommand
=> yes-\long
和\newcommand*
=> no- \long
。)
同样,\par
在情况 (2) 中,它不仅可作为参数有效,还可作为参数分隔符有效。但是,该参数仍将包含终止空格标记:
\def\xy#1\par{x#1y}
Hello \xy World
How are you
\bye
输出(一行,记住我们“吃”了\par
它作为参数分隔符):
你好 xWorld y你好吗
据我所知,这有时会在 ConTeXt 中使用,它允许您摆脱许多括号,例如考虑定义\def\Section#1\par{\section{#1}}
,您的代码将是:
\Section Your well-being
How are you?
输出:
您的健康
你好吗?