Automatically end list item with proper punctuation (semicolon, period)
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}
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.