定理的反向引用

定理的反向引用

是否有可能创建一个等同于方程式的反向引用用于定理、命题定义等?

这意味着在陈述定理之后,将会陈述引用该定理的位置,并且它将与 hyperref 一起工作。

标题中显示的表格/图形的使用几乎提供了一个答案,但如何将其附加到标记定理/定义的末尾以自动发生?

我需要自动发生的情况的示例,除了 \Cref

\documentclass{article}
\usepackage{etoolbox,xstring,xspace}
\usepackage{amsmath,amsthm,amssymb,thmtools}
\usepackage{hyperref}
\usepackage{cleveref}
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}

\makeatletter
\AtBeginDocument{%
\let\origref\ref
\renewcommand*\ref[1]{%
  \origref{#1}\xlabel{#1}}
}
\newrobustcmd*\xlabel[1]{%
   \ifcsdef{siteref@doc@#1}{}{\csgdef{siteref@doc@#1}{,}}%
    \@bsphack%
    \begingroup
       \csxdef{siteref@doc@#1}{\csuse{siteref@doc@#1},\thepage}%
         \protected@write\@auxout{}%
        {\string\SiteRef{siteref@#1}{\csuse{siteref@doc@#1}}}%
     \endgroup
     \@esphack%
}

\newrobustcmd*\SiteRef[2]{\csgdef{#1}{#2}}

\newrobustcmd*\xref[1]{%
\ifcsundef{siteref@#1}{%
     \@latex@warning@no@line{Label `#1' not defined}
     }{%
    \begingroup
      \StrGobbleLeft{\csuse{siteref@#1}}{2}[\@tempa]\relax%
      \def\@tempb{}%
      \@tempcnta=0\relax%
      \@tempcntb=\@ne\relax%
      \def\do##1{\advance\@tempcnta\@ne}%
      \expandafter\docsvlist\expandafter{\@tempa}%
       \def\do##1{%
         \ifnum\@tempcntb=\@tempcnta\relax%
            \hyperpage{##1}%
         \else
            \hyperpage{##1},%
          \fi%
          \advance\@tempcntb\@ne
       }%
       [\expandafter\docsvlist\expandafter{\@tempa}]\xspace%
    \endgroup
   }%
}
\makeatother


\begin{document}

\begin{theorem}\label{fancytheorem}
Fancy Theorem
\end{theorem}
Referenced on page(s)\xref{fancytheorem}

\newpage\section{page two}\ref{fancytheorem}
\end{document}

谢谢!

答案1

这是实现您想要的功能的一种方法。我从您的代码开始,添加和更改了一些内容。一个不太简短的摘要:

  • 我将siteref@其重新命名thmref@,因为这对我来说更有意义:)
  • 我将定理环境包装在一个\NewDocumentEnvironment名为中Theorem,它接受两个参数:环境的可选参数theorem和一个(强制)标签。标签用于定义一个thmref@<label>宏,该宏用于存储包含定理引用的页码。在环境结束时,将调用Theorem\xref命令以自动添加交叉引用信息。
  • 我不再每次调用\SiteRef时都向 auxfile 写入命令,而是只使用 写入一次。\ref\AtEndDocument\SaveTheoremRef
  • 我已经让\refetc 变得足够智能,只保存与定理相关的参考文献的“thmref”信息。以前,无论何时\ref使用,这些信息都会存储在 aux 文件中。
  • 该代码适用于\ref\cref。我没有添加,\Cref但这很容易做到。
  • 我不得不更改\xref命令,因为它不适用于多个引用的情况。我还让它只打印每页的一个页面引用,并根据包含定理引用的页数使用page或。pages
  • 若无参考文献,No references则打印。

编辑

我已经更改了 的定义,\@theoremref以便现在允许在定理之前出现引用。代价是thmref@<label>现在为所有引用(而不仅仅是定理)构建引用,但它们仅存储在定理的辅助文件中。同时,当有多个引用时,我在最后两个页面引用之间添加了一个“and”,这有点棘手,并且我通过将嵌入式环境放入theorem它们自己的组中来修复原始版本代码中的一个错误。我删除了不必要的包并重命名\xref\AddTheoremReferences以避免名称冲突,因为我认为这\xref可能在某个包中定义(?)。最后,根据评论中的要求,我允许将多个标签传递给\ref{...}和朋友。

以下是包含这些更改的我的 MWE 第一页的输出:

在此处输入图片描述

代码如下:

\documentclass{article}
\usepackage{etoolbox}
\usepackage{amsmath,amsthm,amssymb,thmtools}
\usepackage{hyperref}
\usepackage{cleveref}
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}

\makeatletter

% This command is written to the aux file by \SaveTheoremRef, hence
% allowing us to access the cross-referencing data via \thmref@aux@<label>
\newrobustcmd*\TheoremRef[2]{\csgdef{thmref@aux@#1}{#2}}

% save theorem reference data. Called via \AtEndDocument{...}
\newrobustcmd*\SaveTheoremRef[1]{
   \ifcsdef{thmref@#1}{%
     \immediate\write\@auxout{\string\TheoremRef{#1}{\csuse{thmref@#1}}}%
   }{}
}

% stores page reference data in thmref@<label>
\newcommand\@theoremref[1]{%
   \def\do##1{\ifcsdef{thmref@##1}{\csxappto{thmref@##1}{,\number\thepage}}%
                                  {\csxdef{thmref@##1}{\number\thepage}}%
   }%
   \docsvlist{#1}%
}

% Overwrite definitions of \ref and \cref. Since other packages such as
% hyperref and cleverref change these this should be done at the
% beginning of the document.
\AtBeginDocument{
    \let\originalref\ref
    \renewcommand*\ref[1]{\originalref{#1}\@theoremref{#1}}
    \let\originalcref\cref
    \renewcommand*\cref[1]{\originalcref{#1}\@theoremref{#1}}
}

% \AddTheoremReferences<label> prints the cross-referencing information for theorem <label>
\newrobustcmd*\AddTheoremReferences[1]{%
    \ifcsdef{thmref@aux@#1}{% proceed only if thmref data exists
       \def\@tempa{0}% used to check for repeats
       \@tempcnta=0% used to check for plural
       \def\@thmref{}% will contain cross-referencing hyperlinks
       \def\do##1{\ifnum##1=\@tempa\relax% skip over repeat references on each page
                  \else%
                      \ifnum\@tempcnta=1% skip \@tempcnta=0
                        \xappto\@thmref{\noexpand\hyperpage{\@tempa}}% first page reference
                      \else\ifnum\@tempcnta>1% already have ref so add a comma
                           \xappto\@thmref{, \noexpand\hyperpage{\@tempa}}%
                           \fi%
                      \fi%
                      \global\advance\@tempcnta by 1% increment reference counter
                      \edef\@tempa{##1}% store to check for repeat next time
                  \fi%
       }
       \xdef\@@thmref{\csuse{thmref@aux@#1}}
       \expandafter\docsvlist\expandafter{\@@thmref}
       \typeout{Refefenced: \the\@tempcnta.}
       \ifnum\@tempcnta=1% only one reference
           \noindent[Referenced on page \expandafter\hyperpage{\@tempa}]%
       \else% at least two references so add an "and"
           \noindent[Referenced on pages \@thmref\space and \expandafter\hyperpage{\@tempa}]%
       \fi%
       }{\noindent[Not referenced]\@latex@warning@no@line{Theorem reference `#1' is not defined}}%
}

\makeatother

\usepackage{xparse}
% \begin{Theorem}[heading]{label} ... \end{Theorem}
\NewDocumentEnvironment{Theorem}{ o m }
   {\AtEndDocument{\SaveTheoremRef{#2}}
    \IfNoValueTF{#1}{\begin{theorem}}{\begin{theorem}[#1]}
    \label{#2}
   }
   {\end{theorem}\AddTheoremReferences{#2}}


\setcounter{page}{11}% for testing purposes only

\begin{document}
  A reference to \cref{fanciertheorem}.

  \begin{Theorem}{fancytheorem}
  Fancy Theorem
  \end{Theorem}

  \begin{Theorem}[Really fancy!]{fanciertheorem}
  Fancier Theorem
  \end{Theorem}

  \begin{Theorem}[Plain theorem]{plaintheorem}
  Plain Theorem
  \end{Theorem}

  \newpage\section{page two}
    \cref{fancytheorem,fanciertheorem}
    \ref{fanciertheorem}

  \newpage\section{page three}
    \ref{fanciertheorem}
\end{document}

相关内容