为什么 \global\let 不总是全局的?

为什么 \global\let 不总是全局的?

由于 LaTeX 环境打开了一个本地组,因此如果环境中的更改需要在环境之后可用,通常需要使用全局定义:

\documentclass{minimal}
\usepackage{amsmath}
\begin{document}
    \begin{multline}
        \gdef\mylabel{text}
    \end{multline}
    \show\mylabel
\end{document}

其结果是:

> \mylabel=macro:
->text.

不幸的是,这不适用于\global\let。在本地,定义是正确的,如以下示例所示:

\documentclass{minimal}
\usepackage{amsmath}
\begin{document}
    \begin{multline}
        \global\let\mylabel\label
        \show\mylabel
    \end{multline}
\end{document}

其结果是:

> \mylabel=macro:
#1->\begingroup \measuring@false \label@in@display {#1}\endgroup .

没有全局影响:

\documentclass{minimal}
\usepackage{amsmath}
\begin{document}
    \begin{multline}
        \global\let\mylabel\label
    \end{multline}
    \show\mylabel
\end{document}

其结果是:

> \mylabel=\long macro:
#1->.

为什么\global\let这里的 不是全局的?是否有一些(通用的)解决方法来获取\global\let

解决方案(感谢 David Carlisle):

David Carlisle 是正确的。由于 amsmath 调用环境两次,并且\label命令在第一次调用后被删除,因此我们最终得到了一个被删除的命令。解决方案是避免在第二次调用中重置命令:

\documentclass{minimal}
\usepackage{amsmath}
\usepackage{etoolbox}
\begin{document}
    \begin{multline}
        \ifundef{\mylabel}{%
            \global\let\mylabel\label
        }{}%
    \end{multline}
    \show\mylabel
\end{document}

答案1

AMS 比对在内部执行两次,第一次用于测量字段,第二次用于排版。\label第二次被赋予一个空定义,以避免重复写入辅助文件,从而产生错误。

因此,您对真实定义进行了全局 let,但是您没有看到它,因为您在第二遍中全局 let 为空定义。

您可以通过将其放入\show\mylabel您的multline并查看其报告来查看值。您可以使用\ifmeasuring@开关来测试您处于哪个阶段。然后只需在其中一个阶段执行 let 即可。

\documentclass{minimal}
\usepackage{amsmath}


\begin{document}

\makeatletter
    \begin{multline}
  \ifmeasuring@
        \global\let\mylabel\label
    \show\mylabel
\fi
    \end{multline}
    \show\mylabel
\end{document}

生产

> \mylabel=macro:
#1->\begingroup \measuring@false \label@in@display {#1}\endgroup .
l.14     \show\mylabel

相关内容