Skip to content

Commit ca19da1

Browse files
authored
Merge pull request #499 from Tyriar/481_character_sets
Add support for rest of VT100 character sets
2 parents 98614f2 + b5d16ed commit ca19da1

3 files changed

Lines changed: 220 additions & 57 deletions

File tree

src/Charsets.ts

Lines changed: 210 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,29 @@
22
* @license MIT
33
*/
44

5-
// TODO: Give CHARSETS a proper type
65
/**
76
* The character sets supported by the terminal. These enable several languages
87
* to be represented within the terminal with only 8-bit encoding. See ISO 2022
9-
* for a discussion on character sets.
8+
* for a discussion on character sets. Only VT100 character sets are supported.
109
*/
11-
export const CHARSETS: any = {};
10+
export const CHARSETS: {[key: string]: {[key: string]: string}} = {};
1211

13-
// DEC Special Character and Line Drawing Set.
14-
// http://vt100.net/docs/vt102-ug/table5-13.html
15-
// A lot of curses apps use this if they see TERM=xterm.
16-
// testing: echo -e '\e(0a\e(B'
17-
// The xterm output sometimes seems to conflict with the
18-
// reference above. xterm seems in line with the reference
19-
// when running vttest however.
20-
// The table below now uses xterm's output from vttest.
21-
CHARSETS.SCLD = { // (0
12+
/**
13+
* The default character set, US.
14+
*/
15+
export const DEFAULT_CHARSET = CHARSETS['B'];
16+
17+
/**
18+
* DEC Special Character and Line Drawing Set.
19+
* Reference: http://vt100.net/docs/vt102-ug/table5-13.html
20+
* A lot of curses apps use this if they see TERM=xterm.
21+
* testing: echo -e '\e(0a\e(B'
22+
* The xterm output sometimes seems to conflict with the
23+
* reference above. xterm seems in line with the reference
24+
* when running vttest however.
25+
* The table below now uses xterm's output from vttest.
26+
*/
27+
CHARSETS['0'] = {
2228
'`': '\u25c6', // '◆'
2329
'a': '\u2592', // '▒'
2430
'b': '\u0009', // '\t'
@@ -52,16 +58,195 @@ CHARSETS.SCLD = { // (0
5258
'~': '\u00b7' // '·'
5359
};
5460

55-
CHARSETS.UK = null; // (A
56-
CHARSETS.US = null; // (B (USASCII)
57-
CHARSETS.Dutch = null; // (4
58-
CHARSETS.Finnish = null; // (C or (5
59-
CHARSETS.French = null; // (R
60-
CHARSETS.FrenchCanadian = null; // (Q
61-
CHARSETS.German = null; // (K
62-
CHARSETS.Italian = null; // (Y
63-
CHARSETS.NorwegianDanish = null; // (E or (6
64-
CHARSETS.Spanish = null; // (Z
65-
CHARSETS.Swedish = null; // (H or (7
66-
CHARSETS.Swiss = null; // (=
67-
CHARSETS.ISOLatin = null; // /A
61+
/**
62+
* British character set
63+
* ESC (A
64+
* Reference: http://vt100.net/docs/vt220-rm/table2-5.html
65+
*/
66+
CHARSETS['A'] = {
67+
'#': '£'
68+
};
69+
70+
/**
71+
* United States character set
72+
* ESC (B
73+
*/
74+
CHARSETS['B'] = null;
75+
76+
/**
77+
* Dutch character set
78+
* ESC (4
79+
* Reference: http://vt100.net/docs/vt220-rm/table2-6.html
80+
*/
81+
CHARSETS['4'] = {
82+
'#': '£',
83+
'@': '¾',
84+
'[': 'ij',
85+
'\\': '½',
86+
']': '|',
87+
'{': '¨',
88+
'|': 'f',
89+
'}': '¼',
90+
'~': '´'
91+
};
92+
93+
/**
94+
* Finnish character set
95+
* ESC (C or ESC (5
96+
* Reference: http://vt100.net/docs/vt220-rm/table2-7.html
97+
*/
98+
CHARSETS['C'] =
99+
CHARSETS['5'] = {
100+
'[': 'Ä',
101+
'\\': 'Ö',
102+
']': 'Å',
103+
'^': 'Ü',
104+
'`': 'é',
105+
'{': 'ä',
106+
'|': 'ö',
107+
'}': 'å',
108+
'~': 'ü'
109+
};
110+
111+
/**
112+
* French character set
113+
* ESC (R
114+
* Reference: http://vt100.net/docs/vt220-rm/table2-8.html
115+
*/
116+
CHARSETS['R'] = {
117+
'#': '£',
118+
'@': 'à',
119+
'[': '°',
120+
'\\': 'ç',
121+
']': '§',
122+
'{': 'é',
123+
'|': 'ù',
124+
'}': 'è',
125+
'~': '¨'
126+
};
127+
128+
/**
129+
* French Canadian character set
130+
* ESC (Q
131+
* Reference: http://vt100.net/docs/vt220-rm/table2-9.html
132+
*/
133+
CHARSETS['Q'] = {
134+
'@': 'à',
135+
'[': 'â',
136+
'\\': 'ç',
137+
']': 'ê',
138+
'^': 'î',
139+
'`': 'ô',
140+
'{': 'é',
141+
'|': 'ù',
142+
'}': 'è',
143+
'~': 'û'
144+
};
145+
146+
/**
147+
* German character set
148+
* ESC (K
149+
* Reference: http://vt100.net/docs/vt220-rm/table2-10.html
150+
*/
151+
CHARSETS['K'] = {
152+
'@': '§',
153+
'[': 'Ä',
154+
'\\': 'Ö',
155+
']': 'Ü',
156+
'{': 'ä',
157+
'|': 'ö',
158+
'}': 'ü',
159+
'~': 'ß'
160+
};
161+
162+
/**
163+
* Italian character set
164+
* ESC (Y
165+
* Reference: http://vt100.net/docs/vt220-rm/table2-11.html
166+
*/
167+
CHARSETS['Y'] = {
168+
'#': '£',
169+
'@': '§',
170+
'[': '°',
171+
'\\': 'ç',
172+
']': 'é',
173+
'`': 'ù',
174+
'{': 'à',
175+
'|': 'ò',
176+
'}': 'è',
177+
'~': 'ì'
178+
};
179+
180+
/**
181+
* Norwegian/Danish character set
182+
* ESC (E or ESC (6
183+
* Reference: http://vt100.net/docs/vt220-rm/table2-12.html
184+
*/
185+
CHARSETS['E'] =
186+
CHARSETS['6'] = {
187+
'@': 'Ä',
188+
'[': 'Æ',
189+
'\\': 'Ø',
190+
']': 'Å',
191+
'^': 'Ü',
192+
'`': 'ä',
193+
'{': 'æ',
194+
'|': 'ø',
195+
'}': 'å',
196+
'~': 'ü'
197+
};
198+
199+
/**
200+
* Spanish character set
201+
* ESC (Z
202+
* Reference: http://vt100.net/docs/vt220-rm/table2-13.html
203+
*/
204+
CHARSETS['Z'] = {
205+
'#': '£',
206+
'@': '§',
207+
'[': '¡',
208+
'\\': 'Ñ',
209+
']': '¿',
210+
'{': '°',
211+
'|': 'ñ',
212+
'}': 'ç'
213+
};
214+
215+
/**
216+
* Swedish character set
217+
* ESC (H or ESC (7
218+
* Reference: http://vt100.net/docs/vt220-rm/table2-14.html
219+
*/
220+
CHARSETS['H'] =
221+
CHARSETS['7'] = {
222+
'@': 'É',
223+
'[': 'Ä',
224+
'\\': 'Ö',
225+
']': 'Å',
226+
'^': 'Ü',
227+
'`': 'é',
228+
'{': 'ä',
229+
'|': 'ö',
230+
'}': 'å',
231+
'~': 'ü'
232+
};
233+
234+
/**
235+
* Swiss character set
236+
* ESC (=
237+
* Reference: http://vt100.net/docs/vt220-rm/table2-15.html
238+
*/
239+
CHARSETS['='] = {
240+
'#': 'ù',
241+
'@': 'à',
242+
'[': 'é',
243+
'\\': 'ç',
244+
']': 'ê',
245+
'^': 'î',
246+
'_': 'è',
247+
'`': 'ô',
248+
'{': 'ä',
249+
'|': 'ö',
250+
'}': 'ü',
251+
'~': 'û'
252+
};

src/InputHandler.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import { IInputHandler, ITerminal } from './Interfaces';
66
import { C0 } from './EscapeSequences';
7-
import { CHARSETS } from './Charsets';
7+
import { DEFAULT_CHARSET } from './Charsets';
88

99
/**
1010
* The terminal's standard implementation of IInputHandler, this handles all
@@ -842,10 +842,10 @@ export class InputHandler implements IInputHandler {
842842
this._terminal.applicationCursor = true;
843843
break;
844844
case 2:
845-
this._terminal.setgCharset(0, CHARSETS.US);
846-
this._terminal.setgCharset(1, CHARSETS.US);
847-
this._terminal.setgCharset(2, CHARSETS.US);
848-
this._terminal.setgCharset(3, CHARSETS.US);
845+
this._terminal.setgCharset(0, DEFAULT_CHARSET);
846+
this._terminal.setgCharset(1, DEFAULT_CHARSET);
847+
this._terminal.setgCharset(2, DEFAULT_CHARSET);
848+
this._terminal.setgCharset(3, DEFAULT_CHARSET);
849849
// set VT100 mode here
850850
break;
851851
case 3: // 132 col mode

src/Parser.ts

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import { C0 } from './EscapeSequences';
66
import { IInputHandler } from './Interfaces';
7-
import { CHARSETS } from './Charsets';
7+
import { CHARSETS, DEFAULT_CHARSET } from './Charsets';
88

99
const normalStateHandler: {[key: string]: (parser: Parser, handler: IInputHandler) => void} = {};
1010
normalStateHandler[C0.BEL] = (parser, handler) => handler.bell();
@@ -70,7 +70,7 @@ escapedStateHandler['%'] = (parser, terminal) => {
7070
// ESC % Select default/utf-8 character set.
7171
// @ = default, G = utf-8
7272
terminal.setgLevel(0);
73-
terminal.setgCharset(0, CHARSETS.US);
73+
terminal.setgCharset(0, DEFAULT_CHARSET); // US (default)
7474
parser.setState(ParserState.NORMAL);
7575
parser.skipNextChar();
7676
};
@@ -145,28 +145,6 @@ csiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params);
145145
csiStateHandler['s'] = (handler, params) => handler.saveCursor(params);
146146
csiStateHandler['u'] = (handler, params) => handler.restoreCursor(params);
147147

148-
// TODO: Many codes/charsets appear to not be supported
149-
// See: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
150-
const charsetMap = {
151-
'0': CHARSETS.SCLD,
152-
'A': CHARSETS.UK, // United Kingdom
153-
'B': CHARSETS.US, // United States (USASCII)
154-
'4': CHARSETS.Dutch,
155-
'C': CHARSETS.Finnish,
156-
'5': CHARSETS.Finnish,
157-
'f': CHARSETS.French,
158-
'Q': CHARSETS.FrenchCanadian,
159-
'K': CHARSETS.German,
160-
'Y': CHARSETS.Italian,
161-
'E': CHARSETS.NorwegianDanish,
162-
'6': CHARSETS.NorwegianDanish,
163-
'Z': CHARSETS.Spanish,
164-
'H': CHARSETS.Swedish,
165-
'7': CHARSETS.Swedish,
166-
'=': CHARSETS.Swiss,
167-
'/': CHARSETS.ISOLatin // ISOLatin is actually /A
168-
};
169-
170148
enum ParserState {
171149
NORMAL = 0,
172150
ESCAPED = 1,
@@ -371,13 +349,13 @@ export class Parser {
371349
break;
372350

373351
case ParserState.CHARSET:
374-
if (ch in charsetMap) {
375-
cs = charsetMap[ch];
352+
if (ch in CHARSETS) {
353+
cs = CHARSETS[ch];
376354
if (ch === '/') { // ISOLatin is actually /A
377355
this.skipNextChar();
378356
}
379357
} else {
380-
cs = CHARSETS.US; // Default
358+
cs = DEFAULT_CHARSET;
381359
}
382360
this._terminal.setgCharset(this._terminal.gcharset, cs);
383361
this._terminal.gcharset = null;

0 commit comments

Comments
 (0)