11

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.

5 Answers 5

7

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} 

enter image description here

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

7
  • 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? Commented Sep 7, 2019 at 18:06
  • @Marcel see my edit. Commented Sep 7, 2019 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? Commented Sep 7, 2019 at 18:26
  • Actually, it looks like that happens if there is a newline in the itemize. Commented Sep 7, 2019 at 18:37
  • 1
    @Skillmon Probably Marcel is referring to a blank line between items. Try it. Commented Sep 7, 2019 at 20:24
9

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} 

enter image description here

2

I made a separate package to deal with it: https://github.com/Risele/LaTeX---autopunct Supports nesting lists, custom symbols (; and . by default). Compatible with eskdx.

\documentclass[]{article} \usepackage[]{autopunct} %symbols could be redefined as %\usepackage[sep={*},end={!}]{autopunct} \begin{document} \begin{itemize} \item External 1 \item External 2: \begin{enumerate} \item Internal 1 \item Internal 2 \item Internal Last \end{enumerate} \item External Last \end{itemize} \end{document} 

will provide

example

3
  • 1
    Please format the example code not as a picture, but enclose it with three back ticks ` (Markdown notation). Commented Sep 22 at 15:51
  • Please see my comment in your other answer. Commented Sep 22 at 16:06
  • Welcome to TeX.SX! Please don't post code fragments. Instead, put your fragments into a complete compilable document with \documentclass{...}, the required \usepackage's, \begin{document}, and \end{document}. Commented Sep 23 at 19:57
1

Since there is the new (2021) hook system, you are done with:

\AddToHook{env/itemize/end}{.} 

Side effect: an empty space before the dot. No idea how to remove it.

For the manual see /texlive/2021/texmf-dist/doc/latex/base/lthooks-doc.pdf , if you have a full installation of texlive.

1
  • Pointing out the manual is a big help! Commented Nov 12, 2022 at 16:38
0

I needed something like this for the beamer class and put together the following, largely based on the answers here and there. Hope it helps someone:

\documentclass{beamer} \setbeamertemplate{navigation symbols}{} % itemize symbol \setbeamertemplate{itemize item}[circle] % an inline enumerate environment \newcounter{oldenumi}% defined outside environment \newenvironment{enuminline}{% \setlength{\parindent}{-\itemsep}% \setbeamertemplate{enumerate item}{{\color{red}(\insertenumlabel)}~}% \def\itemizepunctuation{\def\itemizepunctuation{\ifhmode\unskip\fi;}}% \let\par\relax% \setcounter{oldenumi}{\value{enumi}}% \setcounter{enumi}{1}% \def\item{\itemizepunctuation\hspace{\itemsep}\usebeamertemplate{enumerate item}\stepcounter{enumi}}% \def\endenuminline{\ifhmode\unskip\fi.\hspace{\itemsep}}% \leavevmode% }{% \setcounter{enumi}{\value{oldenumi}}% } % an inline itemize environment \newenvironment{iteminline}{% \setlength{\parindent}{-\itemsep}% \setbeamertemplate{itemize item}{}% \def\itemizepunctuation{\def\itemizepunctuation{\ifhmode\unskip\fi;}}% \let\par\relax% \def\item{\itemizepunctuation\hspace{\itemsep}\usebeamertemplate{itemize item}}% \def\enditeminline{\ifhmode\unskip\fi.\hspace{\itemsep}}% \leavevmode% }{} \begin{document} \begin{frame} \frametitle{enuminline and iteminline} \begin{itemize} \item \textbf{enuminline environment}: text before: \begin{enuminline} \item A \item B \item C \end{enuminline} text after. paragraph before: \begin{enuminline} \item A \item B \item C \end{enuminline} paragraph after. \item \textbf{iteminline environment}: text before: \begin{iteminline} \item A \item B \item C \end{iteminline} text after. paragraph before: \begin{iteminline} \item A \item B \item C \end{iteminline} paragraph after. \end{itemize} \end{frame} \end{document} 

screenshot

1
  • I'm not in complete control of the spacing before and after the environment, but it'll have to do for now. Commented Apr 4 at 9:31

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.