17

I have an automatically generated document (using Doxygen) that has many different Unicode characters for many languages: Hebrew, Japanese, Greek, Arabic and more.

Some parts of text displayed using monospace fonts.

I've tried to use the DejaVu Sans font, which includes most of glyphs but I still miss some Japanese characters and some characters in the monospace fonts.

Is there any way to tell XeLaTeX to make automatic substitutions if the font is missing glyphs?

So it would for example use one font as main and if something is missing would fall back to another font or at least to a non-monospace font that has the correct glyphs?

3
  • 1
    This looks like a direct application of XeTeX's interchar class mechanism. Read more here. Jul 14, 2011 at 16:53
  • @Andrey can you be more specific, at least I can't find information abut this mechanism in the link your provided.
    – Artyom
    Jul 16, 2011 at 13:50
  • 1
    It's Chapter 3. I haven't tried it, but the workflow for, say, treating Japanese characters specially looks as follows: you assign non-zero to \XeTeXinterchartokenstate; you then use \XeTeXinterchartoks 0 1 = { \SwitchToJapaneseFont } \XeTeXinterchartoks 1 0 = { \SwitchToDefaultFont }. For finer control you will want to use \newXeTeXintercharclass and \XeTeXcharclass. Chapter 3 also has a simple example. Jul 16, 2011 at 14:19

1 Answer 1

13

As Andrey points out, the key is the concept of "interchar tokens". Suppose you have some CJK characters that doesn't appear in the normal font and you want to use another for them; say that the characters are U+4E01 and U+4E02.

Then the following will do:

\usepackage{fontspec}
\setmainfont[Ligatures=TeX]{<a font>}
\newfontfamily{\JapSubstFont}{<another font with the missing chars>}

\XeTeXinterchartokenstate=1
\newXeTeXintercharclass\JapSubst

\XeTeXcharclass"4E01=\JapSubst
\XeTeXcharclass"4E02=\JapSubst

\XeTeXinterchartoks 0 \JapSubst = {\begingroup\JapSubstFont}
\XeTeXinterchartoks 255 \JapSubst = {\begingroup\JapSubstFont}
\XeTeXinterchartoks \JapSubst 0 = {\endgroup}
\XeTeXinterchartoks \JapSubst 255 = {\endgroup}

Each time that a character in the \JapSubst charclass will be at the start or end of a "word" or be preceded or followed by a "normal" character, it will be typeset in the \JapSubstFont.

One can also specify a range:

\count255="4E01
\loop\ifnum\count255<"5000
  \XeTeXcharclass\count255=\JapSubst
  \advance\count255 by 1
\repeat
6
  • 2
    Thanks it may suit you... But is there a way to specify for example a range of Unicode not each character particularly? Because for example for CJK it may be HUGE set?
    – Artyom
    Jul 18, 2011 at 5:24
  • Thanks... I hadn't thought about loop. I forgot that LaTeX is Turing complete language :-)
    – Artyom
    Jul 18, 2011 at 6:09
  • Note that XeTeX version 0.99996 from TL 2016 has increased the number of character classes to 4096, so the boundary class, here denoted by 255, should become 4095. Sep 27, 2016 at 17:28
  • 1
    @JasonZentz Yes, thanks for the update. On the other hand, there are probably better methods, nowadays.
    – egreg
    Sep 27, 2016 at 17:30
  • 1
    Just to confirm that as of 2019, you really do need to change 255 to 4095 as per Jason's comment, otherwise I could not get it to compile. Feb 3, 2019 at 3:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .