# How to append at the end of each \item?

I have an input file with a lot of items enclosed in enumerate. For an unknown reason, I have to append something (by calling a macro) at the end of each item.

I don't want to modify the existing input file by surrounding the contents of each item with a pair of curly braces as implemented in the following MWE.

\documentclass{article}

\def\message{This is the end of item.}

\let\olditem=\item
\def\item#1{\olditem#1\newline\message}

\begin{document}
\begin{enumerate}
\item {This is a book.}
\end{enumerate}
\end{document}


# Questions

How to append a macro call at the end of each item but without having to surround each item contents with a pair of curly braces?

With the help of l3regex we can get rid of blank lines preceding \item or \end{enumerate} and add \mymessage in the appropriate spots.

\documentclass{article}
\usepackage{environ,xparse,l3regex}

\let\latexenumerate\enumerate
\let\endlatexenumerate\endenumerate
\newcommand{\mymessage}{\mbox{}\\End of item}

\ExplSyntaxOn
\RenewEnviron{enumerate}{%
% remove all space tokens and \par preceding \item and prepend \mymessage
\regex_replace_all:nnN { (\c{par}|\s)* \c{item} } { \c{mymessage} \c{item} } \BODY
% remove the first \mymessage
\regex_replace_once:nnN { \c{mymessage} } { } \BODY
% remove the trailing space tokens and \par and add \mymessage
\regex_replace_once:nnN { (\c{par}|\s)* \Z } { \c{mymessage} } \BODY
% do the standard enumerate
\latexenumerate\BODY\endlatexenumerate
}
\ExplSyntaxOff

\begin{document}
\begin{enumerate}

\item This is a book.

\item Other stuff

\item Well and here it goes again

\end{enumerate}
\end{document}


Of course the result would be the same for

\begin{enumerate}
\item This is a book.
\item Other stuff
\item Well and here it goes again
\end{enumerate}


and I added the blank lines only by way of example.

Here is a way without packages. One must be careful to avoid a blank line before \item invocations. The MWE shows how it is set up to affect only enuemerate and not related environments like itemize.

\documentclass{article}
\def\message{This is the end of item.}
\let\svitem\item
\let\svenumerate\enumerate
\let\svendenumerate\endenumerate%
\renewenvironment{enumerate}{%
\def\newitem{\message\svitem}\svenumerate%
\def\item{\let\item\newitem\svitem}%
}{
\message\svendenumerate%
}
\begin{document}
\begin{enumerate}
\item A
\item B
\item[x] C
\item
\item D
\end{enumerate}

\begin{itemize}
\item x
\item y
\item z
\end{itemize}

\begin{enumerate}
\item P
\item Q
\item[x] R
\item
\item T
\end{enumerate}

\end{document}


Not the best way, but it works for the first level of enumeration, however, not for empty \item commands.

I've prepended \item with \newline (Is it really necessary?) -- this does not work for the first item, of course and the last \item will not get it unless, \endenumerate is prepended to.

\documentclass{article}

\def\mymessage{This is the end of item.}

\usepackage{xpatch}

\makeatletter
\xpretocmd{\item}{\ifnum\value{enumi} > 0  \newline\mymessage\fi}{}{}
\xpretocmd{\endenumerate}{\newline\mymessage}{}{}
\makeatother
\begin{document}
\begin{enumerate}
\item This is a book.
\item Other stuff
\item Well and here it goes again
\end{enumerate}
\end{document}

• And possibly avoiding to redefine the primitive \message. ;-) This won't work if there is a blank line before some \item – egreg Oct 27 '15 at 18:00
• @egreg: Oh, yes of course ;-) – user31729 Oct 27 '15 at 18:01
• Does your implementation break itemize? – Steven B. Segletes Oct 27 '15 at 18:12
• @StevenB.Segletes: Yes, unfortunately, but I think I can cure this – user31729 Oct 27 '15 at 20:51