4

Presently, I accomplish this with a combination of three user-defined lists. Two of these (examlist for single-digit labels, and exxamlist for double-digit labels) control the top-level items. The third (examlistii) controls the sub-level items for both of the top-level cases.

The effect (as demonstrated below) is precisely what I want. The means, though, seems barbaric. I'd like to accomplish this using a "single" list, perhaps using the 'enumitem' package, but I can't seem to turn the trick with the list keys. Any assistance would be appreciated.

\documentclass{article}

%examlist
\newcounter{exami}
\newenvironment{examlist}
{\begin{list}{\arabic{exami}.\hfill}
{\usecounter{exami}
\setlength{\labelwidth}{3ex}
\setlength{\labelsep}{0ex}
\setlength{\leftmargin}{3ex}}}
{\end{list}}

%exxamlist
\newcounter{exxam}
\newenvironment{exxamlist}
{\begin{list}{\arabic{exxam}.\hfill}
{\usecounter{exxam}\setcounter{exxam}{9}
\setlength{\labelwidth}{4.2ex}
\setlength{\labelsep}{0ex}
\setlength{\leftmargin}{4.2ex}}}
{\end{list}}

%examlistii
\newcounter{examii} 
\newenvironment{examlistii}
{\begin{list}{\alph{examii})\hfill}
{\usecounter{examii}
\setlength{\labelwidth}{3ex} 
\setlength{\labelsep}{0ex}
\setlength{\leftmargin}{3ex}}}
{\end{list}}

\begin{document}
\noindent
This is the surrounding text. The following list has flush-left labels.   

\begin{examlist}
  \item Problem 1
  \item Problem 2

  \begin{examlistii}
    \item Part (a)
    \item Part (b)
  \end{examlistii}

  \item Problem 3
\end{examlist}

\begin{exxamlist}
  \item Problem 10

  \begin{examlistii}
    \item Part (a)
    \item Part (b)
  \end{examlistii}

  \item Problem 11
\end{exxamlist}
\end{document}

2 Answers 2

2

Here's your lists with enumitem:

\documentclass{article}
\usepackage{enumitem}
%examlist
\newlist{examlist}{enumerate}{1}
\setlist[examlist,1]{
  align=left,
  labelwidth=1.5em,
  labelsep=0pt,
  leftmargin=1.5em,
  label=\arabic*.,
}
\newlist{exxamlist}{enumerate}{1}
\setlist[exxamlist,1]{
  align=left,
  labelwidth=2em,
  labelsep=0pt,
  leftmargin=2em,
  label=\arabic*.,
  before=\setcounter{exxamlisti}{9},
}

%examlistii
\newlist{examlistii}{enumerate}{1}
\setlist[examlistii,1]{
  align=left,
  labelwidth=1.5em,
  labelsep=0pt,
  leftmargin=1.5em,
  label=\alph*),
  nosep,
}

\begin{document}
\noindent
This is the surrounding text. The following list has flush-left labels.   

\begin{examlist}
  \item Problem 1
  \item Problem 2

  \begin{examlistii}
    \item Part (a)
    \item Part (b)
  \end{examlistii}

  \item Problem 3
\end{examlist}

\begin{exxamlist}
  \item Problem 10

  \begin{examlistii}
    \item Part (a)
    \item Part (b)
  \end{examlistii}

  \item Problem 11
\end{exxamlist}
\end{document}

enter image description here

I only changed the ex units into em, which is preferable for horizontal measures. A digit usually is 0.5em wide.

You can get the work with just one environment:

\documentclass{article}
\usepackage{enumitem}

\newlist{examlist}{enumerate}{2}
\setlist[examlist,1]{
  align=left,
  labelwidth=2em,
  labelsep=0pt,
  leftmargin=2em,
  label=\protect\makebox[1em][r]{\arabic*}.,
  ref=\arabic*,
}
\setlist[examlist,2]{
  align=left,
  labelwidth=2em,
  labelsep=0pt,
  leftmargin=2em,
  label=\alph*),
  nosep,
}

\begin{document}
\noindent
This is the surrounding text. The following list has flush-left labels.   

\begin{examlist}
  \item Problem 1
  \item Problem 2

  \begin{examlist}
    \item Part (a)
    \item Part (b)
  \end{examlist}

  \item Problem 3
\end{examlist}

\begin{examlist}\setcounter{examlisti}{8}
  \item Problem 9 

  \item Problem 10

  \begin{examlist}
    \item Part (a)
    \item Part (b)
  \end{examlist}

  \item Problem 11
\end{examlist}
\end{document}

The problem are lists with less than nine items. One can think to a mechanism that checks whether a given list has more than nine items and (at the next pass) adjusts the parameters to take care of this. But this would make different lists of problems, maybe even on facing pages.

Here's the result where in the final environment the numbering has been made to start from 9 to show the effect.

enter image description here

