我正在尝试使用thmtools
,cleveref
但出现了一个相当奇怪的错误。这是一个简单的例子。
\documentclass{article}
\usepackage{thmtools}
\usepackage{cleveref}
\declaretheorem[name=Lemma,Refname={Lemma,Lemmas}]{lem}
\declaretheorem[name=Proposition,Refname={Proposition,Proposition}]{prop}
\declaretheorem[name=Theorem,Refname={Theorem,Theorems}]{thr}
\begin{document}
\begin{lem}\label{lem1}
A lemma.
\end{lem}
\begin{prop}\label{prop1}
A proposition.
\end{prop}
\begin{thr}\label{thr1}
A theorem.
\end{thr}
\Cref{lem1}, \Cref{prop1} and \Cref{thr1}.
\end{document}
当我运行pdflatex
(使用全新默认安装的 TeXLive 2011)时,我收到一条消息:
LaTeX Warning: Cref reference format for label type `prop' undefined on input line 24.
最后一句在 pdf 文件中呈现为“引理 1、?? 1 和定理 1”。奇怪的是,如果我只使用两个\declaretheorem
定义,那么一切都很好。如果我更改定义的顺序,那么总是第二个定义会产生警告。
对于这里发生的事情以及如何解决它,您有什么想法吗?
答案1
中有一个错误thm-autoref.sty
。s magic 的部分设置cleveref
留在文档的开头。因此,它cleveref
维护了已告知的所有标签类型的列表,以便在到达钩子时\begin{document}
,它可以遍历它们并完成必要的配置。
检查您的文档中的此列表(好吧,我的稍微扩展的版本)表明它是:
\thmt@envname ,\thmt@envname ,\thmt@envname ,\thmt@envname ,thr,equation,\@nil
看起来不对! \thmt@envname
在这里被处理了四次。在我的代码中,then恰好\thmt@envname
是prop
我的 s 列表中的最后一个\declaretheorem
(对于您的代码,它将是thr
- 我尝试了一些排列)。因此,某些东西在应该扩展时没有被扩展。在玩了一会儿 Ultimate Code Frisbee(从一个地方到另一个地方追逐定义)之后,我将其追踪到 中的定义thm-autoref.sty
,特别是 的定义\thmt@refnamewithcomma
。它读作:
\def\thmt@refnamewithcomma #1#2#3,#4,#5\@nil{%
\@xa\def\csname\thmt@envname #1utorefname\endcsname{#3}%
\ifcsname #2refname\endcsname
\csname #2refname\endcsname{\thmt@envname}{#3}{#4}%
\fi
}
显然,我们需要扩展\thmt@envname
。一种方法是使用两个\expandafter
s:
\def\thmt@refnamewithcomma #1#2#3,#4,#5\@nil{%
\@xa\def\csname\thmt@envname #1utorefname\endcsname{#3}%
\ifcsname #2refname\endcsname
\csname #2refname\expandafter\endcsname\expandafter{\thmt@envname}{#3}{#4}%
\fi
}
因此,如果你将其放在文档顶部(在\makeatletter ... \makeatother
),它将解决这个问题。 警告相同的命令用于autoref
,我不知道这是否会破坏它(尽管它实际上不应该这样做)。
这是一个完整的例子:
\documentclass{article}
\usepackage{cleveref}
\usepackage{thmtools}
\makeatletter
\def\thmt@refnamewithcomma #1#2#3,#4,#5\@nil{%
\@xa\def\csname\thmt@envname #1utorefname\endcsname{#3}%
\ifcsname #2refname\endcsname
\csname #2refname\expandafter\endcsname\expandafter{\thmt@envname}{#3}{#4}%
\fi
}
\makeatother
\declaretheorem[name=Theorem,Refname={Theorem,Theorems}]{thr}
\declaretheorem[name=Lemma,Refname={Lemma,Lemmas}]{lem}
\declaretheorem[name=Corollary,Refname={Corollary,Corollaries}]{cor}
\declaretheorem[name=Proposition,Refname={Proposition,Proposition}]{prop}
\begin{document}
\begin{lem}\label{lem1}
A lemma.
\end{lem}
\begin{prop}\label{prop1}
A proposition.
\end{prop}
\begin{thr}\label{thr1}
A theorem.
\end{thr}
\begin{cor}\label{cor1}
A Corollary.
\end{cor}
\Cref{lem1}, \Cref{prop1}, \Cref{thr1}, and \Cref{cor1}.
\end{document}
结果:
(哦 - 有些东西不喜欢standalone
。哦亲爱的,回到更传统的工具。)
答案2
第一个提出的错误修复对我有用。我已写信给 cleveref 包的维护者 Toby Cubitt。他同意这是一个错误,但声称这是 thmtools 包中的一个错误,这就是我将问题报告给 thmtools 维护者 Ulrich M. Schwarz 的原因,并提供了此线程的链接。我们将很快查看 thmtools 包是否有更新 =)。在他的邮件中,Toby 批评人们经常在论坛(例如这个)上发布错误和问题(这很好),但很少直接向开发人员本人报告错误。所以请大家,如果您认为您发现了一个错误并且您对此非常有信心,请将其报告给开发人员。
向大家欢呼,我会及时向你们通报最新情况。
大家好。Ulrich Schwarz 回答了我的问题。他告诉我将 thm-autoref.sty 中的第 48 行改为
\csname #2refname\@xa\endcsname\@xa{\thmt@envname}{#3}{#4}%
(另加两个\@xa
)
不要忘记在终端中运行texhash
或更新 TeX 数据库,mktexlsr
否则texconfig[-sys] rehash
更改将无效。(如果您不知道在哪里可以找到 thm-autoref.sty,请locate thm-autoref.sty
在终端中运行。如果您使用 Windows,我不知道您如何更新 TeX 数据库,抱歉)。谢谢,希望它有所帮助。大卫
答案3
这不是一个合适的解决方案,而是一个变通方法,主要取自这个谷歌搜索:
添加如下命令
\crefname{thr}{theorem}{theorems}
\Crefname{thr}{Theorem}{Theorems}
对于每个内部定理类型,在所有\declaretheorem
命令之后。与原始问题完全无关,但您可能希望\cref
在句子中间使用小写引用命令。手册cleveref
至少使用了这种符号。
\documentclass{article}
\usepackage{thmtools}
\usepackage{cleveref}
\declaretheorem[name=Lemma,Refname={Lemma,Lemmas}]{lem}
\declaretheorem[name=Theorem,Refname={Theorem,Theorems}]{thr}
\declaretheorem[name=Thing,Refname={Thing,Things}]{thing}
\declaretheorem[name=Proposition,Refname={Proposition,Propositions}]{prop}
\crefname{thr}{theorem}{theorems}
\Crefname{thr}{Theorem}{Theorems}
\crefname{thing}{thing}{things}
\Crefname{thing}{Thing}{Things}
\begin{document}
\begin{lem}\label{lem1}
A lemma.
\end{lem}
\begin{thr}\label{thr1}
A theorem.
\end{thr}
\begin{prop}\label{prop1}
A proposition.
\end{prop}
\begin{thing}\label{thing1}
A thing.
\end{thing}
\Cref{lem1}, \cref{prop1}, \cref{thing1} and \cref{thr1}.
\end{document}
最新版本的 并未修复此问题cleveref
,但我的其他软件包也未完全更新。我会查看今天的软件包是否仍然存在此问题,并等待更好的答案或对 中真实错误的确认cleveref
。
答案4
解决三个交叉引用问题的直接方法是在整个文档{prop}
中用替换{proposition}
。我无法解释为什么这个修复似乎有效。
还请参阅@AndrewStacey 的详细答复,其中他(i)报告他在文件thm-autoref.sty
(捆绑包的一部分thmtools
)中发现了一个错误,并且(ii)为该错误提供了一个补丁。
但是,鉴于您的 MWE 似乎没有使用thmtools
除指定相应环境的单数和复数形式之外的包的功能,您不妨只使用稳定且调试良好的ntheorem
包而不是thmtools
。 如果需要,您可以给出cleveref
处理环境复数形式的说明(正如我在下面的 MWE 中所做的那样)。
\documentclass{article}
%\usepackage{thmtools} -- use ntheorem instead
\usepackage{ntheorem}
\newtheorem{lem}{Lemma}
\newtheorem{prop}{Proposition} % NOTE: no need to write {proposition}
\newtheorem{thr}{Theorem}
\usepackage{cleveref}
\crefname{lem}{Lemmas}{Lemmas}
\crefname{prop}{Proposition}{Propositions}
\crefname{thr}{Theorem}{Theorems}
\begin{document}
\begin{lem}\label{lem1} A lemma. \end{lem}
\begin{prop}\label{prop1} A proposition. \end{prop}
\begin{lem}\label{lem2} Another lemma. \end{lem}
\begin{prop}\label{prop2} Another proposition. \end{prop}
\begin{thr}\label{thr1} A theorem. \end{thr}
As we stated in \cref{lem1,prop1,thr1,prop2,lem2}, \ldots
\end{document}