天城文基础及计算机处理方法

文字特性

天城文(Devanagari)是诸多南亚语言的文字,其中最有名的当属梵语(Sanskrit)。天城文作为婆罗米系元音附标文字,特点鲜明,下面介绍用计算机处理天城文所需的基础知识。

Unicode字符

Unicode为天城文分配的区间是U+0900-U+097F,共128个码位(code point),表示的字符分为如下几类:

  1. 辅音(consonants)字母。辅音字母附着一个固有元音/a/,比如字符क是Devanagari Letter KA,即表示/ka/而不是/k/。辅音字母和非独立元音组合在一起时,固有的元音会被替代。
  2. 独立元音(independent vowels)字母。可以单独出现的元音,如字符अ是Devanagari Letter A。独立元音用于书写以元音开头的音节。
  3. 非独立元音(dependent vowels)字母。非独立元音不会单独出现,而是基于基本形态和其他字母组合出现,基本形态可能会置于其他字母的左右上下方向。如字符ि是左侧非独立元音字符Devanagari Vowel Sign I,和其他辅音组合后:ि + क = कि,用英文转写表示就是I + KA = KI,即辅音字母和非独立元音组合时替代了固有的元音。
  4. 半音(virama)符号。符号्的作用是抑制辅音的附着元音,क + ् = क्,KA + Virama = K,该符号随处可见。
  5. 部分组合得到的辅音字母。有的辅音字母虽然从视觉上可看成多个基本单元的组合,但Unicode还是为它们分配了单独的码位。
  6. 其他特殊字符。如U+0900-U+0903,详情参考文档。

字素

字素(grapheme)可看成基本书写单元,要么是单个码位的符号,要么是由多个码位构成的组合符号。本文中字素和基本书写单元表达相同的意义。例如,क和क्都是字素,其中क是单个码位,क्由两个码位组合而成。但是非独立元音ि就不是字素,因为它和辅音字母组合后的书写形态才有意义。

天城文中有大量由辅音、非独立元音和特殊符号所组成的字素。如下字素均由两个码位组成,辅音字母分别位于组合后得到的基本书写单元的上下左右方向:शू = श + ू , क़ं = क़ + ं , भो = भ + ो , यि = य + ि 。

需要注意,Unicode字符中除了一些特殊符号和非独立元音字母外,其它可独立出现的字符也是基本书写单元。

合字

其间去除元音的连续辅音(或称为辅音丛)按照法则连写在一起,称为合字(ligature),如:ल्क = ल् + क , त्स्न = त् + स् + न , क्ष्म्य = क् + ष् + म् + य。可看到前面是利用Virama符号去除固有元音后得到的死辅音(dead consonant),末尾是附着固有元音的活辅音(live consonant)。合字规则可看成是字素组合形成新的形态。

天城文的合写规则非常繁杂,可参考Devanagari conjuncts页面。单是由两个辅音构成的合字就有1296种,再加上由多个辅音构成的合字,总共应该超过1500种。一般来说,系统不会支持所有的合字,不同字体文件和应用软件所支持的类型和数量不同。

计算机处理

字符处理

下面的Python代码将U+0900-U+097F范围内的128个Unicode码位所对应的天城文字符打印出来:

1
2
for c in range(0x0900, 0x0980):
print(c, chr(c))

要想得到组成该单词的Unicode字符,可以用for语句遍历Unicode字符串:

1
2
3
4
5
import unicodedata

sanskrit_text = u"सत्याग्रह"
for c in sanskrit_text:
print(c, c.encode("unicode_escape"), unicodedata.name(c))

得到如下结果:

1
2
3
4
5
6
7
8
9
स b'\\u0938' DEVANAGARI LETTER SA
त b'\\u0924' DEVANAGARI LETTER TA
् b'\\u094d' DEVANAGARI SIGN VIRAMA
य b'\\u092f' DEVANAGARI LETTER YA
ा b'\\u093e' DEVANAGARI VOWEL SIGN AA
ग b'\\u0917' DEVANAGARI LETTER GA
् b'\\u094d' DEVANAGARI SIGN VIRAMA
र b'\\u0930' DEVANAGARI LETTER RA
ह b'\\u0939' DEVANAGARI LETTER HA

一共由9个Unicode字符组成,还附有它们的Unicode编码和描述。相反地,我们可以将单个Unicode字符拼在一起,系统会处理合写形态:

1
2
>>> print(u"\u0938\u0924\u094d\u092f\u093e")
सत्या

显示处理过程

从上面的介绍可知,天城文字符根据上下文会改变形态。系统环境中的字体和应用程序的不同,以及字符之间的相对位置都会影响形态。由于很多字素和合写字符没有分配编码,因此计算机显示天城文的过程比较复杂,过程总结如下:

  1. 天城文文本在计算机中存储的内容是Unicode码,具体的存储形态与编码格式(如UTF-8)有关,解析编码格式即得到组成文本的Unicode码;
  2. 字体文件提供字形(glyph),合字的字形都在字体文件中,但有些字素的字形不一定在字体文件中;
  3. 系统软件根据复杂的规则建立从编码到字形的映射,再根据字形将字符显示在屏幕上。对于一些字素,将字形按一定规则重叠起来显示。

汉字的数量虽多,但Unicode为每个汉字都分配了编码,而且编码和字体文件中的字形是一一映射的关系,所以计算机显示汉字的过程比天城文要简单。

参考资料

  1. Devanagari Unicode Characters
  2. Unicode Standard Chapter 12.1
  3. What's the difference between a character, a code point, a glyph and a grapheme?
  4. python - Combining Devanagari characters - Stack Overflow