home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #1 / NN_1993_1.iso / spool / comp / std / internat / 1146 < prev    next >
Encoding:
Text File  |  1993-01-11  |  20.8 KB  |  423 lines

  1. Path: sparky!uunet!haven.umd.edu!darwin.sura.net!newsserver.jvnc.net!yale.edu!ira.uka.de!fauern!uni-erlangen.de!not-for-mail
  2. From: unrza3@cd4680fs.rrze.uni-erlangen.de (Markus Kuhn)
  3. Newsgroups: comp.std.internat
  4. Subject: ISO Latin 1 to ASCII conversion
  5. Date: 11 Jan 1993 20:30:29 +0100
  6. Organization: Regionales Rechenzentrum Erlangen
  7. Message-ID: <1ishslEINNj4o@uni-erlangen.de>
  8. Reply-To: mskuhn@immd4.informatik.uni-erlangen.de
  9. NNTP-Posting-Host: cd4680fs.rrze.uni-erlangen.de
  10. Lines: 411
  11.  
  12. [Ok, another final draft, because I received a lot of suggestions and added
  13. a few things. I hope this text still motivates enoung programmers,
  14. although the described alternatives start getting a little bit
  15. complex.                  --Markus]
  16.  
  17.  
  18. Representation of ISO 8859-1 characters with 7-bit ASCII
  19. --------------------------------------------------------
  20.  
  21. Markus Kuhn -- 1993-01-10
  22.  
  23. SUMMARY: This text describes a technique of displaying the 8-bit
  24. character set, which is used today in many modern network services, on
  25. old 7-bit terminals. Authors of software dealing with text received
  26. from international networks are strongly encouraged to implement this
  27. or similar methods as options in their software for the convenience of
  28. users all over the world. Implementation is often trivial.
  29.  
  30.  
  31.  
  32. The "Latin alphabet No. 1" defined in part 1 of the international
  33. standard
  34.  
  35.   ISO 8859:1987   Information processing -- 8-bit single-byte
  36.                   coded graphic character sets
  37.  
  38. is an increasingly popular 8-bit extension of the traditional 7-bit
  39. US-ASCII character set. It is already supported by many operating
  40. systems and its 191 graphic characters include those used in at least
  41. the following 14 languages (and many others):
  42.  
  43.   Danish, Dutch, English, Faeroese, Finnish, French, German,
  44.   Icelandic, Irish, Italian, Norwegian, Portuguese, Spanish and
  45.   Swedish.
  46.  
  47. ISO 8859-1 contains graphic characters used in at least 44 countries.
  48. ISO Latin 1 is already the de-facto replacement of the old 7-bit
  49. US-ASCII character set and its national ISO 646 variants. In addition,
  50. the first 256 characters of the new 16-bit character set ISO
  51. 10646/Unicode, which will eventually contain all characters used on
  52. this planet and is expected to be the final solution of most of today's
  53. character set troubles, are identical with ISO 8859-1.
  54.  
  55. ISO 8859-1 uses only the codes 32-126 (which are identical with
  56. US-ASCII) and 160-255. The positions 0-31 and 127-159 are reserved for
  57. control characters and normally used in the same way in which they are
  58. used with ASCII.
  59.  
  60. By the way: Only two of the characters have a special meaning for
  61. programs that allow paragraph reformatting. Character NBSP (no-break
  62. space) number 160 (0xa0 = ' '+0x80) looks like a normal space and
  63. should be used if a line break is to be prevented at this space in the
  64. text when it is formated. Character SHY (soft hyphen) at position 173
  65. (0xad = '-'+0x80) looks similar to or exactly like the normal hyphen
  66. ('-') and should be used when a line break has been established within
  67. a word. In this way, SHY can easily be removed again by an editor while
  68. reformating a paragraph, because soft hyphens (0xad) that have only
  69. been inserted for line breaks can be distinguished from real hyphens
  70. (0x2d) that are a permanent part of the text. Both NBSP and SHY are
  71. part of all ISO 8859 character sets.
  72.  
  73. As the ISO Latin 1 character set gains more and more popularity in
  74. international data communication (e.g. the Internet gopher service, the
  75. Internet MIME, parts of USENET), the need arises to extend existing
  76. software with the ability of displaying strings containing ISO 8859-1
  77. characters on old hardware that is only capable of displaying 7-bit
  78. US-ASCII characters. Today, many users of old hardware suffer from
  79. getting the Latin 1 characters between 160 and 255 only displayed as
  80. the corresponding US-ASCII characters with the highest bit cleared.
  81. Then they see e.g. a ')' instead of the copyright symbol. Pessimists
  82. expect that these old 7-bit terminals will be in use at least for the
  83. next ten years.
  84.  
  85. One approach for a Latin 1 to ASCII conversion is to use the
  86. replacements that people commonly use when they have to live with a
  87. system supporting a too limited character set. This seems to be the
  88. most natural method, which often won't even be noticed by users that
  89. use these traditional replacements already today on their old hardware.
  90.  
  91. Of course, there are some disadvantages of this approach (compared to
  92. buying a new terminal), but these are often acceptable if the software
  93. today simply destroys the characters by clearing the highest bit of the
  94. received bytes. These are:
  95.  
  96.   a) No one-to-one mapping between Latin 1 and ASCII strings is possible.
  97.   b) Text layout may be destroyed by multi-character substitutions,
  98.      especially in tables.
  99.   c) Different replacements may be in use for different languages,
  100.      so no single standard replacement table will make everyone happy.
  101.   d) Truncation or line wrapping might be necessary to fit textual data
  102.      into fields of fixed width.
  103.  
  104. There is no optimal solution possible for the problem of displaying
  105. text with ISO Latin 1 characters on old terminals apart from buying new
  106. hardware. The conversion tables proposed here are only intermediate
  107. solutions that are intended to make life easier for people who get
  108. Latin 1 characters currently displayed as the corresponding 7-bit
  109. US-ASCII symbols with the highest bit cleared, which is awful and
  110. frustrates the users of old hardware.
  111.  
  112. Including the tables below in programs like mail user agents, news
  113. readers, gopher clients, file browsers, tty drivers etc. is often a
  114. trivial task. Users should be able to switch between the different
  115. tables and the 8-bit transparent normal mode. 
  116.  
  117. While I discussed these tables with people from many nations in USENET,
  118. it became obvious, that there are a lot of differences in the personal
  119. and cultural preferences for the substitution tables. Much too many
  120. tables would have been necessary to make everyone 100% happy. So I
  121. decided to keep the number of tables as small as possible and tried to
  122. cover only the most important cultural and application dependend
  123. differences. The tables below will perhaps be all right for 80% of the
  124. users. If you as a programmer want to avoid long discussions about the
  125. details of the tables with your users, then offer them a feature to
  126. define their own tables, perhaps in the form of changes to the default
  127. tables listed below (or give at least a pointer in the source code of
  128. public domain software, where user-defined tables might be modified for
  129. local needs).
  130.  
  131. Users should know if the text they read has been converted from the 
  132. original Latin 1 text, the conversion should be clearly explained in
  133. the documentation and perhaps again noticed e.g. after the program
  134. starts. Otherwise, the conversion might cause confusion in some cases.
  135.  
  136. I collected six tables based on information I received from many USENET
  137. readers from various countries in order to cope with the different
  138. needs of ISO Latin 1 users. In some cases, different replacements might
  139. seem to be more suitable based on the semantics of the characters and I
  140. received may suggestions of this kind, but I decided to selected the
  141. replacements based on the way in which these characters might be used,
  142. which differs often dramatically from the originally intended semantics
  143. of the characters. Consequently, I always prefered graphically similar
  144. replacements, where the field of application of the character did not
  145. seem to be very limited. E.g. it has been suggested to replace the
  146. 'left angle quotation mark' [½] by '"' instead of '<' in table 1 based
  147. on the common semantic 'quotation mark', but this character is also
  148. often used as a kind of arrow, so a graphically similar replacement was
  149. choosen. Other characters with more limited applications like the
  150. 'small german letter sharp s' [▀] where replaced by the most often used
  151. replacements (e.g. 'ss') instead of graphically more similar characters
  152. like '3' or 'B'.
  153.  
  154. First of all, a table with the real characters in the range 160 - 255
  155. (0xa0 - 0xff):
  156.  
  157.  
  158.    á   í   ó   ú   ñ   Ñ   ª   º   ¿   ⌐   ¬   ½   ¼   ¡   «   »
  159.    ░   ▒   ▓   │   ┤   ╡   ╢   ╖   ╕   ╣   ║   ╗   ╝   ╜   ╛   ┐
  160.    └   ┴   ┬   ├   ─   ┼   ╞   ╟   ╚   ╔   ╩   ╦   ╠   ═   ╬   ╧
  161.    ╨   ╤   ╥   ╙   ╘   ╒   ╓   ╫   ╪   ┘   ┌   █   ▄   ▌   ▐   ▀
  162.    α   ß   Γ   π   Σ   σ   µ   τ   Φ   Θ   Ω   δ   ∞   φ   ε   ∩
  163.    ≡   ±   ≥   ≤   ⌠   ⌡   ÷   ≈   °   ∙   ·   √   ⁿ   ²   ■    
  164.  
  165. Table 0 is a universal table that is expected to be suitable for many
  166. languages. The letters are simply the ASCII versions without the
  167. diacritics. The fallback substitution character (e.g. '?' or '_') as an
  168. emergency replacement character where no ASCII string is suitable is
  169. used as little as possible, as it carries no information and if we are
  170. pedantic, we have to replace nearly every Latin 1 character over 160 by
  171. question marks etc.
  172.  
  173.        !   c   ?   ?   Y   |   ?   " (c)   a  <<   -   - (R)   -
  174.      +/-   2   3   '   u   P   .   ,   1   o  >> 1/4 1/2 3/4   ?
  175.    A   A   A   A   A   A  AE   C   E   E   E   E   I   I   I   I
  176.    D   N   O   O   O   O   O   x   O   U   U   U   U   Y  Th  ss
  177.    a   a   a   a   a   a  ae   c   e   e   e   e   i   i   i   i
  178.    d   n   o   o   o   o   o   :   o   u   u   u   u   y  th   y
  179.  
  180. Table 1 replaces Latin 1 characters only with single ASCII characters.
  181. This won't destroy the layout of texts designed to be printed with
  182. monospaced fonts, but the replacements are often not very satisfactory:
  183.  
  184.        !   c   ?   ?   Y   |   ?   "   c   a   <   -   -   R   -
  185.        ?   2   3   '   u   P   .   ,   1   o   >   ?   ?   ?   ?
  186.    A   A   A   A   A   A   A   C   E   E   E   E   I   I   I   I
  187.    D   N   O   O   O   O   O   x   O   U   U   U   U   Y   T   s
  188.    a   a   a   a   a   a   a   c   e   e   e   e   i   i   i   i
  189.    d   n   o   o   o   o   o   :   o   u   u   u   u   y   t   y
  190.  
  191. In some languages, only removing the diacritics as in table 0 gives
  192. orthographically incorrect and unappropriate results. The following
  193. table 2 might be much more suitable that table 0 in Danish, Dutch,
  194. German, Norwegian and Swedish:
  195.  
  196.        !   c   ?   ?   Y   |   ?   " (c)   a  <<   -   - (R)   -
  197.      +/-   2   3   '   u   P   .   ,   1   o  >> 1/4 1/2 3/4   ?
  198.    A   A   A   A  Ae  Aa  AE   C   E   E   E   E   I   I   I   I
  199.    D   N   O   O   O   O  Oe   x   O   U   U   U  Ue   Y  Th  ss
  200.    a   a   a   a  ae  aa  ae   c   e   e   e   e   i   i   i   i
  201.    d   n   o   o   o   o  oe   :   o   u   u   u  ue   y  th  ij
  202.  
  203. In some North-European languages, any US-ASCII replacement for the
  204. relevant Latin 1 characters is unacceptable for many people. In these
  205. countries, national variants of 7-bit ISO 646 are still in wide use.
  206. They use consistently some or all of the characters [ ] \ { } | $ and
  207. in one Swedish character set also ~ ^ ` @ for national characters.
  208. Table 3 has been designed for Danish, Finnish, Norwegian and Swedish
  209. users of ISO 646 terminals:
  210.  
  211.        !   c   ?   $   Y   |   ?   " (c)   a  <<   -   - (R)   -
  212.      +/-   2   3   '   u   P   .   ,   1   o  >> 1/4 1/2 3/4   ?
  213.    A   A   A   A   [   ]   [   C   E   @   E   E   I   I   I   I
  214.    D   N   O   O   O   O   \   x   \   U   U   U   ^   Y  Th  ss
  215.    a   a   a   a   {   }   {   c   e   `   e   e   i   i   i   i
  216.    d   n   o   o   o   o   |   :   |   u   u   u   ~   y  th   y
  217.  
  218. Perhaps some users might prefer for four characters the strings from
  219. table 2 instead of ~ ^ ` @, which are only used in one Swedish
  220. character set. Instead of adding yet another table, take this as a
  221. motivation for allowing user-defined modifications to the tables.
  222.  
  223. In RFC 1345, each character from Latin 1 (and from many other character
  224. sets) is assigned a two-character ASCII mnemonic. Table 4 encloses
  225. these mnemonics in braces. The resulting conversion looses nearly no
  226. information and might be useful in special applications, where the risk
  227. of confusing the reader by the Latin1 to ASCII conversion weights more
  228. than the risk of producing ugly output.
  229.  
  230.    [NS][!I][Ct][Pd][Cu][Ye][BB][SE][':][Co][-a][<<][NO][--][Rg]['-]
  231.    [DG][+-][2S][3S][''][My][PI][.M][',][1S][-o][>>][14][12][34][?I]
  232.    [A!][A'][A>][A?][A:][AA][AE][C,][E!][E'][E>][E:][I!][I'][I>][I:]
  233.    [D-][N?][O!][O'][O>][O?][O:][*X][O/][U!][U'][U>][U:][Y'][TH][ss]
  234.    [a!][a'][a>][a?][a:][aa][ae][c,][e!][e'][e>][e:][i!][i'][i>][i:]
  235.    [d-][n?][o!][o'][o>][o?][o:][-:][o/][u!][u'][u>][u:][y'][th][y:]
  236.  
  237. The encoding offered by table 4 is still not 100% free of loss of
  238. information. If you see a '[Co]' in the text, then this might have been
  239. both a copyright sign and the string '[Co]'. To avoid this ambiguity,
  240. one might implement the encoding '&Co' for the copyright sign and '&&'
  241. as an escape string for a single '&' as suggested in RFC 1345. This is
  242. not really appropriate in most situations, because even pure ASCII
  243. texts (e.g. C programs) with '&'s will then be changed.
  244.  
  245. The following table 5 (based on one suggested by Peter da Silva) is
  246. perhaps more a nice intellectual exercise than something really useful.
  247. It uses the BACKSPACE control character (in the table represented by
  248. '@') in oder to get new characters by overstriking ASCII characters.
  249. This gives very poor results for the capital letters on many printers
  250. and is useless on most video terminals, but might be interesting for
  251. languages where often only lowercase characters are used accented (e.g.
  252. French). The quality of the results depends very much on the type of
  253. printer used.
  254.  
  255.        ! c@| L@- o@X Y@=   |   ?   " (c) a@_  << -@,   - (R)   -
  256.      +@_   2   3   '   u   P   .   ,   1 o@_  >> 1/4 1/2 3/4   ?
  257.  A@` A@' A@^ A@~ A@"  Aa  AE C@, E@` E@' E@^ E@" I@` I@' I@^ I@"
  258.  D@- N@~ O@` O@' O@^ O@~ O@"   x O@/ U@` U@' U@^ U@" Y@'  Th  ss
  259.  a@` a@' a@^ a@~ a@"  aa  ae c@, e@` e@' e@^ e@" i@` i@' i@^ i@"
  260.  d@- n@~ o@` o@' o@^ o@~ o@" -@: o@/ u@` u@' u@^ u@" y@'  th y@"
  261.  
  262.  
  263. For the convenience of C programmers, I included the code of these
  264. tables in this text. Just copy the following lines in your software:
  265.  
  266. -----------------------------------------------------------------------
  267. /* Conversion tables for displaying the G1 set (0xa0-0xff) of
  268.    ISO Latin 1 (ISO 8859-1) with 7-bit ASCII characters.
  269.  
  270.    Version 1.0 -- error corrections are welcome
  271.  
  272.    Table   Purpose
  273.      0     universal table for many languages
  274.      1     single-spacing universal table
  275.      2     table for Danish, Dutch, German, Norwegian and Swedish
  276.      3     table for Danish, Finnish, Norwegian and Swedish using
  277.            the appropriate ISO 646 variant.
  278.      4     table with RFC 1345 codes in brackets
  279.      5     table for printers that allow overstriking with backspace
  280.  
  281.    Markus Kuhn <mskuhn@immd4.informatik.uni-erlangen.de>                 */
  282.  
  283. #define SUB "?"        /* used if no reasonable ASCII string is possible */
  284. #define ISO_TABLES 6
  285.  
  286. static char *iso2asc[ISO_TABLES][96] = {{
  287.   " ","!","c",SUB,SUB,"Y","|",SUB,"\"","(c)","a","<<","-","-","(R)","-",
  288.   " ","+/-","2","3","'","u","P",".",",","1","o",">>"," 1/4"," 1/2"," 3/4","?",
  289.   "A","A","A","A","A","A","AE","C","E","E","E","E","I","I","I","I",
  290.   "D","N","O","O","O","O","O","x","O","U","U","U","U","Y","Th","ss",
  291.   "a","a","a","a","a","a","ae","c","e","e","e","e","i","i","i","i",
  292.   "d","n","o","o","o","o","o",":","o","u","u","u","u","y","th","y"
  293. },{
  294.   " ","!","c",SUB,SUB,"Y","|",SUB,"\"","c","a","<","-","-","R","-",
  295.   " ",SUB,"2","3","'","u","P",".",",","1","o",">",SUB,SUB,SUB,"?",
  296.   "A","A","A","A","A","A","A","C","E","E","E","E","I","I","I","I",
  297.   "D","N","O","O","O","O","O","x","O","U","U","U","U","Y","T","s",
  298.   "a","a","a","a","a","a","a","c","e","e","e","e","i","i","i","i",
  299.   "d","n","o","o","o","o","o",":","o","u","u","u","u","y","t","y"
  300. },{
  301.   " ","!","c",SUB,SUB,"Y","|",SUB,"\"","(c)","a","<<","-","-","(R)","-",
  302.   " ","+/-","2","3","'","u","P",".",",","1","o",">>"," 1/4"," 1/2"," 3/4","?",
  303.   "A","A","A","A","Ae","Aa","AE","C","E","E","E","E","I","I","I","I",
  304.   "D","N","O","O","O","O","Oe","x","O","U","U","U","Ue","Y","Th","ss",
  305.   "a","a","a","a","ae","aa","ae","c","e","e","e","e","i","i","i","i",
  306.   "d","n","o","o","o","o","oe",":","o","u","u","u","ue","y","th","ij"
  307. },{
  308.   " ","!","c",SUB,"$","Y","|",SUB,"\"","(c)","a","<<","-","-","(R)","-",
  309.   " ","+/-","2","3","'","u","P",".",",","1","o",">>"," 1/4"," 1/2"," 3/4","?",
  310.   "A","A","A","A","[","]","[","C","E","@","E","E","I","I","I","I",
  311.   "D","N","O","O","O","O","\\","x","\\","U","U","U","^","Y","Th","ss",
  312.   "a","a","a","a","{","}","{","c","e","`","e","e","i","i","i","i",
  313.   "d","n","o","o","o","o","|",":","|","u","u","u","~","y","th","y"
  314. },{
  315.   "[NS]","[!I]","[Ct]","[Pd]","[Cu]","[Ye]","[BB]","[SE]",
  316.   "[':]","[Co]","[-a]","[<<]","[NO]","[--]","[Rg]","['-]",
  317.   "[DG]","[+-]","[2S]","[3S]","['']","[My]","[PI]","[.M]",
  318.   "[',]","[1S]","[-o]","[>>]","[14]","[12]","[34]","[?I]",
  319.   "[A!]","[A']","[A>]","[A?]","[A:]","[AA]","[AE]","[C,]",
  320.   "[E!]","[E']","[E>]","[E:]","[I!]","[I']","[I>]","[I:]",
  321.   "[D-]","[N?]","[O!]","[O']","[O>]","[O?]","[O:]","[*X]",
  322.   "[O/]","[U!]","[U']","[U>]","[U:]","[Y']","[TH]","[ss]",
  323.   "[a!]","[a']","[a>]","[a?]","[a:]","[aa]","[ae]","[c,]",
  324.   "[e!]","[e']","[e>]","[e:]","[i!]","[i']","[i>]","[i:]",
  325.   "[d-]","[n?]","[o!]","[o']","[o>]","[o?]","[o:]","[-:]",
  326.   "[o/]","[u!]","[u']","[u>]","[u:]","[y']","[th]","[y:]"
  327. },{
  328.   " ","!","c\b|","L\b-","o\bX","Y\b=","|",SUB,
  329.   "\"","(c)","a\b_","<<","-\b,","-","(R)","-",
  330.   " ","+\b_","2","3","'","u","P",".",
  331.   ",","1","o\b_",">>"," 1/4"," 1/2"," 3/4","?",
  332.   "A\b`","A\b'","A\b^","A\b~","A\b\"","Aa","AE","C\b,",
  333.   "E\b`","E\b'","E\b^","E\b\"","I\b`","I\b'","I\b^","I\b\"",
  334.   "D\b-","N\b~","O\b`","O\b'","O\b^","O\b~","O\b\"","x",
  335.   "O\b/","U\b`","U\b'","U\b^","U\b\"","Y\b'","Th","ss",
  336.   "a\b`","a\b'","a\b^","a\b~","a\b\"","aa","ae","c\b,",
  337.   "e\b`","e\b'","e\b^","e\b\"","i\b`","i\b'","i\b^","i\b\"",
  338.   "d\b-","n\b~","o\b`","o\b'","o\b^","o\b~","o\b\"","-\b:",
  339.   "o\b/","u\b`","u\b'","u\b^","u\b\"","y\b'","th","y\b\""
  340. }};
  341. -----------------------------------------------------------------------
  342.  
  343. One might perhaps replace the "?" in SUB with "_" or another code that
  344. will be displayed as a blinking question mark, a filled block or
  345. something similar. Then the user will know that the software wants to
  346. tell him/her that it can't display this symbol and that it is not a
  347. question mark. If your software runs on hardware that supports already
  348. another 8-bit characters set (e.g. IBM PC with code page 437, Mac,
  349. etc.), then it might be a much better idea to include only one single
  350. table that uses the supported symbols wherever possible and uses the
  351. strings suggested here only if no better alternative is available.
  352. (BTW: IBM code page 850 which is supported by MS-DOS and OS/2 contains
  353. ALL Latin 1 characters, but at other positions, in order to stay
  354. compatible with the old IBM PC character set.)
  355.  
  356. The following string conversion routine uses these tables. It may
  357. easily be called before a text received from the network is sent to the
  358. terminal, if the user has selected one of the tables:
  359.  
  360. -----------------------------------------------------------------------
  361. /*
  362.  *  Transform an 8-bit ISO Latin 1 string iso in a 7-bit ASCII string asc
  363.  *  readable on old terminals using conversion table t.
  364.  *
  365.  *  worst case: strlen(iso) == 4*strlen(asc)
  366.  */
  367.   void
  368. Latin1toASCII(iso, asc, t)
  369.   unsigned char *iso, *asc;
  370.   int t;
  371. {
  372.   char *p, **tab;
  373.  
  374.   if (iso==NULL || asc==NULL) return;
  375.  
  376.   tab = iso2asc[t] - 0xa0;
  377.   while (*iso) {
  378.     if (*iso > 0x9f) {
  379.       p = tab[*(iso++)];
  380.       while (*p) *(asc++) = *(p++);
  381.     } else {
  382.       *(asc++) = *(iso++);
  383.     }
  384.   }
  385.   *asc = 0;
  386.  
  387.   return;
  388. }
  389. -----------------------------------------------------------------------
  390.  
  391. As a software author, you might decide to offer one of several levels
  392. of latin 1 conversion support:
  393.  
  394.   - The simplest solution is to allow the user to switch between the
  395.     real 8-bit representation and the above tables
  396.   - Highly recommended is a feature that allows the user to create his 
  397.     own table. If this is possible based on one or more of the described 
  398.     default tables, the effort needed for defining a private table will
  399.     be reduced drastically. The system administrator should be allowed 
  400.     to define a default table for his users.
  401.   - More comfortable systems might also allow the user to change the
  402.     SUB string, to select the style (normal, highlighed, underlined, 
  403.     blinking, ...) in which the replacement strings are displayed, etc. 
  404.   - You might even think about possibilities for a user to enter
  405.     Latin 1 characters with an old keyboard and editor, a problem
  406.     that hasn't been addressed here.
  407.  
  408. Many users all over the world are looking forward to your next software
  409. release that will allow them to participate without pain in the world
  410. of 8-bit character communication even before they get modern hardware
  411. with ISO 8859-1 (or even better ISO 10646) character sets.
  412.  
  413. Feel free to contact me or experts in USENET group comp.std.internat if
  414. you have any questions about modern character sets. Many thanks to
  415. everyone from comp.std.internat who helped me to improve these tables!
  416.  
  417. Markus
  418.  
  419. -- 
  420. Markus Kuhn, Computer Science student -=-=- University of Erlangen, Germany
  421. Internet: mskuhn@immd4.informatik.uni-erlangen.de  |  X.500 entry available
  422. --- Wer, wie, was? Wieso, weshalb, warum? Wer nichts fragt bleibt dumm. ---
  423.