问题
本质上我遇到了同样的问题Cleveref 与同名计数器:我有定理、引理和推论,它们都共享同一个计数器,当使用\cref
文本引用它们时总是读作“定理”。
主要区别在于我使用包\mdtheorem
中的mdframed
设置定理环境。我喜欢这些框的外观,因此切换到amsthm
或ntheorem
按照建议那个答案对我来说不是一个选择。我甚至已经amsthm
包括了,但仅凭这一点还不够。
我查看了一下源代码。它似乎cleveref
提供了一个版本\refstepcounter
,可以将环境名称作为可选参数。所以应该使用它。
解决方法
因此,对我而言有用的一个解决方案如下:复制mdframed.sty
并将可选参数添加到正确的位置,大致如下所示。
{%#3 given -- number relationship
\global\@namedef{the#2}{\@nameuse{the#3}}%
\newenvironment{#2}[1][]{%
\refstepcounter[#2]{#3}
\ifstrempty{##1}%
但这是一个丑陋的黑客行为。特别是,这意味着我必须更新mdframed
自己才能将其保留在代码中。
问题
我也没有看到在amsthm
或中使用任何可选参数ntheorem
。所以我的问题是:您知道有什么更优雅的方法来实现我想要做的事情吗?您能告诉我这两个包是如何解决这个问题的吗?我能以某种方式将其移植到 吗mdframed
?
修补
或者我可以使用etoolbox
和\patchcmd
来让它工作吗?我尝试了以下方法,但没有效果:
\expandafter\patchcmd\csname mdtheorem\space code\endcsname
{\refstepcounter{#3}}{\refstepcounter[#2]{#3}}{}{}
日志显示\tracingpatches
修补有效,但实际上没有任何改变。
例子
小重现示例:
\documentclass{article}
\usepackage[framemethod=TikZ]{mdframed}
\usepackage{hyperref}
\usepackage[textwidth=5cm]{geometry}
\usepackage[nameinlink,noabbrev]{cleveref}
\mdtheorem{Theorem}{Theorem}
\mdtheorem{Lemma}[Theorem]{Lemma}
\crefname{Theorem}{theorem}{theorems}
\crefname{Lemma}{lemma}{lemmas}
\begin{document}
\begin{Lemma}\label{x}
Mary had a little lamb.
\end{Lemma}
Now look at \cref{x}.
\end{document}
答案1
以下似乎有效:
\documentclass{article}
\usepackage[framemethod=TikZ]{mdframed}
\usepackage{hyperref}
\usepackage[textwidth=5cm]{geometry}
\usepackage[nameinlink,noabbrev]{cleveref}
\mdtheorem{Theorem}{Theorem}
\mdtheorem{Lemma}[Theorem]{Lemma}
\crefname{Theorem}{theorem}{theorems}
\crefname{Lemma}{lemma}{lemmas}
\let\oldLemma\Lemma
\renewcommand{\Lemma}{%
\crefalias{Theorem}{Lemma}% Theorem counter now looks like Lemma
\oldLemma}
\begin{document}
\begin{Lemma}\label{x}
Mary had a little lamb.
\end{Lemma}
Now look at \cref{x}.
\begin{Theorem}\label{y}
Mary had a little lamb.
\end{Theorem}
Now look at \cref{y}.
\end{document}
Theorem
我们使用别名来改变通用计数器的表示方式。我们必须将其偷偷地放入Lemma
前计数器已步进(暗示settings
密钥已来不及输入),因此我们更新环境打开命令\Lemma
。由于别名是在组内设置的,因此在环境外时会撤销本地更改。