# Use \fauxsc if small caps not avaiaible

I tend to use the IBM Plex font, which does not have small caps — hence I get this message when trying to use \textsc: Font shape T1/IBMPlexSerif-TLF/m/fscn' undefined (Font) usingT1/IBMPlexSerif-TLF/m/n' instead.

To get around this I use \fauxsc (Fake small caps with XeTeX/fontspec?), which seems to work in pdflatex.

What would be really snazzy though would be to extend the functionality of \textsc such that when the font does have small caps, it just uses that; then when it doesn't (e.g. as happens with IBM Plex) instead of giving an error, it automatically switches to using \fauxsc

Would such a thing be possible?

• Using faked small caps will ruin your document. Jul 7 '19 at 21:08
• I imagine by "ruin your document" you mean it won't be as good as true small caps? Jul 8 '19 at 1:03
• Just look at the picture in my answer: the difference in stroke weight is apparent and ugly. Jul 8 '19 at 8:49
• Yea. I know (and can clearly see) what you're talking about. What's nice with Plex though is it's got a good variety of different weights available. Now I just need a way to make the smaller letters be one weight higher. Jul 8 '19 at 9:35
• @egreg if this is of interest, this is what I ended up with: i.postimg.cc/JzyVgKd7/image.png by using this pastebin.com/SDGfBZ3d Jul 8 '19 at 15:05

Here's a possible solution, but if you really need small caps, use a font that has them.

\documentclass{article}
\usepackage{graphicx}
\usepackage{plex-serif}
\usepackage{roboto}

\let\textsc\relax
\DeclareRobustCommand{\textsc}[1]{%
\sbox0{x\xdef\testA{\the\font}}%
\sbox0{\scshape x\xdef\testB{\the\font}}%
\ifx\testA\testB\fauxsc{#1}\else{\scshape #1}\fi
}

\makeatletter
\newlength\fake@f
\newlength\fake@c
\def\fakesc#1{%
\begingroup
\xdef\fake@name{\csname\curr@fontshape/\f@size\endcsname}%
\fontsize{\fontdimen8\fake@name}{\baselineskip}\selectfont
\MakeUppercase{#1}%
\endgroup
}
\makeatother
\newcommand\fauxsc[1]{\fauxschelper#1 \relax\relax}
\def\fauxschelper#1 #2\relax{%
\fauxschelphelp#1\relax\relax
\if\relax#2\relax\else\ \fauxschelper#2\relax\fi
}
\def\Hscale{.83}\def\Vscale{.72}\def\Cscale{1.00}
\def\fauxschelphelp#1#2\relax{%
\ifnum#1>\ifnum#1<\{\scalebox{\Hscale}[\Vscale]{\uppercase{#1}}\else
\scalebox{\Cscale}[1]{#1}\fi\else\scalebox{\Cscale}[1]{#1}\fi
\ifx\relax#2\relax\else\fauxschelphelp#2\relax\fi}

\begin{document}

\textsc{Abc def}

\sffamily % this has true small caps

\textsc{Abc def}

\end{document}


The idea is to compare what font gets chosen if \scshape is applied. In case LaTeX performs a substitution, \testA and \testB will both point to the same font.

• This does not seem to work for me. I'm using it with geschichtsfrkl bibliography, and I'm getting a few strange errors: document.tex:186: Improper alphabetic constant. <to be read again> \MakeLowercase l.186 ...rung bewältigen.\cite{2012SchIg} document.tex:186: Missing = inserted for \ifnum. <to be read again> \protect l.186 ...rung bewältigen.\cite{2012SchIg} document.tex:186: Missing number, treated as zero. <to be read again> \protect l.186 ...rung bewältigen.\cite{2012SchIg}` (And some more every \cite) Jul 31 '20 at 16:26
• @nleanba Oh, the trick for emulating small caps has several limitations and you found one. Use a font that has real small caps and forget about this. Jul 31 '20 at 17:56