For completeness, here's the solution where lists with less than nine items have the number flush left, while for lists with more than nine items, only the two digit figures are flush left.

\documentclass{article}
\usepackage{enumitem,refcount}

\makeatletter
\newlist{xexamlist}{enumerate}{2}
\setlist[xexamlist,1]{
  align=left,
  labelwidth=\examlist@margin,
  labelsep=0pt,
  leftmargin=\examlist@margin,
  label=\protect\makebox[\examlist@label][r]{\arabic*}.,
  ref=\arabic*,
}
\setlist[xexamlist,2]{
  align=left,
  labelwidth=2em,
  labelsep=0pt,
  leftmargin=2em,
  label=\alph*),
  nosep,
}

\newif\if@examlist
\newcounter{count@examlist}
\newenvironment{examlist}
 {\if@examlist
    \@examlistfalse
  \else
    \setup@examlist\@examlisttrue
  \fi
  \xexamlist}
 {\if@examlist\else
    \edef\@currentlabel{\the\value{xexamlisti}}%
    \label{examlist@@@\thecount@examlist}%
  \fi
  \endxexamlist}
\def\setup@examlist{%
  \stepcounter{count@examlist}%
  \ifnum\getrefnumber{examlist@@@\thecount@examlist}>9
    \def\examlist@margin{2em}%
    \def\examlist@label{1em}%
  \else
    \def\examlist@margin{1.5em}%
    \def\examlist@label{.5em}%
  \fi
}
\makeatother

\begin{document}
\noindent
This is the surrounding text. The following list has flush-left labels.   

\begin{examlist}
  \item Problem 1
  \item Problem 2

  \begin{examlist}
    \item Part (a)
    \item Part (b)
  \end{examlist}

  \item Problem 3
\end{examlist}

\begin{examlist}\setcounter{xexamlisti}{8}
  \item Problem 9

  \item Problem 10

  \begin{examlist}
    \item Part (a)
    \item Part (b)
  \end{examlist}

  \item Problem 11
\end{examlist}
\end{document}

enter image description here

3
  • egreg, this produces the desired effect, but I was hoping to accomplish it with a "single" list, which I didn't really make clear in my original post. Let me edit my question. Commented Nov 28, 2014 at 0:53
  • @steven_nevets You don't want that the one digit numbers are flush left, at least when the list has more than nine items. But in my opinion the lists should be the same across the document, so you have not much choice, have you?
    – egreg
    Commented Nov 28, 2014 at 9:29
  • Hi egreg. For reasons that I don't want to bore you with, I require ALL labels (single-digit, double-digit, top-level, and sub-level) to be flush left. I'd hoped to accomplish this with a single list, and your and Werner's solutions demonstrate that this is not a trivial exercise. Ultimately, I think I shall select your original solution (using multiple lists) as my preferred approach. Thank you for your thoughtful and expert attention to my problem. Commented Nov 29, 2014 at 20:19
3

Yes, enumitem can do this in a jiffy. The two nested lists can be modified globally using

\usepackage{enumitem,showframe}
\setlist[enumerate,1]{
  label={\arabic*.},
  ref={\arabic*},
  labelindent=0pt,
  widest={10.},
  leftmargin=*,
  align=left}
\setlist[enumerate,2]{
  label={\alph*)}, 
  ref={\alph*}}

This sets the first enumerate level numbering/label (and reference, if needed) to be \arabic., while the second level is \alph):

enter image description here

\documentclass{article}
\usepackage{enumitem,showframe}
\setlist[enumerate,1]{
  label={\arabic*.},
  ref={\arabic*},
  labelindent=0pt,
  widest={10.},
  leftmargin=*,
  align=left}
\setlist[enumerate,2]{
  label={\alph*)}, 
  ref={\alph*}}

\begin{document}
This is the surrounding text. The following list has flush-left labels.   

\begin{enumerate}
  \item Problem~1

  \item Problem~2

  \begin{enumerate}
    \item Part~(a)

    \item Part~(b)
  \end{enumerate}

  \item Problem~3

  \setcounter{enumi}{9}% Just for this example

  \item Problem~10

  \begin{enumerate}
    \item Part~(a)

    \item Part~(b)
  \end{enumerate}

  \item Problem~11
\end{enumerate}
\end{document}

You can also create your own list names using \newlist. See the enumitem documentation for more information.


It's really unnecessary (in my opinion) to have varying indentations. Here's one way of achieving that though:

enter image description here

\documentclass{article}
\usepackage{enumitem,showframe}
\newlist{exami}{enumerate}{1}
\setlist[exami,1]{
  label={\arabic*.},
  ref={\arabic*},
  labelindent=0pt,
  widest={9.},
  leftmargin=*,
  align=left}
\newlist{examii}{enumerate}{1}
\setlist[examii,1]{
  label={\alph*)}, 
  ref={\alph*}}

\newlength{\indentdiff}
\setlength{\indentdiff}{1.2ex}

