As I’m working on The Preppy Lion, I was not happy with how the LaTeX logo was being typeset in the main body typeface that I’m using, Monotype Ehrhardt. I decided to make some small adjustments to the spacing and decided that I also wanted to make slight variations if the logo was being typeset in bold or italic or bold italic. The catch was being able to identify what the current font was.

This should be simple. I could simply compare \f@shape to \itdefault or \f@series to \bfdefault. Problem solved right?

So I did the following in my code:

\ifx\f@shape\itdefault
   italic code
\else
   non-italic code
\fi

and discovered that it didn’t work.

I typeset the values of \f@shape and \itdefault and they looked the same. So I turned to some TeX debugging skills and typeset \texttt{\meaning\f@shape} and \texttt{\meaning\itdefault} instead and discovered that \itdefault was defined as a long macro thanks to having been defined in latex.ltx with \newcommand{\itdefault}{it} instead of \newcommand*{\itdefault}{it}. I suspected that this might be a subtle bug in LaTeX, did the workaround of adding \renewcommand*{\itdefault}{it} to my class file and started working on the bold adjustments.

These also weren’t working. I’d done the same \renewcommand magic for \bfdefault but something was still wrong. It appeared that the fontspec package was adding \@empty to the end of the \bfdefault definition.

The old-school way to deal with this would be to write something like:

\edef\next{\bfdefault}
\ifx\f@series\next ...

but this was ugly. It turned out though, while digging through the fontspec code in search of where the \@empty was being added that there was a simpler approach. The expl3 macros provide a way to compare the fully expanded definitions of two macros with the \str_if_eq:eeTF command. I ended up creating two utility macros to handle the checks for bold and italic as:

\DeclareDocumentCommand{\ForIt}{ mm }
   {
      \str_if_eq:eeTF
        \f@shape
        \itdefault
        {#1}
        {#2}
   }


\DeclareDocumentCommand{\ForBf}{ mm }
   {
      \str_if_eq:eeTF
        \f@series
        \bfdefault
        {#1}
        {#2}
   }

and was able to make my adjustments without difficulty afterwards.

While working on the manuscript for the book, I noticed that one of my page headings was being rendered as

Putting together a document—part i

thanks to my writing “part I” using a small caps i for the “I.” I was also getting an annoying warning on every odd page:

LaTeX Font Warning: Font shape `TU/EhrhardtMTStd(0)/m/scit' undefined
(Font)              using `TU/EhrhardtMTStd(0)/m/sc' instead on input line 12.

Monotype Ehrhardt does not have an italic small caps and normally I would shun the use of obliquing against the designer’s wishes but here it was going to be a limited case of a single character which, if it were to exist would be obliqued (in fact, other than losing hinting, there’s not a strong argument against using a mechanical oblique for italic small caps, especially not for a small caps I). The catch was how to persuade fontspec to let me do this.

It took a bit of digging through the documentation of fontspec to figure this out (most of the discussion on the topic on Stack Exchange was to express horror at fake italic small caps), but I eventually managed to get the desired result which I present here for anyone trying to solve this particular problem:

\setmainfont[Numbers=OldStyle,Mapping=tex-text,
    ItalicFeatures=
       {
           SmallCapsFont={Ehrhardt MT Std},
           SmallCapsFeatures={FakeSlant=0.2, Letters=SmallCaps}
       }
   ]{Ehrhardt MT Std}