1

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.

1 Answers1

1

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}

enter image description here

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}

enter image description here

egreg
  • 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