![为什么我不能将 \edef 与 hyperref 中的 \pageref 一起使用?](https://linux22.com/image/342016/%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E4%B8%8D%E8%83%BD%E5%B0%86%20%5Cedef%20%E4%B8%8E%20hyperref%20%E4%B8%AD%E7%9A%84%20%5Cpageref%20%E4%B8%80%E8%B5%B7%E4%BD%BF%E7%94%A8%EF%BC%9F.png)
这很有效:
\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 之前使脆弱命令安全。(但安全意味着它可能不会按您的需要扩展,您没有在这里给出您的实际用例)