是否可以使用函数来挂接宏,该函数将一些信息写入文件或日志,而无需更改创建 dvi 文件的流。例如,如果我有宏定义
\def\foo{\mathop{A}}
我把它挂上
\def\foo{{\ifmmode\typeout{math}\else\typeout{text}\fi}\mathop{A}}
它为我提供了类似的表达式的不同输出。
$\max \foo$
因为它会改变流mathop, mathop --> mathop, something, mathop
。我不知道luatex,但是借助lua代码的解决方案也值得赞赏。
答案1
间距差异
\def\foo{{\ifmmode\typeout{math}\else\typeout{text}\fi}\mathop{A}}
不是来自它\typeout
来自{}
你会看到同样的
\def\foo{{}\mathop{A}}
就像在数学模式中一样{}
,生成一个数学原子,从而影响周围符号的空间。$+2
与比较${}+2
。
作为\typeout
一个\immediate\write
并且不在{}
内部使用组(它\begingroup \endgroup
正是出于这个原因使用)它不会将任何原子引入数学列表或将节点引入水平或垂直列表。
正如 Bruno 在评论中指出的那样
\def\foo{\ifmmode\typeout{math}\else\typeout{text}\fi\mathop{A}}
但是,作为数组单元格的开头,它将采取错误的(数学)选择,因为它将在数组前导码代码插入数学分隔符之前展开。您可以将\relax
测试放在前面或移到末尾,或者(也许最好)使用\protected\def
\def\foo{\relax\ifmmode\typeout{math}\else\typeout{text}\fi\mathop{A}}
\def\foo{\mathop{A}\ifmmode\typeout{math}\else\typeout{text}\fi}
\protected\def\foo{\ifmmode\typeout{math}\else\typeout{text}\fi\mathop{A}}
该\protected
版本在\edef
\section{}
和其他移动参数中是“安全的”,尽管它的行为当然不同于未修改的版本,但这意味着例如\foo
在输入目录时写入目录并展开,而不是\mathop{A}
写入目录。
TeX 是一种宏处理语言,其中整个程序都以数据形式提供。我们之所以如此不愿意以任何方式更改 LaTeX 定义(因此有这样的软件包fixltx2e
允许您明确选择更改)的原因之一是经验表明,如果您修改了任何这样,某个人的文档就会被破坏。软件包可以以任意方式执行修补命令,在扩张任意命令,因此如果你改变扩展,事情就会出错。
考虑一个\AtoB
重新定义命令B
以代替的命令A
。它使用原始定义时有效,但使用任何重新定义时失败。如果你浏览这个网站,你会看到这种补丁每时每刻这并非(仅仅)一个虚构的例子。
\def\AtoB#1{\expandafter\xAtoB#1\xAtoB#1}
\def\xAtoB#1#2\xAtoB#3{\def#3{#1{B}}}
\def\foo{\mathop{A}}
\AtoB\foo
\show\foo
\protected\def\foo{\ifmmode\typeout{math}\else\typeout{text}\fi\mathop{A}}
\AtoB\foo
\show\foo
\stop
生产
> \foo=macro:
->\mathop {B}.
l.9 \show\foo
好的。
?
> \foo=macro:
->\ifmmode {B}.
l.14 \show\foo
?
哎呀:-)