这个问题是这个;根据我自己的回答和后来的评论,我决定它值得衍生出来。
我想定义一个重述定理(/lemmata/propositions/etc)的环境,这使得以下代码可以工作:
\documentclass{article}
\usepackage{ntheorem}
% Magic goes here
\newtheorem{theorem}{Theorem}[section]
\newtheorem{prop}[theorem]{Proposition}
\begin{document}
\begin{theorem}\label{myfirst}
This is the first environment.
\end{theorem}
\begin{prop}\label{mysecond}
This is the second environment.
\end{prop}
\begin{theorem}\label{mythird}
This is the third environment.
\end{theorem}
\clearpage
\begin{restatement}[restated]{mysecond}
\label{mysecond-restated}
This is a restatement of the second environment.
\end{restatement}
\begin{theorem}\label{myfourth}
This is the fourth environment.
\end{theorem}
a \verb|ref| to the second environment: \ref{mysecond} \
a \verb|ref| to its restatement: \ref{mysecond-restated} \
a \verb|pageref| to the second environment: \pageref{mysecond} \
a \verb|pageref| to its restatement: \pageref{mysecond-restated}
\end{document}
要求:
- 环境只需要您所引用的定理的标签,不需要其他任何东西。
- 您应该能够引用重述而不是原始声明。
- 您不能假设环境的计数器具有与环境相同的名称(例如,用户可能有
\newtheorem{proposition}[theorem]{Proposition}
,因此命题使用定理计数器)。
可选的、不错的功能:
- 不依赖
hyperref
、cleveref
或thmtools
。(这是赏金中提到的“要求 5”) - 适用的代码
amsthm
。 \autoref
当使用或时,重述或\namecref
工作。hyperref
cleveref
- 编写从右到左的文档时代码不会中断(希伯来语、阿拉伯语)
- 重新陈述未编号定理的可能性。
初步解决方案
我最初的工作已经发展成为一个基本令人满意的解决方案,见下文,在提出引导性问题的帮助下,我找到了解决方案。但该解决方案存在几个问题:
这样做的问题是:
- 我不知道 是做什么
\cref@constructprefix
的ntheorem
,也不知道 的预期用途是什么p@somecounter
,所以我基本上是盲目地复制粘贴了那部分,也许我做错了什么。 - 代码已经不那么短了。
cleveref
如果稍有改变,代码可能会中断ntheorem
。
而且它没有满足上述大多数有用的要求。因此,非常欢迎您提供改进意见!
答案1
好吧,在其他问题中得到了朋友的帮助(这个和这个,看起来我有一个满足基本要求的解决方案:
编辑:现在支持 hyperref,但为此我们需要计数器别名,请参阅这个问题因为我们需要它。
\documentclass{article}
\usepackage{etoolbox}
\usepackage{ntheorem}
\usepackage{hyperref}
% cleveref after hyperref!
\usepackage{cleveref}
\usepackage{aliascnt}
\makeatletter
% usage:
% same as you would use \newtheorem using an existing counter
\def\newaliasedtheorem#1[#2]#3{%
\newaliascnt{#1@alt}{#2}
\newtheorem{#1}[#1@alt]{#3}
\expandafter\newcommand\csname #1@altname\endcsname{#3}
}
% usage:
% \begin{restatement}[comment]{label-of-original-statement}
%
\newenvironment{restatement}[2][]{%
\begingroup%
\@ifundefined{r@cref@#2}{%
\GenericWarning{}{Reference `#2' undefined, using %
environment `\restatement@defaultenv' for restatement.}
\def\restatement@envname{\restatement@defaultenv}
}{%
\cref@gettype{#2}{\restatement@envname}%
\typeout{restatement: env name is \restatement@envname}%
\cref@getlabel{#2}{\restatement@label}%
\typeout{restatement: label is \restatement@label}%
\edef\restatement@countername{\getenvcountername{\restatement@envname}}
\typeout{restatement: counter name is \restatement@countername}%
\patchcmd{\@thm}%
{\@ifnextchar}%
{%
\@namedef{the\restatement@countername}{\restatement@label}%
% This next macro invocation is lifted from latex.ltx; it
% controls the contents of the line which will be written to the aux
% file for a possible \label{..} command within the environment;
% Note that \csname p@\restatement@countername\endcsname seems to
% expand to nothing eventually, for just about any environment you're
% restating
\protected@edef\@currentlabel%
{\csname p@\restatement@countername\endcsname \restatement@label}%
%
\cref@getcounter{#2}{\restatement@counterval}%
\typeout{restatement: counter value is \restatement@counterval}%
% These next two macro invocations are lifted from cleveref.sty,
% which adds its own .aux line for each \label.
% Note the environment-vs-counter-name trickery, and that
% \csname p@#2\endcsname seems to expand to nothing;
% also, I'm not sure what this next line does, if anything
\cref@constructprefix{\restatement@envname}{\cref@result}%
\typeout{restatement: cref@result is \cref@result}%
\typeout{restatement: p@... is \csname p@\restatement@countername\endcsname}%
\protected@xdef\cref@currentlabel{%
[\restatement@envname][\restatement@counterval][\cref@result]%
\csname p@\restatement@countername\endcsname \restatement@label}%
\@ifnextchar}%
{}{}%
}%
\def\restatement@comment{#1}%
\ifx\restatement@comment\@empty%
\begin{\restatement@envname}%
\else%
\begin{\restatement@envname}[#1]%
\fi%
\@ifundefined{r@cref@#2}{%
}{%
\addtocounter{\restatement@countername}{-1}
}%
}%
{%
\end{\restatement@envname}%
\endgroup%
}
% Suggestion at:
% http://tex.stackexchange.com/a/39328/5640
% this works with all of amsthm, ntheorem and thmtools (!)
\def\getenvcountername#1{%
\@ifundefined{mkheader@#1}
{\expandafter\expandafter\expandafter\@getenvcountername@kernel
\csname\ifcsname thmt@original@#1\endcsname thmt@original@\fi#1\endcsname}
{\expandafter\expandafter\expandafter\@getenvcountername@ntheorem\csname mkheader@#1\endcsname}}
\def\@getenvcountername@kernel#1#2#3{#2}
\def\@getenvcountername@ntheorem\csname#1\endcsname#2#3#4#5{#4}
\newcommand{\restatement@defaultenv}{quote}
\makeatother
\newtheorem{theorem}{Theorem}[section]
\newaliasedtheorem{prop}[theorem]{Proposition}
\begin{document}
\begin{theorem}\label{myfirst}
This is the first environment.
\end{theorem}
\begin{prop}\label{mysecond}
This is the second environment.
\end{prop}
\begin{theorem}\label{mythird}
This is the third environment.
\end{theorem}
\clearpage
\begin{restatement}[restated]{mysecond}
\label{mysecond-restated}
This is a restatement of the second environment.
\end{restatement}
\begin{theorem}\label{myfourth}
This is the fourth environment.
\end{theorem}
a \verb|ref| to the second environment: \ref{mysecond} \\
a \verb|ref| to its restatement: \ref{mysecond-restated} \\
a \verb|pageref| to the second environment: \pageref{mysecond} \\
a \verb|pageref| to its restatement: \pageref{mysecond-restated} \\
a \verb|autoref| to the second environment: \autoref{mysecond} \\
a \verb|autoref| to its restatement: \autoref{mysecond-restated}
\end{document}