列出所有引用某内容的部分

列出所有引用某内容的部分

是否有某种方法可以获取引用某些内容的所有部分的列表?

例如,在

This\label{test} is referenced in \magicalthingy{test}.

\section{1}
One\ref{test}

\section{2}
Two

\section{3}
Three\ref{test}

\magicalthingy{test}将会1,3

答案1

更新(请参阅hyperref最后的版本!)

\ref{...}这将存储列表中每个标签出现的部分位置(编号) ,并\newlabel{...}在文档末尾将单独的内容写入.aux文件 - 这样,在通常的双重编译之后,就可以在文档开始时知道位置列表。

请注意:奇怪的是,任意标签名称在这里都可以使用,但如果hyperref使用,则\newlabel必须编写另一个版本。

\documentclass{article}

\usepackage{xparse}
\usepackage{refcount}

\let\latexorigref\ref



\ExplSyntaxOn

\seq_new:N \g_xavier_label_seq

\renewcommand{\ref}[1]{%
  \seq_if_exist:cF {l_#1_label_seq} {%
    \seq_new:c {l_#1_label_seq }%
    \seq_gput_right:Nn \g_xavier_label_seq  {#1}%
  }
  \seq_put_right:cx { l_#1_label_seq }{\thesection}%
  \latexorigref{#1}%
}

\newcommand{\magicalthingy}[1]{%
  \getrefnumber{#1reflabel}
}


\makeatletter
\newcommand{\writerefinfo}{%
  \seq_map_inline:Nn \g_xavier_label_seq {%
    \tl_clear:N \l_tmpa_tl
    \int_zero:N \l_tmpa_int
    \seq_map_inline:cn {l_##1_label_seq} {%
      \int_incr:N \l_tmpa_int 
      \int_compare:nNnTF { \l_tmpa_int } = {\seq_count:c {l_##1_label_seq}}
      { \tl_put_right:Nn \l_tmpa_tl {####1} }
      { \tl_put_right:Nn \l_tmpa_tl {####1,} }
    }%
    \immediate\write\@auxout{%
      \string\newlabel{##1reflabel}{{\tl_use:N \l_tmpa_tl}{-1000}}%
    }
  }
}
\makeatother

\ExplSyntaxOff

\AtEndDocument{%
  \writerefinfo
}

\usepackage{blindtext}
\begin{document}

We have references of 'einstein' in sections \magicalthingy{einstein}


\section{Foo}\label{foo}


In equation \ref{einstein}


\blindtext[5]

\section{Stuff}

\begin{equation}
E=mc^2 \label{einstein}
\end{equation}
In this famous equation \ref{einstein}



\end{document}

在此处输入图片描述

更新

以下是 的版本hyperref

\documentclass{book}

\usepackage{xparse}
\usepackage{xcolor}
\usepackage{refcount}
\usepackage{blindtext}
\usepackage{xpatch}
\usepackage{hyperref}

\usepackage{cleveref}

\makeatletter

\@ifclassloaded{book}{%
  \providecommand{\reflistlevel}{chapter} % Use chapter counting
}{%
  \providecommand{\reflistlevel}{section} % section is the default structure 
}


\AtBeginDocument{%
  \let\latex@@ref\ref
  \let\latex@@hyper@refstar\@refstar
  \let\latex@@hyper@T@ref\T@ref
}


\ExplSyntaxOn

\bool_new:N \l_xavier_hyperref_bool

\makeatletter
\@ifpackageloaded{hyperref}{%
  \bool_set_true:N \l_xavier_hyperref_bool
}{}


\seq_new:N \g_xavier_label_seq % Holds all labels 

\cs_new:Nn \ref_xavier_hook:nn {%
  \seq_if_exist:cF {l_#2_label_seq} {%
    \seq_new:c {l_#2_label_seq }%
    \seq_gput_right:Nn \g_xavier_label_seq  {#2}%  Put the current label name on the list of referenced labels
  }
  \seq_gput_right:cx { l_#2_label_seq }{\use:c{the#1}}%  Write the expanded position of section etc. counter
}

\newcommand{\writerefinfo}{%
  \seq_map_inline:Nn \g_xavier_label_seq {%
    \tl_clear:N \l_tmpa_tl
    \int_zero:N \l_tmpa_int
    \seq_map_inline:cn {l_##1_label_seq} {%
      \int_incr:N \l_tmpa_int 
      \int_compare:nNnTF { \l_tmpa_int } = {\seq_count:c {l_##1_label_seq}}
      { \tl_put_right:Nn \l_tmpa_tl {####1} }
      { \tl_put_right:Nn \l_tmpa_tl {####1,} }
    }%
    \bool_if:NTF \l_xavier_hyperref_bool
    {   
      \immediate\write\@auxout{%
        \string\newlabel{##1reflabel}{{\tl_use:N \l_tmpa_tl}{\seq_count:c {l_##1_label_seq}}{}{}}%  Use two explicitly empty {}{} since we don't want to provide hyperref support for this at all!
      }
    }{%
      \immediate\write\@auxout{%
        \string\newlabel{##1reflabel}{{\tl_use:N \l_tmpa_tl}{\seq_count:c {l_##1_label_seq}}}% 
      }
    }
  }
}

\AtBeginDocument{%
  % Prepare the correct `\ref` command -- depends on hyperref
  \@ifpackageloaded{hyperref}{%
    \RenewDocumentCommand{\@refstar}{O{\reflistlevel}m}{%
    \ref_xavier_hook:nn {#1}{#2}
    \latex@@hyper@refstar{#2}%
  }
  \RenewDocumentCommand{\T@ref}{O{\reflistlevel}m}{%
    \ref_xavier_hook:nn {#1}{#2}
    \latex@@hyper@T@ref{#2}%
  }
  \RenewDocumentCommand{\ref}{sO{\reflistlevel}}{%
    \IfBooleanTF{#1}{%
      \@refstar[#2]%
    }{%
      \T@ref[#2]
    }
  }
}{%
  % No hyperref, just use a slightly modified `\ref` command
  \RenewDocumentCommand{\ref}{O{\reflistlevel}m}{%
    \ref_xavier_hook:nn {#1}{#2}
    \latex@@ref{#2}
  }
}
}

\NewDocumentCommand{\reflist}{om}{%
  \clist_set:Nx \l_tmpa_clist {\getrefnumber{#2reflabel}}
  \IfValueTF{#1}{%
    \clist_map_function:NN \l_tmpa_clist #1
  }{
    \clist_use:Nn \l_tmpa_clist {,} 
  }
}

\makeatother

\ExplSyntaxOff

\AtEndDocument{%
  \writerefinfo
}


\newcommand{\magicalthingy}[1]{%
  \getrefnumber{#1reflabel}
}


\newcommand{\ShowRefList}[1]{%
  \textcolor{blue}{#1}, 
}




\begin{document}

%\makeatletter
%\meaning\T@ref
%\makeatother

\chapter{Foo}\label{foo:chapter}

We have references of 'einstein' in chapters \reflist[\ShowRefList]{einstein}, but in \ref{foo:chapter} we will see that ...


In equation \ref{einstein}


\blindtext[5]

\chapter{Stuff}

Foo, however is referenced only in \magicalthingy{foo:chapter}

\begin{equation}
E=mc^2 \label{einstein}
\end{equation}
In this famous equation \ref{einstein}


\chapter{Another another chapter}


In his famous equation \ref{einstein}, Albert Einstein has shown the equivalence of energy and mass. 




\end{document}

在此处输入图片描述

第二次更新 --\nameref支持 --

\documentclass{book}

\usepackage{xparse}
\usepackage{xcolor}
\usepackage{refcount}
\usepackage{blindtext}
\usepackage{xpatch}
\usepackage{hyperref}

\usepackage{cleveref}

\makeatletter

\@ifclassloaded{book}{%
  \providecommand{\reflistlevel}{chapter} % Use chapter counting
}{%
  \providecommand{\reflistlevel}{section} % section is the default structure 
}


\AtBeginDocument{%
  \let\latex@@ref\ref
  \let\latex@@hyper@refstar\@refstar
  \let\latex@@hyper@T@ref\T@ref
  \let\latex@@hyper@namerefstar\@namerefstar
  \let\latex@@hyper@T@nameref\T@nameref
}


\ExplSyntaxOn

\bool_new:N \l_xavier_hyperref_bool

\makeatletter
\@ifpackageloaded{hyperref}{%
  \bool_set_true:N \l_xavier_hyperref_bool
}{}


\seq_new:N \g_xavier_label_seq % Holds all labels 

\cs_new:Nn \ref_xavier_hook:nn {%
  \seq_if_exist:cF {l_#2_label_seq} {%
    \seq_new:c {l_#2_label_seq }%
    \seq_gput_right:Nn \g_xavier_label_seq  {#2}%  Put the current label name on the list of referenced labels
  }
  \seq_gput_right:cx { l_#2_label_seq }{\use:c{the#1}}%  Write the expanded position of section etc. counter
}

\newcommand{\writerefinfo}{%
  \seq_map_inline:Nn \g_xavier_label_seq {%
    \tl_clear:N \l_tmpa_tl
    \int_zero:N \l_tmpa_int
    \seq_map_inline:cn {l_##1_label_seq} {%
      \int_incr:N \l_tmpa_int 
      \int_compare:nNnTF { \l_tmpa_int } = {\seq_count:c {l_##1_label_seq}}
      { \tl_put_right:Nn \l_tmpa_tl {####1} }
      { \tl_put_right:Nn \l_tmpa_tl {####1,} }
    }%
    \bool_if:NTF \l_xavier_hyperref_bool
    {   
      \immediate\write\@auxout{%
        \string\newlabel{##1reflabel}{{\tl_use:N \l_tmpa_tl}{\seq_count:c {l_##1_label_seq}}{}{}}%  Use two explicitly empty {}{} since we don't want to provide hyperref support for this at all!
      }
    }{%
      \immediate\write\@auxout{%
        \string\newlabel{##1reflabel}{{\tl_use:N \l_tmpa_tl}{\seq_count:c {l_##1_label_seq}}}% 
      }
    }
  }
}

\AtBeginDocument{%
  % Prepare the correct `\ref` command -- depends on hyperref
  \@ifpackageloaded{hyperref}{%
    \RenewDocumentCommand{\@refstar}{O{\reflistlevel}m}{%
      \ref_xavier_hook:nn {#1}{#2}
      \latex@@hyper@refstar{#2}%
    }
    \RenewDocumentCommand{\T@ref}{O{\reflistlevel}m}{%
      \ref_xavier_hook:nn {#1}{#2}
      \latex@@hyper@T@ref{#2}%
    }
    \RenewDocumentCommand{\@namerefstar}{O{\reflistlevel}m}{%
      \ref_xavier_hook:nn {#1}{#2}
      \latex@@hyper@namerefstar{#2}%
    }
    \RenewDocumentCommand{\T@nameref}{O{\reflistlevel}m}{%
      \ref_xavier_hook:nn {#1}{#2}
      \latex@@hyper@T@nameref{#2}%
    }
    \RenewDocumentCommand{\ref}{sO{\reflistlevel}}{%
      \IfBooleanTF{#1}{%
        \@refstar[#2]%
      }{%
        \T@ref[#2]
      }
    }
    \RenewDocumentCommand{\nameref}{sO{\reflistlevel}}{%
      \IfBooleanTF{#1}{%
        \@namerefstar[#2]%
      }{%
        \T@nameref[#2]
      }
    }
  }{%
    % No hyperref, just use a slightly modified `\ref` command
    \RenewDocumentCommand{\ref}{O{\reflistlevel}m}{%
      \ref_xavier_hook:nn {#1}{#2}
      \latex@@ref{#2}
    }
  }
}

\NewDocumentCommand{\reflist}{om}{%
  \clist_set:Nx \l_tmpa_clist {\getrefnumber{#2reflabel}}
  \IfValueTF{#1}{%
    \clist_map_function:NN \l_tmpa_clist #1
  }{
    \clist_use:Nn \l_tmpa_clist {,} 
  }
}

\makeatother

\ExplSyntaxOff

\AtEndDocument{%
  \writerefinfo
}


\newcommand{\magicalthingy}[1]{%
  \getrefnumber{#1reflabel}
}


\newcommand{\ShowRefList}[1]{%
  \textcolor{blue}{#1}, 
}




\begin{document}

%\makeatletter
%\meaning\T@ref
%\makeatother

\chapter{Foo}\label{foo:chapter}

We have references of 'einstein' in chapters \reflist[\ShowRefList]{einstein}, but in \nameref{foo:chapter} we will see that ...


In equation \ref{einstein}


\blindtext[5]

\chapter{Stuff}

Foo, however is referenced only in \magicalthingy{foo:chapter}

\begin{equation}
E=mc^2 \label{einstein}
\end{equation}
In this famous equation \nameref{einstein}


\chapter{Another another chapter}


In his famous equation \nameref*{einstein}, Albert Einstein has shown the equivalence of energy and mass. 




\end{document}

相关内容