Title case an acronym
\capitialisewords
works by applying \makefirstuc
to each space-separated element of its argument. In the case of \capitalisewords{\gls{src}}
, there are no spaces in the argument, so it simply does \makefirstuc{\gls{src}}
.
\makefirstuc
applies a set of rules when deciding how to change the case:
- If the argument starts with a command and that command is followed by an argument, then the uppercasing is applied to the first object of the inner argument.
- If the argument starts with a command and that command isn't followed by an argument, then the uppercasing is applied to the command (unless the command is
\protect
, in which case it's discarded and the rules are reapplied). - If the argument doesn't start with a command, then the uppercasing is applied to the first object in the command.
Examples:
\makefirstuc{\emph{word}}
becomes\emph{\uppercase word}
(first case)\makefirstuc{\oe-ligature}
becomes\uppercase\oe-ligature
(second case)\makefirstuc{word}
becomes\uppercase word
(The uppercasing command used is actually \mfirstucMakeUppercase
, which may be defined as \MakeUppercase
or \MakeTextUppercase
.)
So \makefirstuc{\gls{src}}
comes under the first case. This means that it tries to do \gls{\uppercase src}
. That is, it tries to change the case of the label.
If the actually text that requires case-changing is hidden within the argument of \makefirstuc
(or \capitialisewords
) the first letter can't be accessed. Since \gls
is robust, it can't even be expanded before being passed as the argument. This is why the glossaries
package provides \Gls
, because the case-changing has to be performed deep inside the internals of the command.
I don't know how similar packages deal with the presence of formatting commands (such as \emph
) within the text that needs to have its case-changed, but none of them will be able to access the text if it's embedded within a robust command.
The only solution here is to use one of the expandable commands like this:
\documentclass{article}
\usepackage{glossaries}
\newacronym{srs}{SRS}{spaced repetition system}
\begin{document}
\ecapitalisewords{\glsentrylong{srs}}
\end{document}
This actually works better in page headings, as you're unlikely to want each page header added to the location list for the entry, which is what can happen if you use \gls
in a section or chapter heading. (See Why shouldn't I use commands like \gls in \section, \chapter, \caption etc?)
You can, of course, define a custom command, such as:
\newcommand*{\TCac}[1]{\ecapitalisewords{\glsentrylong{#1}}}
or (index and hyperlink)
\newcommand*{\iTCac}[2][]{\glsdisp[#1]{#2}{\ecapitalisewords{\glsentrylong{#2}}}}
Edit:
Take care using \ecapitialisewords
as it fully expands the argument, which can have unexpected results if the text contains commands. For example:
\documentclass{article}
\usepackage{xcolor}
\usepackage{glossaries}
\newcommand*{\strong}[1]{\textcolor{red}{\textbf{#1}}}
\newacronym{srs}{SRS}{\strong{spaced} repetition system}
\newcommand*{\TCac}[1]{\ecapitalisewords{\glsentrylong{#1}}}
\begin{document}
\TCac{srs}.
\end{document}
This superficially looks like case 1 with \strong{spaced}
, but full expansion means that it's now attempting to do
\capitialisewords{\protect\leavevmode{\protect\color{red}\protect\textbf{spaced}} repetition system}
This now follows the rules: discard initial \protect
, then apply case 1, which ends up as
\leavevmode{\uppercase\protect\color{red}\protect\textbf{spaced}}
which is incorrect. There are two solutions. Either only use robust commands:
\newrobustcmd*{\strong}[1]{\textcolor{red}{\textbf{#1}}}
or first fetch the value of the field and store it in a command using \glsfetchfield
and then apply \capitialisewords
:
\documentclass{article}
\usepackage{xcolor}
\usepackage{glossaries}
\newcommand*{\strong}[1]{\textcolor{red}{\textbf{#1}}}
\newacronym{srs}{SRS}{\strong{spaced} repetition system}
\newrobustcmd*{\TCac}[1]{%
\glsfieldfetch{#1}{long}{\phrase}%
\expandafter\capitalisewords\expandafter{\phrase}%
}
\begin{document}
\TCac{srs}.
\end{document}
There is still a problem here. The value of the long
key is still fully expanded. (You can show the value using \showglslong{srs}
after you define the entry. This uses \show
on the internal command used to store the value of the long
field.) This happens because the field expansion is on by default for the long
key. You can switch this off using \glsnoexpandfields
:
\documentclass{article}
\usepackage{xcolor}
\usepackage{glossaries}
\glsnoexpandfields
\newcommand*{\strong}[1]{\textcolor{red}{\textbf{#1}}}
\newacronym{srs}{SRS}{\strong{spaced} repetition system}
\newrobustcmd*{\TCac}[1]{%
\glsfieldfetch{#1}{long}{\phrase}%
\expandafter\capitalisewords\expandafter{\phrase}%
}
\begin{document}
\TCac{srs}.
\end{document}
This now works correctly.
Note that \xcapitalisewords
is a shortcut for \expandafter\capitalisewords\expandafter
so you can do
\newrobustcmd*{\TCac}[1]{%
\glsfieldfetch{#1}{long}{\phrase}%
\xcapitalisewords{\phrase}%
}
As from glossaries
v4.22, you can use
\glsentrytitlecase{src}{long}
which effectively does the same thing as the \TCac
example above, but the second argument is the field name (e.g. first
or text
or desc
).
Using titlecaps
package.
\documentclass{article}
\usepackage{glossaries}
\usepackage{titlecaps}
\newacronym{srs}{SRS}{spaced repetition system}
\begin{document}
\titlecap{\glsentrylong{srs}}
\end{document}
Note that one can use the \Addlcwords{}
feature that excludes specified words from being upper-cased. Additionally, it automatically masks out (most) punctuation and bracketing when figuring out what to capitalize.
\documentclass{article}
\usepackage{glossaries}
\usepackage{titlecaps}
\newacronym{srs}{SRS}{spaced repetition, of an (ocular) system}
\begin{document}
\titlecap{\glsentrylong{srs}}
\Addlcwords{an of}
\titlecap{\glsentrylong{srs}}
\end{document}
SUPPLEMENT (EDITED)
The OP indicates in a comment that the method does not seem to work in section headings of the new ACM format (https://www.acm.org/publications/proceedings-template). The problem seems to be not with \titlecap
, but that \glsentrylong
does not work in the section heading. The following workaround gets one through it, wherein I \edef
the acronym before using it in the section heading.
\documentclass{sig-alternate-05-2015}
\usepackage{glossaries}
\usepackage{titlecaps}
\Addlcwords{an of}
\newacronym{srs}{SRS}{spaced repetition, of an (ocular) system}
\begin{document}
\edef\tmp{\glsentrylong{srs}}
\section{This is \expandafter\titlecap\expandafter{\tmp} ok? }
\titlecap{\glsentrylong{srs}}
\end{document}
The stringstrings
version is (note the spelling of "capitalize") given below. However, as the author of both stringstrings
and titlecaps
, I strongly recommend, in the name of efficiency, to use titlecaps
rather than stringstrings
for this task.
\documentclass{article}
\usepackage{glossaries}
\usepackage{stringstrings}
\newacronym{srs}{SRS}{spaced repetition system}
\begin{document}
\capitalizewords{\glsentrylong{srs}}
\end{document}