我编写了几个 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
,这是这种宏的完全不同的行为。