1

I am writing a document for which I would like to use a main font, let's call it myfont, which I have as several .otf files. To do so, I use XeTeX along with the fontspec package and the setmainfont command :

\usepackage{fontspec}
\setmainfont[Mapping=tex-text,
  BoldFont={myfont-bold.otf}, 
  ItalicFont={myfont-italic.otf},
  BoldItalicFont={myfont-bolditalic.otf}
]{myfont.otf}

The problem I have with myfont is that I don't like the digits. Therefore, I'd like to use another font, but only for digits. It could be possible if the setmainfont command had a numbers option, which it doesn't. I would also like to precise that the font does not have support for lined digits, and only comes with Old Style.

The way I see it, there would be two ways to do so :

1/ Make all digits use the math font

If I could make every digit call the math font, there would be no problem, as the math font digits look alright. The main problem being that I have no idea if and how this could be done.

2/ Substitute characters manually

This is what is suggested by two resources I have found : here and here - the latter referencing the former. Their solution was to use the fontspec package and to manually swap characters using :

\usepackage{fontspec}
\XeTeXinterchartokenstate=1
\chardef\CharNormal=0
\makeatletter
% Test for old and new versions of the latex kernel
\ifx\e@alloc@intercharclass@top\@undefined
    \chardef\CharBound=255
\else
    \chardef\CharBound=\e@alloc@intercharclass@top
\fi
\makeatother
\newXeTeXintercharclass\CharNumbers
\XeTeXcharclass`0=\CharNumbers
\XeTeXcharclass`1=\CharNumbers
\XeTeXcharclass`2=\CharNumbers
\XeTeXcharclass`3=\CharNumbers
\XeTeXcharclass`4=\CharNumbers
\XeTeXcharclass`5=\CharNumbers
\XeTeXcharclass`6=\CharNumbers
\XeTeXcharclass`7=\CharNumbers
\XeTeXcharclass`8=\CharNumbers
\XeTeXcharclass`9=\CharNumbers
\newtoks\TokSetfont
\TokSetfont={\begingroup\fontspec{Latin Modern Mono}}
\XeTeXinterchartoks\CharNormal\CharNumbers=\TokSetfont
\XeTeXinterchartoks\CharBound\CharNumbers=\TokSetfont
\XeTeXinterchartoks\CharNumbers\CharNormal={\endgroup}
\XeTeXinterchartoks\CharNumbers\CharBound={\endgroup}

The problem with this solution is that it does not seem to work ; it makes XeLaTeX compilation extremely slow, returning memory errors, and in the end the digits stay unchanged. The original solution was given in this answer, and as comments suggest, an infinite loop appears to be running.

Since the posts are rather old, and the solutions do not seem to work anymore, I figured I would ask again if anyone had an idea about how to change the main font for digits only. I am fully aware that this is an extremely unimportant thing to do, but still : any ideas ?

[EDIT] For convenience, a minimal working example with free fonts :

% !TeX program = xelatex
\documentclass{article}

\usepackage{fontspec}
\setmainfont[
    BoldFont={Georgia Bold}, 
    ItalicFont={Georgia Italic},
    BoldItalicFont={Georgia Bold Italic},
    SmallCapsFont={Latin Modern Roman Caps}
    ]{Linux Libertine O}

\begin{document}

Everything \textbf{just} \textsc{Works}, \\
but I don't like this ``1''

\end{document}
  • Welcome to Tex–LaTeX Stack Exchange! In my opinion, what you want to do is not ‘extremely unimportant’ — many older fonts have their lowercase numbers in a separate, small caps font, and they’d be much easier to use if someone found a way to do what you want. – Thérèse Jul 9 '18 at 19:42
  • @Thérèse Well, we already have a solution for those: that's what virtual fonts are for, basically. They allow you to use the oldstyle figures and small-caps from the extended type1 fonts supplied with the main ones. I guess, however, you mean a document-level solution. – cfr Jul 9 '18 at 22:53
  • A complete example would make things easier, especially if it uses fonts everyone has. Do you really need xltxtra? It isn't recommended these days for most cases. – cfr Jul 9 '18 at 22:54
  • Hello @cfr — I knew about virtual fonts for .pfb fonts, but the older fonts I had in mind were older .otf fonts, such as Linotype’s Stempel Schneidler. Are virtual fonts relevant there too? – Thérèse Jul 10 '18 at 2:04
  • @Thérèse Oh, no. I didn't know they did that. I'm not sure. You can use them for truetype fonts. I'd guess you should be able to do it for opentype, too, if you can get the engine to use regular TFMs etc. That is, I don't see why it shouldn't work, since the newer engines can fall back to TeX fonts. However, I would not want to bet much on this without actually trying it. – cfr Jul 10 '18 at 2:14
0

The bottleneck is using \fontspec. Rather declare a new font family, so font allocation is not redone at each start of a run of digits.

\documentclass{article}
\usepackage{fontspec}

\setmainfont{TeX Gyre Termes}
\newfontfamily{\digits}{TeX Gyre Heros}

\XeTeXinterchartokenstate=1
\chardef\CharNormal=0
\makeatletter
% Test for old and new versions of the latex kernel
\ifx\e@alloc@intercharclass@top\@undefined
    \chardef\CharBound=255
\else
    \chardef\CharBound=\e@alloc@intercharclass@top
\fi
\makeatother
\newXeTeXintercharclass\CharNumbers
\XeTeXcharclass`0=\CharNumbers
\XeTeXcharclass`1=\CharNumbers
\XeTeXcharclass`2=\CharNumbers
\XeTeXcharclass`3=\CharNumbers
\XeTeXcharclass`4=\CharNumbers
\XeTeXcharclass`5=\CharNumbers
\XeTeXcharclass`6=\CharNumbers
\XeTeXcharclass`7=\CharNumbers
\XeTeXcharclass`8=\CharNumbers
\XeTeXcharclass`9=\CharNumbers

\XeTeXinterchartoks\CharNormal\CharNumbers={\begingroup\digits}
\XeTeXinterchartoks\CharBound\CharNumbers={\begingroup\digits}
\XeTeXinterchartoks\CharNumbers\CharNormal={\endgroup}
\XeTeXinterchartoks\CharNumbers\CharBound={\endgroup}

\begin{document}

\count255=0

\loop\ifnum\count255<1000
\advance\count255 1
Text 123 text1text\endgraf
123\endgraf
\repeat

\end{document}

I tried these 2000 paragraphs with and without the interchar tokens and the compilation time is comparable.

enter image description here

  • It works like a charm, thank you very much ! – fkrz Jul 11 '18 at 11:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.