According to the brilliant answer to this question it is possible to check whether small caps are available or not. However, trying to actually make a use of this code I get a strange result: When the font shape is undefined the replacement works as expected. When the font shape is not available the test says the font shape is available but Latex uses a replacement, instead.
Is there a way to use \fakedsc
rather than the roman version for the normal sans serif small caps?
In the following code you can see that small caps are replaced when T1/lmr/bx/sc
and T1/lmss/bx/sc
are used (both undefined) but not when T1/lmss/m/sc
is used (not available):
\documentclass{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\usepackage{relsize}
\usepackage{etoolbox}
\newcommand{\fakedsc}[3][1]{#2\begingroup\smaller[#1]{\MakeUppercase{#3}}\endgroup}
\makeatletter
\def\define@newfont{%
\begingroup
\let\typeout\@font@info
\escapechar\m@ne
\expandafter\expandafter\expandafter
\split@name\expandafter\string\font@name\@nil
\try@load@fontshape % try always
\expandafter\ifx
\csname\curr@fontshape\endcsname \relax
\expandafter\gdef\csname \curr@fontshape/sub\endcsname{}% new
\wrong@fontshape\else
\extract@font\fi
\endgroup}
\newcommand\testsc[3][1]{%
\ifcsname \f@encoding/\f@family/\f@series/sc/sub\endcsname
no \fakedsc[#1]{#2}{#3}
\else
\ifcsname \f@encoding/\f@family/\f@series/sc\endcsname yes \textsc{#2#3} \else no \fakedsc[#1]{#2}{#3} \fi
\fi
}
\makeatother
\begin{document}
\detokenize{\rmfamily} \textsc{Test} -- \testsc{T}{ested} -- without \fakedsc{T}{est} => test successful, no replacement
{\bfseries
\detokenize{\rmfamily} \textsc{Test} -- \testsc{T}{ested} -- without \fakedsc{T}{est}} => test successful, replaced
\sffamily
\detokenize{\sffamily} \textsc{Test} -- \testsc{T}{ested} -- without \fakedsc{T}{est} => test \textbf{not successful}, auto replacement
{\bfseries
\detokenize{\sffamily} \textsc{Test} -- \testsc{T}{ested} -- without \fakedsc{T}{est}} => test successful, replaced
\end{document}
EDIT: I found something helpful in the source2e documentation. On top of page 166 it says:
If the \curr@fontshape combination is not available, (i.e. undefined) we call the macro \wrong@fontshape to take care of this case. Otherwise \extract@font will load the external font for us.
341 % \expandafter\ifx
342 % \csname\curr@fontshape\endcsname \relax
343 \try@load@fontshape % try always
344 % \fi
345 \expandafter\ifx
346 \csname\curr@fontshape\endcsname \relax
347 \wrong@fontshape\else
To allow substitution we call the curr@fontshape macro which usually will expand to \relax but may hold code for substitution (see \subst@fontshape definition).
348 % \csname\curr@fontshape\endcsname
349 \extract@font\fi
We are nearly finished and must only restore the \escapechar by closing the group.
350 \endgroup}
... so the magic word is undefined, meaning a solution for a font shape that is not available (according to the LaTeX warnings is still needed).
EDIT2:
As far as I understand, \testsc
tests for a substitution (which leads to the warning "Font shape T1/lmr/bx/sc
undefined(Font) using T1/lmr/bx/n
instead" if \textsc
is used). Then, it tests if the font shape exists. For some reasons, this test is positive for T1/lmss/m/sc
although, with \textsc
it gives the warning "Font shape T1/lmss/m/sc
in size <10.95> not available(Font) Font shape T1/lmr/m/sc
tried instead". Is en extra test for this case needed? In contrast to the first warning, I was not able to find out how this warning is produced. I found a definition of this warning on page 64 of the font installation guide. It looks like the family is changed before testing is done, in this case only.
EDIT3:
I had a closer look at the "not available" warning. It turns out this is produced by t1lmss.fd (located in MiKTeX 2.9/tex/latex/lm). Besides other substitutions it declares:
\DeclareFontShape{T1}{lmss}{m}{sc}
{<->sub*lmr/m/sc}{}
By adding the following code to the preamble I was able to change the substitution to the normal shape of the sans serif font.
\documentclass{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage{lmodern} \sffamily\selectfont
\usepackage[T1]{fontenc}
\usepackage{relsize}
\usepackage{etoolbox}
\DeclareFontShape{T1}{lmss}{m}{sc}
{<->sub*lmss/m/n}{}
\normalfont
...
Is it possible to make a test for this kind of substitution, as well, or to "undeclare" it without messing around with the .fd file?
Disclaimer: I am aware of the problems that arise on faking small caps but using a different font is no solution for me.