我正在尝试创建一个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
,以便它首先在必要时结束数学环境,然后开始一个新的数学环境,可选择排版描述。(properties
与properties*
往常一样,控制参考编号。)
不幸的是,我在跟踪模式时出了点问题。我收到以下错误:
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。