babel 和 fontspec 的问题

babel 和 fontspec 的问题

我刚刚在拉丁字母和西里尔字母环境中使用 babel 与 lualatex(或 xelatex)和 fontspec 时遇到了问题。这是一个简单的例子:

\documentclass[11pt]{article}

\usepackage{fontspec}
\setmainfont{Heuristica}%
\usepackage[english,russian]{babel}
\newcommand*\English{\selectlanguage{english}}

\begin{document}

\textup{\Russian Мороз и солнце, день чудесный}

\English\textit{The sea is calm to-night.}
\end{document} 

最终的 .pdf 格式如下:

在此处输入图片描述

正如我们所见,文本的英语部分使用的字体是Computer Modern,而不是Heuristica,甚至在应该是斜体的地方也没有斜体。

但是,如果我改变语言的顺序([russian, english],一切都很好:

在此处输入图片描述

如果我使用 进行编译pdflatex,相应地修改前言并使用字体的 type 1 版本而不是 opentype,无论语言的顺序如何,一切都会正常。我尝试使用其他字体,问题相同。这是错误还是我错过了什么?

答案1

egreg 的回答现在解释道为什么当我将其作为评论发布时,我并不理解这个工作原理。

如果你加载fontspec babel,然后一切正常:

\documentclass[11pt]{article}

\usepackage[british,russian]{babel}
\newcommand*\English{\selectlanguage{british}}
\usepackage{fontspec}
\setmainfont{Heuristica}%
\usepackage{poetrytex}

\begin{document}

\renewcommand{\poetryheadings}{\pagestyle{myheadings} \markboth{}{}}
\English
\begin{poem}{Title}{Author\\2014}
\textup{\Russian Мороз и солнце, день чудесный}\\
\textit{The sea is calm to-night.}
\end{poem}

\end{document}

启发式

但请注意,fontspec手册中将其描述babel为“实际上不受支持”并建议polyglossia(第 4 页)。我猜他们的意思是后者支持的语言,虽然不是全部,但确实包括俄语。

答案2

相关部分babel.def来自

\AtEndOfPackage{\edef\latinencoding{\cf@encoding}}
\AtBeginDocument{%
  \gdef\latinencoding{OT1}%
  \ifx\cf@encoding\bbl@t@one
    \xdef\latinencoding{\bbl@t@one}%
  \else
    \@ifl@aded{def}{t1enc}{\xdef\latinencoding{\bbl@t@one}}{}%
  \fi
  }

让我们看看会发生什么:在加载结束时babel,指令

\edef\latinencoding{\cf@encoding}

执行;由于fontspec识别到被 XeLaTeX 调用,因此将其设置\cf@encodingEU1。稍后加载的包可能需要此操作。

然后,在文档开始时,\latinencoding将 临时设置为,然后再次检查OT1的值,因为它可能已更改。如果 是,则将更改为;如果 已加载,则执行相同操作。由于您的情况是并且尚未加载,因此什么也不会发生,并保持其值。\cf@encodingT1\latinencodingT1t1enc.def\cf@encodingEU1t1enc\latinencodingOT1

事实上,你会收到来自 LaTeX 的警告,例如

LaTeX Font Warning: Font shape `OT1/Heuristica(0)/m/n' undefined
(Font)              using `OT1/cmr/m/n' instead on input line 11.

\English完成后发出,因为babel执行\edef\encodingdefault{\latinencoding},以便能够使用拉丁字符。

更准确地说,如果fontspec加载了 babel,因为fontspec(实际上fontspec-xetex.sty

\tl_set_eq:NN \cyrillicencoding \g_fontspec_encoding_tl
\tl_set_eq:NN \latinencoding    \g_fontspec_encoding_tl
\AtBeginDocument
 {
  \tl_set_eq:NN \cyrillicencoding \g_fontspec_encoding_tl
  \tl_set_eq:NN \latinencoding    \g_fontspec_encoding_tl
 }

并且\g_fontspec_encoding_tl是,因此对到EU1的错误重新定义被覆盖。\latinencodingOT1

相关内容