是否有某种方法可以获取引用某些内容的所有部分的列表?
例如,在
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}