[Tex/LaTex] Redefine \item command to not typeset some items

#enumeratemacros

Suppose I want to have an enumerate environment, in which I don't want to typeset certain items. I can obtain this in LateX using (let's ignore the problem that the numbers are wrong, this is easy to fix)

\documentclass{article}
\newcounter{excluded}
\newcommand{\exclude}[1]{\setcounter{excluded}{#1}}
\let\Item\item
\renewcommand{\item}[1]{\ifnum\value{enumi}=\value{excluded}%
   \stepcounter{enumi}\else\Item #1\fi}
\begin{document}

\begin{enumerate}
\exclude{2}
\item{This is the first item}
\item{This should not be shown}
\item{This should be shown}
% I would like to be able to use
%\item This is an item without \{ and \}. Would make the course look nicer.
\end{enumerate}
\end{document}

The problem with this setup is that the item text now needs to be an argument to \item, i.e. I need curly brackets around the text. It would be good if I could still use

\item This is the first item

but I can't get it to work.

Any elegant way around this?

Best Answer

Using some ideas from Order items in enumerate environment automatically, the following MWE provides a myenumerate environment where you pass an optional argument as a number, which then excludes that specific item from the list.

enter image description here

\documentclass{article}
\usepackage{environ}% http://ctan.org/pkg/environ
\makeatletter
\newcounter{listcount}
\let\olditem\item% Store regular \item macro
\NewEnviron{myenumerate}[1][]{%
  \if\relax\detokenize{#1}\relax% A normal list (https://tex.stackexchange.com/q/53068/5764)
  \else% A reordered list
    \g@addto@macro{\BODY}{\item\relax\item}% Used to delimit the items; last item identified by \item\relax\item
    \setcounter{listcount}{0}% Restart at the beginning of myenumerate
    \def\item##1\item{% Redefine \item to capture contents
      \def\optarg{##1}%
      \expandafter\ifx\optarg\relax\else% Last item not reached
        \stepcounter{listcount}% Next item being processed
        \ifnum\value{listcount}=#1\stepcounter{enumi}\else% Don't print this item, just step enumi
          \olditem ##1% Print regular item
        \fi
        \expandafter\item% Recursively continue processing items
      \fi
    }%
  \fi
  \enumerate\BODY\endenumerate% Process environment
}
\makeatother
\begin{document}
\begin{myenumerate}
  \item This is the first item.
  \item This is the second item.
  \item This is the third item.
\end{myenumerate}

\begin{myenumerate}[2]
  \item This is the first item.
  \item This is the second item.
  \item This is the third item.
\end{myenumerate}
\end{document}

It could be generalized to process a list of items to be discarded. With a slight modification and the introduction of etoolbox's list processing, the following processes a sequence of numbers at every \item and either sets the item or not.

enter image description here

\documentclass{article}
\usepackage{environ,etoolbox}% http://ctan.org/pkg/{environ,etoolbox}
\makeatletter
\newif\ifprintitem% Condition to print item or not
\newcounter{listcount}
\let\olditem\item% Store regular \item macro
\NewEnviron{myenumerate}[1][]{%
  \if\relax\detokenize{#1}\relax% A normal list
  \else% A reordered list
    \g@addto@macro{\BODY}{\item\relax\item}% Used to delimit the items; last item identified by \item\relax\item
    \setcounter{listcount}{0}% Restart at the beginning of myenumerate
    \def\item##1\item{% Redefine \item to capture contents
      \def\optarg{##1}%\show\optarg%
      \expandafter\ifx\optarg\relax\else% Last item not reached
        \stepcounter{listcount}% Next item being processed
        \printitemtrue% Always print item
        \renewcommand*{\do}[1]{\ifnum\value{listcount}=####1 \printitemfalse\fi}%
        \expandafter\docsvlist\expandafter{#1}% Process list of possible exclusions
        \ifprintitem
          \olditem ##1% Print regular item
        \else\stepcounter{enumi}% Don't print this item, just step enumi
        \fi
        \expandafter\item% Recursively continue processing items
      \fi
    }%
  \fi
  \enumerate\BODY\endenumerate% Process environment
}
\makeatother
\begin{document}
\begin{myenumerate}
  \item This is the first item.
  \item This is the second item.
  \item This is the third item.
  \item This is the fourth item.
  \item This is the fifth item.
  \item This is the sixth item.
  \item This is the seventh item.
  \item This is the eighth item.
\end{myenumerate}

\begin{myenumerate}[2,3,8]
  \item This is the first item.
  \item This is the second item.
  \item This is the third item.
  \item This is the fourth item.
  \item This is the fifth item.
  \item This is the sixth item.
  \item This is the seventh item.
  \item This is the eighth item.
\end{myenumerate}
\end{document}
Related Question