3

I tried to adapt the answer to Automatically add a final period if argument of '\paragraph' does not end with a punctuation character as a way to automatically add a period to a caption when there is none. For reasons I don't understand, this does not work out of the box. What is wrong (see Fig. 3)?

\documentclass{article}

\usepackage{graphicx} \usepackage{caption}

\DeclareCaptionTextFormat{addpunct}{\maybeaddperiod{#1}} \captionsetup{textformat=addpunct}

\ExplSyntaxOn \NewDocumentCommand{\maybeaddperiod}{m} { \userninefourtwoninethree_maybeaddperiod:n { #1 } }

\cs_new_protected:Nn \userninefourtwoninethree_maybeaddperiod:n { \regex_match:nnTF { .*[!?.:] \Z } { #1 } { #1 } { #1. } } \ExplSyntaxOff

\begin{document}

\begin{figure}[h] \centering \includegraphics[height=2cm]{example-image} \caption{This is an image} \end{figure}

\begin{figure}[h] \centering \includegraphics[height=2cm]{example-image-a} \caption{This is image A} \end{figure}

\begin{figure}[h] \centering \includegraphics[height=2cm]{example-image-b} \caption{This is image B.} \end{figure}

\end{document}

enter image description here

user94293
  • 4,254

2 Answers2

6

The following code shows how we can remove optional dot from the end of the argument of a macro and then we can add single period to the output. All is done only by TeX primitive commands.

\def\maybeaddperiod #1{\mbaddperiodA #1\empty.\empty\end}
\def\mbaddperiodA #1.\empty #2\end{#1.}

\maybeaddperiod{Text} % prints: Text.

\maybeaddperiod{Foo. Bar.} % prints: Foo. Bar.

wipet
  • 74,238
  • 1
    Thank you. This is a nice trick. It however adds an unwanted period when there is a punctation different from "."; e.g., \maybeaddperiod{Text!} produces Text!. – user94293 May 15 '23 at 21:49
  • 1
    @user94293 You can remove the !. and ?. pair from the argument by very similar trick. I leave this as an exercise for the reader. – wipet May 16 '23 at 03:44
4

If you add \tl_show:n{#1} in the code for \userninefourtwoninethree_maybeaddperiod:n, you will see that the first call shows

> \ignorespaces \caption@makeanchor {This is an image}.

For its purposes, caption wraps the actual caption text as an argument to \caption@makeanchor.

You see that the argument examined by \maybeaddperiod never ends with a period, but always with a }.

Change into

\cs_new_protected:Nn \userninefourtwoninethree_maybeaddperiod:n
 {
  \regex_match:nnTF { .*[\!\?\.\:] \} \Z } { #1 } { #1 } { #1. }
 }

Full example:

\documentclass{article}

\usepackage{graphicx} \usepackage{caption}

\DeclareCaptionTextFormat{addpunct}{\maybeaddperiod{#1}} \captionsetup{textformat=addpunct}

\ExplSyntaxOn \NewDocumentCommand{\maybeaddperiod}{m} { \userninefourtwoninethree_maybeaddperiod:n { #1 } }

\cs_new_protected:Nn \userninefourtwoninethree_maybeaddperiod:n { \regex_match:nnTF { .*[!?.:] } \Z } { #1 } { #1 } { #1. } } \ExplSyntaxOff

\begin{document}

\begin{figure}[h] \centering \includegraphics[height=2cm]{example-image} \caption{This is an image} \end{figure}

\begin{figure}[h] \centering \includegraphics[height=2cm]{example-image-a} \caption{This is image A} \end{figure}

\begin{figure}[h] \centering \includegraphics[height=2cm]{example-image-b} \caption{This is image B.} \end{figure}

\end{document}

enter image description here

egreg
  • 1,121,712