# Automatically end list item with proper punctuation (semicolon, period)

If I have a list using itemize, I want to automatically end each \item with a semicolon (for all but the last item) or a period (for the last item).

For example:

\begin{itemize}
\item One
\item Two
\item Three
\end{itemize}


Should display as

• One;
• Two;
• Three.

Is there any way to make that happen? I looked around but didn't really find anything. The closest I could find was this, but that seems to be a fancy, custom list rather than a vanilla itemize.

I'm not sure whether it is a good idea to do this, maybe you should use a different environment for that. The following patches \item inside every itemize environment to add a semicolon after the first, and the \enditemize macro is changed to add a dot. You can no longer nest itemize environments with this simple approach. All in all I think this creates more problems than it solves...

\documentclass[]{article}

\usepackage{etoolbox}
\AtBeginEnvironment{itemize}
{%
\def\itemizepunctuation{\def\itemizepunctuation{\ifhmode\unskip\fi;}}%
\pretocmd\item{\itemizepunctuation}{}{}%
\pretocmd\enditemize{\ifhmode\unskip\fi.}{}{}%
}

\newenvironment{punctitemize}
{%
\itemize
\def\itemizepunctuation{\def\itemizepunctuation{\ifhmode\unskip\fi;}}%
\pretocmd\item{\itemizepunctuation}{}{}%
\pretocmd\enditemize{\ifhmode\unskip\fi.}{}{}%
}
{%
\enditemize
}

\begin{document}
\begin{itemize}
\item One
\item Two
\item Three
\end{itemize}

\begin{punctitemize}
\item One
\item Two
\item Three
\end{punctitemize}
\end{document}


EDIT: added the environment approach, nesting is still not supported.

• Thanks for the answer. When you say use a different environment, do you mean add a new punctuateditemize (for example) rather than overriding the default itemize? If so, could you give an example of what this would look like? – Marcel Sep 7 '19 at 18:06
• @Marcel see my edit. – Skillmon Sep 7 '19 at 18:11
• Thanks for the edit. I am nitpicking now, but if I have a newline in the \item, the semicolon / period is on its own line. I don't suppose there is any way to fix that? – Marcel Sep 7 '19 at 18:26
• Actually, it looks like that happens if there is a newline in the itemize. – Marcel Sep 7 '19 at 18:37
• @Skillmon Probably Marcel is referring to a blank line between items. Try it. – egreg Sep 7 '19 at 20:24

You can use xparse, absorbing the whole contents and splitting it at \item; then add a semicolon (and the removed \item) between items.

The processing is complicated by the fact that a blank line between items would introduce a spurious paragraph before the semicolon or the final period, so we need to remove blanks and \par tokens at the end of each item.

Thus the sequence obtained by splitting at \item is mapped to “purify” it.

I added enumitem for maximum flexibility.

\documentclass{article}
\usepackage{xparse}
\usepackage{enumitem}

\ExplSyntaxOn

\NewDocumentEnvironment{autoitemize}{O{} +b}
{
\begin{itemize}[#1]
\marcel_autoitemize:n { #2 }
\end{itemize}
}{}

\seq_new:N \l__marcel_autoitemize_items_seq
\seq_new:N \l__marcel_autoitemize_items_nopar_seq
\tl_new:N \l__marcel_autoitemize_item_tl

\cs_new_protected:Nn \marcel_autoitemize:n
{
% split the contents at \item; this also removes blanks at either end
\seq_set_split:Nnn \l__marcel_autoitemize_items_seq { \item } { #1 }
% remove the first (empty) item
\seq_pop_left:NN \l__marcel_autoitemize_items_seq \l_tmpa_tl
% we need to remove trailing \par tokens
\seq_clear:N \l__marcel_autoitemize_items_nopar_seq
\seq_map_function:NN \l__marcel_autoitemize_items_seq \__marcel_autoitemize_purify:n
% start the first item
\item
% use the sequence, putting a semicolon and \item between items
\seq_use:Nn \l__marcel_autoitemize_items_nopar_seq { ; \item }
% end up with a period
.
}

\cs_new_protected:Nn \__marcel_autoitemize_purify:n
{
\tl_set:Nn \l__marcel_autoitemize_item_tl { #1 }
\regex_replace_once:nnN { \s* \c{par}* \Z } { } \l__marcel_autoitemize_item_tl
\seq_put_right:NV \l__marcel_autoitemize_items_nopar_seq \l__marcel_autoitemize_item_tl
}

\ExplSyntaxOff

\begin{document}

\begin{autoitemize}
\item One

\item Two
\item Three
\end{autoitemize}

\begin{autoitemize}[label=--]
\item One
\item Two
\item Three
\end{autoitemize}

\end{document}