2

This question is closely related to a previous one:

How to order the items of the second level of enumerate according to a prescribed order

The solution proposed by Steven B. Segletes works excellently when only the second level items are required to obey to a prescribed order. Steven himself tells us:

"The prenumerate environment can be embedded inside enumerate, but not nested with other prenumerates."

So, how to proceed when one wants

  1. Example set 1.

    (a) Example set 1-a);

    (b) Example set 1-b);

    (c) Example set 1-c);

    (d) Example set 1-d).

  2. Example set 2.

    (a) Example set 2-a);

    (b) Example set 2-b);

    (c) Example set 2-c);

    (d) Example set 2-d).

following rule (as an example):

2B,2C,2A,2D,1C,1D,1A,1B,

which would have produced the following output:

  1. Example set 2.

    (a) Example set 2-b);

    (b) Example set 2-c);

    (c) Example set 2-a);

    (d) Example set 2-d).

  2. Example set 1.

    (a) Example set 1-c);

    (b) Example set 1-d);

    (c) Example set 1-a);

    (d) Example set 1-b).

Thanks in advance,

Paul

2

The prior (referenced by the OP) answer can be used with a slight syntax variation. Namely, the inner prenumerates need to me enclosed in their own group.

I also added an optional argument to prenumerate to suppress the trailing auto-punctuation, since punctuation following an inner prenumerate falls on a subsequent line all by itself.

