I have a mostly English-language document, with fonts defined like this:
\usemodule[simplefonts]
\setmainfont[MinionPro-Regular]
\setsansfont[MyriadPro-Bold]
Occassionally, I need to have some Chinse text appear, using \language[cn]{}
, and since the above fonts do not have Chinese characters, I need it to temporarily switch to Adobe Song Std, when Chinese text appears amid the main font, and Adobe Heiti Std, when Chinese text appears in places where sans fonts are used.
- How can I set ConTeXt to automatically switch fonts when I switch to a different language?
Best Answer
How can I set ConTeXt to automatically switch fonts when I switch to a different language? There might be a misconception involved here as to what
\language[foo]
actually does. It changes the current hyphenation rules, but is by no means a switch to another script and/or type face.For this reason your question can be interpreted in (at least) two ways:
\language[...]
.The first variant is best implemented using font fallbacks and will work even without the
\language
command. This can be considered a cheap and easy solution. The second approach might appear more complicated at the first glance, but it integrates neatly with the overall interface and is extensible with other language related features (text direction, transliteration, emphases etc.) if needed.Below examples will use Russian for demonstration but should work with any defined language.
The Fallback Method: First we need a list of the codepoint ranges for subsitution, in this case the four defined Cyrillic ranges. The first in the list would already cover contemporary Russian but there’s no reason not to be thorough.
They are predefined in Context so we could refer to them by name. Anyways it does not hurt to address them explicitly.
In the example, we will take the fallback glyphs from Computer Modern Unicode which provide a sufficiently close match for Latin Modern. (The CMU fonts are part of TEX Live.) For each of the four varieties regular, italic, bold, bold italic of the serif type face we need a different fallback, because we want Context to substitute glyphs from the appropriate CMU font. After that the fallbacks are ready for use in our typescript, here under the name mainfont.
The Macro Method: Just switching the font and hyphenation patterns may suffice for the occasional foreign word, but multilingual typesetting in general will have further requirements, like for instance the different spacing conventions for French. Thus a macro that can be extended on demand is of great value. Below listing gives the skeleton code for a Context-style macro generator
\definelazylanguage
, which comes with the companion\setuplazylanguage
. It allows defining commands that, in this basic form, handle both pattern and font switching. All definitions will create (1) an ordinary macro\foo{...}
and (2) the complementing\startfoo
/\stopfoo
environment. These accept an optional first argument (in brackets, of course) for local setups.EDIT: Fyi the
\installnamespace
and\installcorenamespace
that make this all possible currently reside in mult-aux.mkiv, see there for further documentation.ANOTHER EDIT: The following snippet has been revised according to a set of fixes Wolfgang just sent to me. (Many thanks!) It does not only correct a grouping bug but also exploits the namespace functionality more efficiently than the previous version.
Note that the code might look confusing at first but that’s because of the multiple levels of wrapping, so it’s actually a feature =). All you need to understand is that the real action is taking place inside the macro
\lazylanguage_start_indeed
, where you can alway hook further parameters according to the following scheme:Just replace the
<parametername>
dummy with a key of your choice and you can use it in the setup.