crossreftools
与hyperref
和一起使用cleveref
,我可以获得交叉引用,如下面的输出所示,其中包括“命名定理”的名称或普通定理的注释字段:
\documentclass{memoir}
\usepackage{xstring}
\usepackage{suffix}
\usepackage{amsthm,thmtools}
\swapnumbers
\usepackage{hyperref}
\hypersetup{colorlinks,linkcolor=red}
\usepackage[nameinlink,noabbrev,capitalize]{cleveref}
\usepackage{crossreftools} % <--- how eliminate?
\makeatletter
\declaretheoremstyle[
headfont=\bfseries\sffamily,
headpunct={\bfseries\sffamily.},
postheadspace=0.5em,
notefont=\sffamily\mdseries,
headformat=\NAME\NUMBER\let\thmt@space\@empty\NOTE,
bodyfont=\mdseries\slshape,
]{thmstyle}
\declaretheoremstyle[
headfont=\bfseries\sffamily,
postheadspace=0.5em,
notefont=\bfseries\sffamily,
notebraces={}{},
headformat=\NUMBER\let\thmt@space\@empty\NOTE,
bodyfont=\mdseries\slshape,
]{namedthmstyle}
\makeatother
\declaretheorem[name=Theorem, style=thmstyle, numberwithin=chapter]{theorem}
\declaretheorem[name=Theorem, style=namedthmstyle, title={}, numberlike=theorem]{namedtheorem}
\crefname{theorem}{Theorem}{Theorems}
\Crefname{theorem}{Theorem}{Theorems}
\crefname{namedtheorem}{Theorem}{Theorems}
\Crefname{namedtheorem}{Theorem}{Theorems}
% --> HERE is where crossreftools is exploited <--
% Allow names in cross-reference to named theorems, etc.,...
% and optional argument names of theorems, etc:
\newcommand{\crefthm}[1]{%
\IfStrEqCase*{\crtcrefcounter{#1}}{%
{namedtheorem}{\crefthmname{#1}~(\ref{#1})}%
}%
[\crefthmname{#1}~(\cref{#1})]%
}
\WithSuffix\newcommand\crefthm*[1]{%
\IfStrEqCase*{\crtcrefcounter{#1}}{%
{namedtheorem}{\crefthmname*{#1}~(\ref{#1})}%
}%
[\crefthmname*{#1}~(\cref{#1})]%
}
% For upper-casing, i.e., leave names as is:
\newcommand{\crefthmname}[1]{\hyperlink{\crtrefanchor{#1}}{\crtrefname{#1}}}
\WithSuffix\newcommand\crefthmname*[1]{\crtrefname{#1}}
\newcommand{\Crefthmname}[1]{\hyperlink{\crtrefanchor{#1}}{\crtrefname{#1}}}
\WithSuffix\newcommand\Crefthmname*[1]{\crtrefname{#1}}
\begin{document}
\mainmatter
\chapter{Math}
\begin{theorem}\label{thm:plain}
$a + b = b + a$.
\end{theorem}
\begin{theorem}[basic arithmetic]\label{thm:simple}
$1+1=2$.
\end{theorem}
\begin{namedtheorem}[Pythagorean theorem]\label{thm:pythag}
The square upon the hypotenuse of a right triangle equals
the sum of the squares upon the other two sises.
\end{namedtheorem}
While \crefthm*{thm:simple} may seem simple,
the \crefthm{thm:pythag} is not.
Straightforward \verb!\cref! reference \cref{thm:plain} is OK, whereas \verb!\crefthm! gives: \crefthm{thm:plain}.
\end{document}
问题:如何才能完成同样的事情没有使用crossreftools
(或从中重新创建相关代码)?
新的 LaTeX 发布 2023-11-01 \NewProperty
/ RecordProperties
/RefProperty
机制会对此有所帮助吗?(请参阅 LaTeX 新闻,第 38 期,2023 年 11 月)
笔记:
- 与该 MWE 相反,在我的实际文档中还有“命名命题”、“命名引理”等,因此和的定义
\crefthm
在正文\crefthm*
中包含了额外的替代方案\IfStrEqCase*
。 - 提出这个问题的原因是担心它
crossreftools
似乎没有得到积极维护,其当前版本可以追溯到 2020 年。
答案1
好的,那我会添加完整的答案。
方法 1cleveref
:使用's获取类型/计数器\cref@gettype
(参见https://tex.stackexchange.com/a/692754/105447) 以及其余refcount
的\getrefbykeydefault
:
\documentclass{memoir}
\usepackage{xstring}
\usepackage{suffix}
\usepackage{amsthm,thmtools}
\swapnumbers
\usepackage{hyperref}
\hypersetup{colorlinks,linkcolor=red}
\usepackage[nameinlink,noabbrev,capitalize]{cleveref}
% \usepackage{crossreftools} % <--- how eliminate?
\makeatletter
\declaretheoremstyle[
headfont=\bfseries\sffamily,
headpunct={\bfseries\sffamily.},
postheadspace=0.5em,
notefont=\sffamily\mdseries,
headformat=\NAME\NUMBER\let\thmt@space\@empty\NOTE,
bodyfont=\mdseries\slshape,
]{thmstyle}
\declaretheoremstyle[
headfont=\bfseries\sffamily,
postheadspace=0.5em,
notefont=\bfseries\sffamily,
notebraces={}{},
headformat=\NUMBER\let\thmt@space\@empty\NOTE,
bodyfont=\mdseries\slshape,
]{namedthmstyle}
\makeatother
\declaretheorem[name=Theorem, style=thmstyle, numberwithin=chapter]{theorem}
\declaretheorem[name=Theorem, style=namedthmstyle, title={}, numberlike=theorem]{namedtheorem}
\crefname{theorem}{Theorem}{Theorems}
\Crefname{theorem}{Theorem}{Theorems}
\crefname{namedtheorem}{Theorem}{Theorems}
\Crefname{namedtheorem}{Theorem}{Theorems}
% --> HERE is where crossreftools is exploited <--
% Allow names in cross-reference to named theorems, etc.,...
% and optional argument names of theorems, etc:
\newcommand{\mytemptype}{}
\makeatletter
\newcommand{\crefthm}[1]{%
\cref@gettype{#1}{\mytemptype}%
\IfStrEqCase*{\mytemptype}{%
{namedtheorem}{\crefthmname{#1}~(\ref{#1})}%
}%
[\crefthmname{#1}~(\cref{#1})]%
}
\WithSuffix\newcommand\crefthm*[1]{%
\cref@gettype{#1}{\mytemptype}%
\IfStrEqCase*{\mytemptype}{%
{namedtheorem}{\crefthmname*{#1}~(\ref{#1})}%
}%
[\crefthmname*{#1}~(\cref{#1})]%
}
\makeatother
% For upper-casing, i.e., leave names as is:
\newcommand{\crefthmname}[1]{%
\hyperlink{\getrefbykeydefault{#1}{anchor}{}}{\getrefbykeydefault{#1}{name}{}}}
\WithSuffix\newcommand\crefthmname*[1]{\getrefbykeydefault{#1}{name}{}}
\newcommand{\Crefthmname}[1]{%
\hyperlink{\getrefbykeydefault{#1}{anchor}{}}{\getrefbykeydefault{#1}{name}{}}}
\WithSuffix\newcommand\Crefthmname*[1]{\getrefbykeydefault{#1}{name}{}}
\begin{document}
\mainmatter
\chapter{Math}
\begin{theorem}\label{thm:plain}
$a + b = b + a$.
\end{theorem}
\begin{theorem}[basic arithmetic]\label{thm:simple}
$1+1=2$.
\end{theorem}
\begin{namedtheorem}[Pythagorean theorem]\label{thm:pythag}
The square upon the hypotenuse of a right triangle equals
the sum of the squares upon the other two sises.
\end{namedtheorem}
While \crefthm*{thm:simple} may seem simple,
the \crefthm{thm:pythag} is not.
Straightforward \verb!\cref! reference \cref{thm:plain} is OK, whereas \verb!\crefthm! gives: \crefthm{thm:plain}.
\end{document}
方法 2:使用新ltproperties
模块:
(概念证明。我自己会使用方法 1,因为不需要设置任何其他标签。数据已经存在了。)
\documentclass{memoir}
\usepackage{xstring}
\usepackage{suffix}
\usepackage{amsthm,thmtools}
\swapnumbers
\usepackage{hyperref}
\hypersetup{colorlinks,linkcolor=red}
\usepackage[nameinlink,noabbrev,capitalize]{cleveref}
% \usepackage{crossreftools} % <--- how eliminate?
\makeatletter
\declaretheoremstyle[
headfont=\bfseries\sffamily,
headpunct={\bfseries\sffamily.},
postheadspace=0.5em,
notefont=\sffamily\mdseries,
headformat=\NAME\NUMBER\let\thmt@space\@empty\NOTE,
bodyfont=\mdseries\slshape,
]{thmstyle}
\declaretheoremstyle[
headfont=\bfseries\sffamily,
postheadspace=0.5em,
notefont=\bfseries\sffamily,
notebraces={}{},
headformat=\NUMBER\let\thmt@space\@empty\NOTE,
bodyfont=\mdseries\slshape,
]{namedthmstyle}
\makeatother
\declaretheorem[name=Theorem, style=thmstyle, numberwithin=chapter]{theorem}
\declaretheorem[name=Theorem, style=namedthmstyle, title={}, numberlike=theorem]{namedtheorem}
\crefname{theorem}{Theorem}{Theorems}
\Crefname{theorem}{Theorem}{Theorems}
\crefname{namedtheorem}{Theorem}{Theorems}
\Crefname{namedtheorem}{Theorem}{Theorems}
% --> HERE is where crossreftools is exploited <--
% Allow names in cross-reference to named theorems, etc.,...
% and optional argument names of theorems, etc:
\ExplSyntaxOn
\bool_new:N \l__murray_inside_thm_bool % or any kind of boolean you prefer
\AddToHookWithArguments{label}{
\bool_if:NT \l__murray_inside_thm_bool
{ \RecordProperties{#1.thm}{counter,title,target} }
}
\AddToHook{env/theorem/begin}{ \bool_set_true:N \l__murray_inside_thm_bool }
\AddToHook{env/namedtheorem/begin}{ \bool_set_true:N \l__murray_inside_thm_bool }
% Add any other theorem environments you use here...
\ExplSyntaxOff
\newcommand{\crefthm}[1]{%
\IfStrEqCase*{\RefProperty{#1.thm}{counter}}{%
{namedtheorem}{\crefthmname{#1}~(\ref{#1})}%
}%
[\crefthmname{#1}~(\cref{#1})]%
}
\WithSuffix\newcommand\crefthm*[1]{%
\IfStrEqCase*{\RefProperty{#1.thm}{counter}}{%
{namedtheorem}{\crefthmname*{#1}~(\ref{#1})}%
}%
[\crefthmname*{#1}~(\cref{#1})]%
}
% For upper-casing, i.e., leave names as is:
\newcommand{\crefthmname}[1]{%
\hyperlink{\RefProperty{#1.thm}{target}}{\RefProperty{#1.thm}{title}}}
\WithSuffix\newcommand\crefthmname*[1]{\RefProperty{#1.thm}{title}}
\newcommand{\Crefthmname}[1]{%
\hyperlink{\RefProperty{#1.thm}{target}}{\RefProperty{#1.thm}{title}}}
\WithSuffix\newcommand\Crefthmname*[1]{\RefProperty{#1.thm}{title}}
\begin{document}
\mainmatter
\chapter{Math}
\begin{theorem}\label{thm:plain}
$a + b = b + a$.
\end{theorem}
\begin{theorem}[basic arithmetic]\label{thm:simple}
$1+1=2$.
\end{theorem}
\begin{namedtheorem}[Pythagorean theorem]\label{thm:pythag}
The square upon the hypotenuse of a right triangle equals
the sum of the squares upon the other two sises.
\end{namedtheorem}
While \crefthm*{thm:simple} may seem simple,
the \crefthm{thm:pythag} is not.
Straightforward \verb!\cref! reference \cref{thm:plain} is OK, whereas \verb!\crefthm! gives: \crefthm{thm:plain}.
\end{document}
选择: 使用zref-clever
。
因为评论中的讨论表明它可能会引起人们的兴趣。
事实证明,设置起来稍微简单一些,因为zref
可以更直接地提取对不同属性的引用,并zref-clever
允许使用可选参数提供更大的灵活性,因此我们不必手动处理超链接锚点。我还利用了ltcmd
(以前的xparse
)和删除了对和的expl3
依赖。xstring
suffix
\documentclass{memoir}
\usepackage{amsthm,thmtools}
\swapnumbers
\usepackage{hyperref}
\hypersetup{colorlinks,linkcolor=red}
\usepackage{zref-clever}
\zcsetup{
cap,
noabbrev,
countertype={namedtheorem=theorem},
}
\usepackage{zref-titleref,zref-counter}
\makeatletter
\declaretheoremstyle[
headfont=\bfseries\sffamily,
headpunct={\bfseries\sffamily.},
postheadspace=0.5em,
notefont=\sffamily\mdseries,
headformat=\NAME\NUMBER\let\thmt@space\@empty\NOTE,
bodyfont=\mdseries\slshape,
]{thmstyle}
\declaretheoremstyle[
headfont=\bfseries\sffamily,
postheadspace=0.5em,
notefont=\bfseries\sffamily,
notebraces={}{},
headformat=\NUMBER\let\thmt@space\@empty\NOTE,
bodyfont=\mdseries\slshape,
]{namedthmstyle}
\makeatother
\declaretheorem[name=Theorem, style=thmstyle, numberwithin=chapter]{theorem}
\declaretheorem[name=Theorem, style=namedthmstyle, title={}, numberlike=theorem]{namedtheorem}
% Note that this implementation requires that a single label be received as
% the mandatory argument of \zcrefthm. But it is the same as with yours.
\ExplSyntaxOn
\makeatletter
\NewDocumentCommand{\zcrefthm}{sO{}m}{
\tl_if_empty:eF { \zref@extractdefault {#3} { title } { } }
{
\IfBooleanTF{#1}
{ \zcref*[noname,ref=title]{#3} }
{ \zcref[noname,ref=title]{#3} }
\nobreakspace
}
\tl_if_eq:enTF
{ \zref@extractdefault {#3} { counter } { } } { namedtheorem }
{ (\zcref[noname,#2]{#3}) }
{ (\zcref[#2]{#3}) }
}
\makeatother
\ExplSyntaxOff
\begin{document}
\mainmatter
\chapter{Math}
\begin{theorem}\label{thm:plain}
$a + b = b + a$.
\end{theorem}
\begin{theorem}[basic arithmetic]\label{thm:simple}
$1+1=2$.
\end{theorem}
\begin{namedtheorem}[Pythagorean theorem]\label{thm:pythag}
The square upon the hypotenuse of a right triangle equals
the sum of the squares upon the other two sises.
\end{namedtheorem}
While \zcrefthm*{thm:simple} may seem simple, the \zcrefthm{thm:pythag} is
not.
Straightforward \verb!\zcref! reference \zcref{thm:plain} is OK, whereas
\verb!\zcrefthm! gives: \zcrefthm{thm:plain}.
\end{document}