1
0

utf.ms 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248
  1. .HTML "Hello World or Καλημέρα κόσμε or こんにちは 世界
  2. .TL
  3. Hello World
  4. .br
  5. or
  6. .br
  7. .ft R
  8. Καλημέρα κόσμε
  9. .ft
  10. .br
  11. or
  12. .br
  13. \f(Jpこんにちは 世界\fP
  14. .AU
  15. Rob Pike
  16. Ken Thompson
  17. .sp
  18. rob,ken@plan9.bell-labs.com
  19. .AB
  20. .FS
  21. Originally appeared, in a slightly different form, in
  22. .I
  23. Proc. of the Winter 1993 USENIX Conf.,
  24. .R
  25. pp. 43-50,
  26. San Diego
  27. .FE
  28. Plan 9 from Bell Labs has recently been converted from ASCII
  29. to an ASCII-compatible variant of the Unicode Standard, a 16-bit character set.
  30. In this paper we explain the reasons for the change,
  31. describe the character set and representation we chose,
  32. and present the programming models and software changes
  33. that support the new text format.
  34. Although we stopped short of full internationalization\(emfor
  35. example, system error messages are in Unixese, not Japanese\(emwe
  36. believe Plan 9 is the first system to treat the representation
  37. of all major languages on a uniform, equal footing throughout all its
  38. software.
  39. .AE
  40. .SH
  41. Introduction
  42. .PP
  43. The world is multilingual but most computer systems
  44. are based on English and ASCII.
  45. The first release of Plan 9 [Pike90], a new distributed operating
  46. system from Bell Laboratories, seemed a good occasion
  47. to correct this chauvinism.
  48. It is easier to make such deep changes when building new systems than
  49. by refitting old ones.
  50. .PP
  51. The ANSI C standard [ANSIC] contains some guidance on the matter of
  52. `wide' and `multi-byte' characters but falls far short of
  53. solving the myriad associated problems.
  54. We could find no literature on how to convert a
  55. .I system
  56. to larger character sets, although some individual
  57. .I programs
  58. had been converted.
  59. This paper reports what we discovered as we
  60. explored the problem of representing multilingual
  61. text at all levels of an operating system,
  62. from the file system and kernel through
  63. the applications and up to the window system
  64. and display.
  65. .PP
  66. Plan 9 has not been `internationalized':
  67. its manuals are in English,
  68. its error messages are in English,
  69. and it can display text that goes from left to right only.
  70. But before we can address these other problems,
  71. we need to handle, uniformly and comfortably,
  72. the textual representation of all the major written languages.
  73. That subproblem is richer than we had anticipated.
  74. .SH
  75. Standards
  76. .PP
  77. Our first step was to select a standard.
  78. At the time (January 1992),
  79. there were only two viable options:
  80. ISO 10646 [ISO10646] and Unicode [Unicode].
  81. The documents describing both proposals were still in the draft stage.
  82. .PP
  83. The draft of ISO 10646 was not
  84. very attractive to us.
  85. It defined a sparse set of 32-bit characters,
  86. which would be
  87. hard to implement
  88. and have punitive storage requirements.
  89. Also, the draft attempted to
  90. mollify national interests by allocating
  91. 16-bit subspaces to national committees
  92. to partition individually.
  93. The suggested mode of use was to
  94. ``flip'' between separate national
  95. standards to implement the international standard.
  96. This did not strike us as a sound basis for a character set.
  97. As well, transmitting 32-bit values in a byte stream,
  98. such as in pipes, would be expensive and hard to implement.
  99. Since the standard does not define a byte order for such
  100. transmission, the byte stream would also have to carry
  101. state to enable the values to be recovered.
  102. .PP
  103. The Unicode Standard is a proposal by a consortium of mostly American
  104. computer companies formed
  105. to protest the technical
  106. failings of ISO 10646.
  107. It defines a uniform 16-bit code based on the
  108. principle of unification:
  109. two characters are the same if they look the
  110. same even though they are from different
  111. languages.
  112. This principle, called Han unification,
  113. allows the large Japanese, Chinese, and Korean
  114. character sets to be packed comfortably into a 16-bit representation.
  115. .PP
  116. We chose the Unicode Standard for its technical merits and because its
  117. code space was better defined.
  118. Moreover,
  119. the Unicode Consortium was derailing the
  120. ISO 10646 standard.
  121. (Now, in 1995,
  122. ISO 10646 is a standard
  123. with one 16-bit group defined,
  124. which is almost exactly the Unicode Standard.
  125. As most people expected, the two standards bodies
  126. reached a détente and
  127. ISO 10646 and Unicode represent the same character set.)
  128. .PP
  129. The Unicode Standard defines an adequate character set
  130. but an unreasonable representation.
  131. It states that all characters
  132. are 16 bits wide and are communicated and stored in
  133. 16-bit units.
  134. It also reserves a pair of characters
  135. (hexadecimal FFFE and FEFF) to detect byte order
  136. in transmitted text, requiring state in the byte stream.
  137. (The Unicode Consortium was thinking of files, not pipes.)
  138. To adopt this encoding,
  139. we would have had to convert all text going
  140. into and out of Plan 9 between ASCII and Unicode, which cannot be done.
  141. Within a single program, in command of all its input and output,
  142. it is possible to define characters as 16-bit quantities;
  143. in the context of a networked system with
  144. hundreds of applications on diverse machines
  145. by different manufacturers,
  146. it is impossible.
  147. .PP
  148. We needed a way to adapt the Unicode Standard to the tools-and-pipes
  149. model of text processing embodied by the Unix system.
  150. To do that, we
  151. needed an ASCII-compatible textual
  152. representation of Unicode characters for transmission
  153. and storage.
  154. In the draft ISO standard there was an informative
  155. (non-required)
  156. Annex
  157. called UTF
  158. that provided a byte stream encoding
  159. of the 32-bit ISO code.
  160. The encoding uses multibyte sequences composed
  161. from the 190 printable characters of Latin-1
  162. to represent character values larger
  163. than 159.
  164. .PP
  165. The UTF encoding has several good properties.
  166. By far the most important is that
  167. a byte in the ASCII range 0-127 represents
  168. itself in UTF.
  169. Thus UTF is backward compatible with ASCII.
  170. .PP
  171. UTF has other advantages.
  172. It is a byte encoding and is
  173. therefore byte-order independent.
  174. ASCII control characters appear in the byte stream
  175. only as themselves, never as an element of a sequence
  176. encoding another character,
  177. so newline bytes separate lines of UTF text.
  178. Finally, ANSI C's
  179. .CW strcmp
  180. function applied to UTF strings preserves the ordering of Unicode characters.
  181. .PP
  182. To encode and decode UTF is expensive (involving multiplication,
  183. division, and modulo operations) but workable.
  184. UTF's major disadvantage is that the encoding
  185. is not self-synchronizing.
  186. It is in general impossible to find the character
  187. boundaries in a UTF string without reading from
  188. the beginning of the string, although in practice
  189. control characters such as newlines,
  190. tabs, and blanks provide synchronization points.
  191. .PP
  192. In August 1992,
  193. X-Open circulated a proposal for another UTF-like
  194. byte encoding of Unicode characters.
  195. Their major concern was that an embedded character
  196. in a file name
  197. (in particular a slash)
  198. could be part of an escape sequence in UTF and
  199. therefore confuse a traditional file system.
  200. Their proposal would allow all 7-bit ASCII characters
  201. to represent themselves
  202. .I "and only themselves"
  203. in text.
  204. Multibyte sequences would contain only characters
  205. with the high bit set.
  206. We proposed a modification to the new UTF that
  207. would address our synchronization problem.
  208. Our proposal, which was originally known informally as UTF-2 and FSS-UTF,
  209. is now referred to as UTF-8 and has been approved by ISO to become
  210. Annex P to ISO 10646.
  211. .PP
  212. The model for text in Plan 9 is chosen from these
  213. three standards*:
  214. .FS
  215. * ``That's the nice thing about standards\(emthere's so many to choose from.'' \- Andy Tannenbaum (no, the other one)
  216. .FE
  217. the Unicode character set encoded as a byte stream by
  218. UTF-8, from
  219. (soon to be) Annex P of ISO 10646.
  220. Although this mixture may seem like a precarious position for us to adopt,
  221. it is not as bad as it sounds.
  222. ISO 10646 and the Unicode Standard have converged,
  223. other systems such as Linux have adopted the same character set and encoding,
  224. and the general feeling seems to be that Unicode and UTF-8 will be accepted as the way
  225. to exchange text between systems.
  226. The prognosis for wide acceptance is good.
  227. .PP
  228. There are a couple of aspects of the Unicode Standard we have not faced.
  229. One is the issue of right-to-left text such as Hebrew or Arabic.
  230. Since that is an issue of display, not representation, we believe
  231. we can defer that problem for the moment without affecting our
  232. ability to solve it later.
  233. Another issue is diacriticals and `combining characters',
  234. which cause overstriking of multiple Unicode characters.
  235. Although necessary for some scripts, such as Thai, Arabic, and Hebrew,
  236. such characters confuse the issues for Latin languages because they
  237. generate multiple representations for accented characters.
  238. ISO 10646 describes three levels of implementation;
  239. in Plan 9 we decided not to address the issue.
  240. Again, this can be labeled as a display issue and its finer points are still being debated,
  241. so we felt comfortable deferring. Mañana.
  242. .PP
  243. Although we converted Plan 9 in the altruistic interests of
  244. serving foreign languages, we have found the large character
  245. set attractive for other reasons. The Unicode Standard includes many
  246. characters\(emmathematical symbols, scientific notation,
  247. more general punctuation, and more\(emthat we now use
  248. daily in our work. We no longer test our imaginations
  249. to find ways to include non-ASCII symbols in our text;
  250. why type
  251. .CW :-)
  252. when you can use the character ☺?
  253. Most compelling is the ability to absorb documents
  254. and data that contain non-ASCII characters; our browser for the
  255. Oxford English Dictionary
  256. lets us see the dictionary as it really is, with pronunciation
  257. in the IPA font, foreign phrases properly rendered, and so on,
  258. .I "in plain text.
  259. .PP
  260. In the rest of this paper, except when
  261. stated otherwise, the term `UTF' refers to the UTF-8 encoding
  262. of Unicode characters as adopted by Plan 9.
  263. .SH
  264. C Compiler
  265. .PP
  266. The first program to be converted to UTF
  267. was the C Compiler.
  268. There are two levels of conversion.
  269. On the syntactic level,
  270. input to the C compiler
  271. is UTF; on the semantic level,
  272. the C language needs to define
  273. how compiled programs manipulate
  274. the UTF set.
  275. .PP
  276. The syntactic part is simple.
  277. The ANSI C language standard defines the
  278. source character set to be ASCII.
  279. Since UTF is backward compatible with ASCII,
  280. the compiler needs little change.
  281. The only places where a larger character set
  282. is allowed are in character constants, strings, and comments.
  283. Since 7-bit ASCII characters can represent only
  284. themselves in UTF,
  285. the compiler does not have to be careful while looking
  286. for the termination of a string or comment.
  287. .PP
  288. The Plan 9 compiler extends ANSI C to treat any Unicode
  289. character with a value outside of the ASCII range as
  290. an alphabetic.
  291. To a Greek programmer or an English mathematician,
  292. α is a sensible and now valid variable name.
  293. .PP
  294. On the semantic level, ANSI C allows,
  295. but does not tie down,
  296. the notion of a
  297. .I "wide character
  298. and admits string and character constants
  299. of this type.
  300. We chose the wide character type to be
  301. .CW unsigned
  302. .CW short .
  303. In the libraries, the word
  304. .CW Rune
  305. is defined by a
  306. .CW typedef
  307. to be equivalent to
  308. .CW unsigned
  309. .CW short
  310. and is
  311. used to signify a Unicode character.
  312. .PP
  313. There are surprises; for example:
  314. .P1
  315. L'x' \f1is 120\fP
  316. \&'x' \f1is 120\fP
  317. L'ÿ' \f1is 255\fP
  318. \&'ÿ' \f1is -1, stdio \fPEOF\f1 (if \fPchar\f1 is signed)\fP
  319. L'\f1α\fP' \f1is 945\fP
  320. \&'\f1α\fP' \f1is illegal\fP
  321. .P2
  322. In the string constants,
  323. .P1
  324. "\f(Jpこんにちは 世界\fP"
  325. L"\f(Jpこんにちは 世界\fP",
  326. .P2
  327. the former is an array of
  328. .CW chars
  329. with 22 elements
  330. and a null byte,
  331. while the latter is an array of
  332. .CW unsigned
  333. .CW shorts
  334. .CW Runes ) (
  335. with 8 elements and a null
  336. .CW Rune .
  337. .PP
  338. The Plan 9 library provides an output conversion function,
  339. .CW print
  340. (analogous to
  341. .CW printf ),
  342. with formats
  343. .CW %c ,
  344. .CW %C ,
  345. .CW %s ,
  346. and
  347. .CW %S .
  348. Since
  349. .CW print
  350. produces text, its output is always UTF.
  351. The character conversion
  352. .CW %c
  353. (lower case) masks its argument
  354. to 8 bits before converting to UTF.
  355. Thus
  356. .CW L'ÿ'
  357. and
  358. .CW 'ÿ'
  359. printed under
  360. .CW %c
  361. will be identical,
  362. but
  363. .CW L'\f1α\fP'
  364. will print as the Unicode
  365. character with decimal value 177.
  366. The character conversion
  367. .CW %C
  368. (upper case) masks its argument
  369. to 16 bits before converting to UTF.
  370. Thus
  371. .CW L'ÿ'
  372. and
  373. .CW L'\f1α\fP'
  374. will print correctly under
  375. .CW %C ,
  376. but
  377. .CW 'ÿ'
  378. will not.
  379. The conversion
  380. .CW %s
  381. (lower case)
  382. expects a pointer to
  383. .CW char
  384. and copies UTF sequences up to a null byte.
  385. The conversion
  386. .CW %S
  387. (upper case) expects a pointer to
  388. .CW Rune
  389. and
  390. performs sequential
  391. .CW %C
  392. conversions until a null
  393. .CW Rune
  394. is encountered.
  395. .PP
  396. Another problem in format conversion
  397. is the definition of
  398. .CW %10s :
  399. does the number refer to bytes or characters?
  400. We decided that such formats were most
  401. often used to align output columns and
  402. so made the number count characters.
  403. Some programs, however, use the count
  404. to place blank-padded strings
  405. in fixed-sized arrays.
  406. These programs must be found and corrected.
  407. .PP
  408. Here is a complete example:
  409. .P1
  410. #include <u.h>
  411. char c[] = "\f(Jpこんにちは 世界\fP";
  412. Rune s[] = L"\f(Jpこんにちは 世界\fP";
  413. main(void)
  414. {
  415. print("%d, %d\en", sizeof(c), sizeof(s));
  416. print("%s\en", c);
  417. print("%S\en", s);
  418. }
  419. .P2
  420. .PP
  421. This program prints
  422. .CW 23,
  423. .CW 18
  424. and then two identical lines of
  425. UTF text.
  426. In practice,
  427. .CW %S
  428. and
  429. .CW L"..."
  430. are rare in programs; one reason is
  431. that most formatted I/O is done in unconverted UTF.
  432. .SH
  433. Ramifications
  434. .PP
  435. All programs in Plan 9 now read and write text as UTF, not ASCII.
  436. This change breaks two deep-rooted symmetries implicit in most C programs:
  437. .IP 1.
  438. A character is no longer a
  439. .CW char .
  440. .IP 2.
  441. The internal representation (Rune) of a character now differs from its
  442. external representation (UTF).
  443. .PP
  444. In the sections that follow,
  445. we show how these issues were faced in the layers of
  446. system software from the operating system up to the applications.
  447. The effects are wide-reaching and often surprising.
  448. .SH
  449. Operating system
  450. .PP
  451. Since UTF is the only format for text in Plan 9,
  452. the interface to the operating system had to be converted to UTF.
  453. Text strings cross the interface in several places:
  454. command arguments,
  455. file names,
  456. user names (people can log in using their native name),
  457. error messages,
  458. and miscellaneous minor places such as commands to the I/O system.
  459. Little change was required: null-terminated UTF strings
  460. are equivalent to null-terminated ASCII strings for most purposes
  461. of the operating system.
  462. The library routines described in the next section made that
  463. change straightforward.
  464. .PP
  465. The window system, once called
  466. .CW 8.5 ,
  467. is now rightfully called
  468. .CW 8½ .
  469. .SH
  470. Libraries
  471. .PP
  472. A header file included by all programs (see [Pike92]) declares
  473. the
  474. .CW Rune
  475. type to hold 16-bit character values:
  476. .P1
  477. typedef unsigned short Rune;
  478. .P2
  479. Also defined are several constants relevant to UTF:
  480. .P1
  481. enum
  482. {
  483. UTFmax = 3, /* maximum bytes per rune */
  484. Runesync = 0x80, /* can't appear in UTF sequence (<) */
  485. Runeself = 0x80, /* rune==UTF sequence (<) */
  486. Runeerror = 0x80, /* decoding error in UTF */
  487. };
  488. .P2
  489. (With the original UTF,
  490. .CW Runesync
  491. was hexadecimal 21 and
  492. .CW Runeself
  493. was A0.)
  494. .CW UTFmax
  495. bytes are sufficient
  496. to hold the UTF encoding of any Unicode character.
  497. Characters of value less than
  498. .CW Runesync
  499. only appear in a UTF string as
  500. themselves, never as part of a sequence encoding another character.
  501. Characters of value less than
  502. .CW Runeself
  503. encode into single bytes
  504. of the same value.
  505. Finally, when the library detects errors in UTF input\(embyte sequences
  506. that are not valid UTF sequences\(emit converts the first byte of the
  507. error sequence to the character
  508. .CW Runeerror .
  509. There is little a rune-oriented program can do when given bad data
  510. except exit, which is unreasonable, or carry on.
  511. Originally the conversion routines, described below,
  512. returned errors when given invalid UTF,
  513. but we found ourselves repeatedly checking for errors and ignoring them.
  514. We therefore decided to convert a bad sequence to a valid rune
  515. and continue processing.
  516. (The ANSI C routines, on the other hand, return errors.)
  517. .PP
  518. This technique does have the unfortunate property that converting
  519. invalid UTF byte strings in and out of runes does not preserve the input,
  520. but this circumstance only occurs when non-textual input is
  521. given to a textual program.
  522. The Unicode Standard defines an error character, value FFFD, to stand for
  523. characters from other sets that it does not represent.
  524. The
  525. .CW Runeerror
  526. character is a different concept, related to the encoding rather than the character set, so we
  527. chose a different character for it.
  528. .PP
  529. The Plan 9 C library contains a number of routines for
  530. manipulating runes.
  531. The first set converts between runes and UTF strings:
  532. .P1
  533. extern int runetochar(char*, Rune*);
  534. extern int chartorune(Rune*, char*);
  535. extern int runelen(long);
  536. extern int fullrune(char*, int);
  537. .P2
  538. .CW Runetochar
  539. translates a single
  540. .CW Rune
  541. to a UTF sequence and returns the number of bytes produced.
  542. .CW Chartorune
  543. goes the other way, reporting how many bytes were consumed.
  544. .CW Runelen
  545. returns the number of bytes in the UTF encoding of a rune.
  546. .CW Fullrune
  547. examines a UTF string up to a specified number of bytes
  548. and reports whether the string begins with a complete UTF encoding.
  549. All these routines use the
  550. .CW Runeerror
  551. character to work around encoding problems.
  552. .PP
  553. There is also a set of routines for examining null-terminated UTF strings,
  554. based on the model of the ANSI standard
  555. .CW str
  556. routines, but with
  557. .CW utf
  558. substituted for
  559. .CW str
  560. and
  561. .CW rune
  562. for
  563. .CW chr :
  564. .P1
  565. extern int utflen(char*);
  566. extern char* utfrune(char*, long);
  567. extern char* utfrrune(char*, long);
  568. extern char* utfutf(char*, char*);
  569. .P2
  570. .CW Utflen
  571. returns the number of runes in a UTF string;
  572. .CW utfrune
  573. returns a pointer to the first occurrence of a rune in a UTF string;
  574. and
  575. .CW utfrrune
  576. a pointer to the last.
  577. .CW Utfutf
  578. searches for the first occurrence of a UTF string in another UTF string.
  579. Given the synchronizing property of UTF-8,
  580. .CW utfutf
  581. is the same as
  582. .CW strstr
  583. if the arguments point to valid UTF strings.
  584. .PP
  585. It is a mistake to use
  586. .CW strchr
  587. or
  588. .CW strrchr
  589. unless searching for a 7-bit ASCII character, that is, a character
  590. less than
  591. .CW Runeself .
  592. .PP
  593. We have no routines for manipulating null-terminated arrays of
  594. .CW Runes .
  595. Although they should probably exist for completeness, we have
  596. found no need for them, for the same reason that
  597. .CW %S
  598. and
  599. .CW L"..."
  600. are rarely used.
  601. .PP
  602. Most Plan 9 programs use a new buffered I/O library, BIO, in place of
  603. Standard I/O.
  604. BIO contains routines to read and write UTF streams, converting to and from
  605. runes.
  606. .CW Bgetrune
  607. returns, as a
  608. .CW Rune
  609. within a
  610. .CW long ,
  611. the next character in the UTF input stream;
  612. .CW Bputrune
  613. takes a rune and writes its UTF representation.
  614. .CW Bungetrune
  615. puts a rune back into the input stream for rereading.
  616. .PP
  617. Plan 9 programs use a simple set of macros to process command line arguments.
  618. Converting these macros to UTF automatically updated the
  619. argument processing of most programs.
  620. In general,
  621. argument flag names can no longer be held in bytes and
  622. arrays of 256 bytes cannot be used to hold a set of flags.
  623. .PP
  624. We have done nothing analogous to ANSI C's locales, partly because
  625. we do not feel qualified to define locales and partly because we remain
  626. unconvinced of that model for dealing with the problems.
  627. That is really more an issue of internationalization than conversion
  628. to a larger character set; on the other hand,
  629. because we have chosen a single character set that encompasses
  630. most languages, some of the need for
  631. locales is eliminated.
  632. (We have a utility,
  633. .CW tcs ,
  634. that translates between UTF and other character sets.)
  635. .PP
  636. There are several reasons why our library does not follow the ANSI design
  637. for wide and multi-byte characters.
  638. The ANSI model was designed by a committee, untried, almost
  639. as an afterthought, whereas
  640. we wanted to design as we built.
  641. (We made several major changes to the interface
  642. as we became familiar with the problems involved.)
  643. We disagree with ANSI C's handling of invalid multi-byte sequences.
  644. Also, the ANSI C library is incomplete:
  645. although it contains some crucial routines for handling
  646. wide and multi-byte characters, there are some serious omissions.
  647. For example, our software can exploit
  648. the fact that UTF preserves ASCII characters in the byte stream.
  649. We could remove that assumption by replacing all
  650. calls to
  651. .CW strchr
  652. with
  653. .CW utfrune
  654. and so on.
  655. (Because of the weaker properties of the original UTF,
  656. we have actually done so.)
  657. ANSI C cannot:
  658. the standard says nothing about the representation, so portable code should
  659. .I never
  660. call
  661. .CW strchr ,
  662. yet there is no ANSI equivalent to
  663. .CW utfrune .
  664. ANSI C simultaneously invalidates
  665. .CW strchr
  666. and offers no replacement.
  667. .PP
  668. Finally, ANSI did nothing to integrate wide characters
  669. into the I/O system: it gives no method for printing
  670. wide characters.
  671. We therefore needed to invent some things and decided to invent
  672. everything.
  673. In the end, some of our entry points do correspond closely to
  674. ANSI routines\(emfor example
  675. .CW chartorune
  676. and
  677. .CW runetochar
  678. are similar to
  679. .CW mbtowc
  680. and
  681. .CW wctomb \(embut
  682. Plan 9's library defines more functionality, enough
  683. to write real applications comfortably.
  684. .SH
  685. Converting the tools
  686. .PP
  687. The source for our tools and applications had already been converted to
  688. work with Latin-1, so it was `8-bit safe', but the conversion to the Unicode
  689. Standard and UTF is more involved.
  690. Some programs needed no change at all:
  691. .CW cat ,
  692. for instance,
  693. interprets its argument strings, delivered in UTF,
  694. as file names that it passes uninterpreted to the
  695. .CW open
  696. system call,
  697. and then just copies bytes from its input to its output;
  698. it never makes decisions based on the values of the bytes.
  699. (Plan 9
  700. .CW cat
  701. has no options such as
  702. .CW -v
  703. to complicate matters.)
  704. Most programs, however, needed modest change.
  705. .PP
  706. It is difficult to
  707. find automatically the places that need attention,
  708. but
  709. .CW grep
  710. helps.
  711. Software that uses the libraries conscientiously can be searched
  712. for calls to library routines that examine bytes as characters:
  713. .CW strchr ,
  714. .CW strrchr ,
  715. .CW strstr ,
  716. etc.
  717. Replacing these by calls to
  718. .CW utfrune ,
  719. .CW utfrrune ,
  720. and
  721. .CW utfutf
  722. is enough to fix many programs.
  723. Few tools actually need to operate on runes internally;
  724. more typically they need only to look for the final slash in a file
  725. name and similar trivial tasks.
  726. Of the 170 C source programs in the top levels of
  727. .CW /sys/src/cmd ,
  728. only 23 now contain the word
  729. .CW Rune .
  730. .PP
  731. The programs that
  732. .I do
  733. store runes internally
  734. are mostly those whose
  735. .I raison
  736. .I d'être
  737. is character manipulation:
  738. .CW sam
  739. (the text editor),
  740. .CW sed ,
  741. .CW sort ,
  742. .CW tr ,
  743. .CW troff ,
  744. .CW 8½
  745. (the window system and terminal emulator),
  746. and so on.
  747. To decide whether to compute using runes
  748. or UTF-encoded byte strings requires balancing the cost of converting
  749. the data when read and written
  750. against the cost of converting relevant text on demand.
  751. For programs such as editors that run a long time with a relatively
  752. constant dataset, runes are the better choice.
  753. There are space considerations too, but they are more complicated:
  754. plain ASCII text grows when converted to runes; UTF-encoded Japanese
  755. shrinks.
  756. .PP
  757. Again, it is hard to automate the conversion of a program from
  758. .CW chars
  759. to
  760. .CW Runes .
  761. It is not enough just to change the type of variables; the assumption
  762. that bytes and characters are equivalent can be insidious.
  763. For instance, to clear a character array by
  764. .P1
  765. memset(buf, 0, BUFSIZE)
  766. .P2
  767. becomes wrong if
  768. .CW buf
  769. is changed from an array of
  770. .CW chars
  771. to an array of
  772. .CW Runes .
  773. Any program that indexes tables based on character values needs
  774. rethinking.
  775. Consider
  776. .CW tr ,
  777. which originally used multiple 256-byte arrays for the mapping.
  778. The naïve conversion would yield multiple 65536-rune arrays.
  779. Instead Plan 9
  780. .CW tr
  781. saves space by building in effect
  782. a run-encoded version of the map.
  783. .PP
  784. .CW Sort
  785. has related problems.
  786. The cooperation of UTF and
  787. .CW strcmp
  788. means that a simple sort\(emone with no options\(emcan be done
  789. on the original UTF strings using
  790. .CW strcmp .
  791. With sorting options enabled, however,
  792. .CW sort
  793. may need to convert its input to runes: for example,
  794. option
  795. .CW -t\f1α\fP
  796. requires searching for alphas in the input text to
  797. crack the input into fields.
  798. The field specifier
  799. .CW +3.2
  800. refers to 2 runes beyond the third field.
  801. Some of the other options are hopelessly provincial:
  802. consider the case-folding and dictionary order options
  803. (Japanese doesn't even have an official dictionary order) or
  804. .CW -M
  805. which compares by case-insensitive English month name.
  806. Handling these options involves the
  807. larger issues of internationalization and is beyond the scope
  808. of this paper and our expertise.
  809. Plan 9
  810. .CW sort
  811. works sensibly with options that make sense relative to the input.
  812. The simple and most important options are, however, usually meaningful.
  813. In particular,
  814. .CW sort
  815. sorts UTF into the same order that
  816. .CW look
  817. expects.
  818. .PP
  819. Regular expression-matching algorithms need rethinking to
  820. be applied to UTF text.
  821. Deterministic automata are usually applied to bytes;
  822. converting them to operate on variable-sized byte sequences is awkward.
  823. On the other hand, converting the input stream to runes adds measurable
  824. expense
  825. and the state tables expand
  826. from size 256 to 65536; it can be expensive just to generate them.
  827. For simple string searching,
  828. the Boyer-Moore algorithm works with UTF provided the input is
  829. guaranteed to be only valid UTF strings; however, it does not work
  830. with the old UTF encoding.
  831. At a more mundane level, even character classes are harder:
  832. the usual bit-vector representation within a non-deterministic automaton
  833. is unwieldy with 65536 characters in the alphabet.
  834. .PP
  835. We compromised.
  836. An existing library for compiling and executing regular expressions
  837. was adapted to work on runes, with two entry points for searching
  838. in arrays of runes and arrays of chars (the pattern is always UTF text).
  839. Character classes are represented internally as runs of runes;
  840. the reserved value
  841. .CW FFFF
  842. marks the end of the class.
  843. Then
  844. .I all
  845. utilities that use regular expressions\(emeditors,
  846. .CW grep ,
  847. .CW awk ,
  848. etc.\(emexcept the shell, whose notation
  849. was grandfathered, were converted to use the library.
  850. For some programs, there was a concomitant loss of performance,
  851. but there was also a strong advantage.
  852. To our knowledge, Plan 9 is the only Unix-like system
  853. that has a single definition and implementation of
  854. regular expressions; patterns are written and interpreted
  855. identically by all the programs in the system.
  856. .PP
  857. A handful of programs have the notion of character built into them
  858. so strongly as to confuse the issue of what they should do with UTF input.
  859. Such programs were treated as individual special cases.
  860. For example,
  861. .CW wc
  862. is, by default, unchanged in behavior and output; a new option,
  863. .CW -r ,
  864. counts the number of correctly encoded runes\(emvalid UTF sequences\(emin
  865. its input;
  866. .CW -b
  867. the number of invalid sequences.
  868. .PP
  869. It took us several months to convert all the software in the system
  870. to the Unicode Standard and the old UTF.
  871. When we decided to convert from that to the new UTF,
  872. only three things needed to be done.
  873. First, we rewrote the library routines to encode and decode the
  874. new UTF. This took an evening.
  875. Next, we converted all the files containing UTF
  876. to the new encoding.
  877. We wrote a trivial program to look for non-ASCII bytes in
  878. text files and used a Plan 9 program called
  879. .CW tcs
  880. (translate character set) to change encodings.
  881. Finally, we recompiled all the system software;
  882. the library interface was unchanged, so recompilation was sufficient
  883. to effect the transformation.
  884. The second two steps were done concurrently and took an afternoon.
  885. We concluded that the actual encoding is relatively unimportant to the
  886. software; the adoption of large characters and a byte-stream encoding
  887. .I per
  888. .I se
  889. are much deeper issues.
  890. .SH
  891. Graphics and fonts
  892. .PP
  893. Plan 9 provides only minimal support for plain text terminals.
  894. It is instead designed to be used with all character input and
  895. output mediated by a window system such as
  896. .CW 8½ .
  897. The window system and related software are responsible for the
  898. display of UTF text as Unicode character images.
  899. For plain text, the window system must provide a user-settable
  900. .I font
  901. that provides a (possibly empty) picture for each Unicode character.
  902. Fancier applications that use bold and Italic characters
  903. need multiple fonts storing multiple pictures for each
  904. Unicode value.
  905. All the issues are apparent, though,
  906. in just the problem of
  907. displaying a single image for each character, that is, the
  908. Unicode equivalent of a plain text terminal.
  909. With 128 or even 256 characters, a font can be just
  910. an array of bitmaps. With 65536 characters,
  911. a more sophisticated design is necessary. To store the ideographs
  912. for just Japanese as 16×16×1 bit images,
  913. the smallest they can reasonably be, takes over a quarter of a
  914. megabyte. Make the images a little larger, store more bits per
  915. pixel, and hold a copy in every running application, and the
  916. memory cost becomes unreasonable.
  917. .PP
  918. The structure of the bitmap graphics services is described at length elsewhere
  919. [Pike91].
  920. In summary, the memory holding the bitmaps is stored in the same machine that has
  921. the display, mouse, and keyboard: the terminal in Plan 9 terminology,
  922. the workstation in others'.
  923. Access to that memory and associated services is provided
  924. by device files served by system
  925. software on the terminal. One of those files,
  926. .CW /dev/bitblt ,
  927. interprets messages written upon it as requests for actions
  928. corresponding to entry points in the graphics library:
  929. allocate a bitmap, execute a raster operation, draw a text string, etc.
  930. The window system
  931. acts as a multiplexer that mediates access to the services
  932. and resources of the terminal by simulating in each client window
  933. a set of files mirroring those provided by the system.
  934. That is, each window has a distinct
  935. .CW /dev/mouse ,
  936. .CW /dev/bitblt ,
  937. and so on through which applications drive graphical
  938. input and output.
  939. .PP
  940. One of the resources managed by
  941. .CW 8½
  942. and the terminal is the set of active
  943. .I subfonts.
  944. Each subfont holds the
  945. bitmaps and associated data structures for a sequential set of Unicode
  946. characters.
  947. Subfonts are stored in files and loaded into the terminal by
  948. .CW 8½
  949. or an application.
  950. For example, one subfont
  951. might hold the images of the first 256 characters of the Unicode space,
  952. corresponding to the Latin-1 character set;
  953. another might hold the standard phonetic character set, Unicode characters
  954. with value 0250 to 02E9.
  955. These files are collected in directories corresponding to typefaces:
  956. .CW /lib/font/bit/pelm
  957. contains the Pellucida Monospace character set, with subfonts holding
  958. the Latin-1, Greek, Cyrillic and other components of the typeface.
  959. A suffix on subfont files encodes (in a subfont-specific
  960. way) the size of the images:
  961. .CW /lib/font/bit/pelm/latin1.9
  962. contains the Latin-1 Pellucida Monospace characters with lower
  963. case letters 9 pixels high;
  964. .CW /lib/font/bit/jis/jis5400.16
  965. contains 16-pixel high
  966. ideographs starting at Unicode value 5400.
  967. .PP
  968. The subfonts do not identify which portion of the Unicode space
  969. they cover. Instead, a
  970. font file, in plain text,
  971. describes how to assemble subfonts into a complete
  972. character set.
  973. The font file is presented as an argument to the window system
  974. to determine how plain text is displayed in text windows and
  975. applications.
  976. Here is the beginning of the font file
  977. .CW /lib/font/bit/pelm/jis.9.font ,
  978. which describes the layout of a font covering that portion of
  979. the Unicode Standard for which we have characters of typical
  980. display size, using Japanese characters
  981. to cover the Han space:
  982. .P1
  983. 18 14
  984. 0x0000 0x00FF latin1.9
  985. 0x0100 0x017E latineur.9
  986. 0x0250 0x02E9 ipa.9
  987. 0x0386 0x03F5 greek.9
  988. 0x0400 0x0475 cyrillic.9
  989. 0x2000 0x2044 ../misc/genpunc.9
  990. 0x2070 0x208E supsub.9
  991. 0x20A0 0x20AA currency.9
  992. 0x2100 0x2138 ../misc/letterlike.9
  993. 0x2190 0x21EA ../misc/arrows
  994. 0x2200 0x227F ../misc/math1
  995. 0x2280 0x22F1 ../misc/math2
  996. 0x2300 0x232C ../misc/tech
  997. 0x2500 0x257F ../misc/chart
  998. 0x2600 0x266F ../misc/ding
  999. .P2
  1000. .P1
  1001. 0x3000 0x303f ../jis/jis3000.16
  1002. 0x30a1 0x30fe ../jis/katakana.16
  1003. 0x3041 0x309e ../jis/hiragana.16
  1004. 0x4e00 0x4fff ../jis/jis4e00.16
  1005. 0x5000 0x51ff ../jis/jis5000.16
  1006. \&...
  1007. .P2
  1008. The first two numbers set the interline spacing of the font (18
  1009. pixels) and the distance from the baseline to the top of the
  1010. line (14 pixels).
  1011. When characters are displayed, they are placed so as best
  1012. to fit within those constraints; characters
  1013. too large to fit will be truncated.
  1014. The rest of the file associates subfont files
  1015. with portions of Unicode space.
  1016. The first four such files are in the Pellucida Monospace typeface
  1017. and directory; others reside in other directories. The file names
  1018. are relative to the font file's own location.
  1019. .PP
  1020. There are several advantages to this two-level structure.
  1021. First, it simultaneously breaks the huge Unicode space into manageable
  1022. components and provides a unifying architecture for
  1023. assembling fonts from disjoint pieces.
  1024. Second, the structure promotes sharing.
  1025. For example, we have only one set of Japanese
  1026. characters but dozens of typefaces for the Latin-1 characters,
  1027. and this structure permits us to store only one copy of the
  1028. Japanese set but use it with any Roman typeface.
  1029. Also, customization is easy.
  1030. English-speaking users who don't need Japanese characters
  1031. but may want to read an on-line Oxford English Dictionary can
  1032. assemble a custom font with the
  1033. Latin-1 (or even just ASCII) characters and the International
  1034. Phonetic Alphabet (IPA).
  1035. Moreover, to do so requires just editing a plain text file,
  1036. not using a special font editing tool.
  1037. Finally, the structure guides the design of
  1038. caching protocols to improve performance and memory usage.
  1039. .PP
  1040. To load a complete Unicode character set into each application
  1041. would consume too
  1042. much memory and, particularly on slow terminal lines, would take
  1043. unreasonably long.
  1044. Instead, Plan 9 assembles a multi-level cache structure for
  1045. each font.
  1046. An application opens a font file, reads and parses it,
  1047. and allocates a data structure.
  1048. A message written to
  1049. .CW /dev/bitblt
  1050. allocates an associated structure held in the terminal, in particular,
  1051. a bitmap to act as a cache
  1052. for recently used character images.
  1053. Other messages copy these images to bitmaps such as the screen
  1054. by loading characters from subfonts into the cache on demand and
  1055. from there to the destination bitmap.
  1056. The protocol to draw characters is in terms of cache indices,
  1057. not Unicode character number or UTF sequences.
  1058. These details are hidden from the application, which instead
  1059. sees only a subroutine to draw a string in a bitmap from a
  1060. given font, functions to discover character size information,
  1061. and routines to allocate and to free fonts.
  1062. .PP
  1063. As needed, whole
  1064. subfonts are opened by the graphics library, read, and then downloaded
  1065. to the terminal.
  1066. They are held open by the library in an LRU-replacement list.
  1067. Even when the program closes a subfont, it is retained
  1068. in the terminal for later use.
  1069. When the application opens the subfont, it asks the terminal
  1070. if it already has a copy to avoid reading it from the file
  1071. server if possible.
  1072. This level of cache has the property that the bitmaps for, say,
  1073. all the Japanese characters are stored only once, in the terminal;
  1074. the applications read only size and width information from the terminal
  1075. and share the images.
  1076. .PP
  1077. The sizes of the character and subfont caches held by the
  1078. application are adaptive.
  1079. A simple algorithm monitors the cache miss rate to enlarge and
  1080. shrink the caches as required.
  1081. The size of the character cache is limited to 2048 images maximum,
  1082. which in practice seems enough even for Japanese text.
  1083. For plain ASCII-like text it naturally stays around 128 images.
  1084. .PP
  1085. This mechanism sounds complicated but is implemented by only about
  1086. 500 lines in the library and considerably less in each of the
  1087. terminal's graphics driver and
  1088. .CW 8½ .
  1089. It has the advantage that only characters that are
  1090. being used are loaded into memory.
  1091. It is also efficient: if the characters being drawn
  1092. are in the cache the extra overhead is negligible.
  1093. It works particularly well for alphabetic character sets,
  1094. but also adapts on demand for ideographic sets.
  1095. When a user first looks at Japanese text, it takes a few
  1096. seconds to read all the font data, but thereafter the
  1097. text is drawn almost as fast as regular text (the images
  1098. are larger, so draw a little slower).
  1099. Also, because the bitmaps are remembered by the terminal,
  1100. if a second application then looks at Japanese text
  1101. it starts faster than the first.
  1102. .PP
  1103. We considered
  1104. building a `font server'
  1105. to cache character images and associated data
  1106. for the applications, the window system, and the terminal.
  1107. We rejected this design because, although isolating
  1108. many of the problems of font management into a separate program,
  1109. it didn't simplify the applications.
  1110. Moreover, in a distributed system such as Plan 9 it is easy
  1111. to have too many special purpose servers.
  1112. Making the management of the fonts the concern of only
  1113. the essential components simplifies the system and makes
  1114. bootstrapping less intricate.
  1115. .SH
  1116. Input
  1117. .PP
  1118. A completely different problem is how to type Unicode characters
  1119. as input to the system.
  1120. We selected an unused key on our ASCII keyboards
  1121. to serve as a prefix for multi-keystroke
  1122. sequences that generate Unicode characters.
  1123. For example, the character
  1124. .CW ü
  1125. is generated by the prefix key
  1126. (typically
  1127. .CW ALT
  1128. or
  1129. .CW Compose )
  1130. followed by a double quote and a lower-case
  1131. .CW u .
  1132. When that character is read by the application, from the file
  1133. .CW /dev/cons ,
  1134. it is of course presented as its UTF encoding.
  1135. Such sequences generate characters from an arbitrary set that
  1136. includes all of Latin-1 plus a selection of mathematical
  1137. and technical characters.
  1138. An arbitrary Unicode character may be generated by typing the prefix,
  1139. an upper case X, and four hexadecimal digits that identify
  1140. the Unicode value.
  1141. .PP
  1142. These simple mechanisms are adequate for most of our day-to-day needs:
  1143. it's easy to remember to type `ALT 1 2' for ½\^ or `ALT accent letter'
  1144. for accented Latin letters.
  1145. For the occasional unusual character, the cut and paste features of
  1146. .CW 8½
  1147. serve well. A program called (perhaps misleadingly)
  1148. .CW unicode
  1149. takes as argument a hexadecimal value, and prints the UTF representation of that character,
  1150. which may then be picked up with the mouse and used as input.
  1151. .PP
  1152. These methods
  1153. are clearly unsatisfactory when working in a non-English language.
  1154. In the native country of such a language
  1155. the appropriate keyboard is likely to be at hand.
  1156. But it's also reasonable\(emespecially now that the system handles Unicode characters\(emto
  1157. work in a language foreign to the keyboard.
  1158. .PP
  1159. For alphabetic languages such as Greek or Russian, it is
  1160. straightforward to construct a program that does phonetic substitution,
  1161. so that, for example, typing a Latin `a' yields the Greek `α'.
  1162. Within Plan 9, such a program can be inserted transparently
  1163. between the real keyboard and a program such as the window system,
  1164. providing a manageable input device for such languages.
  1165. .PP
  1166. For ideographic languages such as Chinese or Japanese the problem is harder.
  1167. Native users of such languages have adopted methods for dealing with
  1168. Latin keyboards that involve a hybrid technique based on phonetics
  1169. to generate a list of possible symbols followed by menu selection to
  1170. choose the desired one.
  1171. Such methods can be
  1172. effective, but their design must be rooted in information about
  1173. the language unknown to non-native speakers.
  1174. .CW Cxterm , (
  1175. a Chinese terminal emulator built by and for
  1176. Chinese programmers,
  1177. employs such a technique
  1178. [Pong and Zhang].)
  1179. Although the technical problem of implementing such a device
  1180. is easy in Plan 9\(emit is just an elaboration of the technique for
  1181. alphabetic languages\(emour lack of familiarity with such languages
  1182. has restrained our enthusiasm for building one.
  1183. .PP
  1184. The input problem is technically the least interesting but perhaps
  1185. emotionally the most important of the problems of converting a system
  1186. to an international character set.
  1187. Beyond that remain the deeper problems of internationalization
  1188. such as multi-lingual error messages and command names,
  1189. problems we are not qualified to solve.
  1190. With the ability to treat text of most languages on an equal
  1191. footing, though, we can begin down that path.
  1192. Perhaps people in non-English speaking countries will
  1193. consider adopting Plan 9, solving the input problem locally\(emperhaps
  1194. just by plugging in their local terminals\(emand begin to use
  1195. a system with at least the capacity to be international.
  1196. .SH
  1197. Acknowledgements
  1198. .PP
  1199. Dennis Ritchie provided consultation and encouragement.
  1200. Bob Flandrena converted most of the standard tools to UTF.
  1201. Brian Kernighan suffered cheerfully with several
  1202. inadequate implementations and converted
  1203. .CW troff
  1204. to UTF.
  1205. Rich Drechsler converted his Postscript driver to UTF.
  1206. John Hobby built the Postscript ☺.
  1207. We thank them all.
  1208. .SH
  1209. References
  1210. .LP
  1211. [ANSIC] \f2American National Standard for Information Systems \-
  1212. Programming Language C\f1, American National Standards Institute, Inc.,
  1213. New York, 1990.
  1214. .LP
  1215. [ISO10646]
  1216. ISO/IEC DIS 10646-1:1993
  1217. \f2Information technology \-
  1218. Universal Multiple-Octet Coded Character Set (UCS) \(em
  1219. Part 1: Architecture and Basic Multilingual Plane\fP.
  1220. .LP
  1221. [Pike90] R. Pike, D. Presotto, K. Thompson, H. Trickey,
  1222. ``Plan 9 from Bell Labs'',
  1223. UKUUG Proc. of the Summer 1990 Conf.,
  1224. London, England,
  1225. 1990.
  1226. .LP
  1227. [Pike91] R. Pike, ``8½, The Plan 9 Window System'', USENIX Summer
  1228. Conf. Proc., Nashville, 1991, reprinted in this volume.
  1229. .LP
  1230. [Pike92] R. Pike, ``How to Use the Plan 9 C Compiler'', this volume.
  1231. .LP
  1232. [Pong and Zhang] Man-Chi Pong and Yongguang Zhang, ``cxterm:
  1233. A Chinese Terminal Emulator for the X Window System'',
  1234. .I
  1235. Software\(emPractice and Experience,
  1236. .R
  1237. Vol 22(1), 809-926, October 1992.
  1238. .LP
  1239. [Unicode]
  1240. \f2The Unicode Standard,
  1241. Worldwide Character Encoding,
  1242. Version 1.0, Volume 1\f1,
  1243. The Unicode Consortium,
  1244. Addison Wesley,
  1245. New York,
  1246. 1991.