设想
我有一堆 TeX 文件,它们可能由外部过滤器处理。该过滤器(不幸的是)是不可变的:它会执行字符串替换,例如,%d
将 扩展为某个日期。所有“原语”的形式都是 ,%X
其中X
是一个字母。例如,日期需要插入到文档的各个位置。
但是,如果用户忘记运行过滤器,我还希望文档仍然可以编译(通过 LaTeX);在这种情况下,日期引用应该保留为%d
。
一个明显的解决方案
定义一个字符串,其中包含将被过滤器更改的对象。定义时切换字符的 catcode %
。
\documentclass{article}
\catcode`\%=12
\gdef\datestring{ %d }
\catcode`\%=14
\begin{document}
\datestring
\end{document}
这似乎做到了我想要它做的事情。我是否忽略了什么?有没有更好的解决方案?
需要澄清的是,运行过滤器后,上面的 TeX 测试文件将转换为(例如)
\documentclass{article}
\catcode`\%=12
\gdef\datestring{ 2015-06-10 }
\catcode`\%=14
\begin{document}
\datestring
\end{document}
这就是为什么我不能仅仅使用其他形式的%
;该字符串必须与%d
TeX 文件中的完全相同。
答案1
你做的事情没有问题,尽管我更愿意保留类别代码的恢复:
\documentclass{article}
\begingroup
\catcode`\%=12
\gdef\datestring{ %d }
\endgroup
\begin{document}
\datestring
\end{document}
如果过滤器已经变成%d
其他东西,也不会有问题,因为的定义\datestring
无论如何都是全局的。
答案2
已经为此用途定义了“另一种形式” [百分比命令]。
\@percentchar
它由您所展示的构造准确定义。
因此,在包或类代码中,您可以直接使用\@percentchar
。但是,要在文档序言中使用,您需要制作@
字母,这会带来完全相同的问题,但使用@
而不是%
。在这种情况下,您可以使用\makeatother
而不是显式 catcode 设置
避免设置 catcode 或全局定义并且可能适用于您的过滤器的替代方案是
\def\datestring{
%d
}
一旦被替换,这将给出相同的定义%d
,尽管默认定义现在是空格而不是%d