我知道 cleveref 包\cref
可以添加正确的引用名称(参见:
自动插入“Section”、“Subsection”等)。我有一些参考资料指向下一节,有些人觉得在这种情况下给出编号而不是只说“在下一节”很奇怪。有时我移动了各个部分,这些参考资料突然变得非常不完整。为了两全其美,有没有办法自动进行这种更改?
例如:替换“这将在第1.4节“与“这将在下一节“
答案1
这是一个基于cleveref
包的解决方案。如果hyperref
包被加载,单词“section”(或 chapter/subsection/...)就是一个可点击的超链接。
\documentclass{article}
%\usepackage{hyperref}
\usepackage{cleveref}
\crefname{subsection}{subsection}{subsections}
\providecommand\hyperref[2][]{#2}
\makeatletter
\newcommand{\mt@ref}[1]{%
\cref@gettype{#1}{\@temptype}%
\cref@getcounter{#1}{\@tempctr}%
\def\mtt{\the\csname c@\@temptype\endcsname}%
\ifnum\mtt=\numexpr\@tempctr-1\relax \mtcase the next \hyperref[#1]{\@temptype}\else%
\ifnum\mtt=\numexpr\@tempctr+1\relax \mtcase the previous \hyperref[#1]{\@temptype}\else%
\cref{#1}\fi\fi}
\newcommand{\mtref}{\let\mtcase\relax\mt@ref}
\newcommand{\Mtref}{\let\mtcase\MakeUppercase\mt@ref}
\makeatother
\begin{document}
\section{Foo}\label{sec:foo}
this is \Mtref{sec:bar} and this is \mtref{sec:baz}
\subsection{Sub foo}\label{ss:sfoo}
this is \mtref{sec:baz} and this is \mtref{sec:bar}
and \mtref{ss:sfbla} and \mtref{ss:sfbaz}
\subsection{Bla foo}\label{ss:sfbla}
bla bla bla
\subsection{Bar foo}\label{ss:sfbar}
bla bla bla
\subsection{Baz foo}\label{ss:sfbaz}
bla bla bla
\section{Bar}\label{sec:bar}
bla bla bla
\section{Baz}\label{sec:baz}
bla bla bla
\end{document}
结果大致如下(使用以前版本的代码进行编译):
答案2
修改尝试
除了\Unitref{<label>}
提供单元名称和引用,如“第 2 节”或“第 1.1 小节”等(参见原始尝试),我现在还引入了\Ref{<unit>}{<label>}
,其中<unit>
是要比较的内容,“节”、“小节”或“小小节”。如果\ref{<label>}
实际上是单元的下一个增量,它将输出“下一个”。如果\ref{<label>}
不是单元的下一个增量,它将输出“ \ref{<label>}
”。
\documentclass{article}
\usepackage{ifthen}
\let\svsection\section
\let\svsubsection\subsection
\let\svsubsubsection\subsubsection
\def\section{\xdef\Unit{section}\svsection}
\def\subsection{\xdef\Unit{subsection}\svsubsection}
\def\subsubsection{\xdef\Unit{subsubsection}\svsubsubsection}
\let\svlabel\label
\def\label#1{\expandafter\xdef\csname Unit-#1\endcsname{\Unit}\svlabel{#1}}
\def\Unitref#1{\csname Unit-#1\endcsname~\ref{#1}}
\def\thenextsection{\the\numexpr\thesection+1\relax}
\def\thenextsubsection{\thesection.\the\numexpr\arabic{subsection}+1\relax}
\def\thenextsubsubsection{\thesection.\arabic{subsection}%
.\the\numexpr\arabic{subsubsection}+1\relax}
\def\Ref#1#2{%
\ifthenelse{\equal{\ref{#2}}{\csname thenext#1\endcsname}}%
{the next #1}{#1~\ref{#2}}
}
\begin{document}
\section{The First Section\label{s:first}}
``The First Subsection'' is \Ref{subsection}{ss:first},
whereas ``The Second Subsection'' is \Ref{subsection}{ss:second}.
\subsection{The First Subsection\label{ss:first}}
In the prior unit, \Unitref{s:first}, not to be confused with the
current unit, \Unitref{ss:first}, we have successfully captured the data
``A Subsubsection'' is \Ref{subsubsection}{sss:first},
whereas ``Second Subsubsection'' is \Ref{subsubsection}{sss:second}.
\subsubsection{A subsubsection\label{sss:first}}
``The First Section'' is \Ref{section}{s:first},
whereas ``The Second Section'' is \Ref{section}{s:second}.
\section{The Second Section\label{s:second}}
\subsection{The Section Subsection\label{ss:second}}
The prior unit, \Unitref{s:second} is not to be confused with the
way back references to either \Unitref{s:first}, \Unitref{ss:first},
or \Unitref{sss:first}. But the current unit is \Unitref{ss:second}.
We have successfully captured the data.
\subsubsection{Second subsubsection\label{sss:second}}
\end{document}
需要改进的领域包括“单位”名称的可选大写,例如,如果出现在句子开头。此外,\Ref
只能比较“苹果和苹果”。也就是说,如果标签是子节的标签,则\Ref
只能用于查看它是否是下一个子节,这就是为什么目前必须明确指定参数#1
的原因。\Ref
最初的(误导性)尝试
在这里,我只是在序言中稍微玩了一下,并创建了\Unitref{}
“第 2 节”或“第 1.1 小节”等。
\Unit
我的做法是,每当我输入这样的单元时,将名称“section”、“subsection”等保存在宏中。然后,在调用时\label
,我使用当前的值\Unit
作为新宏的值\csname Unit-<label>\endcsname
。
最后,在调用时\Unitref{<label>}
,它会调用\csname Unit-<label>\endcsname
并跟进硬空格以及对\ref{<label>}
\documentclass{article}
\let\svsection\section
\let\svsubsection\subsection
\let\svsubsubsection\subsubsection
\def\section{\xdef\Unit{section}\svsection}
\def\subsection{\xdef\Unit{subsection}\svsubsection}
\def\subsubsection{\xdef\Unit{subsubsection}\svsubsubsection}
\let\svlabel\label
\def\label#1{\expandafter\xdef\csname Unit-#1\endcsname{\Unit}\svlabel{#1}}
\def\Unitref#1{\csname Unit-#1\endcsname~\ref{#1}}
\begin{document}
\section{The First Section\label{s:first}}
\subsection{First Subsection\label{ss:first}}
In the prior unit, \Unitref{s:first}, not to be confused with the
current unit, \Unitref{ss:first}, we have successfully captured the data
\subsubsection{A subsubsection\label{sss:first}}
Blah-Blah
\section{The Next Section\label{s:second}}
\subsection{Next Subsection\label{ss:second}}
The prior unit, \Unitref{s:second} is not to be confused with the
way back references to either \Unitref{s:first}, \Unitref{ss:first},
or \Unitref{sss:first}. But the current unit is \Unitref{ss:second}.
We have successfully captured the data.
\end{document}
答案3
(评论太长,因此作为答案发布。)
\label
该软件包用于生成输出的基本 LaTeX机制cleveref
仅存储与“项目”(例如部分、方程、定理等)相关的两个特征:项目的数字——更准确地说,任何计数器的值都是通过\refstepcounter
指令最近增加的——以及页码输出产品编号。
不幸的是,由于\label
没有捕获其他项目特征(例如章节、节或小节编号),\cref
如果交叉引用标注恰好发生在第 1.3 节中,您就无法使用它来创建“在下一节中”(而不是“在第 1.4 节中”)类型的标注。
你可能想看看zref 包构建您描述类型的增强交叉引用功能。