我正在通过编号、类型和名称引用一些部分(实际上这些部分最终将被自定义)。但碰巧没有名称。所以我想把它省略掉。我该如何测试呢?
一位 MWE 表示:
\documentclass{article}
\usepackage{xcolor}
\definecolor{darkred}{rgb}{0.5,0,0}
\usepackage[colorlinks, linkcolor=darkred]{hyperref}
\newcommand\doubleref[1]{\autoref{#1} (\nameref{#1})}
\begin{document}
\section{This and That about Everything}\label{sec:thisthat}
Some text.
\section{}\label{sec:two}
Like meantioned in \doubleref{sec:thisthat} and \doubleref{sec:two}.
\end{document}
因此,在这个例子中,第二个引用应该自动仅为第 2 节并不是第 2 节()。
我试过
\newcommand\doubleref[1]{\autoref{#1}\edef\nae@tmp{\nameref{#1}}\ifx\empty\name@tmp\relax\else\ (\name@tmp)\fi}
但\nameref
似乎没有返回名称的可扩展版本。
答案1
当您说 时\label{x}
,LaTeX 将数据存储在名为 的宏中\r@x
;标题(使用 时可用hyperref
)是五个标记列表中的第三个。在您的例子中,我们想测试标题是否为空,这意味着相关标记列表仅包含\relax
,它hyperref
始终附加到标题。
\documentclass{article}
\usepackage{xcolor}
\definecolor{darkred}{rgb}{0.5,0,0}
\usepackage[colorlinks, linkcolor=darkred]{hyperref}
\makeatletter
\long\def\cana@extract#1#2#3#4#5{\unexpanded{#3}}
\def\cana@relax{\relax}
\newcommand\doubleref[1]{\autoref{#1}%
\@ifundefined{r@#1}\relax{\edef\cana@temp{%
\expandafter\expandafter\expandafter\cana@extract\csname r@#1\endcsname}%
\ifx\cana@temp\cana@relax\else~(\nameref{#1})\fi}}
\makeatother
\begin{document}
\section{This and That about Everything}\label{sec:thisthat}
Some text.
\section{}\label{sec:two}
Like meantioned in \doubleref{sec:thisthat} and \doubleref{sec:two}.
\end{document}
我使用\edef
,但使用 保护标题\unexpanded
,这样它就不会完全展开,否则可能会导致大问题。仅当与标签关联的宏已从文件中读入时才进行测试.aux
。
更新
使用较新的 LaTeX 内核时,由于交叉引用的内部管理发生变化,上述代码不再起作用。
\documentclass{article}
\usepackage{xcolor}
\definecolor{darkred}{rgb}{0.5,0,0}
\usepackage[colorlinks, linkcolor=darkred]{hyperref}
\makeatletter
\long\def\cana@extract#1#2#3#4#5{\unexpanded{#3}}
\newcommand\doubleref[1]{\autoref{#1}%
\@ifundefined{r@#1}{\relax}{%
\edef\cana@temp{%
\expandafter\expandafter\expandafter\cana@extract\csname r@#1\endcsname
}%
\ifx\cana@temp\@empty\else~(\nameref{#1})\fi}}
\makeatother
\begin{document}
\section{This and That about Everything}\label{sec:thisthat}
Some text.
\section{}\label{sec:two}
Like meantioned in \doubleref{sec:thisthat} and \doubleref{sec:two}.
\end{document}
答案2
使用包 重新实现 Gregorio 的解决方案refcount
。
\getrefbykeydefault{#1}{name}{}
提取引用 的 nameref 部分#1
。该命令是完全可扩展的。如果没有名称,则测试变为\if\vcenter\vcenter
。否则,名称将扩展为与 不同的不可扩展内容\vcenter
。也可以使用 ,而不是\vcenter
其他不可扩展的标记,它应该是不出现在名称开头的标记。
\documentclass{article}
\usepackage{xcolor}
\definecolor{darkred}{rgb}{0.5,0,0}
\usepackage[colorlinks, linkcolor=darkred]{hyperref}
\usepackage{refcount}
\newcommand*{\doubleref}[1]{%
\autoref{#1}%
\if\vcenter\getrefbykeydefault{#1}{name}{}\vcenter
\else
~(\nameref{#1})%
\fi
}
\begin{document}
\section{This and That about Everything}\label{sec:thisthat}
Some text.
\section{}\label{sec:two}
Like meantioned in \doubleref{sec:thisthat} and \doubleref{sec:two}.
\end{document}
一种变体,将整个表达式变成一个链接:
\newcommand*{\doubleref}[1]{%
\hyperref[{#1}]{%
\autoref*{#1}%
\if\vcenter\getrefbykeydefault{#1}{name}{}\vcenter
\else
~(\nameref*{#1})%
\fi
}%
}