为什么 inputenc 在“基于 utf8 的引擎”下这么快就放弃了?

为什么 inputenc 在“基于 utf8 的引擎”下这么快就放弃了?

当使用指定使用 -encoded 字体的源时,为什么我需要做一些额外的工作才能\ifdefined在 pdf 输出中正确显示法语 guillemets ?xelatexT1

\documentclass[french]{article}

    \usepackage[T1]{fontenc}
    \usepackage[utf8]{inputenc}

\ifdefined\XeTeXinterchartoks
     \catcode`« \active
     \catcode`» \active
     \def«{\char19 }
     \def»{\char20 }% ça marche, même avec Babel+frenchb
\fi

\usepackage{newtxtext}

\usepackage{babel}
\frenchbsetup{og=«, fg=»}

\begin{document}

\showboxbreadth\maxdimen
\showboxdepth\maxdimen
\showoutput

«coucou»
\end{document}

法国金枪鱼

日志内容如下:

Package: inputenc 2015/03/17 v1.2c Input encoding file
\inpenc@prehook=\toks14
\inpenc@posthook=\toks15


Package inputenc Warning: inputenc package ignored with utf8 based engines.

但是它是在 之后加载的fontenc。 并不禁止使用fontencxelatexinputenc在它之后加载的。 因此它应该知道要使用 T1 编码的字体插槽。 那么为什么它不执行使这些字符处于活动状态并将它们映射到合适的插槽的工作\char xx呢?

这里有一些东西我不明白……

请注意,代码示例还使用了babel+frenchb添加自动间距的功能。它似乎没有因为我使字符处于活动状态而受到干扰。

为了进一步解释这个问题,请考虑以下输入:

\documentclass{article}

    \usepackage[T1]{fontenc}
    \usepackage[utf8]{inputenc}

\begin{document}

\showboxbreadth\maxdimen
\showboxdepth\maxdimen
\showoutput

«coucou»

\end{document}

如果使用以下命令进行编译,则会产生xelatex

巴德吉耶梅

解释很简单:ascii 字符«和分别»位于插槽171和中187。因此,使用编码中的相应字形T1,给出结果。inputenc什么也不做,但它可以做一些类似于我上面的代码的事情。

...\hbox(6.63332+0.0)x345.0, glue set 290.00977fil
....\hbox(0.0+0.0)x15.0
....\T1/cmr/m/n/10 «
....\T1/cmr/m/n/10 c
....\T1/cmr/m/n/10 o
....\T1/cmr/m/n/10 u
....\T1/cmr/m/n/10 c
....\T1/cmr/m/n/10 o
....\T1/cmr/m/n/10 u
....\T1/cmr/m/n/10 »

答案1

inputenc被抛弃,因为它确实没有什么使用 XeTeX 或 LuaLaTeX。更确切地说,它可以坏的

fontenc 与 inputenc

本质上, 执行的任务inputenc是将输入字符转换为 LICR 格式。使用 8 位引擎,«长度为两个字节,inputenc能够将它们转换为和\guillemotleft。但要做到这一点,它必须激活一些字符。这正是您稍后要做的事情,但没有指示这样做,因为它被认为是 8 位引擎。»\guillemotrightinputenc

我添加了一个更友好的界面newunicodechar

\documentclass[french]{article}

\usepackage[T1]{fontenc}
\usepackage{newunicodechar}

\newunicodechar{«}{\guillemotleft}
\newunicodechar{»}{\guillemotright}

\usepackage{newtxtext}

\usepackage{babel}
\frenchbsetup{og=«, fg=»}

\begin{document}

«coucou»

\end{document}

在此处输入图片描述

如果您的目的是为中的字符提供翻译t1enc.dfu,那么您可以用不同的方式使用它。

\documentclass[french]{article}

\usepackage[T1]{fontenc}
\usepackage{newunicodechar}

\newcommand\DeclareUnicodeCharacter[2]{%
  \expandafter\newunicodechar\Uchar"#1{#2}%
}
\input{t1enc.dfu}

\usepackage{newtxtext}

\usepackage{babel}
\frenchbsetup{og=«, fg=»}

\begin{document}

«coucou»

\end{document}

软件包的概念证明xeinputenc

\ProvidesPackage{xeinputenc}[2015/12/12]
\RequirePackage{newunicodechar}

\AtBeginDocument{\xeinputenc@process}

\newcommand{\xeinputenc@process}{%
  \begingroup
  \gdef\xeinputenc@list{}%
  \def\cdp@elt##1##2##3##4{%
    \g@addto@macro\xeinputenc@list{\lowercase{\xeinputenc@input{##1}}}%
  }%
  \cdp@list
  \aftergroup\xeinputenc@list
  \endgroup
}

\newcommand{\DeclareUnicodeCharacter}[2]{%
  \expandafter\newunicodechar\Uchar"#1{#2}%
}

\newcommand{\xeinputenc@input}[1]{%
  \InputIfFileExists
    {#1enc.dfu}
    {\wlog{... processing UTF-8 mapping file for font encoding #1}\catcode`\ 9\relax}%
    {\wlog{... no UTF-8 mapping file for font encoding #1}}%
}


\@onlypreamble\DeclareUnicodeCharacter
\@onlypreamble\xeinputenc@list
\@onlypreamble\xeinputenc@process
\@onlypreamble\xeinputenc@input
\endinput

现在您的测试文档可以

\documentclass[french]{article}

\usepackage{xeinputenc}

\usepackage{newtxtext}

\usepackage{babel}
\frenchbsetup{og=«, fg=»}

\begin{document}

«coucou»

\end{document}

在这种情况下不需要明确加载fontenc,因为这已经由处理了newtxtext,但对它的调用将被尊重。

答案2

inputenc 的 utf8 选项旨在将表示 utf8 表示形式的字节的字符序列作为单个字符并将它们收集在一起并使用 utf8 编码将每个这样的序列扩展为适合该字符的 tex 命令。

当 xetex 读取 utf8 文件时,每个字符都会被报告为单个字符标记,并且 utf8 编码中的字节根本不会报告给宏层,因此 inputenc 代码无法执行任何有用的操作。

答案3

您说的是“不禁止将 fontenc 与 xelatex 一起使用”。这是真的。实际上,fontenc 通常与 xelatex 一起使用,因为 fontspec 会加载 fontenc,但不是通过 T1 选项而是通过 EU1。

fontenc 是一个相当特殊的包,可以多次加载。在您的问题中,您隐含地假设如果加载了 T1,它也是文档的唯一、主要的字体编码。但这在这里也是非常有效的:

\documentclass{article}
\usepackage[T1,LGR,LSF]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{fontspec} % calls \usepackage[EU1]{fontenc}
\begin{document}
abc
\end{document}

inputenc 在这里应该做什么?

稍微扩展一下答案:文档可以通过 fontenc 加载各种编码,有时甚至在用户不知道或甚至不想要的情况下,例如本地类或(数学)包可以做到这一点。甚至可能在用户背后加载 inputenc。如果 inputenc 会实现一些复杂的启发式方法来激活多个字符,那将造成很大的混乱——通常 xelatex 用户既不需要也不想要。

相关内容