Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
235 changes: 210 additions & 25 deletions src/Charsets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,29 @@
* @license MIT
*/

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

// DEC Special Character and Line Drawing Set.
// http://vt100.net/docs/vt102-ug/table5-13.html
// A lot of curses apps use this if they see TERM=xterm.
// testing: echo -e '\e(0a\e(B'
// The xterm output sometimes seems to conflict with the
// reference above. xterm seems in line with the reference
// when running vttest however.
// The table below now uses xterm's output from vttest.
CHARSETS.SCLD = { // (0
/**
* The default character set, US.
*/
export const DEFAULT_CHARSET = CHARSETS['B'];

/**
* DEC Special Character and Line Drawing Set.
* Reference: http://vt100.net/docs/vt102-ug/table5-13.html
* A lot of curses apps use this if they see TERM=xterm.
* testing: echo -e '\e(0a\e(B'
* The xterm output sometimes seems to conflict with the
* reference above. xterm seems in line with the reference
* when running vttest however.
* The table below now uses xterm's output from vttest.
*/
CHARSETS['0'] = {
'`': '\u25c6', // '◆'
'a': '\u2592', // '▒'
'b': '\u0009', // '\t'
Expand Down Expand Up @@ -52,16 +58,195 @@ CHARSETS.SCLD = { // (0
'~': '\u00b7' // '·'
};

CHARSETS.UK = null; // (A
CHARSETS.US = null; // (B (USASCII)
CHARSETS.Dutch = null; // (4
CHARSETS.Finnish = null; // (C or (5
CHARSETS.French = null; // (R
CHARSETS.FrenchCanadian = null; // (Q
CHARSETS.German = null; // (K
CHARSETS.Italian = null; // (Y
CHARSETS.NorwegianDanish = null; // (E or (6
CHARSETS.Spanish = null; // (Z
CHARSETS.Swedish = null; // (H or (7
CHARSETS.Swiss = null; // (=
CHARSETS.ISOLatin = null; // /A
/**
* British character set
* ESC (A
* Reference: http://vt100.net/docs/vt220-rm/table2-5.html
*/
CHARSETS['A'] = {
'#': '£'
};

/**
* United States character set
* ESC (B
*/
CHARSETS['B'] = null;

/**
* Dutch character set
* ESC (4
* Reference: http://vt100.net/docs/vt220-rm/table2-6.html
*/
CHARSETS['4'] = {
'#': '£',
'@': '¾',
'[': 'ij',
'\\': '½',
']': '|',
'{': '¨',
'|': 'f',
'}': '¼',
'~': '´'
};

/**
* Finnish character set
* ESC (C or ESC (5
* Reference: http://vt100.net/docs/vt220-rm/table2-7.html
*/
CHARSETS['C'] =
CHARSETS['5'] = {
'[': 'Ä',
'\\': 'Ö',
']': 'Å',
'^': 'Ü',
'`': 'é',
'{': 'ä',
'|': 'ö',
'}': 'å',
'~': 'ü'
};

/**
* French character set
* ESC (R
* Reference: http://vt100.net/docs/vt220-rm/table2-8.html
*/
CHARSETS['R'] = {
'#': '£',
'@': 'à',
'[': '°',
'\\': 'ç',
']': '§',
'{': 'é',
'|': 'ù',
'}': 'è',
'~': '¨'
};

/**
* French Canadian character set
* ESC (Q
* Reference: http://vt100.net/docs/vt220-rm/table2-9.html
*/
CHARSETS['Q'] = {
'@': 'à',
'[': 'â',
'\\': 'ç',
']': 'ê',
'^': 'î',
'`': 'ô',
'{': 'é',
'|': 'ù',
'}': 'è',
'~': 'û'
};

/**
* German character set
* ESC (K
* Reference: http://vt100.net/docs/vt220-rm/table2-10.html
*/
CHARSETS['K'] = {
'@': '§',
'[': 'Ä',
'\\': 'Ö',
']': 'Ü',
'{': 'ä',
'|': 'ö',
'}': 'ü',
'~': 'ß'
};

/**
* Italian character set
* ESC (Y
* Reference: http://vt100.net/docs/vt220-rm/table2-11.html
*/
CHARSETS['Y'] = {
'#': '£',
'@': '§',
'[': '°',
'\\': 'ç',
']': 'é',
'`': 'ù',
'{': 'à',
'|': 'ò',
'}': 'è',
'~': 'ì'
};

/**
* Norwegian/Danish character set
* ESC (E or ESC (6
* Reference: http://vt100.net/docs/vt220-rm/table2-12.html
*/
CHARSETS['E'] =
CHARSETS['6'] = {
'@': 'Ä',
'[': 'Æ',
'\\': 'Ø',
']': 'Å',
'^': 'Ü',
'`': 'ä',
'{': 'æ',
'|': 'ø',
'}': 'å',
'~': 'ü'
};

/**
* Spanish character set
* ESC (Z
* Reference: http://vt100.net/docs/vt220-rm/table2-13.html
*/
CHARSETS['Z'] = {
'#': '£',
'@': '§',
'[': '¡',
'\\': 'Ñ',
']': '¿',
'{': '°',
'|': 'ñ',
'}': 'ç'
};

/**
* Swedish character set
* ESC (H or ESC (7
* Reference: http://vt100.net/docs/vt220-rm/table2-14.html
*/
CHARSETS['H'] =
CHARSETS['7'] = {
'@': 'É',
'[': 'Ä',
'\\': 'Ö',
']': 'Å',
'^': 'Ü',
'`': 'é',
'{': 'ä',
'|': 'ö',
'}': 'å',
'~': 'ü'
};

/**
* Swiss character set
* ESC (=
* Reference: http://vt100.net/docs/vt220-rm/table2-15.html
*/
CHARSETS['='] = {
'#': 'ù',
'@': 'à',
'[': 'é',
'\\': 'ç',
']': 'ê',
'^': 'î',
'_': 'è',
'`': 'ô',
'{': 'ä',
'|': 'ö',
'}': 'ü',
'~': 'û'
};
10 changes: 5 additions & 5 deletions src/InputHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import { IInputHandler, ITerminal } from './Interfaces';
import { C0 } from './EscapeSequences';
import { CHARSETS } from './Charsets';
import { DEFAULT_CHARSET } from './Charsets';

/**
* The terminal's standard implementation of IInputHandler, this handles all
Expand Down Expand Up @@ -842,10 +842,10 @@ export class InputHandler implements IInputHandler {
this._terminal.applicationCursor = true;
break;
case 2:
this._terminal.setgCharset(0, CHARSETS.US);
this._terminal.setgCharset(1, CHARSETS.US);
this._terminal.setgCharset(2, CHARSETS.US);
this._terminal.setgCharset(3, CHARSETS.US);
this._terminal.setgCharset(0, DEFAULT_CHARSET);
this._terminal.setgCharset(1, DEFAULT_CHARSET);
this._terminal.setgCharset(2, DEFAULT_CHARSET);
this._terminal.setgCharset(3, DEFAULT_CHARSET);
// set VT100 mode here
break;
case 3: // 132 col mode
Expand Down
32 changes: 5 additions & 27 deletions src/Parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import { C0 } from './EscapeSequences';
import { IInputHandler } from './Interfaces';
import { CHARSETS } from './Charsets';
import { CHARSETS, DEFAULT_CHARSET } from './Charsets';

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

// TODO: Many codes/charsets appear to not be supported
// See: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
const charsetMap = {
'0': CHARSETS.SCLD,
'A': CHARSETS.UK, // United Kingdom
'B': CHARSETS.US, // United States (USASCII)
'4': CHARSETS.Dutch,
'C': CHARSETS.Finnish,
'5': CHARSETS.Finnish,
'f': CHARSETS.French,
'Q': CHARSETS.FrenchCanadian,
'K': CHARSETS.German,
'Y': CHARSETS.Italian,
'E': CHARSETS.NorwegianDanish,
'6': CHARSETS.NorwegianDanish,
'Z': CHARSETS.Spanish,
'H': CHARSETS.Swedish,
'7': CHARSETS.Swedish,
'=': CHARSETS.Swiss,
'/': CHARSETS.ISOLatin // ISOLatin is actually /A
};

enum ParserState {
NORMAL = 0,
ESCAPED = 1,
Expand Down Expand Up @@ -371,13 +349,13 @@ export class Parser {
break;

case ParserState.CHARSET:
if (ch in charsetMap) {
cs = charsetMap[ch];
if (ch in CHARSETS) {
cs = CHARSETS[ch];
if (ch === '/') { // ISOLatin is actually /A
this.skipNextChar();
}
} else {
cs = CHARSETS.US; // Default
cs = DEFAULT_CHARSET;
}
this._terminal.setgCharset(this._terminal.gcharset, cs);
this._terminal.gcharset = null;
Expand Down