Monday, November 3, 2014

Using Macros with "titlecaps" in a LaTeX Document

The LaTeX template that I wrote for Arizona State University’s dissertations and theses makes use of the titlecaps package. The titlecaps package has commands for selectively capitalizing words, so that titles can be correctly capitalized in what is often called headline style. Titles of chapters and sections, for example, should usually appear in headline style.

Style guides vary a little bit on the particular rules for headline style, but in general, the rules are the following:

  • Always capitalize the first and last word.
  • Capitalize all remaining words unless they are:
    • articles (i.e., a, an, the),
    • prepositions (e.g., of and for), or
    • conjunctions (e.g., and, but, and or).

Any particular style guide should give more details about exactly which words should not be capitalized.

In any case, the titlecaps package can be used to perform this capitalization on a string of text. Here is an example of a memoir class document that shows how to use the titlecaps package:

\documentclass{memoir}
\usepackage{titlecaps}
\Resetlcwords
\Addlcwords{a an the} 
\Addlcwords{and but for or nor} 
\Addlcwords{aboard about above across %
  after against along amid among anti %
  around as at before behind below %
  beneath beside besides between %
  beyond but by concerning considering %
  despite down during except excepting %
  excluding following for from in %
  inside into like minus near of off %
  on onto opposite outside over past %
  per plus regarding round save since %
  than through to toward towards under %
  underneath unlike until up upon %
  versus via with within without}

\renewcommand{\cfttableaftersnumb}% 
  {\titlecap}%                      
  
\begin{document}

\listoftables
\clearpage

\begin{table}[h] % Table float
\caption{Here is a table caption ending in ``of''}
\label{table1}
\begin{tabular}{l c c} \\ \hline
Column1 & Column2 & Column3 \\ \hline
Row1 & 2.0 & 3.0 \\
Row2 & 2.0 & 3.0 \\
Row3 & 7.0 & 8.0 \\ \hline
\end{tabular}
\end{table}

\end{document}

This setup will send the \titlecap command to all the table captions in the list of tables, which should appear after the table of contents. The table captions in the running text will not be changed.

As far as I can discern, the titlecaps package is relatively new; it appears that it was written in 2013 or maybe 2012, so it still has some rough edges. (Then again, LaTeX is pretty old by now, and it’s full of rough edges.)

One problem with titlecaps is that it does not ignore the last word in a title. In the example above, the last word of the table caption of will not be capitalized in the list of tables because of is in the list of words to leave lowercase (defined by the \Addlcwords command). This behavior contradicts some style guides (such as the Chicago Manual of Style), and there does not seem to be a way to change this behavior.

Another problem is that macros in text sent to \titlecap are likely to break. In the above example, all captions are sent to \titlecap. Users might want to refer to another figure or table in a caption (e.g., with the \ref command) or put a citation in a caption (e.g., with \cite). But these macros will break if they’re sent to \titlecap. (By the way, I am not scolding the package author here. Capitalization in LaTeX is tricky, and when text gets sent to a macro for capitalization, odd things can happen.)

So I started searching for solutions. \textnc is a macro from the titlecaps package that causes \titlecap to ignore text within, so it seemed that wrapping a macro with \textnc would be a way to get \titlecap to skip over the macro. Unfortunately, that strategy did not work.

To (sort of) fix this problem, I read through the titlecaps documentation to see how its \textnc macro was defined. The other clue from the titlecaps documentation was that wrapping text with {{}} can also cause \titlecap to leave the text alone. Between this tidbit, the definition of \textnc, and a bunch of trial and error, I arrived at the following macro:

\newcommand{\macrocapwrap}[1]{% 
  {\bgroup\bgroup{{#1}}\egroup\egroup}%
}

Below is an example of this macro in action:

\documentclass{memoir}
\usepackage{titlecaps}
\Resetlcwords
\Addlcwords{a an the} 
\Addlcwords{and but for or nor}
\Addlcwords{aboard about above across %
  after against along amid among anti %
  around as at before behind below %
  beneath beside besides between %
  beyond but by concerning considering %
  despite down during except excepting %
  excluding following for from in %
  inside into like minus near of off %
  on onto opposite outside over past %
  per plus regarding round save since %
  than through to toward towards under %
  underneath unlike until up upon %
  versus via with within without}

\renewcommand{\cfttableaftersnumb}%
  {\titlecap}%

\newcommand{\macrocapwrap}[1]{% 
  {\bgroup\bgroup{{#1}}\egroup\egroup}%
}

\begin{document}

\listoftables
\clearpage

\begin{table}[h] % Table float
\caption{Here is a table caption ending in %
  ``of'' with number \macrocapwrap{\ref{table1}}}
\label{table1}
\begin{tabular}{l c c} \\ \hline
Column1 & Column2 & Column3 \\ \hline
Row1 & 2.0 & 3.0 \\
Row2 & 2.0 & 3.0 \\
Row3 & 7.0 & 8.0 \\ \hline
\end{tabular}
\end{table}

\end{document}

Why does this macro work? I honestly have no idea. As I said, I arrived at it mostly through trial and error. It’s not ideal, and it seems a bit fragile, but I hope it can help other people until something more robust comes along.