如何在不修改日志文档类的情况下使用 cleveref?

如何在不修改日志文档类的情况下使用 cleveref?

我正在向一家期刊 (EJP) 投稿,该期刊要求使用其文档类进行投稿。我已经使用 cleveref 包制作了整个文档,并且不想手动删除它,但期刊的文档类破坏了它。这是一个最小的工作示例

\documentclass[EJP]{ejpecp}
% or
%\documentclass{article}
%\newtheorem{proposition}{proposition}

\usepackage{nameref,hyperref,cleveref}
\Crefname{proposition}{Proposition}{Propositions}

\begin{document}
\begin{proposition}\label{prop:zeronotone}
    One has $0 \neq 1$.
\end{proposition}

\Cref{prop:zeronotone} is very useful.

\end{document}

documentclass ejpecp 是 Linux 上的 texlive 的自带程序,如果你没有,可以从以下位置获取:https://ctan.org/pkg/ejpecp

由于某种原因,引用显示为“定理 1”而不是“命题 1”。将 documentclass 更改为 article 并取消注释 newtheorem 行可更正引用。

问题肯定在于所有包需要按微妙的顺序加载。ejpecp 类会自动加载 hyperref,但不会加载 nameref 或 cleveref。我可以通过修改我机器上的 ejpecp.sty 文件并在\RequirePackage{nameref}其前面RequirePackage{hyperref}\RequirePackage{cleveref}后面添加来解决这个问题。但是,为了简化提交过程,如果可能的话,我希望避免告诉他们文档要求他们使用修改后的 documentclass 版本。当然,我也不想手动更改文档中的数百个引用以手动指定定理、命题等。有什么简单的解决方法吗?

答案1

加载hyperref文档类总是有问题的,因为它通常必须放在最后(除了cleveref和其他一些包)。

无论如何,这不是主要问题:最大的问题是在加载之前声明了类似定理的环境cleveref

在我看来,该类应该提供一个cleveref选项,以便在正确的位置加载包,即在加载之后hyperref和声明类似定理的环境和其他计数器之前。

加载类hyperref之前cleveref先加载是我能想到的最糟糕的建议。修改类是不可能的。

您可以通过重新声明环境和标记输入来解决问题,以便文字编辑知道发生了什么。

\documentclass[EJP]{ejpecp}

\usepackage{cleveref}

%%% I have to redefine the theorem-like environments
%%% in order to use cleveref; output will be exactly the
%%% same, because the environments are declared in the
%%% same styles as in the class.
\makeatletter
\def\redeclare@theorems#1{%
  \@for\next:=#1\do{\expandafter\redeclare@theorem\next}%
}
\def\redeclare@theorem#1#2{%
  \expandafter\let\csname #1\endcsname\relax
  \expandafter\let\csname end#1\endcsname\relax
  \newtheorem{#1}[theorem]{#2}%
}
\theoremstyle{ejpecpbodyit}
\redeclare@theorems{%
  {assumptions}{Assumptions},%
  {assumption}{Assumption},%
  {claim}{Claim},%
  {condition}{Condition},%
  {conjecture}{Conjecture},%
  {corollary}{Corollary},%
  {definitions}{Definitions},%
  {definition}{Definition},%
  {facts}{Facts},%
  {fact}{Fact},%
  {heuristics}{Heuristics},%
  {hypothesis}{Hypothesis},%
  {hypotheses}{Hypotheses},%
  {lemma}{Lemma},%
  {notations}{Notations},%
  {notation}{Notation},%
  {proposition}{Proposition}%
}
\theoremstyle{ejpecpbodyrm}
\redeclare@theorems{%
  {example}{Example},%
  {exercise}{Exercise},%
  {problem}{Problem},%
  {question}{Question},%
  {remark}{Remark}%
}
\makeatother
%%% end of modifications

\SHORTTITLE{Title}
\TITLE{Title}
\AUTHORS{Me}

\KEYWORDS{EJP; ECP; typesetting; \LaTeX} % Separate items with ;
\AMSSUBJ{NA} % Edit. Separate items with ;
\SUBMITTED{January 2, 2013} % Edit.
\ACCEPTED{December 13, 2014} % Edit.
\VOLUME{0}
\YEAR{2016}
\PAPERNUM{0}
\DOI{10.1214/YY-TN}

\begin{document}

\section{Introduction}

\begin{proposition}\label{prop:zeronotone}
    One has $0 \neq 1$.
\end{proposition}

\Cref{prop:zeronotone} is very useful.

\begin{theorem}\label{thm:zeronotone}
    One has $0 \neq 1$.
\end{theorem}

\Cref{thm:zeronotone} is very useful.

\end{document}

在大型列表中,您当然可以省略不使用的环境。

在此处输入图片描述

添加的代码也可以缩写,考虑到所有声明都是以下形式\newtheorem{foo}[theorem]{Foo}

