3

Recently I've seen this post and I felt that I'd like to have something similar, but with math environment, so that if I write a single line of equation, it will put it at the centre, like equation does. And if I add line break \\, it should be left-aligned.

Here is how it should look like: enter image description here


And if it is possible I would also really like to be able to use & in order to make columns that are centered i.e. & is only responsible for the columns, not the alignment.

enter image description here

Bernard
  • 271,350
antshar
  • 4,238
  • 9
  • 30
  • For the centred sibgle-lined equation, you have the equation environment (numbered) or \[ ... \] (unnumbered). For the the multilined equations, use the dedicated environments from amsmath (gather,align, alignat, multline, flalign) – Bernard May 19 '20 at 16:35

1 Answers1

4

Not really a good markup, in my opinion. But the customer is always right. ;-)

The environment has an optional argument (default 2em) to set the spacing between columns.

\documentclass{article}
\usepackage{amsmath,array}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentEnvironment{mymath}{O{2em}b}
 {
  % #1 = spacing between columns, #2 = body
  \tl_if_in:nnT { #2 } { & }
   {
    \bool_set_true:N \l__antshar_mymath_ampersand_bool
   }
  \seq_set_split:Nnn \l__antshar_mymath_body_seq { \\ } { #2 }
  \int_compare:nTF { \seq_count:N \l__antshar_mymath_body_seq = 1 }
   {
    \__antshar_mymath_single:nn { #1 } { #2 }
   }
   {
    \__antshar_mymath_multiple:n { #1 }
   }
 }
 {\ignorespacesafterend}

\seq_new:N \l__antshar_mymath_body_seq
\seq_new:N \l__antshar_mymath_row_seq
\bool_new:N \l__antshar_mymath_ampersand_bool
\int_new:N \l__antshar_mymath_cols_int

\cs_new_protected:Nn \__antshar_mymath_single:nn
 {
  \bool_if:NTF \l__antshar_mymath_ampersand_bool
   {
    \seq_set_split:Nnn \l__antshar_mymath_row_seq { & } { #2 }
    \[
    \begin{array}
     {
      @{}
      >{\displaystyle}c
      *{\int_eval:n { \seq_count:N \l__antshar_mymath_row_seq - 1 }}
       {@{\hspace{#1}}>{\displaystyle}c}
      @{}
     }
    #2
    \end{array}
    \]
   }
   {
    \[ #2 \]
   }
 }

\cs_new_protected:Nn \__antshar_mymath_multiple:n
 {
  \bool_if:NTF \l__antshar_mymath_ampersand_bool
   {
    % count the maximum number of columns
    \int_zero:N \l__antshar_mymath_cols_int
    \seq_map_inline:Nn \l__antshar_mymath_body_seq
     {
      \seq_set_split:Nnn \l__antshar_mymath_row_seq { & } { ##1 }
      \int_set:Nn \l__antshar_mymath_cols_int
       {
        \int_max:nn { \l__antshar_mymath_cols_int } { \seq_count:N \l__antshar_mymath_row_seq }
       }
     }
    \[
    \begin{array}
     {
      @{}
      >{\displaystyle}c
      *{\int_eval:n { \l__antshar_mymath_cols_int - 1 } }
       {@{\hspace{#1}}>{\displaystyle}c}
      @{}
     }
    \seq_use:Nn \l__antshar_mymath_body_seq { \\\noalign{\vspace{\jot}} }
    \end{array}
    \]
   }
   {
    \seq_set_map:NNn \l__antshar_mymath_row_seq \l__antshar_mymath_body_seq
     {
      & \exp_not:n { {##1} } &&
     }
    \begin{flalign*}
    \seq_use:Nn \l__antshar_mymath_row_seq { \\ }
    \end{flalign*}
   }
 }

\ExplSyntaxOff

\begin{document}

\noindent Some text in front of the display, just for separation
\begin{mymath}
a=b
\end{mymath}
Some text in front of the display, just for separation
\begin{mymath}
a=b & c=d & e=ffffffff
\end{mymath}
Some text in front of the display, just for separation
\begin{mymath}
a=b & c=d & e=ffffffff \\
1=1 & 120\ne1000 & u
\end{mymath}
Some text in front of the display, just for separation
\begin{mymath}[4em]
a=b & c=d & e=ffffffff
\end{mymath}
Some text in front of the display, just for separation
\begin{mymath}
abc+def\\
=x+y
\end{mymath}

\end{document}

enter image description here

The image has been produced adding showframe.

Addition

The mymath* environment puts everything to the left.

\documentclass{article}
\usepackage{amsmath,array}
\usepackage{xparse}
\usepackage{showframe}

\ExplSyntaxOn

\NewDocumentEnvironment{mymath}{O{2em}b}
 {
  \bool_set_false:N \l__antshar_mymath_left_bool
  \antshar_mymath_main:nn { #1 } { #2 }
 }
 {\ignorespacesafterend}

\NewDocumentEnvironment{mymath*}{O{2em}b}
 {
  \bool_set_true:N \l__antshar_mymath_left_bool
  \antshar_mymath_main:nn { #1 } { #2 }
 }
 {\ignorespacesafterend}

\seq_new:N \l__antshar_mymath_body_seq
\seq_new:N \l__antshar_mymath_row_seq
\bool_new:N \l__antshar_mymath_ampersand_bool
\bool_new:N \l__antshar_mymath_left_bool
\int_new:N \l__antshar_mymath_cols_int

\cs_new_protected:Nn \antshar_mymath_main:nn
 {
  % #1 = spacing between columns, #2 = body
  \tl_if_in:nnT { #2 } { & }
   {
    \bool_set_true:N \l__antshar_mymath_ampersand_bool
   }
  \seq_set_split:Nnn \l__antshar_mymath_body_seq { \\ } { #2 }
  \int_compare:nTF { \seq_count:N \l__antshar_mymath_body_seq = 1 }
   {
    \__antshar_mymath_single:nn { #1 } { #2 }
   }
   {
    \__antshar_mymath_multiple:n { #1 }
   }
 }

\cs_new_protected:Nn \__antshar_mymath_single:nn
 {
  \bool_if:NTF \l__antshar_mymath_ampersand_bool
   {
    \seq_set_split:Nnn \l__antshar_mymath_row_seq { & } { #2 }
    \[
    \bool_if:NT \l__antshar_mymath_left_bool { \hspace{0pt} }
    \begin{array}
     {
      @{}
      >{\displaystyle}c
      *{\int_eval:n { \seq_count:N \l__antshar_mymath_row_seq - 1 }}
       {@{\hspace{#1}}>{\displaystyle}c}
      @{}
     }
    #2
    \end{array}
    \bool_if:NT \l__antshar_mymath_left_bool { \hspace{1000pt minus 1fill} }
    \]
   }
   {
    \[
    \bool_if:NT \l__antshar_mymath_left_bool { \hspace{0pt} }
    #2
    \bool_if:NT \l__antshar_mymath_left_bool { \hspace{1000pt minus 1fill} }
    \]
   }
 }

\cs_new_protected:Nn \__antshar_mymath_multiple:n
 {
  \bool_if:NTF \l__antshar_mymath_ampersand_bool
   {
    % count the maximum number of columns
    \int_zero:N \l__antshar_mymath_cols_int
    \seq_map_inline:Nn \l__antshar_mymath_body_seq
     {
      \seq_set_split:Nnn \l__antshar_mymath_row_seq { & } { ##1 }
      \int_set:Nn \l__antshar_mymath_cols_int
       {
        \int_max:nn { \l__antshar_mymath_cols_int } { \seq_count:N \l__antshar_mymath_row_seq }
       }
     }
    \[
    \bool_if:NT \l__antshar_mymath_left_bool { \hspace{0pt} }
    \begin{array}
     {
      @{}
      >{\displaystyle}c
      *{\int_eval:n { \l__antshar_mymath_cols_int - 1 } }
       {@{\hspace{#1}}>{\displaystyle}c}
      @{}
     }
    \seq_use:Nn \l__antshar_mymath_body_seq { \\\noalign{\vspace{\jot}} }
    \end{array}
    \bool_if:NT \l__antshar_mymath_left_bool { \hspace{1000pt minus 1fill} }
    \]
   }
   {
    \[
    \hspace{0pt}
    \begin{array}{@{}>{\displaystyle}l@{}}
    \seq_use:Nn \l__antshar_mymath_body_seq { \\\noalign{\vspace{\jot}} }
    \end{array}
    \hspace{1000pt minus 1fill}
    \]
   }
 }

\ExplSyntaxOff

\begin{document}

\noindent Some text in front of the display, just for separation
\begin{mymath}
a=b
\end{mymath}
Some text in front of the display, just for separation
\begin{mymath}
a=b & c=d & e=ffffffff
\end{mymath}
Some text in front of the display, just for separation
\begin{mymath}
a=b & c=d & e=ffffffff \\
1=1 & 120\ne1000 & u
\end{mymath}
Some text in front of the display, just for separation
\begin{mymath}[4em]
a=b & c=d & e=ffffffff
\end{mymath}
Some text in front of the display, just for separation
\begin{mymath}
abc+def\\
=x+y
\end{mymath}
Some text in front of the display, just for separation
\begin{mymath*}
a=b
\end{mymath*}
Some text in front of the display, just for separation
\begin{mymath*}
a=b & c=d & e=ffffffff
\end{mymath*}
Some text in front of the display, just for separation
\begin{mymath*}
a=b & c=d & e=ffffffff \\
1=1 & 120\ne1000 & u
\end{mymath*}
Some text in front of the display, just for separation
\begin{mymath*}[4em]
a=b & c=d & e=ffffffff
\end{mymath*}
Some text in front of the display, just for separation
\begin{mymath*}
abc+def\\
=x+y
\end{mymath*}

\end{document}

enter image description here

egreg
  • 1,121,712
  • Fantastic! Thank you so much! – antshar May 19 '20 at 17:28
  • You've done a great job and absolutely did answer my original question. I'm really grateful for that. Don't want to seem impudent, but I'd like to know whether it is possible to put an asterisk, like so mymath* and have everything left-aligned, both single line and tabular-like structures? – antshar May 19 '20 at 17:43
  • @antshar Not so difficult, if you know how to do it. ;-) – egreg May 19 '20 at 22:06
  • Brilliant! You helped me a lot. Thank you so much! – antshar May 20 '20 at 10:17
  • I just remembered that you left such an amazing answer a couple of years ago. Now I'm struggling with this post. Can you explain you managed to achieve just the right spacing in array, like in other amsmath environments? – antshar May 27 '22 at 07:39
  • @antshar I'd go with IEEEeqnarray (but first trying to limit the number of objects in displays). – egreg May 27 '22 at 07:53
  • But you still managed to do that even without IEEEeqnarray. Seems like I found what solves the problem: \\\noalign{\vspace{\jot}}. But how does it work exactly? – antshar May 27 '22 at 08:13