更新:

更新:

有没有办法测试 a 是否\pageref是当前页面?例如,在下面的代码中:

\newcommand\figureref[1]{%
  Figure~\ref{#1} (p.~\pageref{#1})
}

(p.~\pageref{#1})如果引用的图与参考在同一页,我想消除。我尝试使用该varioref包,但无法将其调整为所需的行为。

更新:

回到最初的问题测试当前页面,这几乎奏效了:

\newcounter{cPage}
\newcommand\figureref[1]{%
  Figure~\ref{#1}%
  \setcounter{cPage}{\value{page}}\addtocounter{cPage}{1}%
  \ifthenelse{\value{cPage}=\pageref{#1}}{}{(p.~\pageref{#1})}%
}

但是,页面值不太一致。有时它会在页面中间发生变化。偏移量在 -1/1 和 +1/2 之间变化,我似乎找不到背后的任何逻辑。

答案1

如果您想要将 \pageref 与当前页面进行比较,则也应该通过设置内部标签对当前页面使用 \pageref。例如:

\documentclass{article}
\usepackage{ifthen}
\newcounter{cPage}
\newcommand\figureref[1]{%
  Figure~\ref{#1}%
 \refstepcounter{cPage}\label{current\thecPage}%
 \ifthenelse{\equal{\pageref{#1}}{\pageref{current\thecPage}}}%
  {}{~(p.~\pageref{#1})}}%

\begin{document}
\begin{figure}
 \caption{blub}\label{bla}
 \end{figure}

 \figureref{bla} \newpage \figureref{bla} abc
\end{document}

(varioref 也设置了这样的内部标签,我相当确定可以使用 varioref 获得想要的行为,但我没有时间去查找它)。

您的 \spacefactor 错误可能是由于缺少 \makeatletter 造成的。

答案2

看起来你想要类似的东西

\newcommand*\figureref[1]{Figure~\vref{#1}}
\renewcommand*\reftextbefore{(p.~\thevpagerefnum)}
\let\reftextfacebefore\reftextbefore
\let\reftextafter\reftextbefore
\let\reftextfaceafter\reftextbefore
\renewcommand*\reftextfaraway[1]{(p.~\pageref{#1})}

编辑:varioref仔细阅读后,我发现我对 \vref 的重新定义是不必要的。

修改 2:您之前没有提到任何内容hyperref。我不确定最好的解决方法是什么,但下面的方法可行。

\newcommand*\figureref[1]{Figure~\ref{#1}\vpageref[]{#1}}
\makeatletter
\let\old@vpageref\@vpageref
\def\@vpageref[#1]{\@ifnextchar[%]
        {\vpageref@interpose{#1}}%
        {\vpageref@interpose{#1}[\unskip\vref@space]}%
}
\def\vpageref@interpose#1[#2]#3{%
        \def\thereflabel{#3}%
        \@@vpageref{#1}[#2]{#3}%
}
\makeatother
\renewcommand*\reftextbefore{\reftextfaraway{\thereflabel}}
\let\reftextfacebefore\reftextbefore
\let\reftextafter\reftextbefore
\let\reftextfaceafter\reftextbefore
\renewcommand*\reftextfaraway[1]{(p.~\pageref{#1})}

我认为hyperref会发生变化\@@vpageref,这就是为什么我不直接修改它。

更新:

好的,回到你最初的问题。这本质上就是varioref解决这个问题的方法。

\documentclass{article}

\newcount\testpagecount
\testpagecount0
\DeclareRobustCommand\ifrefthispage[3]{%
        \global\advance\testpagecount1
        \getpagenum\refstartnum{tpcstart\the\testpagecount}%
        \getpagenum\refendnum{tpcend\the\testpagecount}%
        \getpagenum\labelnum{#1}%
        \ifx\refstartnum\refendnum\else
                \GenericWarning{}{Reference to #1 fell on page
                boundary \refstartnum-\refendnum}%
        \fi
        \testpagelabel{tpcstart\the\testpagecount}%
        \ifx\labelnum\refendnum
                #2%
        \else
                #3%
        \fi
        \testpagelabel{tpcend\the\testpagecount}%
}

\makeatletter
\def\getpagenum#1#2{%
        \@ifundefined{r@#2}{\@namedef{r@#2}{{??}{??}}}{}%
        \protected@edef#1{\expandafter\expandafter\expandafter
                \@cdr\csname r@#2\endcsname\@nil}%
}

\def\testpagelabel#1{%
        \protected@write\@auxout{}{\string\newlabel{#1}{{}{\thepage}}}%
}
\makeatother

\begin{document}

\section{Foo}\label{sec:foo}
\ifrefthispage{sec:foo}{Ref is on this page}{Ref is not on this page}
\newpage
\ifrefthispage{sec:foo}{Ref is on this page}{Ref is not on this page}
\end{document}

基本上,它会生成两个新标签,一个位于两个替换文本的两侧,使用\testpagelabel与标准几乎相同\label,只是没有实际标签。在后续运行中,它会检查两个标签是否跨越页面边界。如果是,则会发出警告。(诚然,我没有检查该代码路径。)然后,如果第二个标签与您要测试的标签位于同一页面上,则它使用第二个参数中的标记,否则它使用第三个参数中的标记。

请注意,在页面边界上,每次编译时它都可能发生变化。我真的不知道该如何处理。

相关内容