7

I have a custom environment properties (that is almost ready for release to Github) that works like so:

\begin{properties}
\item[no max in reals] \forall a \in \Re, \exists b \in \Re : a < b
\item[minimum natural] \exists n \in \Na : \forall m \in \Na, n \le m
\end{properties}

and would produce (sans typo)

output

However, for a more complicated example, the spacing seems to be off:

output

I think this has something to do with the behavior of \NewDocumentEnvironment that I'm not accounting for…

MWE

\documentclass{article}
\usepackage{amsmath,amsthm} % \text{...}; \newtheorem{...}{...}
\usepackage{xparse,expl3}
\usepackage[hidelinks]{hyperref} % For some reason, this affects
                                 % numbering of the equations.
\ExplSyntaxOn

% 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
}

\bool_new:N \g_property_first_item_bool

\NewDocumentEnvironment { properties } { }
 {
  \bool_set_true:N \g_property_first_item_bool
  % 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 }
   {
    \bool_if:NTF \g_property_first_item_bool
     { \bool_set_false:N \g_property_first_item_bool }
     { \property_do_end: }
    \IfValueTF { ##1 }
     { \property_do_begin:n { ##1 } }
     { \property_do_begin: }
   }
 }
 { \property_do_end: }


\theoremstyle{definition}
\newtheorem{definition}{Definition}





%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Extra %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% This stuff isn't necessary for compilation, but is stuff that I use
% in the example.  Feel free, of course, to use it in your own stuff
% (LPPL and all that jazz).  I find it helps further logicall organize
% stuff, although it acts a little weird with AUCTeX's fold mode.



% Save the old \forall
\cs_set_eq:NN \for_all: \forall

% create a *new* forall that takes two arguments: the predicate and
% the other thing.  Because I forgot FOM.
\cs_new:Nn \for_all:nn
 {
  \for_all: #1,\; #2
 }
\DeclareDocumentCommand \forall { s }
 {
  \IfBooleanTF { #1 }
   \for_all:
   \for_all:nn
 }

% Save the old \exists
\cs_set_eq:NN \exists: \exists

% create a *new* forall that takes two arguments: the predicate and
% the other thing.  Because I forgot FOM.
\cs_new:Nn \exists:nn
 {
  \exists:\,#1:#2
 }
\DeclareDocumentCommand \exists { s }
 {
  \IfBooleanTF { #1 }
   \exists:
   \exists:nn
 }

\ExplSyntaxOff

\def\Na{\mathbf N}

\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}
3
  • That's not the only typographically disputable aspect. The formulas' horizontal alignment is really poor. Redefining \exists and \forall to commands with arguments is something I'd never do (and your redefinitions break common LaTeX syntax).
    – egreg
    Sep 11 '13 at 9:11
  • @egreg I noticed it too; but it seemed related to the vertical space (I was thinking along the lives of \parindent). Point taken about redefinitions; I suppose I should just caps them (\ForAll) instead? Sep 11 '13 at 12:11
  • The bad alignment is due to the fact you're doing independent equation environments.
    – egreg
    Sep 11 '13 at 12:17
7

I think this is due to your code uses

\equation...\endequation

sequentially such that under the first item we have a \belowdisplayskip and for all other items we have \belowdisplayshortskip. So if we add

\belowdisplayskip\belowdisplayshortskip\relax

inside the new environment then the problem will be, at least temporarily, fixed.

Result: enter image description here

More:

Ideally one should consider using align or gather for multiple equations, so maybe with something like:

\documentclass{article}
\usepackage{amsmath,amsthm} % \text{...}; \newtheorem{...}{...}
\usepackage{xparse,expl3}
\usepackage[hidelinks]{hyperref} % For some reason, this affects
                                 % numbering of the equations.
\ExplSyntaxOn

\cs_new:Nn \property_do_begin: 
{
  &\quad\bullet&
}

\cs_new:Nn \property_do_begin:n 
{
  &\quad\bullet\enspace\text{\slshape #1}&
}

\bool_new:N \g_property_first_item_bool
\DeclareDocumentCommand \item { o }
   {
    \IfValueTF { #1 }
     { \property_do_begin:n { #1 } }
     { \property_do_begin: }
   }

\theoremstyle{definition}
\newtheorem{definition}{Definition}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Extra %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% This stuff isn't necessary for compilation, but is stuff that I use
% in the example.  Feel free, of course, to use it in your own stuff
% (LPPL and all that jazz).  I find it helps further logicall organize
% stuff, although it acts a little weird with AUCTeX's fold mode.



% Save the old \forall
\cs_set_eq:NN \for_all: \forall

% create a *new* forall that takes two arguments: the predicate and
% the other thing.  Because I forgot FOM.
\cs_new:Nn \for_all:nn
 {
  \for_all: #1,\; #2
 }
\DeclareDocumentCommand \forall { s }
 {
  \IfBooleanTF { #1 }
   \for_all:
   \for_all:nn
 }

% Save the old \exists
\cs_set_eq:NN \exists: \exists

% create a *new* forall that takes two arguments: the predicate and
% the other thing.  Because I forgot FOM.
\cs_new:Nn \exists:nn
 {
  \exists:\,#1:#2
 }
\DeclareDocumentCommand \exists { s }
 {
  \IfBooleanTF { #1 }
   \exists:
   \exists:nn
 }

\ExplSyntaxOff

\def\Na{\mathbf N}

\begin{document}
\begin{definition}[group]
  A group is a set $G$ together
    with a binary operation $*$ on $G$
    that satisfies the following axioms:
  \begin{align}
  \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{align}
\end{definition}
\end{document}

Check out the result: enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.