我有一份主要由英文组成的文档,其字体定义如下:
\usemodule[simplefonts]
\setmainfont[MinionPro-Regular]
\setsansfont[MyriadPro-Bold]
有时候需要出现一些中文,使用\language[cn]{}
,由于上述字体没有中文,所以当主字体中间出现中文时,需要它暂时切换到 Adobe Song Std,当在使用 sans 字体的地方出现中文时,需要它暂时切换到 Adobe Heiti Std。
- 如何设置 ConTeXt 在切换到其他语言时自动切换字体?
答案1
如何设置 ConTeXt 在切换到其他语言时自动切换字体?
这里可能存在误解,不知道它\language[foo]
到底起什么作用。它改变了当前的连字规则,但绝不是切换到另一种脚本和/或字体。
因此,您的问题至少可以用两种方式来解释:
- 一旦完成了,您希望能够使用另一个脚本
\language[...]
。 - 您需要一个通用的语言环境切换。
第一种方案最好使用字体回退即使没有命令也可以工作\language
。这可以被认为是一种廉价而简单的解决方案。第二种方法乍一看可能更复杂,但它与整体界面完美集成,并且可以根据需要扩展其他语言相关功能(文本方向、音译、强调等)。
下面的例子将使用俄语进行演示但应该适用于任何定义的语言。
后备方法:首先,我们需要一个用于替换的代码点范围列表,在本例中是四个已定义的西里尔字母范围。列表中的第一个已经涵盖了当代俄语,但没有理由不彻底一点。
- 0x0400:0x04ff 西里尔文
- 0x0500:0x052f 西里尔文补充
- 0x2de0:0x2dff 西里尔扩展 A
- 0xa640:0xa69f 西里尔扩展 B
他们是在上下文中预定义这样我们就可以直呼其名。无论如何,明确地称呼他们也无妨。
在示例中,我们将从计算机现代 Unicode这与 Latin Modern 非常接近。(CMU 字体是 TEX Live 的一部分。)对于四种变体中的每一种常规的,斜体,大胆的,加粗斜体衬线字体需要不同的后备字体,因为我们希望 Context 替换相应 CMU 字体的字形。之后,后备字体就可以在我们的 TypeScript 中使用了,这里的名称为主字体。
\definefontfallback [cyrillic_regular] [name:CMUSerifRoman]
[0x0400:0x04ff,0x0500:0x052f,0x2de0:0x2dff,0xa640:0xa69f] [force=yes]
\definefontfallback [cyrillic_bold] [name:CMUSerifBold]
[0x0400:0x04ff,0x0500:0x052f,0x2de0:0x2dff,0xa640:0xa69f] [force=yes]
\definefontfallback [cyrillic_italic] [name:CMUSerifItalic]
[0x0400:0x04ff,0x0500:0x052f,0x2de0:0x2dff,0xa640:0xa69f] [force=yes]
\definefontfallback [cyrillic_bolditalic] [name:CMUSerifBoldItalic]
[0x0400:0x04ff,0x0500:0x052f,0x2de0:0x2dff,0xa640:0xa69f] [force=yes]
%% Now we hook the fallbacks into their respective type faces.
\starttypescript [serif] [mainfont]
\setups[font:fallback:serif]
\definefontsynonym [Serif] [name:Latin Modern Roman] [fallbacks=cyrillic_regular]
\definefontsynonym [SerifBold] [name:Latin Modern Roman Bold] [fallbacks=cyrillic_bold]
\definefontsynonym [SerifItalic] [name:Latin Modern Roman Italic] [fallbacks=cyrillic_italic]
\definefontsynonym [SerifBoldItalic] [name:Latin Modern Roman Bold Italic] [fallbacks=cyrillic_bolditalic]
\stoptypescript
%% Complete the typescript for all four type faces. Note that we default
%% to the predefined Latin Modern setups for the three other faces.
\starttypescript [mainfont]
\definetypeface [mainfont] [rm] [serif] [mainfont] [default]
\definetypeface [mainfont] [ss] [sans] [latin-modern] [default]
\definetypeface [mainfont] [tt] [mono] [latin-modern] [default]
\definetypeface [mainfont] [mm] [math] [latin-modern] [default]
\stoptypescript
%% Finally, we are ready to activate the typescript.
\setupbodyfont [mainfont,20pt]
\starttext
English {\italic English} {\bold English} {\bolditalic English}
\language[ru] %% does only switch the hyphenation pattern
Маленький мальчик нашел пулемет. Больше в деревне никто не живет. \par
{\italic Маленький мальчик нашел пулемет. Больше в деревне никто не живет.}\par
{\bold Маленький мальчик нашел пулемет. Больше в деревне никто не живет.}\par
{\bolditalic Маленький мальчик нашел пулемет. Больше в деревне никто не живет.}\par
\stoptext
宏方法:对于偶尔出现的外来词,只需切换字体和连字符模式即可,但多语言排版通常会有进一步的要求,例如法语的不同间距约定。因此,可以根据需求扩展的宏具有很大的价值。下面的清单给出了\definelazylanguage
随附的上下文样式宏生成器的骨架代码\setuplazylanguage
。它允许定义以这种基本形式处理模式和字体切换的命令。所有定义都将创建(1)一个普通宏\foo{...}
和(2)补充\startfoo
/\stopfoo
环境。它们接受可选的第一个参数(当然在括号中)用于本地设置。
编辑:仅供\installnamespace
参考\installcorenamespace
使这一切成为可能的目前居住在多重辅助.mkiv,请参阅那里以获取更多文档。
另一项编辑:以下代码片段已根据 Wolfgang 刚刚发给我的一组修复进行了修改。(非常感谢!)它不仅纠正了分组错误,而且比以前的版本更有效地利用了命名空间功能。
% macros=mkvi
\unprotect
\installnamespace {lazylanguage}
\installcommandhandler \????lazylanguage {lazylanguage} \????lazylanguage
\appendtoks
\setuevalue {\currentlazylanguage}{\lazylanguage_direct[\currentlazylanguage]}%
\setuevalue{\e!start\currentlazylanguage}{\lazylanguage_start [\currentlazylanguage]}%
\setuevalue{\e!stop \currentlazylanguage}{\lazylanguage_stop }%
\to \everydefinelazylanguage
\unexpanded\def\lazylanguage_direct[#id]%
{\edef\currentlazylanguage{#id}%
\dosingleempty\lazylanguage_direct_indeed}
\def\lazylanguage_direct_indeed[#options]%
{\groupedcommand
{\lazylanguage_start_indeed[#options]}%
\donothing}
\unexpanded\def\lazylanguage_start[#id]%
{\bgroup
\edef\currentlazylanguage{#id}%
\dosingleempty\lazylanguage_start_indeed}
% %% This is the macro that implements the core switching functionality.
\def\lazylanguage_start_indeed[#options]%
{\iffirstargument
\setupcurrentlazylanguage[#options]%
\fi
%% Here would be the place where you can hook further language
%% settings into your command, imitating the pattern of below
%% expressions.
\language[\lazylanguageparameter{patterns}]
\doifsomething{\lazylanguageparameter{bodyfont}}
{\switchtobodyfont[\lazylanguageparameter{bodyfont}]}}
\let\lazylanguage_stop\egroup
\protect
\definelazylanguage [lru]
\setuplazylanguage [lru] [
bodyfont=antykwa,
patterns=ru,
]
\startlru
Маленький мальчик нашел пулемет. Больше в деревне никто не живет. \par
{\italic Маленький мальчик нашел пулемет. Больше в деревне никто не живет.}\par
{\bold Маленький мальчик нашел пулемет. Больше в деревне никто не живет.}\par
{\bolditalic Маленький мальчик нашел пулемет. Больше в деревне никто не живет.}\par
\stoplru
English {\italic English} {\bold English} {\bolditalic English}
\stoptext
请注意,代码乍一看可能令人困惑,但这是因为多层包装,所以它实际上是一个功能 =)。您需要了解的是,真正的操作发生在宏内部\lazylanguage_start_indeed
,您可以根据以下方案随时挂钩进一步的参数:
\doifsomething{\lazylanguageparameter{<parametername>}}
{\lazylanguageparameter{<parametername>}}%
只需<parametername>
用您选择的钥匙替换假人,您就可以在设置中使用它。