推导/证明环境中的自定义编号

推导/证明环境中的自定义编号

简单介绍一下背景,我正在写一篇论文,其中有定理(证明和推导)以及可能还有一些其他“定理”类型的环境。这个问题中的代码实际上运行良好,它正在做我想要的事情,但我觉得它可以被整理/改进。

对于方程,我选择了一种只针对实际证明或推导的编号格式。因此,这涉及存储现有方程编号、将其重置为零、更改样式(分别针对证明或推导)执行内容,然后恢复为现有值。

此外,一些推导/证明可以通过使用 multicol 来压缩,这是我之前的一篇文章阴影多色用于将证明/推导与周围内容区分开来,但是为了解决这个问题,这些格式样式已被删除。

下面是代码的精简版,它是一个完整的 MWE:

\documentclass{article}

%------------LOAD THE PACKAGES---------------%
%Load Single Packages Together
\usepackage{amsmath,amsfonts,amssymb,amsthm,mathtools,mathpazo,calc,ifthen}
\usepackage{environ,multicol,xcolor}

%DEFINE MY THEOREM STYLE
\let\oldproof\proof\let\proof\relax
\let\oldendproof\endproof\let\endproof\relax
\newcommand{\theoremLetter}{}
\newtheoremstyle{mythm} % name
    {0pt}                        % Space above
    {0pt}                        % Space below
    {\small}% Body font
    {}                           % Indent amount
    {\bf\color{blue!50!black}}% Theorem head font
    {.}% Punctuation after theorem head
    {.5em}                       % Space after theorem head
    {}  % Theorem head spec (can be left empty, meaning ‘normal’)
\theoremstyle{mythm} %SELECT THE THEOREM
\newtheorem{derivation}{Derivation}
\newtheorem{proof}{Proof}

%Renew Formats, Equation, Figure, Table.
\renewcommand{\thederivation}{D\arabic{derivation}}
\renewcommand{\theproof}{P\arabic{proof}}

