# Set enumeration level explicitly

I have the need for a custom list environment at the outermost level, defined as follows:

\newboolean{odd}
\setboolean{odd}{true}
\usepackage{environ}
\newcounter{exnum}[section]% Exercise counter (within section)
\NewEnviron{solution}{% Solution
\stepcounter{exnum}%
\ifthenelse{\isodd{\theexnum}}% Condition on oddness
{\ifthenelse{\boolean{odd}}{}{\item \BODY}}% Print odd
}
\newenvironment{outerlist}%
{\begin{list}%
{{\bfseries\arabic{exnum}.}}{}}%
{\end{list}}%

The point of all of this is to be able to set the odd boolean and change whether all items, or just the odd-numbered items, are output.

This all works fine, except that this list environment, outerlist, does not increment the enumeration level. As a result, inner enumerations start at level 1. This is not consistent with the visual appearance (outerlist obviously looks like an outer enumeration in the output), and is confusing to the maintainer (I confused myself a couple of times :)

Can I tell LaTeX to start with enumeration level 2? Or is there a better way to write the above so as to get the behavior I want?

Edit: Per request, here is an MWE:

\documentclass{article}
\usepackage{environ}

\newcounter{itemnum}
\NewEnviron{outeritem}{% Solution
\stepcounter{itemnum}%
{\item \BODY}%
}

\newenvironment{outerlist}%
{\begin{list}%
{{\bfseries\arabic{itemnum}.}}{}}%
{\end{list}}%

\renewcommand{\labelenumi}{{\bfseries(\alph{enumi})}}
\renewcommand{\labelenumii}{{\bfseries(\roman{enumii})}}

\begin{document}

\begin{outerlist}
\begin{outeritem}
This level is numbered with arabic numerals, but is not really an enumerate list.
\end{outeritem}
\begin{outeritem}
This is outer list item 2.
\begin{enumerate}
\item This looks visually to be at level 2, but LaTeX thinks of it as a level 1 enum,
and it is governed by $\backslash$labelenumi. I would like it to be governed by
$\backslash$labelenumii, so that the TeX file can use level 2 definitions for
this list level format.
\end{enumerate}
\end{outeritem}
\end{outerlist}
\end{document}
-
Couldn't you just use the enumerate environment instead of outerlist? Replace itemnum with enumi and omit the \stepcounter command since \item will automatically do that to enumi. Also, it is not necessary for outeritem to be an environment. It could just be a \newcommand that takes an argument. –  Dan Feb 28 at 20:00

It is possible to adjust the list depth/level. Let's see what enumerate does (taken from latex.ltx):

\def\enumerate{%
\ifnum \@enumdepth >\thr@@\@toodeep\else
\edef\@enumctr{enum\romannumeral\the\@enumdepth}%
\expandafter
\list
\csname label\@enumctr\endcsname
{\usecounter\@enumctr\def\makelabel##1{\hss\llap{##1}}}%
\fi}

Within the definition \advance\@enumdepth\@ne increases the depth/level of the enumeration. We could define

and use it where needed:

\documentclass{article}
\usepackage{environ}% http://ctan.org/pkg/environ

\newcounter{itemnum}
\NewEnviron{outeritem}{% Solution
\stepcounter{itemnum}%
{\item \BODY}%
}
\makeatletter
\makeatother

\newenvironment{outerlist}%
{\begin{list}%
{{\bfseries\arabic{itemnum}.}}{}}%
{\end{list}}%

\renewcommand{\labelenumi}{{\bfseries(\alph{enumi})}}
\renewcommand{\labelenumii}{{\bfseries(\textit{\roman{enumii}})}}

\begin{document}

\begin{outerlist}
\begin{outeritem}
This level is numbered with arabic numerals, but is not really an enumerate list.
\end{outeritem}
\begin{outeritem}
This is outer list item 2.
\begin{enumerate}
\item This looks visually to be at level 2, but LaTeX thinks of it as a level 1 enum,
and it is governed by $\backslash$labelenumi. I would like it to be governed by
$\backslash$labelenumii, so that the TeX file can use level 2 definitions for
this list level format.
\end{enumerate}
\end{outeritem}
\end{outerlist}
\end{document}

Since I don't know the full extent of usage for enumerate inside your lists, you may have to consider demoting the level at the end of outeritem. For example, the following may be sufficient:

\makeatletter
\makeatother
\newenvironment{outerlist}%
\begin{list}%
{{\bfseries\arabic{itemnum}.}}{}}%
{\end{list}%
\retractenumeratelevel}%
-
Yes, that works perfectly. Thanks. –  rogerl Feb 28 at 18:54

