我正在向一家期刊 (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 中存在导致奇怪行为的某些内容(也值得报告)。
我希望这有帮助!