我喜欢使用\let
将一个宏别名化为另一个宏。例如,我经常执行类似这样的操作\let\brand\textit
,然后我就可以执行\brand{Aloc Acoc}
。
这似乎运行良好,但在hyperref
加载时会导致问题。
考虑一下这个MWE:
\documentclass{article}
\usepackage{hyperref}
\let\foo\textit
\begin{document}
\section{Command \foo{aliasing}}
Here I use \texttt{\textbackslash foo} to
\foo{to typeset this in italic}.
\end{document}
编译失败,原因! Argument of \@sect has an extra }.
如下\section
。
你知道为什么会发生这种情况吗?提前致谢!
答案1
首先,这样做\let\foo\textit
是错误的,看看何时使用 \LetLtxMacro?。
使用最新的 LaTeX 你应该可以做到
\NewCommandCopy{\foo}{\textit}
或者\LetLtxMacro
如果\NewCommandCopy
您被困在过时的版本中。
但这还不够。事实上,hyperref.sty
你会发现
346 \def\pdfstringdef#1#2{%
347 \begingroup
[...]
403 \let\emph\@firstofone
404 \let\textnormal\@firstofone
405 \let\textrm\@firstofone
406 \let\textsf\@firstofone
407 \let\texttt\@firstofone
408 \let\textbf\@firstofone
409 \let\textmd\@firstofone
410 \let\textit\@firstofone
411 \let\textsc\@firstofone
412 \let\textsl\@firstofone
413 \let\textup\@firstofone
[...]
因此\textit
被添加到“书签例外”中,而您的\foo
命令却没有。
如果要为命令添加别名,则需要将其添加到例外列表中。
\NewCommandCopy{\foo}{\textit}
\makeatletter
\pdfstringdefDisableCommands{\let\foo\@firstofone}
\makeatother
完整示例。
\documentclass{article}
\usepackage{hyperref}
\NewCommandCopy{\foo}{\textit}
\makeatletter
\pdfstringdefDisableCommands{\let\foo\@firstofone}
\makeatother
\begin{document}
\section{Command \foo{aliasing}}
Here I use \texttt{\textbackslash foo} to
\foo{to typeset this in italic}.
\end{document}
答案2
hyperref 包有一些交互。如果我没记错的话,有些甚至在文档中描述过。在这里可以找到更多信息。
你为什么不直接使用/newcommand?
\documentclass{article}
\usepackage{hyperref}
\newcommand\foo\textit % <<<
\begin{document}
\section{Command \foo{aliasing}}
Here I use \texttt{\textbackslash foo} to
\foo{to typeset this in italic}.
\end{document}
如果您无法放开/let,请使用/renewcommand 重新定义您的 let。