我想在 latex(/pdflatex)的输出中使用 Unicode 字符(对于韩语,即 Hangul:U+AC00 - U+D7A3;也可能是 U+1100 - U+11FF),而 LaTeX 源文件应像以前一样以 7 位 ASCII 编码。
我希望有类似于\ding{number}
ZapfDingbats 的通过其十六进制码选择的 Unicode 内容,例如:
\unicodechar{bc73}
生成一个字符。输出应与之前一样:
latex -> dvips -> ps2pdfwr
到目前为止,我只见过源代码中使用 UTF-8 编码的 unicode 示例 - 这对我来说不是一个选择 - 并且通常使用 xelatex(破坏了我的书 - 我正在使用的软件包有问题)。我在 Xubuntu 12.10 下使用完全安装的 TeXLive 2012(Debian)(包括 CJK 软件包),因此原则上字体应该在那里。
我将非常感激任何答案,或至少是解决方案的提示 - 或者在最坏的情况下,说明为什么这根本不可能实现。
新增:请阅读上述事实。没有任何评论或答案与问题相关 - 看看这里的 unicode 问题 - 这个问题完全不同。没有德语变音符号或 Eurosign - 这很简单。编辑器或其他地方均禁止输入 Unicode 字符,仅在输出中可见。没有 XeLaTeX 或 LuaLaTeX。
仅举一个在上述条件下打印韩语字符的例子,或者说明为什么它不能与 latex/pdflatex 一起使用的原因。
答案1
理论上你可以用 ascii 输入你的整个文本,你只需要知道要使用哪些八位字节(8 位数据包):
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{textcomp}
\usepackage[utf8]{inputenc}
\begin{document}
Euro (€): ^^e2^^82^^ac
ä: ^^c3^^a4
\end{document}
主要问题是从 unicode 名称 (U+20AC) 获取 utf8-hex-notation (e282ac)。理论上可以计算 (并且 inputenc 在处理时会进行计算\DeclareUnicodeCharacter{20AC}{\texteuro}
),但我不知道使用 inputenc 命令获取值的简单方法。
此输入符号也应适用于 cjk-package(带有 utf8 选项)。
使用 ucs-package (使用选项 utf8x 时加载),您可以使用命令\unichar
。但您应该知道 ucs 可能与某些软件包发生冲突,例如,它在 biblatex 不兼容软件包列表中被提及。
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{textcomp}
\usepackage[utf8x]{inputenc}
\begin{document}
\unichar{"00E4}
\unichar{"20AC}
\end{document}
我不知道它是否可以与 cjk 一起工作。
cjk 还提供了一些文本命令来输入符号,例如\Li4 \chun1
。但我不知道这是否也涵盖了您的符号。
答案2
我认为enctex
可以让你做到这一点。
首先,在 a 中写入 unicode 字符串\message{¾}
(例如)。然后编译文件,您将在输出中看到多字节字符串 —^^c2^^be
在此示例中。
现在,在文件顶部(或者更好的是,在格式中),输入\mubyte \someTeXCommand ^^c2^^be\endmubyte
和\mubytein=1
。
使用该选项编译您的文件(或您的格式)enc
(它ini
也需要选项,并且 LaTeX 可能需要etex
顶部的选项),一切都应该很好 — 希望如此!
我个人在我的格式中保留了此类编码的列表,例如以 unicode 排版数学或在文本中使用特殊字符,如“...”
答案3
我刚刚遇到了一个问题,@UlrikeFischer 和 @RD6137 的回答基本上是正确的,但我会在这里发布一篇文章;虽然我不确定韩文字符本身,但我将重点关注问题的“Unicode 字符”和“十六进制码”部分;所有这些都经过了测试pdflatex
。
没有德语变音符号或欧元符号 - 这很简单。
其实并不简单(命令 \texteuro 在编码 T1 中不可用)——只是复杂性被textcomp
包隐藏了。
首先,让我们关注一下输入。如果我在终端(bash
Linux 上的 shell)中执行此操作:
$ echo -n € | hexdump -C
00000000 e2 82 ac |...|
00000003
...我可以看到我€
在 shell 中输入的内容实际上是三个字节的序列:0xE2、0x82 和 0xAC。也许使用我的脚本会更容易utfinfo.pl:
$ echo -n € | perl utfinfo.pl
Got 1 uchars
Char: '€' u: 8364 [0x20AC] b: 226,130,172 [0xE2,0x82,0xAC] n: EURO SIGN [Currency Symbols]
这告诉我们,欧元符号的字符/字形€
在 Unicode 表中的条目编号为 8364(十六进制 0x20AC),并且编码(我猜是按照 UTF-8)为字节序列 226,130,172(十六进制为 0xE2,0x82,0xAC);与之前提供给我们的完全相同hexdump
。这让我们想到了这一点:
禁止在编辑器或其他地方输入 Unicode 字符,
如果这是对@RD6137 的引用\message{¾}
,我相信这只是关于如何获取 Unicode 字符的实际字节序列的一种方法的建议。当您有像 U+20AC 这样的代码时,那只是 Unicode 名称 - 将其视为 Unicode 表中条目的整数索引。但那是不是UTF-8 中的实际字节序列。
而且,您唯一可以直接在 Latex 源文件中输入的是原始 UTF-8 字节,方法是使用双插入符号^^
转义序列(我认为这后面的两个字符被解释为十六进制);因此拥有 U+20AC Unicode 索引/名称对您没有太大帮助 - 您需要实际的 UTF-8 字节序列 0xE2,0x82,0xAC。(如前所述,似乎没有方便/简单的 Latex 宏可以自动从 Unicode 索引映射到 UTF-8 字节序列)。
因此,通过^^e2^^82^^ac
在 Latex 源文档中输入 ASCII 文本,Latex 将解析并解释它,就像您输入字节序列 0xE2,0x82,0xAC 一样 - 如果您将字符粘贴€
到文本编辑器中,并使用 UTF-8 编码保存文本文件,结果将完全相同。但是,如果在 Latex 文档中输入这三个字节,它们将被解释为单个 unicode 字符仅有的如果有的话\usepackage[utf8]{inputenc}
!否则,Latex 会将它们映射到单独的字形,无论其当前字体设置如何。
这给我们带来了另一个问题 - 字体编码。考虑这个 MWE:
\documentclass{article}
% \usepackage[T1]{fontenc}
\usepackage{lmodern} % use font Latin Modern (lmodern / lmr)
\usepackage{fonttable}
\makeatletter
\def\myfontinfo{font: encoding \f@encoding, family: \f@family, series: \f@series, shape: \f@shape, size: \f@size, baselineskip: \f@baselineskip}
\makeatother
\begin{document}
\typeout{\myfontinfo} % write to stdout
\myfontinfo % typeset in document
, ^^e2^^82^^ac %
\vspace*{-2em}
\makeatletter
%% \xfonttable{ encoding }{ family }{ series }{ shape }
\xfonttable{\f@encoding}{\f@family}{\f@series}{\f@shape}
\makeatother
\end{document}
如果你按原样编译它,那么 Latex 会自动假定它采用 OT1 编码,并打印字体表,如左图所示(单击可查看完整尺寸):
...如果您启用[T1]{fontenc}
并重新编译,Latex 将使用 T1 编码,生成完全不同的字体表 - 如中间图片所示。您会注意到,由于[utf8]{inputenc}
未指定,Latex 在两种情况下都将其解释^^e2^^82^^ac
为单个字符âĆň
,与每种情况下的表格完全一致(字体表的阅读说明:左侧和顶部'
是八进制;右侧和底部"
是十六进制;因此%
十进制为 37,'04x
& '5
='045
八进制,"2x
& '5
="25
十六进制;而-
十进制为 45,'05x
& '5
='055
八进制,"2x
& "D
="2D
十六进制)。但是,您还会注意到 OT1 和 T1 都不包含欧元符号 - 那么它在哪里?事实证明,它在另一种名为的字体编码中TS1
,位于上图最右边(只需[TS1]{fontenc}
在上面的 MWE 中使用),其中它是十进制的字形编号 191('277
八进制,"BF"
十六进制)。
因此,如果我们仅添加\usepackage[utf8]{inputenc}
上述示例,它现在就会崩溃:
! Package inputenc Error: Unicode char \u8:€ not set up for use with LaTeX.
See the inputenc package documentation for explanation.
Type H <return> for immediate help.
...
l.15 , ^^e2^^82^^ac
%
?
我们可以通过使用\DeclareUnicodeCharacter
- 来从表面上解决这个问题,现在它需要十六进制的 Unicode 索引,而不是 UTF-8 字节序列。因此,假设您在 ;\DeclareUnicodeCharacter{20AC}{TheEURO}
之后添加\usepackage[utf8]{inputenc}
,您会注意到,现在序列^^e2^^82^^ac
结果只有单词TheEURO
! 因此,\DeclareUnicodeCharacter
当遇到与 Unicode 字符匹配的二进制/字节序列时,基本上可以为您调用一个宏 - 但这仍然在相同的当前字体编码中(上面 MWE 中的 OT1 或 T1)。
那么,为了排版欧元符号 - 无论您将其输入为 还是^^e2^^82^^ac
,€
正如我们现在讨论的启用时一样[utf8]{inputenc}
- 都是通过调用\DeclareUnicodeCharacter
某个宏来实现的,它将暂时切换到 TS1,并从那里输出字形编号 191。这似乎正是该textcomp
包所做的(尽管我无法弄清楚编号细节):
$ grep euro `kpsewhich utf8enc.dfu`
\DeclareUnicodeCharacter{20AC}{\texteuro}
$ grep euro `kpsewhich textcomp.sty`
\space\space 4 = 5 + \string\texteuro\MessageBreak
\DeclareOption{euro}{\DeclareEncodingSubset{TS1}{?}{4}}
\def\tc@fake@euro#1{%
\DeclareTextCommandDefault{\texteuro}
{\CheckEncodingSubset\UseTextSymbol{TS1}\tc@fake@euro5\texteuro}
\DeclareUnicodeCharacter{20AC}{TheEURO}
因此,如果您\usepackage{textcomp}
在 之后添加而不是,您将在 Tex 源中\usepackage[utf8]{inputenc}
看到以字形排版的 pdf 格式。^^e2^^82^^ac
€
回到韩文字符:如果我有这些字符,我就能找到它们的 Unicode 索引和 UTF-8 字节序列:
$ echo -n 각갓갥갷 | perl utfinfo.pl
Got 4 uchars
Char: '각' u: 44033 [0xAC01] b: 234,176,129 [0xEA,0xB0,0x81] n: HANGUL SYLLABLE GAG [Hangul Syllables]
Char: '갓' u: 44051 [0xAC13] b: 234,176,147 [0xEA,0xB0,0x93] n: HANGUL SYLLABLE GAS [Hangul Syllables]
Char: '갥' u: 44069 [0xAC25] b: 234,176,165 [0xEA,0xB0,0xA5] n: HANGUL SYLLABLE GAELG [Hangul Syllables]
Char: '갷' u: 44087 [0xAC37] b: 234,176,183 [0xEA,0xB0,0xB7] n: HANGUL SYLLABLE GAEH [Hangul Syllables]
... 并使用,我们可以轻松地在 Latex 文档中[utf8]{inputenc}
输入(十六进制的 UTF-8 字节序列) ;甚至可以为其定义一个处理程序,使用(使用十六进制的 Unicode 索引)——问题是,我们需要知道哪种字体^^ea^^b0^^81
'각' HANGUL SYLLABLE GAG
\DeclareUnicodeCharacter{AC13}{\myHangulGAGhandler}
和哪种字体编码包含该字形(以及在什么位置),以便我们可以编程\myHangulGAGhandler
来选择和排版该字形。不幸的是,我对韩文/韩语字体一无所知(尽管我有一个CJKutf8
例子如何在 LaTeX 中输入中文?,这可能作为起点很有用)。无论如何,使用上述代码检查 Latex 文档中的字体设置(也使用字体表),您知道这些文档可以很好地编译为韩文/韩语,可能会有所帮助。
否则,就直接使用 Unicode 索引十六进制输出字符而言\unicodechar{bc73}
,似乎没有方便的宏;尽管正如 @UlrikeFischer 指出的那样,\inputenc
已经在后台执行了此操作 - 因为它必须将20AC
in 转换\DeclareUnicodeCharacter{20AC}...
为字节序列,以便稍后做出反应。然而,这非常复杂;您可以使用类似以下代码:
...
\usepackage[utf8]{inputenc}
\usepackage{trace}
\traceon
\DeclareUnicodeCharacter{20AC}{TheEURO}
\traceoff
...
.. 获取如下打印输出:
\UTFviii@tmp ->\UTFviii@three@octets €
{\expandafter}
{\expandafter}
\UTFviii@three@octets #1#2#3->\csname u8:#1\string #2\string #3\endcsname
#1<-
#2<-�
#3<-�
{\expandafter}
....
...但在 shell 中,这看起来完全是错误的;如果.log
在十六进制编辑器中打开该文件less
,则可以看到:
...
\UTFviii@three@octets #1#2#3->\csname u8:#1\string #2\string #3\endcsname
#1<-<E2>
#2<-<82>
#3<-<AC>
{\expandafter}
{\csname}
...
...inputenc
基于此20AC
Unicode 十六进制 ID,创建一个命令,其名称中包含原始 UTF 字节序列(0xE2、0x82、0xAC - 或至少是其第一个字节)!(实际上,我认为inputenc
以某种方式将字节 0xE2 设为宏的别名\UTFviii@three@octets
,这样它就会对扩展的 UTF-8 字符“作出反应”)。理解这一点不仅需要了解 Latex 内部结构,还需要了解实际的 UTF-8 编码,我认为这是这里的部分机制 - 不幸的是我没有。不过,希望这能有用...