替代实施方案

替代实施方案

我正在尝试创建一个新的命令,其作用类似于,\nameref但输出将操纵我所引用的原始名称。更具体地说,我将举一个例子:

\documentclass{book}

\usepackage{hyperref}
\usepackage{xstring}

\makeatletter
\newcommand{\getnamereftext}[1]{%
  \@ifundefined{r@#1}{}{%
    \unexpanded\expandafter\expandafter\expandafter{%
      \expandafter\expandafter\expandafter\@thirdoffive\csname r@#1\endcsname
    }%
  }%
}

\newcommand{\shortRef}[1]{%
  \StrBefore{\getnamereftext{#1}}{:}[\myref]%
  \IfBeginWith{\myref}{``}{\StrBetween{\myref}{``}{''}}{\myref}%
}

\begin{document}

\tableofcontents

\chapter{``First Part'': Second Part}
\label{ch:1}

\section{This section doesn't have parts}
\label{sc:1}
\section{section parts: it contains them}
\label{sc:2}

I want to be able to reference Section~``\shortRef{sc:2}'' and only show the first part.
But I also want it to be a link so it's clickable and pointing to the actual chapter/section.
I want \nameref{sc:2} to still display the full name.

And I want to remove any quotations from the first part if they are present.
So citing Chapter~``\shortRef{ch:1}'' wouldn't show double quotation marks.

\end{document}

我接到了\getnamereftext来自如何使用 \nameref 和 xstring 包来检查字符串长度

我不想重新定义,\nameref因为我仍然希望能够像示例中所示那样引用该章节的全名。我也不想使用,\chapter[short name]{long name}因为这也会使所有\nameref内容都使用简称,最糟糕的是,我的目录也会使用简称(这非常重要,因此\tableofcontents在示例中添加了命令)。

如果存在引号,代码还会尝试删除它。

代码中缺少的部分是从引用创建链接。我不知道该怎么做。如能提供任何帮助我将不胜感激。

答案1

%可以通过在几行末尾添加字符来修复代码(请参阅行末百分号(%)有什么用?)然后您可以使用\hyperref包中的命令hyperref来创建所需的链接:

\hyperref[LaTeX label]{text}

还:

  • 不要忘记\makeatother

  • 确保hyperref最后加载(除非你还加载了cleveref,必须加载 hyperref)。

得出:

\documentclass{book}
\usepackage{xstring}
\usepackage{hyperref}           % load this last, except cleveref comes after

\makeatletter
\newcommand*{\getnamereftext}[1]{%
  \@ifundefined{r@#1}{}{%
    \unexpanded\expandafter\expandafter\expandafter{%
      \expandafter\expandafter\expandafter\@thirdoffive\csname r@#1\endcsname
    }%
  }%
}

\newcommand*{\shortRef}[1]{%
  \StrBefore{\getnamereftext{#1}}{:}[\myref]%
  \hyperref[{#1}]{\IfBeginWith{\myref}{``}{\StrBetween{\myref}{``}{''}}{\myref}}%
}
\makeatother

\begin{document}

\tableofcontents

\chapter{``First Part'': Second Part}
\label{ch:1}

\section{This section doesn't have parts}
\label{sc:1}
\section{section parts: it contains them}
\label{sc:2}

I want to be able to reference Section~``\shortRef{sc:2}'' and only show the
first part. But I also want it to be a link so it's clickable and pointing to
the actual chapter/section. I want \nameref{sc:2} to still display the full
name.

And I want to remove any quotations from the first part if they are present.
So citing Chapter~``\shortRef{ch:1}'' wouldn't show double quotation marks.

\end{document}

在此处输入图片描述

(...)

在此处输入图片描述

这应该可以按你希望的方式工作。不过,我个人倾向于以不同的方式实现,我们将会看到。

替代实施方案

我建议使用refcount包来实现这一点,以便提取nameref分段命令。这是一个非常方便的包,允许以可扩展的方式从参考文献(\ref文本、页码等)中检索所有内容。此外,它不会让您依赖于命令中使用的宏nameref的特定语法(此语法可能取决于文档加载的特定包,例如、和)。简而言之,为您处理所有无聊的细节。\r@〈ref〉\getnamereftextnamerefhyperrefcleverefrefcount

我还建议使用l3regex而不是xstringl3regex是语言的一部分expl3,并且是“字符串处理”的一个非常强大的工具(在 LaTeX 世界中,这将转化为代币列表处理)。现在开始:

\documentclass{book}
\usepackage{refcount}
\usepackage{xparse}
\usepackage{hyperref}           % load this last, except cleveref comes after

\ExplSyntaxOn
\tl_new:N \l__felipe_name_tl

% Code-level command
\cs_new_protected:Npn \felipe_short_ref:n #1
  {
    \tl_set:Nx \l__felipe_name_tl { \getrefbykeydefault {#1} { name } { ?? } }
    % Print the “Label(s) may have changed. Rerun to get cross-references
    % right.” message if appropriate.
    \refused {#1}
    \regex_replace_once:nnN { \A ( [^\cO\:]* ) ( \cO\: .* )? \Z } { \1 }
      \l__felipe_name_tl
    \regex_replace_once:nnN { \A \`\` (.*) \'\' \Z } { \1 } \l__felipe_name_tl
    \hyperref [{#1}] { \l__felipe_name_tl }
  }

% Document-level command
\NewDocumentCommand \shortRef { m }
  { \felipe_short_ref:n {#1} }
\ExplSyntaxOff

\begin{document}

\tableofcontents

\chapter{``First Part'': Second Part}
\label{ch:1}

\section{This section doesn't have parts}
\label{sc:1}
\section{Section parts: it contains them}
\label{sc:2}

I want to be able to reference Section~``\shortRef{sc:2}'' and only show the
first part. But I also want it to be a link so it's clickable and pointing to
the actual chapter/section. I want \nameref{sc:2} to still display the full
name.

And I want to remove any quotations from the first part if they are present.
So citing Chapter~``\shortRef{ch:1}'' wouldn't show double quotation marks.

\end{document}

输出与上面相同。

答案2

您可以使用\hyperref[<label>]{<modified nameref>}

\documentclass{book}

\usepackage{hyperref}
\usepackage{xstring}

\makeatletter
\newcommand{\getnamereftext}[1]{%
  \@ifundefined{r@#1}{}{%
    \unexpanded\expandafter\expandafter\expandafter{%
      \expandafter\expandafter\expandafter\@thirdoffive\csname r@#1\endcsname
    }%
  }%
}

\newcommand{\shortRef}[1]{%
  % get only what comes earlier than the colon
  \StrBefore{\getnamereftext{#1}}{:}[\myref]%
  % but if it starts with ``, we want only what's up to ''
  \IfBeginWith{\myref}{``}{\StrBetween{\myref}{``}{''}[\myref]}{}%
  \hyperref[#1]{\myref}%
}

\begin{document}

\tableofcontents

\chapter{``First Part'': Second Part}
\label{ch:1}

\section{This section doesn't have parts}
\label{sc:1}
\section{section parts: it contains them}
\label{sc:2}

I want to be able to reference Section~``\shortRef{sc:2}'' and only show the first part.
But I also want it to be a link so it's clickable and pointing to the actual chapter/section.
I want \nameref{sc:2} to still display the full name.

And I want to remove any quotations from the first part if they are present.
So citing Chapter~``\shortRef{ch:1}'' wouldn't show double quotation marks.

\end{document}

在此处输入图片描述

相关内容