While we have \textit
and \textsc
, \itshape
and \scshape
etc., there's no \textuc
and \ucshape
to typeset its argument in uppercase. There is \MakeUppercase
, but -- as uppercase is not a font style -- it's not a font selection command and cannot be used like one. That's why it's of no use in, e.g., formatting headings. There's the seamus-egreg workaround, but that has its limitations, for example when exotic languages are used: \section{daß}
produces »DAß« rather than »DASS«, etc.
Traditionally, the only way towards a proper \textuc
/\ucshape
seemed to be via creating a virtual font in which all lowercase letters are replaced by uppercase ones. While I've seen a couple of people suggesting that approach, I don't think anyone has ever done it, probably because it's tedious and inflexible, as it's always tied to one specific font.
My question is if it might be a good idea to rethink that issue now that we have Xe and Lua, where we can use OpenType Fonts and, via fontspec, OpenType feature files. In those feature files, we can define substitution rules that can be switched on and off. In OpenType, an f_i ligature, for example, is produced via such a substitution rule, saying »whenever in the code you come across an f
followed by an i
, replace the two by the glyph f_i
in the output«. To tentatively answer my own question: yes, it might be. Consider the following example. [edit: now including a comparison with the \MakeTextUppercase
command from the textcase
package barbara mentioned.]
\documentclass{scrartcl}
\usepackage{fontspec,blindtext,microtype,filecontents,textcase}
\begin{filecontents*}{universalcaps.fea}
languagesystem DFLT dflt;
languagesystem latn dflt;
feature caps {
lookup ligatures {
sub f_i by F I;
sub f_l by F L;
sub f_f_l by F F L;
sub f_f_i by F F I;
sub f_f by F F;
sub f_j by F J;
sub f_f_j by F F J;
sub f_t by F T;
sub f_f_t by F F T;
} ligatures;
lookup eszett {
sub germandbls by S S;
} eszett;
lookup single {
sub [a-z] by [A-Z];
sub agrave by Agrave;
sub aacute by Aacute;
sub acircumflex by Acircumflex;
sub atilde by Atilde;
sub adieresis by Adieresis;
sub aring by Aring;
sub ccedilla by Ccedilla;
sub egrave by Egrave;
sub eacute by Eacute;
sub ecircumflex by Ecircumflex;
sub edieresis by Edieresis;
sub igrave by Igrave;
sub iacute by Iacute;
sub icircumflex by Icircumflex;
sub idieresis by Idieresis;
sub eth by Eth;
sub ntilde by Ntilde;
sub ograve by Ograve;
sub oacute by Oacute;
sub ocircumflex by Ocircumflex;
sub otilde by Otilde;
sub odieresis by Odieresis;
sub ugrave by Ugrave;
sub uacute by Uacute;
sub ucircumflex by Ucircumflex;
sub udieresis by Udieresis;
sub yacute by Yacute;
sub thorn by Thorn;
sub ydieresis by Ydieresis;
sub oe by OE;
sub ae by AE;
sub scaron by Scaron;
sub zcaron by Zcaron;
} single;
} caps;
\end{filecontents*}
\setmainfont[FeatureFile=universalcaps.fea]{TeX Gyre Termes}
\setsansfont[FeatureFile=universalcaps.fea]{TeX Gyre Heros}
\newcommand*{\ucshape}{\addfontfeature{RawFeature=+caps}}
\newcommand{\textuc}[1]{{\ucshape #1}}
\setkomafont{section}{\ucshape}
\begin{document}
\section{Lorem Ipsum}
\textuc{\blindtext
àéîàáâãäåæ çèéêëìíîï ðñòóôõö ùúûüýþÿœš
fi ff fl ffi ffl fj ffj}
\MakeTextUppercase{daß}
\textuc{daß}
\begin{titlepage}
\ucshape
\begin{center}
John Doe\par
{\huge Title}
\end{center}
\end{titlepage}
\end{document}
This will create a feature file, adding to whatever font is loaded a new feature called caps
that can be turned on and off like any other. Note that this will work with TrueType fonts as well, {Georgia}
etc; fontspec
seems to transfer what's in the .fea file to even non-OpenType fonts.
Are there any potential drawbacks that I may not have had in mind? I'm still thinking it seems too simple to be true. (While it may be simple, it may of course still be a lot of work to take are of all lowercase glyphs in advanced multi-language fonts).
Has anyone else ever done or seen something like that? I find it hard to believe I should be the first to come up with that idea...
If noone has done it so far, would it be a good idea to turn it into a little package?
\ucshape
and\itshape
,\scshape
,… should be completely interchangeable. They work on different levels:\ucshape
would change unicode codepoints;\itshape
,\scshape
only change the glyphs representing the same unicode codepoint. An all uppercase text has less information than a mixed case text, in contrast to a\itshape
text compared to an\upshape
text. This might be not important in English, but in German it is, as nouns always start with uppercase letters.ß
bySS
via a feature file wouldn't adapt to changes in hyphenation. Consider, e.g., bei-ßen vs. BEIS-SEN in German reformed orthography.