3

Currently I'm trying to create an environment with several different \item-like commands. I want the arguments of the different commands to be ordered by their type.

Basically the usage of

\begin{ordered}
  \fruit{Apple}
  \vegetable{Salad}
  \vegetable{Bell Pepper}
  \fruit{Strawberry}
\end{ordered}

should result in

Apple
Strawberry
Salad
Bell Pepper

With the following Code this can be done on a basic level

\newenvironment{ordered}{
  \newcommand{\fruits}{}
  \newcommand{\fruit}[1]{
    \begingroup\def\temp{\renewcommand{\fruits}}
    \expandafter\expandafter\expandafter\endgroup
    \expandafter\temp\expandafter{\fruits{##1\\}}}
  \newcommand{\vegetables}{}
  \newcommand{\vegetable}[1]{
    \begingroup\def\temp{\renewcommand{\vegetables}}
    \expandafter\expandafter\expandafter\endgroup
    \expandafter\temp\expandafter{\vegetables{##1\\}}}
}{
  \fruits
  \vegetables
}

However, If I want my ordered environment to open a tabular containing the fruits and vegetables I get problems:

\newenvironment{ordered}{
  ...
  \begin{tabular}{l}
}{
  \fruits
  \vegetables
  \end{tabular}
}

Results in ! Missing } inserted. <inserted text> } l.31 \end{ordered}

Is there any way to use \fruits and \vegetables inside the ordered environment inside tabular?

4

You're including groups in your addition to \fruits and \vegetables. Instead, the \g@addto@macro<cs>{<stuff>} macro can help adding <stuff> to <cs> (it requires a \makeatletter...\makeatother pair):

enter image description here

\documentclass{article}

\makeatletter
\newcommand{\fruits}{}
\newcommand{\fruit}[1]{\g@addto@macro\fruits{#1\\}}
\newcommand{\vegetables}{}
\newcommand{\vegetable}[1]{\g@addto@macro\vegetables{#1\\}}
\makeatother
\newenvironment{ordered}{%
  \renewcommand{\fruits}{\relax}\renewcommand{\vegetables}{\relax}% Clear fruits/vegetables
  \tabular{l}
}{%
  \expandafter\ifx\fruits\relax\else\fruits\hline\fi% Print fruits
  \vegetables% Prints vegetables
  \endtabular
}
\begin{document}

\begin{ordered}
  \fruit{Apple}%
  \vegetable{Salad}%
  \vegetable{Bell Pepper}%
  \fruit{Strawberry}%
\end{ordered}

\begin{ordered}
  \vegetable{Salad}%
  \vegetable{Bell Pepper}%
\end{ordered}

\end{document}

I've also removed some spurious spaces that are introduced from line breaks. For more on this see What is the use of percent signs (%) at the end of lines?

| improve this answer | |
  • Thanks, just what I wanted. But now I have some kind of enhancement: what if I want to put an \hline between \fruits and \vegetables, but only if there is at least one fruit in \fruits? I tried to check for empty \fruits by using \IfStrEq{\fruits}{\empty{}}{}{\fruits\hline} instead of \fruits but this results in ! Argument of \@firstoftwo has an extra }. <inserted text> \par l.16 \end{ordered} – Marcel Aug 14 '13 at 15:24
  • @Marcel: I've updated my answer. It includes resetting \fruits and \vegetables to \relax, which is used for testing whether or not to insert an \hline. – Werner Aug 14 '13 at 16:10

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.