2

I'm modifying an older university template that requires all table captions to be set in uppercase in the text, but does not require this in the list of tables. To automate the process, I've patched the corresponding parts of the template to use \MakeTextUppercase in the caption macros. This works until the option final is passed to the underlying book class, and hyperref clashes with with \MakeTextUppercase. Here's a MWE:

\documentclass[final]{book}

\usepackage{hyperref}
\usepackage{textcase}


\makeatletter
\renewenvironment{table}{%
   \let\@makecaption\@maketablecaption
   \@float{table}}{\end@float}
\long\def\@maketablecaption#1#2{
  \begin{center}
    \makebox[\linewidth]{
      \parbox{\linewidth}{
      \centering
      \MakeTextUppercase{#1}\\
      \MakeTextUppercase{#2}%\par
      }%
    }%
  \end{center}
}
\makeatother

\begin{document}
\listoftables
\chapter{One}

\begin{table}
  \caption{A Caption}
\end{table}

\end{document}

And here is the resulting error message that disappears if \MakeTextuppercase is removed:

! Undefined control sequence.
\@hyper@@anchor ...r@spot {#2#3}\let \put@me@back
                                                  \@empty \ifx \relax #2\rel...

l.30   \caption{A Caption}

I don't want to list of tables to have an uppercase table caption, the caption should only be in upper case in the running text. Is there a simple modification of the above example that allows for that? How do I apply \MakeTextUppercase to the text caption part only and not the caption part in the list of tables? I don't want to include additional packages, since this is all part of a larger template…

matz-e
  • 23
  • Maybe \caption[A Caption]{A CAPTION}. You could embody it as \newcommand\mycaption[1]{\caption[#1]{\uppercase{#1}}} – Steven B. Segletes Jun 19 '17 at 13:08
  • That is what I would like to automate on the template level, and don't want to have to do manually with all table captions. It makes changes a bit cumbersome. I'll see if I can redefine \caption only for the table environment. – matz-e Jun 19 '17 at 13:10
  • 2
    If you want it for ALL captions, then \let\svcaption\caption \renewcommand\caption[1]{\svcaption[#1]{\uppercase{#1}}} – Steven B. Segletes Jun 19 '17 at 13:11
  • The university requires figure captions to be all normal case, unfortunately. – matz-e Jun 19 '17 at 13:21
  • Are you saying the older template does the capitalization of captions, but that you don't want it? If that's the case, then change the template's \MakeTextUppercase{#1}\\\MakeTextUppercase{#2} to #1\\#2. – Steven B. Segletes Jun 19 '17 at 13:29
  • It was all manual, that is why I want to automate it. I just realized that I can actually just redefine the caption with \let\scaption\caption\renewcommand*{\caption}[2][\shortcaption]{\def\shortcaption{##2}\scaption[\shortcaption]{\MakeTextUppercase{##2}}}% in the table redefinition, after this comment, and it will leave figure captions unchanged. – matz-e Jun 19 '17 at 13:35
  • Use caption? Maybe? – cfr Jul 02 '17 at 03:08

1 Answers1

2

The second argument to \@makecaption (or in this case \@maketablecaption is not simply the input to the argument of \caption but a lot of different instructions with it. \MakeTextUppercase cannot cope with this.

It is much easier (and a cleaner solution IMHO, too) to use the caption package for tasks like this.

\documentclass[final]{book}

\usepackage{caption} \usepackage{textcase}

\DeclareCaptionLabelFormat{uppercase}{\MakeTextUppercase{#1~#2}} \DeclareCaptionTextFormat{uppercase}{\MakeTextUppercase{#1}} \captionsetup{ labelsep = newline , justification = centering , labelformat = uppercase , textformat = uppercase }

\usepackage{hyperref}

\begin{document}

\listoftables

\chapter{One}

\begin{table} \caption{A Caption} \end{table}

\end{document}

enter image description here


The code above formats all captions. If you want to only apply this to tables then use

\captionsetup[table]{
  ..
}
cgnieder
  • 66,645