\documentclass{article}
\usepackage{listofitems,environ}
\NewEnviron{prenumerate}[2][\relax]{%
  \ignoreemptyitems
  \setsepchar{,}%
  \readlist\listorder{#2}%
  \setsepchar{\item||\par\item}%
  \expandafter\readlist\expandafter*\expandafter
    \prenumlist\expandafter{\expandafter\item\expandafter\relax\BODY}%
  \begin{enumerate}
  \foreachitem\x\in\listorder[]{%
    \expandafter\expandafter\expandafter\item 
      \prenumlist[\the\numexpr\x+1\relax]%
    \ifx\relax#1\relax\ifnum\xcnt=\listlen\listorder[]\relax.\else;\fi\fi%
  }%
  \end{enumerate}
}
\begin{document}
\newcommand\preordB{3,1,4,2}

To nest prenumerate environments, group the inner environments.
Also, optional argument provided to suppress trailing auto-punctuation.

\begin{prenumerate}[x]{2,1}
\item Examples.
{\begin{prenumerate}{4,3,1,2}

\item Example 1

\item Example 2
\item Example 3
\item Example 4

\end{prenumerate}}
\item Examples ordered differently.
{\begin{prenumerate}{\preordB}
\item Example 1
\item Example 2
\item[$\bullet$] Example 3
\item Example 4
\end{prenumerate}}
\end{prenumerate}
\end{document}

enter image description here


SUPPLEMENT

User PaulSmith asks if the prenumerate environment can be reworked with a deferred output; that is, saved for later use. With a lot of \expandafters, the answer is yes.

I name this environment renumerate and it takes an extra mandatory argument, a unique macro name used to store internal list data. For example, here I provide the name \z:

\begin{renumerate}[x]{2,1}{\z}
\item The first

\item the second
\end{renumerate}

Later, when the list is desired, it is to be recalled with the macro \zlist, essentially tacking the word list onto the end of the unique macro name provided.

In the MWE, I use a normal prenumerate. Then I create 2 renumerates, and later present the second one first, followed by the first one (using the resume key of enumitem).

\documentclass{article}
\usepackage{listofitems,environ}
\NewEnviron{prenumerate}[2][\relax]{%
  \ignoreemptyitems
  \setsepchar{,}%
  \readlist\listorder{#2}%
  \setsepchar{\item||\par\item}%
  \expandafter\readlist\expandafter*\expandafter
    \prenumlist\expandafter{\expandafter\item\expandafter\relax\BODY}%
  \begin{enumerate}
  \foreachitem\x\in\listorder[]{%
    \expandafter\expandafter\expandafter\item 
      \prenumlist[\the\numexpr\x+1\relax]%
    \ifx\relax#1\relax\ifnum\xcnt=\listlen\listorder[]\relax.\else;\fi\fi%
  }%
  \end{enumerate}
}
\makeatletter
\NewEnviron{renumerate}[3][\relax]{%
  \edef\tmp{\expandafter\@gobble\string#3}%
  \ignoreemptyitems
  \setsepchar{,}%
  \greadlist#3{#2}%
  \setsepchar{\item||\par\item}%
  \expandafter\greadlist\expandafter*\csname prenum\tmp\expandafter
    \endcsname\expandafter{\expandafter\item\expandafter\relax\BODY}%
  \def\tempA{\begin{enumerate}\foreachitem\x\in#3[]}%
  \def\tempB{\expandafter\expandafter\expandafter\item}%
  \def\tempC{\csname prenum}%
  \expandafter\gdef\csname \tmp list\expandafter\expandafter\expandafter
    \expandafter\expandafter\expandafter\expandafter
    \expandafter\expandafter\expandafter\expandafter
    \expandafter\expandafter\expandafter\expandafter
    \endcsname\expandafter\expandafter\expandafter\expandafter\expandafter
      \expandafter\expandafter\expandafter\expandafter\expandafter
      \expandafter\expandafter\expandafter\expandafter\expandafter{%
      \expandafter\expandafter\expandafter\expandafter\expandafter
      \expandafter\expandafter\tempA\expandafter\expandafter\expandafter
      \expandafter\expandafter\expandafter\expandafter{\expandafter
      \expandafter\expandafter\tempB\expandafter
      \tempC\tmp[\the\numexpr\x+1\relax]\endcsname%
      \ifx\relax#1\relax\ifnum\xcnt=\listlen#3[]\relax.\else;\fi\fi%
  }%
  \end{enumerate}
}%
}
\makeatother
\begin{document}

Here is one that is not deferred:
\newcommand\preordB{3,1,4,2}

To nest prenumerate environments, group the inner environments.
Also, optional argument provided to suppress trailing auto-punctuation.

\begin{prenumerate}[x]{2,1}
\item Examples.
{\begin{prenumerate}{4,3,1,2}

\item Example 1

\item Example 2
\item Example 3
\item Example 4

\end{prenumerate}}
\item Examples ordered differently.
{\begin{prenumerate}{\preordB}
\item Example 1
\item Example 2
\item[$\bullet$] Example 3
\item Example 4
\end{prenumerate}}
\end{prenumerate}

\hrulefill

\begin{renumerate}[x]{2,1}{\z}
\item The first

\item the second
\end{renumerate}

Saved the first renumerate

\hrulefill

\begin{renumerate}[x]{2,1}{\zz}
\item Examples.
{\begin{prenumerate}{4,3,1,2}

\item Example 1

\item Example 2
\item Example 3
\item Example 4

\end{prenumerate}}
\item Examples ordered differently.
{\begin{prenumerate}{\preordB}
\item Example 1
\item Example 2
\item[$\bullet$] Example 3
\item Example 4
\end{prenumerate}}
\end{renumerate}

Saved the second renumerate.

\hrulefill

Now we present the 2nd

\zzlist

Now here is the first:\setlist{resume}

\zlist

\end{document}

enter image description here

  • That works greatly! But suppose now, to finish this question, that one wants to add an optional argument to prenumerate with the number of columns to used with package multicol inside the second level of prenumerate environment: the optional argument would indicate the number of columns; the absence of the optional argument would mean not using the multicols environment at all inside the second level of prenumerate. – Paul Smith Apr 30 at 13:40
  • 1
    By inserting \ifnum #1>1 \begin{multicols}{#1} \fi just before \begin{enumerate} and \ifnum #1>1 \end{multicols} \fi just after \end{enumerate}, where #1 is an optional argument, I get precisely what I want. Thanks, Steven! – Paul Smith Apr 30 at 15:14
  • 1
    @StevenBSegletes Is it possible to adapt your code to accommodate the possibility of suspended enumerates? Thanks! – Paul Smith May 30 at 17:58
  • 1
    @StevenBSegletes Exactly! Likewise the resume option of enumitem. – Paul Smith May 30 at 18:12
  • 1
    @StevenBSegletes Thanks! I have just used that in a complex document with minipages and tables inside prenumerate and renumerate, and everything works great! – Paul Smith May 30 at 21:14

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.