%%% I have to redefine the theorem-like environments
%%% in order to use cleveref; output will be exactly the
%%% same, because the environments are declared in the
%%% same styles as in the class.
\makeatletter
\def\redeclare@theorems#1{%
  \@for\next:=#1\do{\expandafter\redeclare@theorem\expandafter{\next}}%
}
\def\redeclare@theorem#1{\lowercase{%
    \expandafter\let\csname #1\endcsname\relax
    \expandafter\let\csname end#1\endcsname\relax
    \newtheorem{#1}}[theorem]{#1}%
}
\theoremstyle{ejpecpbodyit}
\redeclare@theorems
 {Assumptions,Assumption,Claim,Condition,Conjecture,Corollary,%
  Definitions,Definition,Facts,Fact,Heuristics,Hypothesis,%
  Hypotheses,Lemma,Notations,Notation,Proposition}
\theoremstyle{ejpecpbodyrm}
\redeclare@theorems{Example,Exercise,Problem,Question,Remark}
\makeatother
%%% end of modifications

答案2

ejpecp您可以通过插入指令来解决该类引起的包加载问题

\RequirePackage{amsthm,nameref,hyperref,cleveref}

就在之前

\documentclass[EJP]{ejpecp}

使用此设置,你甚至不需要指令\Crefname{proposition}{Proposition}{Propositions}(因为它默认由cleveref)。

通常不会放置包裹装载说明指令\documentclass。但是,实际上完全可以使用\RequirePackage指令来实现这一点。


附录:这是修改后的 MWE(最小工作示例)和相关的屏幕截图。

\RequirePackage{amsthm,nameref,hyperref,cleveref}
\documentclass[EJP]{ejpecp}
\begin{document}

\setcounter{section}{2} % just for this example
\begin{proposition}\label{prop:zeronotone}
One has $0 \neq 1$.
\end{proposition}
\Cref{prop:zeronotone} is very useful.
\end{document}

在此处输入图片描述

答案3

问题如下:ejpecp.cls 将“命题”环境定义为

\newtheorem{proposition}[theorem]{Proposition},

这意味着环境使用与“定理”相同的计数器。根据“cleveref”文档,当你说

\Crefname{<type>}{<singular>}{<plural>},

通常应该<type>是环境计数器的名称(请参阅文档的第 8.1.2 节)。由于“命题”和“定理”共享计数器,因此这似乎是导致问题的原因。

获得所需行为的一种方法是创建指示参数的标签。例如,

\label[<type>]{<label>}

或者,针对你的具体情况,

\label[proposition]{prop:zeronotone}

根据 cleveref 的文档,amsthm 应该提供足够的信息,以便正确引用共享相同计数器的环境。因此问题似乎出在 ejpecp.cls 中。事实上,如果你转到以下行

\newtheorem{proposition}[theorem]{Proposition}

并将其更改为

    \newtheorem{proposition}{Proposition}

(删除“[定理]”),问题就消失了。也许你应该把这个问题报告给 ejpecp.cls 的作者,这样他们就可以检查代码了。

最后一件事:如果您将定理、命题等的定义从 ejpecp.cls 复制到 LaTeX 文档中,问题就会消失。要查看此问题,您可以将以下代码添加到文档中:

\theoremstyle{ejpecpbodyit}
\newtheorem{theorem}{Theorem}[section]
\newtheorem{assumptions}[theorem]{Assumptions}
\newtheorem{assumption}[theorem]{Assumption}
\newtheorem{claim}[theorem]{Claim}
\newtheorem{condition}[theorem]{Condition}
\newtheorem{conjecture}[theorem]{Conjecture}
\newtheorem{corollary}[theorem]{Corollary}
\newtheorem{definitions}[theorem]{Definitions}
\newtheorem{definition}[theorem]{Definition}
\newtheorem{facts}[theorem]{Facts}
\newtheorem{fact}[theorem]{Fact}
\newtheorem{heuristics}[theorem]{Heuristics}
\newtheorem{hypothesis}[theorem]{Hypothesis}
\newtheorem{hypotheses}[theorem]{Hypotheses}
\newtheorem{lemma}[theorem]{Lemma}
\newtheorem{notations}[theorem]{Notations}
\newtheorem{notation}[theorem]{Notation}
\newtheorem{proposition}[theorem]{Proposition}
\theoremstyle{ejpecpbodyrm}
\newtheorem{example}[theorem]{Example}
\newtheorem{exercise}[theorem]{Exercise}
\newtheorem{problem}[theorem]{Problem}
\newtheorem{question}[theorem]{Question}
\newtheorem{remark}[theorem]{Remark}

当然,您应该删除/注释 .cls 文件中的相同行,以免发生冲突。这将保持与您的示例文档相同的样式,但不会导致您报告的问题。这让我认为 .cls 中存在导致奇怪行为的某些内容(也值得报告)。

我希望这有帮助!

相关内容