I'd go with enumitem.

\documentclass{article}
\usepackage{environ}
\usepackage{enumitem}

\NewEnviron{outeritem}{% Solution
\item \BODY
}

\newlist{outerlist}{enumerate}{1}
\setlist[enumerate,2]{label=\bfseries(\roman*)}
\makeatletter
% hook into LaTeX's enumerate depth
\makeatother

\begin{document}

\begin{outerlist}
\begin{outeritem}
This level is numbered with arabic numerals
\end{outeritem}
\begin{outeritem}
This is outer list item 2.
\begin{enumerate}
\item This is at level 2.
\end{enumerate}
\end{outeritem}
\end{outerlist}
\end{document}

The printing only of even numbered items is easy to add:

\documentclass{article}
\usepackage{environ}
\usepackage{enumitem,etoolbox}

\newtoggle{printodd}
\NewEnviron{outeritem}{% Solution
\iftoggle{printodd}
{%
\item \BODY
}
{%
\ifnumodd{\value{outerlisti}}
{\item\BODY}% the next item is even, print it
{\stepcounter{outerlisti}}% the next item is odd, skip it
}%
}

\newlist{outerlist}{enumerate}{1}
\setlist[enumerate,2]{label=\bfseries(\roman*)}
\makeatletter
\makeatother

\begin{document}

The toggle is initially false, only even numbered items are printed

\begin{outerlist}
\begin{outeritem}
This level is numbered with arabic numerals
\end{outeritem}
\begin{outeritem}
This is outer list item 2.
\begin{enumerate}
\item This is at level 2.
\end{enumerate}
\end{outeritem}
\end{outerlist}

Now we set the toggle to true, all items are printed
\toggletrue{printodd}

\begin{outerlist}
\begin{outeritem}
This level is numbered with arabic numerals
\end{outeritem}
\begin{outeritem}
This is outer list item 2.
\begin{enumerate}
\item This is at level 2.
\end{enumerate}
\end{outeritem}
\end{outerlist}

\end{document}

-
Well, that's pretty cool. But one of the things I removed in my MWE, which is actually the reason that I implemented this odd-looking thing to begin with, is that I want the ability at runtime to emit or not emit even-numbered top-level list items by setting a switch (see the original posted TeX). Are there any hooks I can put into your answer to make that happen? –  rogerl Feb 28 at 18:46
I posted a comment but forgot to tag you, so I'm doing that now. –  rogerl Feb 28 at 19:03
@rogerl I added a possible way to go –  egreg Feb 28 at 20:32

I refer to what you really wanted: just outputting odd/even items if the relevant boolean is set that way.

\documentclass{article}
\usepackage{ifthen}
\newboolean{oodd}
\setboolean{oodd}{true}
\usepackage{environ}
\makeatletter
\NewEnviron{Item}{%
\ifthenelse{\boolean{oodd}}
{
\ifthenelse{\isodd{\value{enum\romannumeral\@enumdepth}}}{\item \BODY}{\refstepcounter{enum\romannumeral\@enumdepth}}
}
{\item\BODY}
}
\makeatother
\begin{document}
\begin{enumerate}
\begin{Item}
Eins
\end{Item}
\begin{Item}
Zwei
\begin{enumerate}
\begin{Item}
Hallo
\end{Item}
\begin{Item}
Du
\end{Item}
\begin{Item}
Da
\end{Item}
\begin{Item}
!
\end{Item}
\end{enumerate}
\end{Item}
\begin{Item}
Drei
\end{Item}
\begin{Item}
Vier
\end{Item}
\end{enumerate}
\end{document}
-