# Math-mode inception: creating a list environment for individually referenced equations

I'm trying to create a list-like environment properties that could be used as such:

\begin{properties}
\item a^2 + b^2 = c^2
\item[identity] \forall
\end{properties}


The idea is to redefine \item local to the properties environment such that it first ends a math environment if necessary and then starts a new one, optionally typesetting a description. (properties vs. properties* controls reference numbers, as usual.)

Unfortunately, I'm screwing up somewhere in keeping track of my modes. I receive the following error:

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.


Where am I messing things up? Here is the code: (This is new code based on the information egreg provided; it is pared down a bit in functionality from the original, but the error remains. The old code, an apparent model of bad style, is forever available in the edit log.)

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

\NewDocumentEnvironment { definition } { m }
{
% typeset the title of the definition
\par\noindent\hangindent\parindent
}
{
% 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
\property_do_fill:
}

% enters math mode and starts a property
% does typeset math comment
\cs_new:Nn \property_do_begin:n
{
\equation
\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}

-
\equation* is two tokens, not one; and you can't abbreviate \begin{equation*} into \equation*. You can't test \IfBooleanTF{#1} in a \cs_new:Nn instruction; that's reserved to \NewDocumentCommand (and the alike commands). While you can do \NewDocumentEnvironment{foo}{s}, the relative \IfBooleanTF will be true when you call \begin{foo}*, not \begin{foo*} (which is undefined). –  egreg Sep 6 '13 at 21:09
@egreg — so general misunderstandings all around? I'll see if I can fix it up myself given this information –  Sean Allred Sep 6 '13 at 21:23

I'm afraid your code is wrong in so many respects that almost nothing can be salvaged.

## First error

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


The \IfBooleanTF function makes sense only in the body of \NewDocumentCommand (or alike functions), because it's this function that sets up things so that a * will set the internal boolean to true or false. In \cs_new:Nn the result is basically unpredictable. See the third error for other problems; actually this might work in some cases, because the argument is passed from an "interface" command; but it's considered "bad style" anyway.

## Second error

Even if \IfBooleanTF{#1} were successful (which may not), when you use it in

\IfBooleanTF { #1 } \endequation* \endequation


you'd get \equation if a * follows and a * otherwise; in both cases the second \equation would be executed. This is because \equation* is two tokens and you can't abbreviate \begin{equation*} with \equation*. The same for \endequation*, of course.

## Third error

With \NewDocumentEnvironment{foo}{<arg specs>}{<start>}{<end>} you're basically doing

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


and the arguments passed to \foo after \begin{foo} will be passed also to \endfoo when called by \end{foo}.

Thus \NewDocumentEnvironment{foo}{s} would define only the foo environment, not the foo* environment. When you call

\begin{foo}


your \IfBooleanTF{#1} will evaluate to false. And \begin{foo*} will raise an error. You could call \begin{foo}*, however, and \IfBooleanTF{#1} would evaluate to true.

-
Most of this was stemming from my blatant oversight of \begin{env*} vs. \begin{env}*; I've made (what I thought to be) the necessary modifications to my code and simplified it significantly—but to no effect (the same error). Should I edit my question to reflect the new code, or should I ask a new one? –  Sean Allred Sep 7 '13 at 3:58