之后...

之后...

出于好奇,我想知道为什么这会失败:

\documentclass{article}

\usepackage{xparse}

\NewDocumentCommand{\bla}{mm}{#1.#2!}

\begin{document}

\begingroup
\obeylines
\everypar={\bla}
{C}{G} skdjfs;ldjkf;sjkf
{ERT}{ERTERT} djkfsjdfl;ksjdf;l
\endgroup

\end{document}

错误:Argument of \bla has an extra }.我确实看过参数文本中的 \par(作为参数分隔符)和 \everypar 宏中的 \vbox{#1}但这些都不是分隔宏的参数。

之后...

我发现这xparse提供了一种解决方案,尽管我认为这可能被看作是虐待

\documentclass{article}

\usepackage{xparse}

\NewDocumentCommand{\bla}{O{}O{}}{#1.#2!}

\begin{document}

\begingroup
\obeylines
\everypar={\bla}
[C][Gin] skdjfs;ldjkf;sjkf
[ERT][ERTERT] djkfsjdfl;ksjdf;l
\endgroup

\end{document}

我认为这个方法有效,因为讨厌的那个{不再起作用了。这很方便,因为我可以避免\bla在每一行(几十行)前面都放上。

答案1

{C}TeX 在读取段落开头的文本时处于垂直模式。{开始一个组,但不是改变模式。当 TeX 读取 时会发生这种情况C,它必须处于水平模式,因此会开始一个段落。\everypar标记被插入,并且您的宏会抓取C#1(如果您使用只有一个参数的宏,您会看到这一点)。在当前情况下,}输入流中有一个。这不可能是#2,所以您会收到 TeX 错误。

避免这种情况的最简单方法可能是强制 TeX 退出垂直模式。该标准\leavevmode将不起作用,因为它会插入一些来自 \everypar。我们可以使用 e-TeX 定义来修复这个问题\leavevmode

\protected\def\leavevmode{\ifvmode\expandafter\indent\fi}

然后可以插入

\documentclass{article}

\usepackage{xparse}

\NewDocumentCommand{\bla}{mm}{#1.#2!}
\protected\def\leavevmode{\ifvmode\expandafter\indent\fi}

\begin{document}

\begingroup
\everypar={\bla}
\leavevmode
{C}{G} skdjfs;ldjkf;sjkf
{ERT}{ERTERT} djkfsjdfl;ksjdf;l
\endgroup

\end{document}

相关内容