thmtools 和 cleveref 的问题

thmtools 和 cleveref 的问题

我正在尝试使用thmtoolscleveref但出现了一个相当奇怪的错误。这是一个简单的例子。

\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@envnameprop我的 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。一种方法是使用两个\expandafters:

\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。哦亲爱的,回到更传统的工具。)

修复 cleveref 和 thmtools

答案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}

在此处输入图片描述

相关内容