定义宏时忽略制表符和换行符是否安全?

定义宏时忽略制表符和换行符是否安全?

我编写了几个 LaTeX 环境来为一个大学项目格式化“用例流”序列。作为一名计算机程序员,我发现不能使用换行符和缩进(如 C/Java 代码)来格式化 LaTeX 代码并使其更具可读性非常烦人,因为我知道我必须注意“虚假空格”问题。我知道我可以使用 来制作安全的换行符%,但这仍然很奇怪。

然后,我记得 TeX 读取的每个字符都分配了一个“catcode”来控制其行为,并且有一个必须忽略的字符的 catcode (9)。因此,我想到在定义宏时暂时更改换行符和制表符的 catcode(将用于代码格式化)并忽略它们。例如,此代码:

% UCSubFlow counter definition, etc
\newenvironment{subflow}[1]{%
\subparagraph{Subflow \arabic{UCSubFlow}: #1}%
\stepcounter{UCSubFlow}%
\begin{enumerate}%
}{%
\end{enumerate}%
}

在我看来,读起来更令人愉快:

% Ignore tabs and newlines
\catcode9=9
\catcode13=9

% UCSubFlow counter definition, etc
\newenvironment{subflow}[1]{
    \subparagraph{Subflow \arabic{UCSubFlow}: #1}
    \stepcounter{UCSubFlow}
    \begin{enumerate}
}{
    \end{enumerate}
}
% More macro definitions...

% Return tabs and newlines back to normal
\catcode9=10
\catcode13=5

行首的间距是制表符,而不是空格(它们仍在使用)。我假设:

  • 大多数情况下,宏<tab>在定义中不使用 s
  • 大多数情况下,宏不会包含大段文字。如果我想在宏中开始一个段落,最好使用\par
  • 宏总是可以写在一行中(很长,但无论如何都是一行)

我已经在我的文档中使用过它,似乎一切正常。环境按预期工作,似乎没有破坏任何东西。当然,我的环境非常简单(一个特殊列表)。我的问题是:当涉及到宏编写时,这种“黑客”行为总体上是否安全,是否存在一些隐患?(特别是如果我在宏中使用其他包的宏)

答案1

首先,通过设置 ,您的意图可以简单地实现\endlinechar=-1。您不需要为 设置 catcode,^^M因为\endlinechar-1会导致不插入此字符。您不需要为^^I(tab) 设置 catcode,因为空格和制表符的 catcode 为 10,它们在每行的开头被忽略。

但这种设置很危险,当然不能放在文档的普通文本中,因为之后:

 Hello
 world!

结果就是 Helloworld!。而且这个设置只在宏读取时使用?想象一下这个定义:

\def\a{Hello
       world!}

那么就会出现和上面同样的问题。而且问题可能更加隐蔽,例如:

\def\b{\ifnum\something=0
            123%
        \else
            456%
        \fi
}

现在,如果每行末尾都有空格,那么我们就有,if(somenthing=0) 123 else 456 fi但是如果这里没有空格,那么我们就有if(something=0123) else 456 fi,这是这种宏的完全不同的行为。

相关内容