Cleveref:为标签添加页码

Cleveref:为标签添加页码

我想使用 cleveref 的所有功能,但我想添加一项。我希望标签后面有一个下标,标有页码,如果是前一页,则标有向左的箭头,如果是下一页,则标有向右的箭头。例如,“公式 5_1”或“定理 1_10 和 2_12”。

我尝试使用 varioref 和 cleveref 包来实现这一点,如下面的 MWE 所示。

\documentclass{article}

\usepackage{MnSymbol}

\usepackage{varioref}
\newcommand*{\reallythepageref}[1]{\pageref{#1}}
\renewcommand*{\reftextbefore}{\unskip\textsubscript{\(\lcurvearrowleft\)}}
\renewcommand*{\reftextfacebefore}{}
\renewcommand*{\reftextcurrent}{}
\renewcommand*{\reftextafter}{\unskip\textsubscript{\(\lcurvearrowright\)}}
\renewcommand*{\reftextfaceafter}{\unskip}
\renewcommand*{\reftextfaraway}[1]{\unskip\textsubscript{{\upshape\reallythepageref{#1}}}}
\renewcommand*{\reftextpagerange}[2]{\unskip\textsubscript{\upshape{\reallythepageref{#1}--\reallythepageref{#2}}}}
\renewcommand*{\reftextlabelrange}[2]{{\ref{#1}--\ref{#2}}}

\usepackage{cleveref}

\begin{document}

\vref{sec1} --- \vref{sec2} --- \vref{sec3}

\vref{sec1,sec2} --- \vref{sec1,sec2} --- \vref{sec1,sec3}

\vref{sec1,sec2,sec3}

\clearpage
\section{Section 1}
\label{sec1}

\clearpage
\section{Section 2}
\label{sec2}

\clearpage
\section{Section 3}
\label{sec3}

\end{document}

如果我构建这个,我会得到一些奇怪的行为: 编译的MWE 显然,我们得到了不想要的结果...有什么想法可以消除这种情况吗?

答案1

我认为最优雅的解决方案是修补聪明人\crefdefaultlabelformat命令等不仅提供
#1- 格式化的计数器值
#2- 形成超链接嵌套开始的标记
#3- 形成超链接嵌套结束的标记
,而且还提供#4或类似用于获取所引用的引用标签本身。

然后,您可以通过引用格式规范应用嵌套的引用命令(不执行超链接)。

我查看了聪明人并发现修补聪明人需要做大量工作,因为所有用于实际排版参考文献的内部命令也需要进行修补,以便考虑到另一个参数——这不是我在周日晚上可以即兴完成的事情。;-)

作为一种快速而肮脏的解决方法 — — !!!不提供任何形式的担保!!! — — 我建议如下:

因为它也涉及引用页码,并且瓦里雷夫是关于美化对页面/页码的引用,我建议不要使用\vref-command而是使用\vpageref-command。

可以修补底层命令\@@@setvpageref,以不仅提供页码(通过\thevpagerefnum),还提供显示的值和引用标签本身(以便它可以用于嵌套引用命令)。

(您可能希望通过使用 Heiko Oberdiek 的 abspage 模块来进一步增强参考值-无论是否提供表示正整数的阿拉伯数字,都可获得“绝对页码”的包\thepage。但这需要修补所有用于放置引用标签的例程和所有用于从引用标签中提取页码的例程,以便计算引用短语,即 varioref 的标签放置和页码提取例程。)

\documentclass{article}

\usepackage{MnSymbol}
\usepackage{refcount}
\usepackage{varioref}
\usepackage{hyperref}
\usepackage{cleveref}

\makeatletter

% Something that checks whether the label placed by the current varioref-command
% is somewhere before/behind/on the same page as the label that is to be referenced:

\DeclareRobustCommand\LabelBeforeOnAfterCurrentPage[5]{% Label, Before, On, After, Undefined
  \is@pos@number{\getrefbykeydefault{\the\c@vrcnt @vr}{page}{-1}}{%
    \is@pos@number{\getrefbykeydefault{#1}{page}{-1}}{%
      \ifnum\numexpr
              \getrefbykeydefault{\the\c@vrcnt @vr}{page}{-1}%
              -%
              \getrefbykeydefault{#1}{page}{-1}%
            \relax=0 %
      \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
      {#3}{%
        \ifnum\numexpr
                \getrefbykeydefault{\the\c@vrcnt @vr}{page}{-1}%
                -%
                \getrefbykeydefault{#1}{page}{-1}%
              \relax<0 %
        \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
        {#4}{#2}%
      }%
    }{#5}%
  }{#5}%
}%

%
% Patch the page-referencing-mechanism of varioref to also make the number of the counter
% and the name of the referencing-label available:
%
\newcommand\thevrefnum{}%
\newcommand\thevlabel{}%
\def\@@@setvpageref#1[#2]#3{%
  \leavevmode%\unskip  <<<
  \global\advance\c@vrcnt\@ne\relax%
  \vref@pagenum\@tempa{\the\c@vrcnt @vr}%
  \vref@pagenum\@tempb{\the\c@vrcnt @xvr}%
  %\vref@label{\the\c@vrcnt @xvr}%  <<<
  \ifx\@tempa\@tempb\else%
    \vref@err{\noexpand\vref or \noexpand\vpageref at page boundary
              \@tempb-\@tempa\space (may loop)%
              }%
  \fi%
  \vrefpagenum\thevpagerefnum{#3}%
  %%%%%%%%%%%%%%%
  \expandafter\expandafter\expandafter\def
  \expandafter\expandafter\expandafter\thevrefnum
  \expandafter\expandafter\expandafter{%
    \getrefbykeydefault{#3}{}{%
      \nfss@text{\reset@font\bfseries??}\refused{#3}%
    }%
  }%
  \def\thevlabel{#3}%
  %%%%%%%%%%%%%%%
  \vref@space%
  \ifx\@tempa\thevpagerefnum%
    \def\@tempc{#1}%
    \ifx\@tempc\@empty%
       \unskip%
    \else%
       #1%
    \fi%
  \else%
    #2%
    \is@pos@number\thevpagerefnum%
       {%
        \is@pos@number\@tempa%
         {\@tempcnta\@tempa%
          \advance\@tempcnta\@ne\relax%
         }%
         {\@tempcnta\maxdimen}%
        \ifnum \thevpagerefnum =\@tempcnta%
         \ifodd\@tempcnta%
           \if@twoside%
             \reftextfaceafter%
           \else%
             \reftextafter%
           \fi%
         \else%
           \reftextafter%
         \fi%
        \else%
          \advance\@tempcnta-2\relax%
          \ifnum \thevpagerefnum =\@tempcnta%
            \ifodd\@tempcnta%
              \reftextbefore%
            \else%
              \if@twoside%
                \reftextfacebefore%
              \else%
                \reftextbefore%
              \fi%
            \fi%
          \else%
            \reftextfaraway{#3}%
          \fi%
        \fi%
       }%
       {\reftextfaraway{#3}}%
  \fi%
  \vref@label{\the\c@vrcnt @xvr}%  <<<
  \vref@label{\the\c@vrcnt @vr}%
}%

\newcommand\MyVref@SwitchDefaults[1]{%
  \renewcommand*{\reftextbefore}{%
   #1{\hyperref[\thevlabel]}{%
    \autoref*{\thevlabel}%
    \textsubscript{%
      {\upshape\thevpagerefnum}\LabelBeforeOnAfterCurrentPage{\thevlabel}{\(\lcurvearrowleft\)}{}{\(\lcurvearrowright\)}{}%
    }%
   }%
  }%
  \renewcommand*{\reftextfacebefore}{%
   #1{\hyperref[\thevlabel]}{%
    \autoref*{\thevlabel}%
    \textsubscript{%
      {\upshape\thevpagerefnum}\LabelBeforeOnAfterCurrentPage{\thevlabel}{\(\lcurvearrowleft\)}{}{\(\lcurvearrowright\)}{}%
    }%
   }%
  }%
  \renewcommand*{\reftextcurrent}{%
   #1{\hyperref[\thevlabel]}{%
    \autoref*{\thevlabel}%
    \textsubscript{%
      {\upshape\thevpagerefnum}\LabelBeforeOnAfterCurrentPage{\thevlabel}{\(\lcurvearrowleft\)}{}{\(\lcurvearrowright\)}{}%
    }%
   }%
  }%
  \renewcommand*{\reftextafter}{%
   #1{\hyperref[\thevlabel]}{%
    \autoref*{\thevlabel}%
    \textsubscript{%
      {\upshape\thevpagerefnum}\LabelBeforeOnAfterCurrentPage{\thevlabel}{\(\lcurvearrowleft\)}{}{\(\lcurvearrowright\)}{}%
    }%
   }%
  }%
  \renewcommand*{\reftextfaceafter}{%
   #1{\hyperref[\thevlabel]}{%
    \autoref*{\thevlabel}%
    \textsubscript{%
      {\upshape\thevpagerefnum}\LabelBeforeOnAfterCurrentPage{\thevlabel}{\(\lcurvearrowleft\)}{}{\(\lcurvearrowright\)}{}%
    }%
   }%
  }%
  \renewcommand*{\reftextfaraway}[1]{%
   #1{\hyperref[\thevlabel]}{%
    \autoref*{\thevlabel}%
    \textsubscript{%
      {\upshape\thevpagerefnum}\LabelBeforeOnAfterCurrentPage{\thevlabel}{\(\lcurvearrowleft\)}{}{\(\lcurvearrowright\)}{}%
    }%
   }%
  }%
  \renewcommand*{\reftextpagerange}[2]{%
   #1{\hyperref[##1]}{%
    \autoref*{##1}%
    \textsubscript{%
      {\upshape\getrefbykeydefault{##1}{page}{\refused{##1}}}%
      \LabelBeforeOnAfterCurrentPage{##1}{\(\lcurvearrowleft\)}{}{\(\lcurvearrowright\)}{}%
    }%
   }%
   ~to~%
   #1{\hyperref[##2]}{%
    \autoref*{##2}%
    \textsubscript{%
      {\upshape\getrefbykeydefault{##2}{page}{refused{##2}}}%
      \LabelBeforeOnAfterCurrentPage{##2}{\(\lcurvearrowleft\)}{}{\(\lcurvearrowright\)}{}%
    }%
   }%
  }%
}%

\DeclareRobustCommand\MyVref{\@ifstar{\@MyVref{\@secondoftwo}{*}}{\@MyVref{\@firstofone}{}}}%
\newcommand\@MyVref[2]{\@ifnextchar[{\@@MyVref{#1}{#2}}{\@@@@MyVref{#1}{#2}}}%
\@ifdefinable\@@MyVref{%
  \long\def\@@MyVref#1#2[#3]{%
     \@ifnextchar[{\@@@MyVref{#1}{#2[{#3}]}}{\@@@@MyVref{#1}{#2[{#3}]}}%
  }%
}%
\@ifdefinable\@@@MyVref{\long\def\@@@MyVref#1#2[#3]{\@@@@MyVref{#1}{#2[{#3}]}}}%
\newcommand\@@@@MyVref[3]{%
  \begingroup
  \MyVref@SwitchDefaults{#1}%
  \vpageref#2{#3}%
  \endgroup
}%

\makeatother

% \errorcontextlines=1000

\begin{document}

\MyVref{sec1} --- \MyVref{sec2} --- \MyVref{sec3}

\MyVref{sec1,sec2} --- \MyVref{sec1,sec2} --- \MyVref{sec1,sec3}

\MyVref{sec1,sec2,sec3}

\MyVref{sec1,sec2,sec3,sec4}

\MyVref{sec1,sec2,sec3,sec5}

\MyVref{sec1,sec2,sec3,sec4,sec5}

\clearpage
\section{Section 1}
\label{sec1}

\MyVref{sec1} --- \MyVref{sec2} --- \MyVref{sec3}

\MyVref{sec1,sec2} --- \MyVref{sec1,sec2} --- \MyVref{sec1,sec3}

\MyVref{sec1,sec2,sec3}

\MyVref{sec1,sec2,sec3,sec4}

\MyVref{sec1,sec2,sec3,sec5}

\MyVref{sec1,sec2,sec3,sec4,sec5}

\clearpage
\section{Section 2}
\label{sec2}

\MyVref{sec1} --- \MyVref{sec2} --- \MyVref{sec3}

\MyVref{sec1,sec2} --- \MyVref{sec1,sec2} --- \MyVref{sec1,sec3}

\MyVref{sec1,sec2,sec3}

\MyVref{sec1,sec2,sec3,sec4}

\MyVref{sec1,sec2,sec3,sec5}

\MyVref{sec1,sec2,sec3,sec4,sec5}

\clearpage
\section{Section 3}
\label{sec3}

\MyVref{sec1} --- \MyVref{sec2} --- \MyVref{sec3}

\MyVref{sec1,sec2} --- \MyVref{sec1,sec2} --- \MyVref{sec1,sec3}

\MyVref{sec1,sec2,sec3}

\MyVref{sec1,sec2,sec3,sec4}

\MyVref{sec1,sec2,sec3,sec5}

\MyVref{sec1,sec2,sec3,sec4,sec5}

\clearpage
\section{Section 4}
\label{sec4}

\MyVref{sec1} --- \MyVref{sec2} --- \MyVref{sec3}

\MyVref{sec1,sec2} --- \MyVref{sec1,sec2} --- \MyVref{sec1,sec3}

\MyVref{sec1,sec2,sec3}

\MyVref{sec1,sec2,sec3,sec4}

\MyVref{sec1,sec2,sec3,sec5}

\MyVref{sec1,sec2,sec3,sec4,sec5}

\clearpage
\section{Section 5}
\label{sec5}

\MyVref{sec1} --- \MyVref{sec2} --- \MyVref{sec3}

\MyVref{sec1,sec2} --- \MyVref{sec1,sec2} --- \MyVref{sec1,sec3}

\MyVref{sec1,sec2,sec3}

\MyVref{sec1,sec2,sec3,sec4}

\MyVref{sec1,sec2,sec3,sec5}

\MyVref{sec1,sec2,sec3,sec4,sec5}

\end{document}

关于软件包版本:

近几个月来,CTAN 进行了大量更新。

我的系统上的 .log 文件显示:

This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2019/dev/Debian) (preloaded format=pdflatex 2020.2.13)  
LaTeX2e <2018-12-01>
Document Class: article 2018/09/03 v1.4i Standard LaTeX document class
Package: MnSymbol 2007/01/21 v1.4 support for the MnSymbol font
Package: amsmath 2018/12/01 v2.17b AMS math features
Package: amstext 2000/06/29 v2.01 AMS text
Package: amsbsy 1999/11/29 v1.2d Bold Symbols
Package: amsopn 2016/03/08 v2.02 operator names
Package: textcomp 2018/08/11 v2.0j Standard LaTeX package
Package: eufrak 2009/06/22 v3.00 Euler Fraktur fonts
Package: refcount 2016/05/16 v3.5 Data extraction from label references (HO)
Package: ltxcmds 2016/05/16 v1.23 LaTeX kernel commands for general use (HO)
Package: infwarerr 2016/05/16 v1.4 Providing info/warning/error messages (HO)
Package: varioref 2016/02/16 v1.5c package for extended references (FMi)
Package: hyperref 2018/11/30 v6.88e Hypertext links for LaTeX
Package: hobsub-hyperref 2016/05/16 v1.14 Bundle oberdiek, subset hyperref (HO)
Package: hobsub-generic 2016/05/16 v1.14 Bundle oberdiek, subset generic (HO)
Package: hobsub 2016/05/16 v1.14 Construct package bundles (HO)
Package: ifluatex 2016/05/16 v1.4 Provides the ifluatex switch (HO)
Package: ifvtex 2016/05/16 v1.6 Detect VTeX and its facilities (HO)
Package: intcalc 2016/05/16 v1.2 Expandable calculations with integers (HO)
Package: ifpdf 2018/09/07 v3.3 Provides the ifpdf switch
Package: etexcmds 2016/05/16 v1.6 Avoid name clashes with e-TeX commands (HO)
Package: kvsetkeys 2016/05/16 v1.17 Key value parser (HO)
Package: kvdefinekeys 2016/05/16 v1.4 Define keys (HO)
Package: pdftexcmds 2018/09/10 v0.29 Utility functions of pdfTeX for LuaTeX (HO)
Package: pdfescape 2016/05/16 v1.14 Implements pdfTeX's escape features (HO)
Package: bigintcalc 2016/05/16 v1.4 Expandable calculations on big integers (HO)
Package: bitset 2016/05/16 v1.2 Handle bit-vector datatype (HO)
Package: uniquecounter 2016/05/16 v1.3 Provide unlimited unique counter (HO)
Package: letltxmacro 2016/05/16 v1.5 Let assignment for LaTeX macros (HO)
Package: hopatch 2016/05/16 v1.3 Wrapper for package hooks (HO)
Package: xcolor-patch 2016/05/16 xcolor patch
Package: atveryend 2016/05/16 v1.9 Hooks at the very end of document (HO)
Package: atbegshi 2016/06/09 v1.18 At begin shipout hook (HO)
Package: hycolor 2016/05/16 v1.8 Color options for hyperref/bookmark (HO)
Package: keyval 2014/10/28 v1.15 key=value parser (DPC)
Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional
Package: auxhook 2016/05/16 v1.4 Hooks for auxiliary files (HO)
Package: kvoptions 2016/05/16 v3.12 Key value format for package options (HO)
Package: url 2013/09/16  ver 3.4  Verb mode for urls, etc.
Package: cleveref 2018/03/27 v0.21.4 Intelligent cross-referencing
Package: nameref 2016/05/21 v2.44 Cross-referencing by name of section
Package: gettitlestring 2016/05/16 v1.5 Cleanup title references (HO)

在此处输入图片描述

在此处输入图片描述

在此处输入图片描述

在此处输入图片描述

在此处输入图片描述

在此处输入图片描述


顺便一提:

的定义瓦里雷夫-macro\@@vpageref经过少许修改后复制到宏中\cref@old@@vpageref,并让其等于\@@@setvpageref包中的聪明人\cref@old@@vpageref修改版/变体的定义文本略有修改,\@@@setvpageref内容如下:

\vref@label{\the\c@vrcnt @xvr}%  <<<
\vref@label{\the\c@vrcnt @vr}%

这产生了一些模式:

\@bsphack
⟨Things done by the 1st \vref@label that do not yield visible material⟩
\@ephack
\@bsphack
⟨Things done by the 2nd \vref@label that do not yield visible material⟩
\@ephack

其他修改瓦里雷夫完成者聪明人产量相同。

连续的\@bsphack..\@esphack可能会扰乱水平间距,因此不是好的做法。
也许更好的做法是:

\@bsphack
\begingroup
\def\@bsphack{}%
\def\@esphack{}%
\vref@label{\the\c@vrcnt @xvr}%  <<<
\vref@label{\the\c@vrcnt @vr}%
\endgroup
\@esphack

这值得报告错误吗?

相关内容