当您在几乎任何文本编辑器中打开 UTF-8 文件时,您都会看到文本中每个字符都正确呈现,与周围的其他字符区分开。这就是 Unicode 表存在的原因,字体提供了模型。为什么 LaTeX 比这复杂得多?
我见过许多打印多语言文本的方法,一些使用 pdflatex,其他使用 xelatex 或 luatex......然后有许多软件包包含字体编码,一些 babel、polyglossia 和其他......然而,每当我想使用另一种语言时,我仍然需要告诉 LaTeX“嘿,下一个字符是俄语字符”,即使文件的编码(UTF)已经说明了这一点!
为什么没有一个简单的解决方案,比如:一个包用于定义编码(例如 UTF-8 而不是 UTF-16),另一个包用于提供字体?不是如果我想要 Ж,我打算写出像“Zh”这样的有趣组合。如果我想要 Ж,我会像在任何文本编辑器中一样写 Ж。因此,如果没有这些有趣的技巧,按照 Unicode 标准进行解释就非常简单了。
答案1
LaTeX 默认不允许这样做的原因在于,主要原因是它只pdflatex
使用 8 位字体,并且 XeLaTeX 或 LuaLaTeX 中使用的 OpenType/TrueType 字体也不一定覆盖所有 Unicode。
例如,(Xe|Lua)LaTeX 中的默认拉丁现代字体既不涵盖西里尔文,也不涵盖希腊文。
话虽如此,你可以pdflatex
通过设置字母的默认编码来启用西里尔字符的输入。如果你遇到不方便的连字问题,不要怪我。
\documentclass{article}
\usepackage[T2A,T1]{fontenc}
\ExplSyntaxOn
\tl_gclear:N \g_tmpa_tl
\group_begin:
% disable a few commands
\newcommand{\xxxignoredtc}{}
\newcommand{\ignoredtc}[1][0]{\renewcommand{\xxxignoredtc}[#1]}
\renewcommand\DeclareTextCommand[2]{\ignoredtc}
\cs_set_eq:NN \DeclareTextAccent \use_none:nnn
\cs_set_eq:NN \DeclareTextComposite \use_none:nnnn
\cs_set:Npn \DeclareTextSymbol #1 #2 #3
{
\str_if_eq:eeT { \__donaastor_three:n { #1 } } { cyr }
{
\tl_gput_right:Nn \g_tmpa_tl { \DeclareTextSymbolDefault{#1}{T2A} }
}
}
\cs_set:Nn \__donaastor_three:n
{
\str_foldcase:e { \str_range:enn { \token_to_str:N #1 } { 2 } { 4 } }
}
\cs_generate_variant:Nn \str_foldcase:n { e }
\cs_generate_variant:Nn \str_range:nnn { e }
\file_input:n { t2aenc.def }
\group_end:
\tl_use:N \g_tmpa_tl
\ExplSyntaxOff
\begin{document}
Ж is not Zh
The Russian word Спасибо means ``thanks''.
\end{document}
t2aenc.def
这个想法是以不同的方式使用的,但有些命令必须首先被禁用,并且\DeclareTextSymbol
必须转换为执行,例如,
\DeclareTextSymbolDefault{\CYRA}{T2A}
\DeclareTextSymbolDefault{\cyra}{T2A}
从
\DeclareTextSymbol{\CYRA}{\LastDeclaredEncoding}{192}
\DeclareTextSymbol{\cyra}{\LastDeclaredEncoding}{224}
然而,诸如
\DeclareTextSymbol{\guillemotleft}{\LastDeclaredEncoding}{190}
应该被忽略。因此,上面的代码首先重新定义 中出现的其他命令,t2aenc.def
使其不执行任何操作。然后,它重新定义\DeclareTextSymbol
以检查其第一个参数,该参数已“字符串化”并折叠大小写;然后将第二个到第四个字符与 进行比较cyr
。如果测试成功,我们将适合的添加\DeclareTextSymbolDefault
到全局临时标记列表中。
一切都是在一个组中完成的,因此重新定义的命令的含义将在组结束时恢复;但全局临时令牌列表在组结束后仍然存在,我们可以执行其内容。
对于较短的西里尔文插入,这可能就足够了。对于较长的段落,请babel
以适当的方式加载并标记语言变化。