钩住 tex 宏而不改变 token 流

钩住 tex 宏而不改变 token 流

是否可以使用函数来挂接宏,该函数将一些信息写入文件或日志,而无需更改创建 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

? 

哎呀:-)

相关内容