7

It is quite common in film studies to print film titles in small caps. In my documents I use the command \film{} to do this. I currently have a document which mixes both serif and sans serif fonts. But since the sans serif font does not come with small caps, I have to rely on fake small caps (using this solution).

What I would like to achieve is that \film{} automatically uses either \textsc{} or fake small caps depending on the font being used. In other words, I need a way to determine whether the current font is sans serif or not.

  • 1
    The current font family is stored in \f@family. – Ulrike Fischer Apr 3 '15 at 13:20
9

You have to compare the current value of \f@family and of \sfdefault: if they match, then you're typesetting in sans serif type.

Basically you do

\ifnum\pdf@strcmp{\f@family}{\sfdefault}=\z@
   <we are using sans serif>
\else
   <we are not using sans serif>
\fi

Example:

\usepackage{pdftexcmds}
\makeatletter
\DeclareRobustCommand{\film}[1]{%
  \ifnum\pdf@strcmp{\f@family}{\sfdefault}=\z@
    \fakesc{#1}%
  \else
    \textsc{#1}%
  \fi
}
\makeatother

Just for the fun of it, here's an implementation that uses l3regex:

\documentclass{article}

\usepackage{fontspec}
\usepackage{xparse,l3regex}

\setmainfont{Linux Libertine O} % has small caps
\setsansfont{Alegreya Sans} % has no small caps

\ExplSyntaxOn
\NewDocumentCommand{\film}{ m }
 {
  \simifilm_film:n { #1 }
 }

\tl_new:N \l__simifilm_fakesc_tl

\cs_new_protected:Npn \simifilm_film:n #1
 {
  \str_if_eq_x:nnTF { \use:c { f@family } } { \sfdefault }
   {
    \simifilm_fakesc:n { #1 }
   }
   {
    \textsc{ #1 }
   }
 }

\cs_new_protected:Npn \simifilm_fakesc:n #1
 {
  \use:c { protected@edef } \l__simifilm_fakesc_tl { #1 }
  \regex_replace_all:NnN
   \c_simifilm_lowercase_regex % search any run of lowercase letters 
   { \c{simifilm_reduce:n}\cB\{\1\cE\} } % replace it with \simifilm_reduce:n{<run>}
   \l__simifilm_fakesc_tl
  \tl_use:N \l__simifilm_fakesc_tl
 }

\cs_new_protected:Npn \simifilm_reduce:n #1
 {
  { \fontsize{ \fp_eval:n { .8 * \use:c { f@size } } }{0}\selectfont \tl_upper_case:n {#1} }
 }

% update the constant for accommodating the accented characters you need
\regex_const:Nn \c_simifilm_lowercase_regex { ( [ a-z é ]+ ) }

\ExplSyntaxOff

\begin{document}

\film{Stagecoach} is a great movie

\sffamily

\film{La Chevauchée fantastique} is the French title

\end{document}

Accented characters are supported, but you need to add the needed ones in the search regex.

enter image description here

  • Great answer and used to work fine, but seems broken in TL2018 pretest (error about runaway definition, because of \tl_to_uppercase which should be \tl_upper_case). – TeXnician Mar 30 '18 at 8:54
  • @TeXnician Definitely, thanks for pointing it out. – egreg Mar 30 '18 at 9: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.