仅当有名称时才使用 \nameref

仅当有名称时才使用 \nameref

我正在通过编号、类型和名称引用一些部分(实际上这些部分最终将被自定义)。但碰巧没有名称。所以我想把它省略掉。我该如何测试呢?

一位 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
  }%
}

相关内容