用于重述类似定理的环境的易于使用的可参考环境?

用于重述类似定理的环境的易于使用的可参考环境?

这个问题是这个;根据我自己的回答和后来的评论,我决定它值得衍生出来。

我想定义一个重述定理(/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}

要求:

  1. 环境只需要您所引用的定理的标签,不需要其他任何东西。
  2. 您应该能够引用重述而不是原始声明。
  3. 您不能假设环境的计数器具有与环境相同的名称(例如,用户可能有\newtheorem{proposition}[theorem]{Proposition},因此命题使用定理计数器)。

可选的、不错的功能:

  1. 不依赖hyperrefcleverefthmtools。(这是赏金中提到的“要求 5”)
  2. 适用的代码amsthm
  3. \autoref当使用或时,重述或\namecref工作。hyperrefcleveref
  4. 编写从右到左的文档时代码不会中断(希伯来语、阿拉伯语)
  5. 重新陈述未编号定理的可能性。

初步解决方案

我最初的工作已经发展成为一个基本令人满意的解决方案,见下文,在提出引导性问题的帮助下,我找到了解决方案。但该解决方案存在几个问题:

这样做的问题是:

  • 我不知道 是做什么\cref@constructprefixntheorem,也不知道 的预期用途是什么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}

相关内容