为什么我不能将 \edef 与 hyperref 中的 \pageref 一起使用?

为什么我不能将 \edef 与 hyperref 中的 \pageref 一起使用?

这很有效:

\documentclass{article}
\begin{document}
    \label{mylabel}
    \pageref{mylabel}
    \edef\mypage{\pageref{mylabel}}
\end{document}

但是使用hyperref,从而替换\pageref\pageref*只有页码而没有链接,这是行不通的:

\documentclass{article}
\usepackage{hyperref}
\begin{document}
    \label{mylabel}
    \pageref*{mylabel}
    \edef\mypage{\pageref*{mylabel}}
\end{document}

错误是:

! Undefined control sequence.
l.6     \edef\mypage
                 {\pageref*{mylabel}}
The control sequence at the end of the top line
of your error message was never \def'ed.

为什么会这样?我怎样才能做得更好?

答案1

采用 *-variant 的命令不可扩展,因此不能在 中使用\edef

这个特定的错误其实没有什么意义;如果你忽略它并尝试再次运行 LaTeX,你会得到

! Undefined control sequence.
\HyRef@StarSetRef ...Hy@safe@activestrue \edef \x 

你可以得到你想要的refcount\getpagerefnumber

\documentclass{article}
\usepackage{refcount}
\usepackage{hyperref}

\begin{document}

\label{mylabel}
\pageref*{mylabel}
\edef\mypage{\getpagerefnumber{mylabel}}

\mypage

\end{document}

输出如预期显示两次 1。

使用\protected@edef另一个答案中建议的方法并不是您想要的。这是一个扩展示例:

\documentclass{article}
\usepackage{refcount}
\usepackage{hyperref}

\begin{document}

\label{mylabel}
\pageref*{mylabel}
\edef\mypage{\getpagerefnumber{mylabel}}

\mypage

\makeatletter
\protected@edef\mypageagain{\pageref*{mylabel}}
\makeatother

\texttt{\meaning\mypage}

\texttt{\meaning\mypageagain}

\end{document}

在此处输入图片描述

您可以看到它\mypageagain不包含页码。

答案2

一般情况下,您不能\edef在一般的 latex 文本上使用,第一次使用时没有出错纯属偶然。或多或少,任何*命令都会失败,因为\@ifnextchar无法通过扩展工作,因此无论*命令定义如何,它都会在前瞻中失败。

这就是 LaTeX 中“脆弱命令”区别的起源,也是为什么乳胶命令应该使用的原因,\protected@edef这样\protect设置是为了在 edef 之前使脆弱命令安全。(但安全意味着它可能不会按您的需要扩展,您没有在这里给出您的实际用例)

相关内容