# Align environment with optional columns

I'm working with formal grammar in LaTeX and would like to write some of the shorter rules in the same row in order to save space. The rules are aligned using the array environment and I'd like to define some kind of optional columns to align the rules in the rows with multiple ones correctly.

Example mwe.tex:

\documentclass{article}

\begin{document}
$\begin{array}{rl} S \rightarrow& aaaaaABbbbbb | aaaaABbbbb | aaaABbbb | aaABbb | aABb | ab\\ A \rightarrow& aaCbb | aDb | ab, B \rightarrow aaEbb | aFb | ab\\ C \rightarrow& c, D \rightarrow d, E \rightarrow e, F \rightarrow f\\ \end{array}$
\end{document}


The MWE currently produces this result:

The result I desire would be similar to the following:

I've found this relevant question, but it appears to be a rather ugly hack and also hard to auto-apply, as the actual work document uses a lot more rules than this MWE.

I also tried nesting the arrays, but compiling the file with three indented, nested arrays produced a damaged PDF that I'm both unable to view or delete

You can do that with the alignat environment, and the \mathrlap command from mathtools:

\documentclass{article}
\usepackage{geometry}
\usepackage{mathtools}

\begin{document}

\begin{alignat*}{4}
S &\rightarrow \mathrlap{aaaaaABbbbbb | aaaaABbbbb | aaaABbbb | aaABbb | aABb | ab} \\
A &\rightarrow \mathrlap{aaCbb | aDb | ab,} & & &B &\rightarrow \mathrlap{aaEbb | aFb | ab} \\
C &\rightarrow c, &\hspace{3.25em} D & \rightarrow d, &\hspace{3.25em} E & \rightarrow e, &\hspace{3.25em} F & \rightarrow f \\
\end{alignat*}

\end{document}


I've understood your objective as follows: The two comma-separated chunks to right of the & symbol in the second row should be placed in cells that are half as wide as the cell that contains the long chunk in the first row, and each of the four comma-separated chunks in the third row should be placed in cells that are half as wide as the cells in the second. Moreover, all chunks should be left-aligned in their respective cells.

Assuming this understanding is correct, you could proceed along the lines given in the code below, which uses a tabularx environment whose width is calculated off of the width of the long chunk in the first row.

\documentclass{article}

\newcommand\longchunk{$aaaaaABbbbbb | aaaaABbbbb | aaaABbbb | aaABbb | aABb | ab$}
\newlength\mylena
\settowidth{\mylena}{\longchunk} % save width of "\longchunk"
\newlength\mylenb
\settowidth\mylenb{$C\to$}
\newlength\mylenc
%%% Calculate width of tabularx environment

\usepackage{tabularx}

\begin{document}
\begin{center}
\setlength\tabcolsep\arraycolsep % (6pt-> 5pt)
\begin{tabularx}{\mylenc}{ >{$}r<{$} *{4}{>{$}X<{$}} }
S \to & \multicolumn{4}{l}{\longchunk}\\
A \to & \multicolumn{2}{l}{$aaCbb | aDb | ab,$} & \multicolumn{2}{l}{$B \to aaEbb | aFb | ab$}\\
C \to & c, &  D\to d, & E\to e, & F\to f\\
\end{tabularx}
\end{center}

\end{document}


Here's a simple solution using a plain TeX halign - sometimes you can get nice elegant solutions using the "old" way. In this particular case, I think that separating the rules with & characters provides slightly more straightforward semantic mark up.

\documentclass{article}
\begin{document}
\vbox{\let\\\cr\openup4pt\halign{&\makebox[1in][l]{#}\\ S \to aaaaaABbbbbb \mid aaaaABbbbb \mid aaaABbbb \mid aaABbb \mid aABb \mid ab\\ A \to aaCbb \mid aDb \mid ab && B \to aaEbb \mid aFb \mid ab\\ C \to c & D \to d & E \to e & F \to f\\ }}
\end{document}


## Notes

• To put an halign inside a maths display, it's best to wrap it up in a vertical box

• Inside the vbox, I can make some local definitions: \let\\\cr allows you to go on using \\ to end the lines; \openup4pt adds 4pt of extra space between each row of the alignment

• The header of the alignment sets every "cell" into a one-inch left-aligned horizontal box regardless of the actual width of the contents. Because the header starts with an & it will be repeated as often as needed. So I'm assuming you won't have too many cells in each row.

• The main change to the body of the table is to move the & characters so that they separate each cell; note that there's a blank cell between the "A" and "B" rules.

• I've also made a couple of small cosmetic improvements: I changed all the | characters into \mid so that they are set with better spacing; and I've used the short form of \rightarrow to save space

• At the end, the }} close the opening braces after the \vbox and the \halign.