5

I would like an environment to be called by \begin{myenv} that conditionally adds multicols if called by \begin{myenv}{<number of columns>}.

This is what I tried:

\documentclass{article}
   \usepackage{enumitem}
   \usepackage{multicol}

\makeatletter
\newenvironment{myenv}[1]{
    \def\@tempa{#1}%
   \ifx\@tempa\@empty
        \expandafter\@firstoftwo
   \else
        \expandafter\@secondoftwo
    \fi
        {%
        \begin{enumerate}[label=\Alph*),itemsep=0pt,#1]
        }
        {%
        \setlength{\multicolsep}{5pt}
        \begin{multicols}{#1}
            \begin{enumerate}[label=\Alph*),itemsep=0pt]
        }
    }
    {\ifx\@firstoftwo
        \end{enumerate}
    \else
        \end{enumerate}\end{multicols}
    \fi
    }
\makeatother
\begin{document}

\begin{myenv}{5}
   \item dog
   \item cat
   \item duck
   \item fly
\item spider
\end{myenv}
\end{document}

Unfortunately it only works when a number of columns is specified, if I call just \begin{myenv} and error is triggered and latex tells me that 0 columns is not a good idea.

Is there a way to fix this?

Jason T.
  • 225

1 Answers1

7

In my opinion the argument to \myenv should be optional, so if it's not expressed it's taken to be one.

However, the error is in the \end part, where \ifx\@firstoftwo is wrong. Also using \@tempa is wrong, because it turns out it is used by multicol, so it changes value before the \end part is evaluated.

\documentclass{article}

\usepackage{enumitem}
\usepackage{multicol}

\makeatletter
\newenvironment{myenv}[1][]% one optional argument
  {\def\myenv@tempa{#1}%
   \ifx\myenv@tempa\@empty
     \expandafter\@firstoftwo
   \else
     \expandafter\@secondoftwo
   \fi
   {%
    \begin{enumerate}[label=\Alph*),itemsep=0pt,#1]%
   }%
   {%
    \setlength{\multicolsep}{5pt}
    \begin{multicols}{#1}
    \begin{enumerate}[label=\Alph*),itemsep=0pt]
   }%
  }
  {\ifx\myenv@tempa\@empty
     \expandafter\@firstoftwo
   \else
     \expandafter\@secondoftwo
   \fi
   {\end{enumerate}}%
   {\end{enumerate}\end{multicols}}
  }
\makeatother
\begin{document}

\begin{myenv}[5]% <--- number of columns in square brackets!
  \item dog
  \item cat
  \item duck
  \item fly
  \item spider
\end{myenv}
\end{document}

Here's a different implementation with xparse, that allows to carry argument specifiers also in the \end part.

\documentclass{article}

\usepackage{enumitem}
\usepackage{multicol}
\usepackage{xparse}

\NewDocumentEnvironment{myenv}{o}
 {%
  \IfValueT{#1}
   {%
    \setlength{\multicolsep}{5pt}%
    \begin{multicols}{#1}%
   }%
  \begin{enumerate}[label=\Alph*),itemsep=0pt]%
 }
 {%
  \end{enumerate}
  \IfValueT{#1}
   {%
    \end{multicols}%
   }%
 }

\begin{document}

\begin{myenv}[5]
  \item dog
  \item cat
  \item duck
  \item fly
  \item spider
\end{myenv}
\end{document}

enter image description here

egreg
  • 1,121,712