数学模式初始:为单独引用的方程式创建列表环境

数学模式初始:为单独引用的方程式创建列表环境

我正在尝试创建一个properties可以这样使用的类似列表的环境:

\begin{properties}
  \item[Lemonade Rule] \forall \text{lemons} \exists \text{lemonade}
  \item a^2 + b^2 = c^2
  \item[identity] \forall
\end{properties}

这个想法是重新定义\item本地环境properties,以便它首先在必要时结束数学环境,然后开始一个新的数学环境,可选择排版描述。(propertiesproperties*往常一样,控制参考编号。)

不幸的是,我在跟踪模式时出了点问题。我收到以下错误:

ERROR: LaTeX Error: Bad math environment delimiter.

--- TeX said ---

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.90   \item[inverse]
                      \label{def:group:inverse}
--- HELP ---
TeX has found either a math-mode-starting command such as \[ or \(
when it is already in math mode, or else a math-mode-ending command
such as \) or \] while in LR or paragraph mode.  The problem is caused
by either unmatched math mode delimiters or unbalanced braces.

我哪里搞错了?代码如下:(这是基于 egreg 提供的信息的新代码;它的功能比原来的代码少了一些,但错误仍然存​​在。旧代码显然是糟糕风格的典范,永远存在于编辑日志中。)

\documentclass{article}
\usepackage{amsmath,xparse,expl3}
\ExplSyntaxOn

\NewDocumentEnvironment { definition } { m }
 {
  % typeset the title of the definition
  \par\noindent\hangindent\parindent
  \textbf{#1}\quad
 }
 {
   % end environment 'definition'
 }



% makes sure math content is centered
\cs_new:Nn \property_do_fill:
 {
  \hskip \textwidth minus \textwidth
 }

% enters math mode and starts a property
% does not typeset a math comment
\cs_new:Nn \property_do_begin:
 {
  \equation
  \quad\bullet
  \property_do_fill:
 }

% enters math mode and starts a property
% does typeset math comment
\cs_new:Nn \property_do_begin:n
 {
  \equation
  \quad\bullet\enspace\text{\slshape #1}
  \property_do_fill:
 }

% ends this property and exists math mode
\cs_new:Nn \property_do_end:
 {
  \property_do_fill:
  \endequation
 }


% declare a new item-like environment 'properties', where each item
% * [mathcomment]   a^2 + b^2 = c^2   (1.3)
\NewDocumentEnvironment { properties } { }
 {
   % Delimits properties
   % starts off by beginning a property, and then redefines itself
   % to end a previous property before starting a new one.
  \DeclareDocumentCommand \item { o }
   {
    \IfValueTF { ##1 }
    { \property_do_begin:n { ##1 } }
    { \property_do_begin:          }

    % redefine \item now to take care of *ending* the last one
    \DeclareDocumentCommand \item { o }
     {
      % end the last property
      \property_do_end:
      % and start a new one
      \IfValueTF { ####1 }
      { \property_do_begin:n { ####1 } }
      { \property_do_begin:            }
     }
   }
 }
 {
   % end environment properties
   % make sure to end the last property
   \property_do_end:
 }

\ExplSyntaxOff

\begin{document}
\begin{definition}{group}
  A group is a set $G$ together
    with a binary operation $*$ on $G$
    that satisfies the following axioms:

  \begin{properties}
  \item[associativity]
    \label{def:group:assoc}
    \forall{a,b,c \in G}{(a * b) * c = a * (b * c)}
  \item[identity]
    \label{def:group:identity}
    \exists e \in G : \forall{a \in G}{a * e = a = e * a}
  \item[inverse]
    \label{def:group:inverse}
    \forall{x \in G}{\exists b \in G : a * b = b * a = e}
  \end{properties}
\end{definition}
\end{document}

答案1

我担心您的代码在很多方面都有错误,几乎没有什么可以挽救的。

第一个错误

\cs_new:Nn \property_do_begin:n
 {
  \IfBooleanTF { #1 } \equation* \equation
  \quad\bullet
  \property_do_fill:
 }

\IfBooleanTF函数仅在(或类似函数)的主体中才有意义\NewDocumentCommand,因为正是该函数设置了一些东西,以便将*内部布尔值设置为 true 或 false。\cs_new:Nn结果基本上是不可预测的。有关其他问题,请参阅第三个错误;实际上这可能在某些情况下可以工作,因为参数是从“接口”命令传递的;但无论如何,它被认为是“糟糕的风格”。

第二个错误

即使\IfBooleanTF{#1}成功了(也可能不会),当你使用它

\IfBooleanTF { #1 } \endequation* \endequation

\equation如果 a跟在后面,则将得到*a,否则将得到 a *;在这两种情况下,第二个\equation都会被执行。这是\equation*因为标记,您不能\begin{equation*}用缩写。当然, 也\equation*一样。\endequation*

第三个错误

\NewDocumentEnvironment{foo}{<arg specs>}{<start>}{<end>}基本上在做

\NewDocumentCommand{\foo}{<arg specs>}{<start>}{<end>}
\NewDocumentCommand{\endfoo}{<arg specs>}{<start>}{<end>}

\foo并且传递给after 的参数\begin{foo}也将\endfoo在被调用时传递给\end{foo}

因此\NewDocumentEnvironment{foo}{s}只会定义foo环境,而不是foo*环境。当你调用

\begin{foo}

你的\IfBooleanTF{#1}计算结果将为 false。并且\begin{foo*}将引发错误。\begin{foo}*但是,你可以调用,并且\IfBooleanTF{#1}将计算结果为 true。

相关内容