13

I have a command \Notes which simply is a caption under a figure:

\newcommand{\Notes}[1]{\captionsetup{position=below}\caption*{#1}}

I would like the punctuation to be consistent in the caption, always closing with a full stop. That is, I'd like the following MWE to have Notes. in the first figure, as well as Notes with full stop. (as is) in the second figure. Can LaTeX enforce this policy?

\documentclass{scrartcl}
\usepackage{caption}
\usepackage{graphicx}

\newcommand{\Notes}[1]{\captionsetup{position=below}\caption*{#1}}

\begin{document}

\begin{figure}
\caption{Actual caption}
\includegraphics{Example-image}
\Notes{Notes}
\end{figure}

\begin{figure}
\caption{Another caption}
\includegraphics{Example-image}
\Notes{Notes with full stop.}
\end{figure}

\end{document}
  • 3
    This is a really good question – Au101 Oct 19 '16 at 2:17
8

It's as easy as loading amsthm, which defines an \@addpunct command, which will insert its argument only if no punctuation precedes it.

\documentclass{scrartcl}
\usepackage{amsthm}% yes, that's it!
\usepackage{caption}
\usepackage{graphicx}

\makeatletter
\newcommand{\Notes}[1]{\captionsetup{position=below}\caption*{#1\@addpunct{.}}}
\makeatother

\begin{document}

\begin{figure}[htp]
\centering
\caption{Actual caption}
\includegraphics[width=4cm]{example-image}
\Notes{Notes}
\end{figure}

\begin{figure}[htp]
\centering
\caption{Another caption}
\includegraphics[width=4cm]{example-image}
\Notes{Notes with full stop.}
\end{figure}

\begin{figure}[htp]
\centering
\caption{Another caption}
\includegraphics[width=4cm]{example-image}
\Notes{Notes with exclamation mark!}
\end{figure}

\end{document}

enter image description here

|improve this answer|||||
7

The following example evaluates the space factor at the end of the caption to detect, if there was a punctuation char before.

\documentclass[a5paper]{scrartcl}
\usepackage[paperheight=7cm]{geometry}% for smaller image in answer for TeX.SX
\usepackage{caption}
\usepackage{graphicx}

\newcommand{\Notes}[1]{\captionsetup{position=below}\caption*{#1}}

\makeatletter
\newcommand*{\RedefCaption}{%
  \let\org@caption\@caption
  \let\@caption\dot@caption
}
\def\dot@caption#1[#2]#3{%
  \dot@test@def\tmp@a{#2}%
  \dot@test@def\tmp@b{#3}%
  \org@caption{#1}[\tmp@a]\tmp@b
}
\newcommand*{\dot@test@def}[2]{%
  \begingroup
    % Set space factor to values larger than 1000 for punctuation characters
    \nonfrenchspacing
    % Set space factor to 1000 for upper case letter, which usually
    % have 999. This supports abbreviations: After an uppercase letter
    % the space factor is 999, a period would want it to set to 3000,
    % but TeX does not increase over 1000 in one step. Thus, the
    % space factor is 1000 after "A.".
    % Here, we do not want to support abbreviations, because
    % a period needs to be omitted, if there was a dot before,
    % regardless if the previous dot marks the end of the sentence
    % or belongs to an abbreviation.
    \count@=`\@\relax
    \@whilenum\count@<`\Z\do{%
      \advance\count@\@ne % \@ne = 1
      \sfcode\count@=\@m % \@m = 1000
    }%
    \sbox0{#2%
      \ifnum\spacefactor>\@m
        \global\let\dot@found=Y%
      \else
        \global\let\dot@found=N%
      \fi
    }%
  \endgroup
  \if\dot@found Y%
    \def#1{#2}%
  \else
    \def#1{#2.}%
  \fi
}
\AtBeginDocument{\RedefCaption}
\makeatother

\begin{document}

\begin{figure}
\caption{Actual caption}
% \includegraphics{Example-image}
\Notes{Notes}
\end{figure}

\begin{figure}
\caption{Another caption}
% \includegraphics{Example-image}
\Notes{Notes with full stop.}
\end{figure}

\end{document}

Result

|improve this answer|||||
3

(Your requirement wasn't entirely clear to me. I assume that you want periods (full stops) at the ends of the arguments of both \caption and \Notes. If it's only needed for \Notes, I trust you'll be able to figure out how to modify the code shown below.)

Here's a LuaLaTeX-based solution. It adds missing periods ("full stops") at the end of the arguments of \caption and \Notes instructions. It works by scanning the input, at a very early stage of processing, for instances of \caption{...} and \Notes{...} and examining the arguments; if they lack a period at the end, a period is inserted.

The only requirement for the input stream is that the commands \caption and \Notes and their respective arguments all be on the same line. I trust that this doesn't constitute a binding restriction.

enter image description here

%% Compile with LuaLaTeX
\documentclass{scrartcl}
\usepackage{caption}

\usepackage{luacode}
\begin{luacode*}
function add_period ( s )
  if string.find ( s , "\\caption%s-{" ) then
    s = string.gsub ( s , "(\\caption)%s-(%b{})", 
           function ( capt , argu )
              argu = string.sub ( argu , 2 , -2 )
              if not string.find ( argu , "%.%s-$" ) then 
                argu = argu .. "."
              end
              return ( capt .. "{" .. argu .. "}" )
           end )
  end
  if string.find ( s , "\\Notes%s-{" ) then
    s = string.gsub ( s , "(\\Notes)%s-(%b{})", 
           function ( capt , argu )
              argu = string.sub ( argu , 2 , -2 )
              if not string.find ( argu , "%.%s-$" ) then 
                argu = argu .. "."
              end
              return ( capt .. "{" .. argu .. "}" )
           end )
  end
  return ( s ) 
end
luatexbase.add_to_callback( "process_input_buffer" , add_period , "add_period" )
\end{luacode*}        

\newcommand{\Notes}[1]{\captionsetup{position=below}\caption*{#1}}

\begin{document}

\begin{figure}[ht!]
\caption {Actual caption}
\Notes{Notes}
\end{figure}

\begin{figure}[h!]
\caption {Another caption. } \Notes {Notes with full stop. }
\end{figure}

\end{document}
|improve this answer|||||
1

Use \@addpunct (egreg's) is clearly better/simpler than this (+1). But for the for the sake of completeness, with the xstring package you can check the end of some string with \IfEndWith.

For simplicity, assuming that you only check for full stops, not other punctuation signs, and assuming no punctuation signs in sort captions, the macro could be:

\documentclass[12pt]{article}
\usepackage{xstring,xifthen}
\newcommand\Note[2][]{
\ifthenelse{\isempty{#1}}{%
\IfEndWith{#2}{.}{\caption[#2]{#2}}{\caption[#2.]{#2.}}}{%
\IfEndWith{#2}{.}{\caption[#1.]{#2}}{\caption[#1.]{#2.}}}}
\begin{document}
\begin{figure}
\Note{Caption with period.}
\Note{Caption without period}
\Note[No]{No, without period}
\Note[Yes]{Yes, with period.}
\end{figure}
\listoffigures
\end{document}

mwe

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.