\makeatletter
\let\olditem\item
\renewcommand{\item}{%
  \ifnum\pdfstrcmp{\@enumctr}{examii}=0
    \ifnum\value{examii}<9
      \olditem
    \else
      \end{exami}
      \begin{exami}[widest={10.}, start=10]
        \olditem
        \let\item\olditem
    \fi
  \else
    \olditem
  \fi
}
\makeatother

\begin{document}
This is the surrounding text. The following list has flush-left labels.   

\begin{exami}
  \item Problem~1 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce 
  dictum lacus velit, et malesuada enim fringilla eget. Nulla id sem eget odio fringilla 
  ornare ac non urna. Phasellus id sem tincidunt, posuere ante sed, efficitur risus. 
  Phasellus sagittis augue non diam lacinia volutpat. Duis tempus arcu nec arcu porttitor, 
  sit amet gravida velit pretium.

  \item Problem~2 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce 
  dictum lacus velit, et malesuada enim fringilla eget. Nulla id sem eget odio fringilla 
  ornare ac non urna. Phasellus id sem tincidunt, posuere ante sed, efficitur risus. 
  Phasellus sagittis augue non diam lacinia volutpat. Duis tempus arcu nec arcu porttitor, 
  sit amet gravida velit pretium.

  \begin{examii}
    \item Part~(a)

    \item Part~(b)
  \end{examii}

  \item Problem~3 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce 
  dictum lacus velit, et malesuada enim fringilla eget. Nulla id sem eget odio fringilla 
  ornare ac non urna. Phasellus id sem tincidunt, posuere ante sed, efficitur risus. 
  Phasellus sagittis augue non diam lacinia volutpat. Duis tempus arcu nec arcu porttitor, 
  sit amet gravida velit pretium.

  \setcounter{examii}{9}% Just for this example

  \item Problem~10 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce 
  dictum lacus velit, et malesuada enim fringilla eget. Nulla id sem eget odio fringilla 
  ornare ac non urna. Phasellus id sem tincidunt, posuere ante sed, efficitur risus. 
  Phasellus sagittis augue non diam lacinia volutpat. Duis tempus arcu nec arcu porttitor, 
  sit amet gravida velit pretium.

  \begin{examii}
    \item Part~(a)

    \item Part~(b)
  \end{examii}

  \item Problem~11 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce 
  dictum lacus velit, et malesuada enim fringilla eget. Nulla id sem eget odio fringilla 
  ornare ac non urna. Phasellus id sem tincidunt, posuere ante sed, efficitur risus. 
  Phasellus sagittis augue non diam lacinia volutpat. Duis tempus arcu nec arcu porttitor, 
  sit amet gravida velit pretium.
\end{exami}
\end{document}

The idea behind this solution is to redefine \item to close down the existing exami environment and restart a new one with slightly different parameters (widest={10.} and start=10) before self-redefining to the original \item (\olditem).

Here is a pseudo-code representation of the redefinition of \item:

We will need the current definition of \item later, so 
  make a duplicate of \item and store it in \olditem (\let\olditem\item)
With a copy stored, change \item to now do the following:
  if (the enumeration counter being used is "examii") then
    if (the value of counter "examii" < 9) then
      \olditem (remember, this is the original definition of \item that we stored)
    else
      end environment exami (\end{exami})
      begin environment exami (\begin{exami}) with parameters
          that will start at 10 (start = 10); and
          that will only be as wide as "10." (widest = {10.})
        \olditem (the original definition of \item that we stored)
        Immediately reset \item to what it was before (completely destroying this new 
          redefinition since it is no longer needed)
    end if
  else
    \olditem (the original definition of \item that we stored)
  end if

Note that we check whether we're using the enumeration counter examii even though we're in environment exami. That's because exami is a regular enumerate-like environment (because of \newlist{exami}{enumerate}{1}) and enumerate-like environment <list> is automatically assigned a level 1 counter called <list>i; a level 2 counter called <list>ii; ... with a lowercase Roman suffix indicating the level counter.

10
  • Werner, this looked promising, but the labels are not ALL flush-left as I require - the single-digit labels float right in your example. Please see my MWI to see the desired effect. Thanks for your help. Commented Nov 28, 2014 at 0:48
  • @steven_nevets: See the updated answer. I've added the align=left key to the list of other keys for level 1 in enumerate.
    – Werner
    Commented Nov 28, 2014 at 0:55
  • This is close, but the space between the single-digit labels and items is larger than the space between the double-digit labels and items. I'd like the space to be the same as in my MWI. This results in two different left-margins, of course, but that's what I'm looking for. Commented Nov 28, 2014 at 1:03
  • I'd also like the 2nd level labels to be flush left with the text of their parent items. Commented Nov 28, 2014 at 4:36
  • @steven_nevets: See my updated answer.
    – Werner
    Commented Nov 28, 2014 at 6:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .