我正在尝试创建一个新的命令,其作用类似于,\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〉
\getnamereftext
nameref
hyperref
cleveref
refcount
我还建议使用l3regex
而不是xstring
。l3regex
是语言的一部分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}