# Detect if \item is followed by \begin{enumerate}

Consider the following code:

\documentclass{article}

\usepackage{enumitem}

\setlist[enumerate,1]{label = \bfseries \Alph*.}
\setlist[enumerate,2]{label = \bfseries \Alph{enumi}.\arabic*}
\setlist[enumerate,3]{label = \bfseries \Alph{enumi}.\arabic{enumii}.\alph*.}

\begin{document}

\begin{enumerate}
\item
\begin{enumerate}
\item
\begin{enumerate}
\item
\item
\end{enumerate}
\end{enumerate}
\end{enumerate}

\end{document}


The output is:

Is there a way to make \item detects it is followed by another enumerate environment so that it does not print its label? I could then get something like:

[3rd level indent]A.1.a
[3rd level indent]A.1.b


I'd like the solution being compatible with enumitem.

• that seems like a package bug really, the list code in the format always checks if there is a pending label, which means effectively the previous thing was \item. It should not be necessary for \item to look ahead. – David Carlisle Feb 21 '17 at 12:19
• @DavidCarlisle Same result if I change labels directly with LaTeX, without enumitem (as I expected, because \makelabel is based on \llap). – Javier Bezos Feb 21 '17 at 15:50
• That looks like an XY problem. What do yo want to get exactly? – Javier Bezos Feb 21 '17 at 16:01
• @JavierBezos See code below screenshot (and thanks for your interest in my question). – cjorssen Feb 21 '17 at 16:03
• @JavierBezos but doing it by hand you'd increase the label width to match the wider format. the default \makelabel only uses llap as it "knows" space has been left for the label... – David Carlisle Feb 21 '17 at 16:08

I hope the following suits your needs:

\documentclass{article}

\usepackage{enumitem}

\makeatletter
\newcommand\remlabels{\if@inlabel\setbox\@labels=\hbox{}\fi}
\makeatother

\setlist[enumerate,1]{before = \remlabels, label = \Alph*.}
\setlist[enumerate,2]{before = \remlabels, label = \Alph{enumi}.\arabic*}
\setlist[enumerate,3]{before = \remlabels, label = \Alph{enumi}.\arabic{enumii}.\alph*.}

\begin{document}

\begin{enumerate}
\item 1st
\item
\begin{enumerate}
% \item 2nd
\item
\begin{enumerate}
\item
\item
\end{enumerate}
\end{enumerate}
\item 3r
\end{enumerate}

\end{document}

• Thanks (+1). This is a good complement to David's answer. – cjorssen Feb 21 '17 at 22:09

You can redefine the \item macro to look ahead for \begin{enumerate}. The following code isn't pretty but does that:

\documentclass{article}

\usepackage{enumitem}
\usepackage{ifthen}

\setlist[enumerate,1]{label = \bfseries \Alph*.}
\setlist[enumerate,2]{label = \bfseries \Alph{enumi}.\arabic*}
\setlist[enumerate,3]{label = \bfseries \Alph{enumi}.\arabic{enumii}.\alph*.}

\makeatletter
\let\@lditem=\item
\def\n@witem\begin#1{%
\ifthenelse{\equal{#1}{enumerate}}{%
% Use empty label but step the counter
\refstepcounter{\@listctr}\@lditem[]\begin{#1}%
}{%
\@lditem\begin{#1}%
}%
}
\def\item{%
\@ifnextchar\begin{%
% Then check for {enumerate}
\n@witem
}{%
\@lditem
}%
}
\makeatother

\begin{document}

\begin{enumerate}
\item
\item[ZZ]
\item
\begin{enumerate}
\item
\begin{enumerate}
\item
\item
\end{enumerate}
\item
$$1+1=2$$
\end{enumerate}
\end{enumerate}

\end{document}

• Great (+1). Works fine. Tranks. – cjorssen Feb 21 '17 at 12:09
• Unfortunately, spacings fail with \setlist{wide}. – cjorssen Feb 21 '17 at 12:20
• As far as I can see, \setlist{wide} makes \item' insert all three labels in a row with gaps between them. So, indeed spacing becomes wrong. I'm not sure I can easily fix this. – Sergei Golovan Feb 21 '17 at 12:39
• You can use something like \setlist{wide = -5pt} as a very ugly workaround. – Sergei Golovan Feb 21 '17 at 12:43

I'm not sure but I think you mean you want

\documentclass{article}

\usepackage{enumitem}

\setlist[enumerate,1]{label = \bfseries \Alph*.}
\setlist[enumerate,2]{label = \bfseries \Alph{enumi}.\arabic*}
\setlist[enumerate,3]{label = \bfseries \Alph{enumi}.\arabic{enumii}.\alph*.}

\makeatletter
\def\@trivlist{%
\if@noskipsec \leavevmode \fi
\ifvmode
\else
\unskip \par
\fi
\if@inlabel
\@noparitemtrue
\setbox\@labels\hbox{}%
\@noparlisttrue
\else
\if@newlist \@noitemerr \fi
\@noparlistfalse
\fi
\leftskip \z@skip
\rightskip \@rightskip
\parfillskip \@flushglue
\par@deathcycles \z@
\@setpar{\if@newlist
\ifnum \par@deathcycles >\@m
\@noitemerr
{\@@par}%
\fi
\else
{\@@par}%
\fi}%
\global \@newlisttrue
\@outerparskip \parskip}

\begin{document}

\begin{enumerate}
\item
\begin{enumerate}
\item
\begin{enumerate}
\item
\item
\end{enumerate}
\end{enumerate}
\item hmmm
\end{enumerate}

\end{document}

• That's exactly what I want. I think I can wrap your code inside the before key of enumitem keyvals. Now, I'd like to understand :-) Can you comment a bit your code? Thanks (+1, obviously). – cjorssen Feb 21 '17 at 16:35
• @cjorssen you may prefer to use etoolbox to patch all I added was a single line \setbox\@labels\hbox{}% that discards any pending label from outside the list at the point that trivlist is anyway doing \if@inlabel which is testing for exactly this situation. – David Carlisle Feb 21 '17 at 16:39
• This is the way to go. The point is \item prints nothing, but waits until there is text. Therefore, a \begin{enumerate} just after \item can modify its label (and this is the very reason I said it was an XY problem). I'm not sure before can be used for that - I must investigate, but in the meanwhile you can use etoolbox` as suggested by David. – Javier Bezos Feb 21 '17 at 16:55