重新定义 \LaTeX 命令以引用词汇表条目

重新定义 \LaTeX 命令以引用词汇表条目

我正在写一个相当大的文档,并决定将其放入\LaTeX{}我的词汇表中

\newglossaryentry{latex}
{
    name={\protect\LaTeX}, 
    description={blabla},
    sort={latex}
}

为了将每个链接\LaTeX{}到词汇表,我可以将每次在文本中使用宏时替换为,\gls{latex}但我发现重新定义更方便\LaTeX{}。不幸的是,它不起作用。当我使用

\renewcommand{\LaTeX}{\gls{latex}}

什么都没发生。当我使用

\DeclareRobustCommand{\LaTeX}{\gls{latex}}

我得到了!TeX capacity exceeded, sorry [grouping levels=255] 所以我认为,我可能需要避免\LaTeX在词汇表本身中,并补充说

\DeclareRobustCommand{\origLaTeX}{\LaTeX}
\newglossaryentry{latex}
{
    name={\protect\origLaTeX}, 
    description={blabla},
    sort={latex}
}

但我仍然收到错误:

! TeX capacity exceeded, sorry [grouping levels=255].
\XC@edef #1#2->\begingroup
\ifnum \catcode `\!=13 \edef !{\string !}\fi \ifn...
l.1 ...some text with \LaTeX macro in it

答案1

当我们定义

\renewcommand{\LaTeX}{\gls{latex}}

我们告诉 TeX 宏\LaTeX应该扩展为\gls{latex}。因此,每当 TeX 遇到 时\LaTeX,它都会尝试使用\gls{latex}

谢谢

\newglossaryentry{latex}
{
    name={\protect\LaTeX}, 
    description={blabla},
    sort={latex}
}

\gls{latex}在许多情况下最终都会打印\protect\LaTeX(除其他事项外;该命令执行更多操作)。但现在 LaTeX 看到 中\LaTeX\protect\LaTeX,将其展开,并发现它展开为\gls{latex}。这会导致无限循环。

结果与

\DeclareRobustCommand{\LaTeX}{\gls{latex}}

这里 LaTeX 并不直接定义\LaTeX\gls{latex}。而是\LaTeX通过辅助宏进行定义,然后将其扩展为\gls{latex}。这只是为我们的无限循环添加了另一层,但不会改变最终结果。


如果可以的话,我们可以避免这个问题复制的实际定义\LaTeX并赋予它不同的名称。然后,我们可以覆盖\LaTeX并根据 的副本定义它\LaTeX。这样,我们就可以摆脱无限循环,因为没有宏会尝试扩展自身。

这就是 的方法\let\origLaTeX\LaTeX。不幸的是,这种方法行不通,因为\LaTeX是用 定义的\DeclareRobustCommand{\LaTeX},正如上面提到的那样,它实际上并没有\LaTeX直接定义,而是通过包含实际定义的辅助宏来定义。当我们这样做时\let\origLaTeX\LaTeX,TeX 会将 的定义复制\LaTeX到 中\origLaTeX。但实际上包含 定义的辅助宏不会被复制或更改。由于我们也用\LaTeX定义了新版本的,因此实际上最终会再次通过辅助宏进行调用。\LaTeX\DeclareRobustCommand{\LaTeX}{\gls{latex}}\origLaTeX\gls{latex}

长话短说,您无法正确使用\let通过定义的宏\DeclareRobustCommand有时人们会很幸运,事情似乎会起作用,但这不是您可以依赖的东西。这就是为什么包letltxmacro编写该包的原因。 另请参阅https://tex.stackexchange.com/a/47372/35864。使用当前版本的 LaTeX,您不需要额外的包,您可以使用\NewCommandCopy来实际复制宏定义,而不必担心宏是否用\newcommand或定义\DeclareRobustCommand

因此

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage{babel}
\usepackage{csquotes}
\usepackage{glossaries}

\newglossaryentry{latex}
{
  name={\protect\origLaTeX}, 
  description={blabla},
  sort={latex}
}

\makeglossaries

\NewCommandCopy\origLaTeX\LaTeX
\renewcommand*{\LaTeX}{\gls{latex}}

\begin{document}
\LaTeX

\printglossaries
\end{document}

按预期工作并生产

文本中的 LaTeX 徽标和词汇表中的“LaTeX blabla. 1”。


正如我在评论中所说,我认为没有技术上的理由说明为什么使用\NewCommandCopy这里不是一个特别好的主意:我们只是会更改 LaTeX 核心宏的定义以执行与其原始定义截然不同的操作。当您无法控制的代码使用该宏时,这可能会产生意想不到的后果。当然,\LaTeX这可能不是什么大问题。但一般来说,以一种让它们比以前做更多事情的方式重新定义核心宏可能会很危险。

相关内容