为了防止从数据库收集练习时与标签发生冲突,我需要重新定义命令\label
,\ref
并\pageref
为标签添加本地前缀。不幸的是,该包varioref
不再起作用。
这是一个 MWE。
\documentclass{article}
\usepackage{varioref}
\newcommand*{\globallabel}[1]{global:#1}
\AtBeginDocument{%
\let\origref\ref
\renewcommand*{\ref}[1]{%
\origref{\globallabel{#1}}%
}
\let\origpageref\pageref
\renewcommand*{\pageref}[1]{%
\origpageref{\globallabel{#1}}%
}
\let\origlabel\label%
\renewcommand*{\label}[1]{%
\origlabel{\globallabel{#1}}
}
}
\makeatother
\begin{document}
Example 1: figure~\vref{fig:example1}.
Example 2: figure~\vpageref{fig:example2}.
\begin{figure}
\caption{Example 1}
\label{fig:example1}
\end{figure}
\clearpage
\begin{figure}
\caption{Example 2}
\label{fig:example2}
\end{figure}
\end{document}
我明白了
Example 1: figure 1 on page 1.
Example 2: figure on page 2.
代替
Example 1: figure 1.
Example 2: figure on the next page.
在日志文件中,我发现
LaTeX Warning: Reference `fig:example1' on page 1 undefined on input line 31.
LaTeX Warning: Reference `fig:example2' on page 1 undefined on input line 33.
我尝试以相同的方式重新定义命令,但没有成功\vref
。\pagreref
答案1
重新定义名称有点困难,因为您需要重新定义两者\vref
并\ref
捕捉顶级使用,但在内部\vref
使用\ref
,并且事物得到双重前缀。可以打开源代码只是为了在正确的位置添加前缀,但更简单的方法是使用新的顶级名称来添加前缀,然后一切按预期工作,因为前缀只需添加一次,内部使用使用\ref
已经加前缀的键而无需再次添加前缀。
\documentclass{article}
\usepackage{varioref}
\newcommand*{\globallabel}[1]{global:#1}
\newcommand*{\myref}[1]{%
\ref{\globallabel{#1}}%
}
\newcommand*{\myvref}[1]{%
\vref{\globallabel{#1}}%
}
\newcommand*{\myvpageref}[1]{%
\vpageref{\globallabel{#1}}%
}
\newcommand*{\mypageref}[1]{%
\pageref{\globallabel{#1}}%
}
\newcommand*{\mylabel}[1]{%
\label{\globallabel{#1}}%
}
\begin{document}
Example 1: figure~\myvref{fig:example1}.
Example 2: figure~\myvpageref{fig:example2}.
\begin{figure}
\caption{Example 1}
\mylabel{fig:example1}
\end{figure}
\clearpage
\begin{figure}
\caption{Example 2}
\mylabel{fig:example2}
\end{figure}
\end{document}
答案2
varioref
还需要重新定义包的一些内部内容,例如:
\documentclass{article}
\usepackage{varioref}
\newcommand*{\globallabel}[1]{global:#1}
\makeatletter
\AtBeginDocument{%
\let\origref\ref
\renewcommand*{\ref}[1]{%
\origref{\globallabel{#1}}%
}%
\let\origpageref\pageref
\renewcommand*{\pageref}[1]{%
\origpageref{\globallabel{#1}}%
}%
\let\origlabel\label%
\renewcommand*{\label}[1]{%
\origlabel{\globallabel{#1}}%
}%
\let\orig@@vpageref\@@vpageref
\def\@@vpageref#1[#2]#3{%
\begingroup
\let\pageref\origpageref
\orig@@vpageref{#1}[{#2}]{\globallabel{#3}}%
\endgroup
}%
\let\origvr@f\vr@f
\renewcommand*{\vr@f}[1]{%
\begingroup
\let\ref\origref
\let\@@vpageref\orig@@vpageref
\origvr@f{\globallabel{#1}}%
\endgroup
}%
}
\makeatother
\begin{document}
Example 1: figure~\vref{fig:example1}.
Example 2: figure~\vpageref{fig:example2}.
\begin{figure}
\caption{Example 1}
\label{fig:example1}
\end{figure}
\clearpage
\begin{figure}
\caption{Example 2}
\label{fig:example2}
\end{figure}
\end{document}
结果:
Example 1: figure 1.
Example 2: figure on the next page.
评论:
- 使用内部函数而不是
\vref
或可以更容易地支持和的\vpageref
各种语法形式(星号、可选参数)\vref
。\vpageref
- 在重新定义
\vref
/时\vpageref
,一些原有的引用命令被启用,以避免出现双前缀。
补丁hyperref
- 通过本地禁用
\globallabel
可以避免嵌套。\vref
例子:
\documentclass{article}
\usepackage{nameref}
\usepackage{varioref}
\usepackage{hyperref}
\usepackage{letltxmacro}
\newcommand*{\globallabel}[1]{global:#1}
\makeatletter
\AtBeginDocument{%
\LetLtxMacro\origref\ref
\renewcommand*{\ref}[1]{%
\origref{\globallabel{#1}}%
}%
\LetLtxMacro\origpageref\pageref
\renewcommand*{\pageref}[1]{%
\origpageref{\globallabel{#1}}%
}%
\LetLtxMacro\origlabel\label%
\renewcommand*{\label}[1]{%
\origlabel{\globallabel{#1}}%
}%
\let\orig@@vpageref\@@vpageref
\def\@@vpageref#1[#2]#3{%
\begingroup
\let\pageref\origpageref
\orig@@vpageref{#1}[{#2}]{\globallabel{#3}}%
\endgroup
}%
\let\origvr@f\vr@f
\renewcommand*{\vr@f}[1]{%
\begingroup
\let\ref\origref
\let\@@vpageref\orig@@vpageref
\expandafter\let\expandafter\globallabel\expandafter\@firstofone
\expandafter\origvr@f\expandafter{\globallabel{#1}}%
\endgroup
}%
}
\makeatother
\begin{document}
Example 1: figure~\vref{fig:example1}.
Example 2: figure~\vpageref{fig:example2}.
\documentclass{article}
\usepackage{varioref}
\newcommand*{\globallabel}[1]{global:#1}
\makeatletter
\AtBeginDocument{%
\let\origref\ref
\renewcommand*{\ref}[1]{%
\origref{\globallabel{#1}}%
}%
\let\origpageref\pageref
\renewcommand*{\pageref}[1]{%
\origpageref{\globallabel{#1}}%
}%
\let\origlabel\label%
\renewcommand*{\label}[1]{%
\origlabel{\globallabel{#1}}%
}%
\let\orig@@vpageref\@@vpageref
\def\@@vpageref#1[#2]#3{%
\begingroup
\let\pageref\origpageref
\orig@@vpageref{#1}[{#2}]{\globallabel{#3}}%
\endgroup
}%
\let\origvr@f\vr@f
\renewcommand*{\vr@f}[1]{%
\begingroup
\let\ref\origref
\let\@@vpageref\orig@@vpageref
\origvr@f{\globallabel{#1}}%
\endgroup
}%
}
\makeatother
\begin{document}
Example 1: figure~\vref{fig:example1}.
Example 2: figure~\vpageref{fig:example2}.
\begin{figure}
\caption{Example 1}
\label{fig:example1}
\end{figure}
\clearpage
\begin{figure}
\caption{Example 2}
\label{fig:example2}
\end{figure}
\end{document}