This will sound like a strange question, but there is a rhyme and reason for it. Is there a way to have fontspec or XeTeX commands affect only letters of one case--say lowercase? For example, suppose you wanted to substitute all lowercase characters in one font with those in another. I think the answer is probably in some variation of David Carlisle's answer here: Replace a single letter in xelatex. Is there an easy way to do this or will it need to be done character-by-character? I am interested in text mode. David already showed me how to do this in math mode. I am using OpenType text fonts.
- 95
1 Answers
Fill in all that you consider “lowercase”.
\documentclass{article}
\usepackage{fontspec}
\setmainfont{Libertinus Serif}
\newfontfamily{\LCL}{Futura}% Lower Case Letters
\XeTeXinterchartokenstate=1
\newXeTeXintercharclass\LOWERCASELETTERS
\count255=\numexpra-1\relax \loop\ifnum\count255<z
\advance\count255 by 1
\XeTeXcharclass \count255 \LOWERCASELETTERS
\repeat
\XeTeXinterchartoks 0 \LOWERCASELETTERS {\begingroup\LCL}
\XeTeXinterchartoks \LOWERCASELETTERS 0 {\endgroup}
\XeTeXinterchartoks 4095 \LOWERCASELETTERS {\begingroup\LCL}
\XeTeXinterchartoks \LOWERCASELETTERS 4095 {\endgroup}
\begin{document}
Some text AbCdE.
\end{document}
If you want the substitution only for the main font, you can modify as follows.
\documentclass{article}
\usepackage{fontspec}
\setmainfont{Libertinus Serif}[
NFSSFamily=mainfont,
]
\newfontfamily{\LCL}{Futura}% Lower Case Letters
\XeTeXinterchartokenstate=1
\newXeTeXintercharclass\LOWERCASELETTERS
\count255=\numexpra-1\relax \loop\ifnum\count255<z
\advance\count255 by 1
\XeTeXcharclass \count255 \LOWERCASELETTERS
\repeat
% some syntactic sugar
\ExplSyntaxOn
\NewDocumentCommand{\replacemainfont}{}
{
\str_if_eq:eeT { \use:c { f@family } } { mainfont } { \LCL }
}
\ExplSyntaxOff
\XeTeXinterchartoks 0 \LOWERCASELETTERS {\begingroup\replacemainfont}
\XeTeXinterchartoks \LOWERCASELETTERS 0 {\endgroup}
\XeTeXinterchartoks 4095 \LOWERCASELETTERS {\begingroup\replacemainfont}
\XeTeXinterchartoks \LOWERCASELETTERS 4095 {\endgroup}
\begin{document}
Some text AbCdE.
\textsf{Some text AbCdE.}
\texttt{Some text AbCdE.}
\end{document}
- 1,121,712
-
One last question: is there a way to have this only affect one family (or for that matter a single font)? I thought at first glance this would affect the main font but not the sans or mono, so I had hoped to modify the code to change only a particular family (which is probably sufficient for my purposes). But this is replacing the lowercase in whatever the active font happens to be. – Mike Pugh Jul 13 '23 at 16:35
-
@MikePugh Added as requested – egreg Jul 13 '23 at 20:04
-
Perfect! Just what I needed. Thank you! – Mike Pugh Jul 14 '23 at 12:57

