12

Is there any way to make LaTeX tolerate empty itemize/enumerate (i.e. no \item)?

Specifically, I would welcome any package/elegant hack that would gracefully "cancel" a list if no elements are found (instead of firing up a Latex Error).

Before jumping to the obvious answer (which I expect would be something along the lines of "don't use itemize if you don't have items to put in" ;)) please consider my use-case:

  • I want to format remotely stored elements (say, bibliographic items), which I can only access as an XML file.

    <elems>
      <bibelem><title>Cool result 1</title><author>joe</author></bibelem>
      <bibelem><title>Cool result 2</title><author>jim</author></bibelem>
    </elems>
    
  • I have a python script that downloads/parses the XML and outputs its content in a file bib.tex as a list of Latex macros-decorated data

    \BibElem{Cool result 1}{joe}
    \BibElem{Cool result 2}{jim}
    
  • Now, I want to grant the end-user complete control over the styling of her/his produced document, so the intended usage within Latex is something like

    \documentclass{article}
    \begin{document}
      \newcommand{\BibElem}[2]{\item {\em #1} by {#2}}
      \begin{itemize}
        \input{bib.tex}
      \end{itemize}
    \end{document}
    

The rationale behind this design choice is that the user should be restricted as little as possible in her/his styling choices. For instance, the user may either want to display the bibelems within a list as shown in the example, or may prefer a fancy-formatted tabular. On the other hand, the user should design the latex document once, and should be able to run it regardless of the amount of data produced by the source.

Therefore, the python script cannot make any assumption regarding the context in which its latex product will be included, and it should be up to the user to deal with empty bibliographies, i.e. with empty lists. How could one possibly do that?

Update: Werner proposed a nice solution that redefines the list environment to make Latex oblivious of the fact he is currently in a list. However, this only seems to work if the empty list is the last list in the document, as revealed by the following mwa:

\documentclass{article}
\makeatletter
\newenvironment{myitemize}
  {\itemize}
  {\@newlistfalse\enditemize}
\makeatother
\begin{document}
  % Empty Itemize
  \begin{myitemize}
  \end{myitemize}
  % Next non-nested itemize environment (can be itemize/enumerate/description) 
  \begin{myitemize}
    \item Arghh!
  \end{myitemize}
\end{document}
2
  • 2
    You shouldn't be using \include there, but \input
    – egreg
    Jul 25, 2013 at 19:24
  • Fixed, thanks + I answered the question below
    – Yann Ponty
    Jul 26, 2013 at 9:00

2 Answers 2

10

You should create your own myitemize environment that allows you to do this:

enter image description here

\documentclass{article}
\makeatletter
\newenvironment{myitemize}
  {\itemize\@newlistfalse}% \begin{myitemize}
  {\enditemize}% \end{myitemize}
\makeatother
\begin{document}
\noindent Here is some text.
\begin{myitemize}% A list with items
  \item An item
  \item Another item
\end{myitemize}
Here is some more text.
\begin{myitemize}% An empty list
\end{myitemize}
Here is a final piece of text.
\end{document}

The myitemize environment is exactly the same as itemize, except that it (re)sets the boolean condition \@newlistfalse. This is set to true (\@newlisttrue) at the start of a regular list (itemize, enumerate, ...), which causes the error when no \items are used.

This may cause problems with nested lists, although I don't think this fits your use case.

6
  • 2
    I think that moving \@newlistfalse to the end of myitemize might solve the issue with empty lists, or not?
    – yo'
    Dec 11, 2012 at 16:04
  • Isn't there some package that helps in creating derived itemize environments? Dec 12, 2012 at 9:41
  • Works perfectly for me, and can be trivially adapted to enumerate environments. Still does not seem to work for description (getting the ! LaTeX Error: Something's wrong--perhaps a missing \item.), which I thought was more or less a regular list. Any idea?
    – Yann Ponty
    Dec 12, 2012 at 11:27
  • @YannPonty: I'm not receiving any problems, even under the description environment (placing \@newlistfalse at the start or end). If you could reproduce the problem in the form of a minimal working example (MWE), add it to your original post.
    – Werner
    Dec 13, 2012 at 3:07
  • Actually, I was a bit trigger happy in accepting your initial solution. I must unaccept it as it seems to work only if the empty itemize is the last list of the document (see new mwa in my edited post)
    – Yann Ponty
    Jul 25, 2013 at 17:54
1

I solved my problem by combining Werner's proposal with simply turning off error messages, as described in How to avoid the "perhaps a missing \item." message in itemize/enumerate. The final hack reads as follows, and does not modify standard lists environment (which could be used by some packages):

\makeatletter
  \let\@oldnoitemerr\@noitemerr %Save the command definition                      
  \newcommand\noitemerroroff{\let\@noitemerr\relax}
  \newcommand\noitemerroron{\let\@noitemerr\@oldnoitemerr}
  % Redefine any other environment, as done by Werner
  \newenvironment{myitemize}
  {\itemize\noitemerroroff}
  {\enditemize\noitemerroron}
\makeatother
2
  • I think \noitemerroroff should be before \itemize. This would matches with the fact that after \enditemize you turn it back on. Actually, since it is within an environment (which forms a group) there is no need o turn it back on (although it makes your intent clearer by doing so). Oct 17, 2014 at 0:38
  • Taking into account @PeterGrill's comment about environments forming groups, you could shorten this to \makeatletter \newenvironment{myitemize}{\itemize\let\@noitemerr\relax}{\enditemize} \makeatother Oct 9, 2019 at 14:59

You must log in to answer this question.

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