![让反向引用更美观](https://linux22.com/image/264488/%E8%AE%A9%E5%8F%8D%E5%90%91%E5%BC%95%E7%94%A8%E6%9B%B4%E7%BE%8E%E8%A7%82.png)
问题LaTeX 中的反向引用被标记为重复,所以我无法在该主题中发帖。尽管如此,我发现 Ryan Reich 在那里提供的代码是一个很好的学习练习。他的解决方案提供了一个逗号分隔的反向引用列表,没有空格。
我只是认为,如果可以修改他的方法,使其不仅生成一串以逗号分隔的数字,而且还生成可以在文档中使用的实际可读文本,那么他的方法将更加有用。
所以我尝试改进他的解决方案
答案1
这cleveref-usedon
包允许轻松地使用cleveref
的格式进行反向引用(例如,“定理 1”、“第 II 节”)。
要使用它,我需要安装它,因为它不是我的 LaTeX 安装的一部分。
编辑:截至 2023 年 8 月,存在一个错误,cleverf-usedon
导致某些反向引用不出现。请参阅这个问题在 GitHub 上。
答案2
因此,这里有一个解决方案:
\documentclass{article}
\usepackage{etoolbox}
\usepackage{stringstrings}
\makeatletter
\def\@newbackl@bel#1#2#3{%
\@ifundefined{#1@#2}%
{\global\@namedef{#1@#2}{#3}}
{\cs@g@appendpair{#1@#2}{#3}}%
}
% #1 and #2 are each of the form {a}{b}, and the a and b groups are to be
% concatenated independently.
\def\cs@g@appendpair#1#2{{%
\edef\first{\csname #1\endcsname}%
\edef\firsta{\expandafter\@firstoftwo\first}%
\convertword[q]{\firsta}{and}{}%
\edef\firsta{\thestring}%
\edef\firstb{\expandafter\@secondoftwo\first}%
\convertword[q]{\firstb}{and}{}%
\edef\firstb{\thestring}%
\csxdef{#1}%
{{\firsta, and \@firstoftwo#2}%
{\firstb, and \@secondoftwo#2}}%
}}
% Patching into the existing commands
\def\newbacklabel{\@newbackl@bel B}
\let\backlabel=\label
\patchcmd\backlabel{\newlabel}{\newbacklabel}{}{}
\let\backref=\ref
\patchcmd\backref{r@#1}{B@#1}{}{}
\let\pagebackref=\pageref
\patchcmd\pagebackref{r@#1}{B@#1}{}{}
\pretocmd\ref{\backlabel{#1}}{}{}
\makeatother
\begin{document}
\begin{enumerate}
\item \label{e:1} Part 1, referenced by part(s) \backref{e:1}
on page(s) \pagebackref{e:1}.
\item \label{e:x} Part 2, referenced by part(s) \backref{e:x} on
page(s) \pagebackref{e:x}, and referencing part \ref{e:1}.
\item \label{e:2} Part 3, referencing part \ref{e:1} and \ref{e:x}
\item \label{e:3} Part 4, referencing part \ref{e:1}.
\end{enumerate}
\newpage
\section{A section}
\label{s:1}
Here is another reference to part \ref{e:1}.
\end{document}
对于那些对 stringstrings 包的缓慢感到沮丧的人来说,这里有一个更长但更快的替代方案
\documentclass{article}
\usepackage{etoolbox}
\usepackage{stringstrings}
\makeatletter
\def\@newbackl@bel#1#2#3{%
\@ifundefined{#1@#2}%
{\global\@namedef{#1@#2}{#3}}
{\cs@g@appendpair{#1@#2}{#3}}%
}
% #1 and #2 are each of the form {a}{b}, and the a and b groups are to be
% concatenated independently.
\def\cs@g@appendpair#1#2{{%
\edef\first{\csname #1\endcsname}%
\edef\firsta{\expandafter\@firstoftwo\first}%
\replacewordF[q]{\firsta}{and}{}%
\edef\firsta{\thestring}%
\edef\firstb{\expandafter\@secondoftwo\first}%
\replacewordF[q]{\firstb}{and}{}%
\edef\firstb{\thestring}%
\csxdef{#1}%
{{\firsta, and \@firstoftwo#2}%
{\firstb, and \@secondoftwo#2}}%
}}
% Patching into the existing commands
\def\newbacklabel{\@newbackl@bel B}
\let\backlabel=\label
\patchcmd\backlabel{\newlabel}{\newbacklabel}{}{}
\let\backref=\ref
\patchcmd\backref{r@#1}{B@#1}{}{}
\let\pagebackref=\pageref
\patchcmd\pagebackref{r@#1}{B@#1}{}{}
\pretocmd\ref{\backlabel{#1}}{}{}
\usepackage{ifnextok}
\usepackage{ifthen}
\def\string@end{$}
\def\converttilde{T}
\newcounter{arg@index}
\let\SaveHardspace~
\def\getargsF#1{%
\if T\converttilde\def~{ }\fi%
\protected@edef\the@string{#1}%
\def\argi{}\setcounter{arg@index}{1}%
\expandafter\parse@Block\the@string\string@end%
\let~\SaveHardspace%
}
%ifthenelse needed when leading spaces end up as \argi
\def\parse@Block{\IfNextToken\string@end%
{\edef\narg{\arabic{arg@index}}\@gobble}%
{\IfNextToken\@sptoken{\addtocounter{arg@index}{1}%
\ifthenelse{\equal{\argi}{}}{\addtocounter{arg@index}{-1}}{}%
\expandafter\def\csname arg\roman{arg@index}\endcsname{}%
\add@to{\parse@Block}}%
{\add@to{\parse@Block}}}}
\def\add@to#1#2{\if\@sptoken#2\else\expandafter\protected@edef%
\csname arg\roman{arg@index}\endcsname%
{\csname arg\roman{arg@index}\endcsname#2}\fi#1}
\newcounter{word@count}
% Replaces a word of alphanumeric phrase with another
% Syntax: \replacewordF[mode]{orig_string}{word}{replacement}
% mode is v for verbose, q for quiet (saved in \thestring}
% word is one whole word; cannot contain spaces.
% replacement can be multiword
\newcommand\replacewordF[4][v]{%
\getargsF{#2}%
\edef\thestring{\argi}%
\setcounter{word@count}{1}%
\whiledo{\value{word@count} < \narg}{%
\addtocounter{word@count}{1}%
\ifthenelse{\equal{\csname arg\roman{word@count}\endcsname}{#3}}%
{\edef\the@string{\thestring\@sptoken}\edef\thestring{\the@string#4}}%
{\edef\the@string{\thestring\@sptoken}%
\edef\thestring{\the@string\csname arg\roman{word@count}\endcsname}}%
}%
\if v#1\thestring\fi%
}
\makeatother
\begin{document}
\begin{enumerate}
\item \label{e:1} Part 1, referenced by part(s) \backref{e:1}
on page(s) \pagebackref{e:1}.
\item \label{e:x} Part 2, referenced by part(s) \backref{e:x} on
page(s) \pagebackref{e:x}, and referencing part \ref{e:1}.
\item \label{e:2} Part 3, referencing part \ref{e:1} and \ref{e:x}
\item \label{e:3} Part 4, referencing part \ref{e:1}.
\end{enumerate}
\newpage
\section{A section}
\label{s:1}
Here is another reference to part \ref{e:1}.
\end{document}