如何以与 varioref 兼容的方式重新定义 \label、\ref 和 \pageref?

如何以与 varioref 兼容的方式重新定义 \label、\ref 和 \pageref?

为了防止从数据库收集练习时与标签发生冲突,我需要重新定义命令\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}

相关内容