8

Sometimes in my document I wish to use an acronym. Sometimes I want the acronym to appear in title case (for example if it appears in a title).*

*I need this to work in all environments, not specifically titles.

Variants on this question have been asked all over the site, however none of the proposed solutions actually work. The closest example is one that would require me to rewrite my entire glossary file, something I am unwilling to do, as it is shared by other documents and other people.

Three solutions proposed use titlecaps, mfirstuc, and stringstrings, however none of them work on acronyms.

\documentclass{article}
\usepackage{glossaries}
\usepackage{titlecaps}
\usepackage{mfirstuc}
\usepackage{stringstrings}

\newacronym{srs}{SRS}{spaced repetition system}

\begin{document}
  \titlecap{\gls{srs}}
  \capitalisewords{\gls{srs}}
  \capitalizetitle{\gls{srs}}
\end{document} 

Without having to modify my glossary, and preferably without having to include a huge wodge of impenetrable code in my tex file, how can I capitalise the first letter of an acronym sometimes?

EDIT: For clarity I am looking for a way to get Spaced Repetition System and not Spaced repetition system, or SPACED REPETITION SYSTEM.

  • To what questions are you referring? This one? – Clément Feb 17 '16 at 17:58
  • And this one, this one, this one, and this one. – jhoyla Feb 17 '16 at 18:03
  • This might be naive (or reflect my misunderstanding of your question), but doesn't \Gls or \GLS (see p. 107 of glossaries manual) solve your problem? If you don't know how to find the documentation, have a look at this post – Clément Feb 17 '16 at 18:10
  • Sadly not. They allow you to capitalize the first letter of the first word, or to capitalise the entire string. You can't just capitalise the first letter of each word. – jhoyla Feb 17 '16 at 18:14
  • 1
    \capitalisewords{\gls{srs}} is (approximately) equivalent to \gls{\uppercase srs}. That is, it's trying to apply the case change to the argument of \gls (the label). This creates a reference to a non-existent label. (The argument syntax rules of \capitalisewords are the same as for \makefirstuc.) The problem is that \gls{srs} doesn't expand to a simple string that can then be manipulated. – Nicola Talbot Apr 13 '16 at 16:16
9
+50

\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:

  1. 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.
  2. 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).
  3. 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).

5

Using titlecaps package.

\documentclass{article}
\usepackage{glossaries}
\usepackage{titlecaps}
\newacronym{srs}{SRS}{spaced repetition system}
\begin{document}
\titlecap{\glsentrylong{srs}}
\end{document} 

enter image description here

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} 

enter image description here

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} 

enter image description here


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} 
  • This doesn't work in a section heading/title. \section{\titlecap{\glsentrylong{ata}}} gives an empty section heading, rather than a section with the heading properly formatted. – jhoyla Apr 19 '16 at 14:28
  • @jhoyla It works for me (see SUPPLEMENT to my answer). – Steven B. Segletes Apr 19 '16 at 14:35
  • You are correct, on further inspection it appears that it's some conflict with the new ACM format. Not quite sure what causes it, but given that I have to use their format is there anything you can suggest? – jhoyla Apr 19 '16 at 15:45
  • @jhoyla When all else fails, try \protect\titlecap{...} – Steven B. Segletes Apr 19 '16 at 15:45
  • 1
    @jhoyla See revised SUPPLEMENT. – Steven B. Segletes Apr 19 '16 at 16:01

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.