\newcounter{mytemp}%
\newenvironment{myenv}[3]{%
    \def\envvar{#1}%
    \def\mycols{#2}%

    \par\vspace{0.5em} %add space

    %Set the first letter depending on the type of environment.
    %DERIVATION
    \providecommand{\theoremLetter}{}%RESET
    \ifthenelse{\equal{\envvar}{derivation}}{%
        \renewcommand{\theoremLetter}{D}%
    }{}%
    %PROOF
    \ifthenelse{\equal{\envvar}{proof}}{%
        \renewcommand{\theoremLetter}{P}%
    }{}%

    \begin{\envvar}{\textbf{#3}}%
        \setcounter{mytemp}{\value{equation}}%
        \providecommand{\existingEquationFormat}{\theequation}%
        \setcounter{equation}{0}%
        \renewcommand{\theequation}{%
            \theoremLetter\arabic{\envvar}.\arabic{equation}%
        }%
        \setlength{\abovedisplayskip}{0pt}%Set DisplaySkip Value.
        \ifthenelse{\equal{\mycols}{1}}{}{\begin{multicols}{\mycols}}%
}{%BODY CONTENT OF ENVIRONMENT  
        \ifthenelse{\equal{\mycols}{1}}{}{\end{multicols}}%
        \setcounter{equation}{\value{mytemp}}%
        \renewcommand{\theequation}{\existingEquationFormat}%
        \renewcommand{\existingEquationFormat}{\relax}%
    \end{\envvar}%
}

以下是示例输出:

\begin{document}
    \hrule

    \section{Default Equation Format}
    \begin{align}
            y &= A\\
              &= B
    \end{align}

    \hrule

    \section{Sample Derivation and Proof (Multicolumn)}
    \begin{myenv}{proof}{2}{Sample Proof}
        Column 1
        \begin{align}%
            y &= A\\
              &= B
        \end{align}%
        Column 2
        \begin{align}
            y &= C\\
              &= D
        \end{align}
    \end{myenv}

    \begin{myenv}{derivation}{2}{Sample Derivation}
        Column 1
        \begin{align}%
            y &= A\\
              &= B
        \end{align}%
        Column 2
        \begin{align}
            y &= C\\
              &= D
        \end{align}
    \end{myenv}

    \hrule

    \section{Demonstrate Reset/Continuation of Format}
    \begin{align}
            y &= A\\
              &= B
    \end{align}

    \hrule

    \section{Further Derivation and Proof (Single Column)}
    \begin{myenv}{proof}{1}{Another Proof}
        \begin{align}%
            y &= A\\
              &= B
        \end{align}%
    \end{myenv}

    \begin{myenv}{derivation}{1}{Another Derivation}
        \begin{align}%
            y   &= A\\
                &= B
        \end{align}%
    \end{myenv}

    \hrule

\end{document}

上述代码产生以下结果:

示例输出

在此输出中,可以清楚地看到以下特征:

  1. 推导与证明的编号样式是特定推导与证明的局部样式,该样式已更改为以 P 或 D 开头,以便清楚地将该编号与作为文档其余部分的标准方程编号区分开来。
  2. 标准方程编号被破坏,并在 thm 的两侧恢复
  3. 使用单列和多列模式。

所以我的问题是,如何在代码中替换以下内容:

%Set the first letter depending on the type of environment.
%DERIVATION
\providecommand{\theoremLetter}{}%RESET
\ifthenelse{\equal{\envvar}{derivation}}{%
    \renewcommand{\theoremLetter}{D}%
}{}%
%PROOF
\ifthenelse{\equal{\envvar}{proof}}{%
    \renewcommand{\theoremLetter}{P}%
}{}%

...因此,它采用特定定理样式的首字母(大写),目前,重新格式化实际上是“硬编码的”,我想消除这个限制。

有没有更有效的方法来完成我在这里所做的编码,我相信有,也许\newenvironment{myenv}{...}可以完全删除。

答案1

您可以通过以下定义提取第一个字母,无需额外的包:

\def\tempa##1##2!{##1}%
\uppercase{\def\theoremLetter{\tempa#1!}}%%

该计划xstring提供了类似的方法

\uppercase{\StrLeft{#1}{1}[\theoremLetter]}%

这是你修改后的环境

\newenvironment{myenv}[3]{%
    \def\envvar{#1}%
    \def\mycols{#2}%
    \par\vspace{0.5em} %add space
    %Set the first letter depending on the type of environment.
    %DERIVATION
%Approach 1
    \def\tempa##1##2!{##1}%
    \uppercase{\def\theoremLetter{\tempa#1!}}%%
%Approach 2
 %   \uppercase{\StrLeft{#1}{1}[\theoremLetter]}%%
%
    \begin{\envvar}{\textbf{#3}}%
        \setcounter{mytemp}{\value{equation}}%
        \providecommand{\existingEquationFormat}{\theequation}%
        \setcounter{equation}{0}%
        \renewcommand{\theequation}{%
            \theoremLetter\arabic{\envvar}.\arabic{equation}%
        }%
        \setlength{\abovedisplayskip}{0pt}%Set DisplaySkip Value.
        \ifthenelse{\equal{\mycols}{1}}{}{\begin{multicols}{\mycols}}%
}{%BODY CONTENT OF ENVIRONMENT  
        \ifthenelse{\equal{\mycols}{1}}{}{\end{multicols}}%
        \setcounter{equation}{\value{mytemp}}%
        \renewcommand{\theequation}{\existingEquationFormat}%
        \renewcommand{\existingEquationFormat}{\relax}%
    \end{\envvar}%
}

改进(从我的角度来看):

  • 定义/重新定义在\renewcommand本地起作用。因此每次重置都是不必要的。
  • 通常setcounter也是本地的,但是如果你加载包,calc这些分配将始终是全局的。所以你必须重置计数器。
  • 我更喜欢用这种方式对环境进行较小的定义,以便大多数作业都在额外的宏中完成。

如果您编写了一个包,那么您应该做更多的测试,无论环境是否存在。


\let\innerenv\relax
\let\endinnerenv\relax
\newenvironment{myenv}[3]{%
    \def\envvar{#1}%
    \par\vspace{0.5em} %add space
    \begin{\envvar}{\textbf{#3}}%
    \def\tempa##1##2!{##1}%
    \uppercase{\def\theoremLetter{\tempa#1!}}%%
    \setcounter{mytemp}{\value{equation}}%
    \setlength{\abovedisplayskip}{0pt}%
    \setcounter{equation}{0}%
     \expandafter\let\expandafter\theequaction\csname the#1\endcsname
   \ifnum#2>1
        \def\innerenv{\begin{multicols}{#2}}%
        \def\endinnerenv{\end{multicols}}%
   \fi%
   \innerenv
}{%BODY CONTENT OF ENVIRONMENT  
   \endinnerenv%
   \setcounter{equation}{\value{mytemp}}%
  \end{\envvar}%
}

相关内容