package vt220 type Grapheme *rune func G(r rune) Grapheme { return &r } func N(r *rune) Grapheme { return r } type GraphemeTableRow [6]Grapheme type GraphemeTable [16]GraphemeTableRow type lookupTable map[rune][2]int func (t lookupTable) Has(r rune) bool { if _, ok := t[r]; ok { return true } return false } func (t lookupTable) Get(r rune) *[2]int { if coords, ok := t[r]; ok { return &coords } return nil } type CharacterSet struct { table GraphemeTable lookup lookupTable dscsInter0 *byte dscsInter1 *byte dcscFinal byte decdld *ControlSequence } func (set CharacterSet) IsDownLineLoadable() bool { if set.decdld == nil { return false } return true } // Dscs returns the DEC-Select-Character-Set byte sequence for this CharacterSet. func (set CharacterSet) Dscs() []byte { dscsLen := 1 if set.dscsInter0 != nil { if set.dscsInter1 == nil { panic("Invalid DSCS intermediate 1!") } dscsLen = 3 } dscs := make([]byte, dscsLen, dscsLen) if dscsLen == 3 { dscs[0] = *set.dscsInter0 dscs[1] = *set.dscsInter1 } dscs[dscsLen-1] = set.dcscFinal return dscs } func CharacterSetFromTable(t GraphemeTable, id byte) *CharacterSet { set := CharacterSet{} set.table = t set.dcscFinal = id set.lookup = lookupTable{} for i, row := range set.table { for j, graph := range row { if graph == nil { continue } set.lookup[*graph] = [2]int{i, j} } } return &set } func CharacterSetFromArray(a [94]*rune) *CharacterSet { gto := CharacterSet{} gto.lookup = lookupTable{} var i int for j, graph := range a { i = j / 16 gto.table[i][j] = graph if graph != nil { gto.lookup[*graph] = [2]int{i, j} } } return >o } var ( mscASCIIGraphic = GraphemeTable{ {G(' '), G('0'), G('@'), G('P'), G('`'), G('p')}, {G('!'), G('1'), G('A'), G('Q'), G('a'), G('q')}, {G('"'), G('2'), G('B'), G('R'), G('b'), G('r')}, {G('#'), G('3'), G('C'), G('S'), G('c'), G('s')}, {G('$'), G('4'), G('D'), G('T'), G('d'), G('t')}, {G('%'), G('5'), G('E'), G('U'), G('e'), G('u')}, {G('&'), G('6'), G('F'), G('V'), G('f'), G('v')}, {G('\''), G('7'), G('G'), G('W'), G('g'), G('w')}, {G('('), G('8'), G('H'), G('X'), G('h'), G('x')}, {G(')'), G('9'), G('I'), G('Y'), G('i'), G('y')}, {G('*'), G(':'), G('J'), G('Z'), G('j'), G('z')}, {G('+'), G(';'), G('K'), G('['), G('k'), G('{')}, {G(','), G('<'), G('L'), G('\\'), G('l'), G('|')}, {G('-'), G('='), G('M'), G(']'), G('m'), G('}')}, {G('.'), G('>'), G('N'), G('^'), G('n'), G('~')}, {G('/'), G('?'), G('O'), G('_'), G('o'), G('\u007F')}, } mscSupplementalGraphic = GraphemeTable{ {N(nil), G('°'), G('À'), N(nil), G('à'), N(nil)}, {G('¡'), G('±'), G('Á'), G('Ñ'), G('á'), G('ñ')}, {G('¢'), G('²'), G('Â'), G('Ò'), G('â'), G('ò')}, {G('£'), G('³'), G('Ã'), G('Ó'), G('ã'), G('ó')}, {N(nil), N(nil), G('Ä'), G('Ô'), G('ä'), G('ô')}, {G('¥'), G('µ'), G('Å'), G('Õ'), G('å'), G('õ')}, {N(nil), G('¶'), G('Æ'), G('Ö'), G('æ'), G('ö')}, {G('§'), G('·'), G('Ç'), G('Œ'), G('ç'), G('œ')}, {G('¤'), N(nil), G('È'), G('Ø'), G('è'), G('ø')}, {G('©'), G('¹'), G('É'), G('Ù'), G('é'), G('ù')}, {G('ª'), G('º'), G('Ê'), G('Ú'), G('ê'), G('ú')}, {G('«'), G('»'), G('Ë'), G('Û'), G('ë'), G('û')}, {N(nil), G('¼'), G('Ì'), G('Ü'), G('ì'), G('ü')}, {N(nil), G('½'), G('Í'), G('Ÿ'), G('í'), G('ÿ')}, {N(nil), N(nil), G('Î'), N(nil), G('î'), N(nil)}, {N(nil), G('¿'), G('Ï'), G('ß'), G('ï'), N(nil)}, } specialGraphics = GraphemeTable{ {N(nil), G('0'), G('@'), G('P'), G('♦'), G('⎻')}, {G('!'), G('1'), G('A'), G('Q'), G('█'), G('―')}, {G('"'), G('2'), G('B'), G('R'), G('␉'), G('⎼')}, {G('#'), G('3'), G('C'), G('S'), G('␌'), G('⎽')}, {G('$'), G('4'), G('D'), G('T'), G('␍'), G('├')}, {G('%'), G('5'), G('E'), G('U'), G('␊'), G('┤')}, {G('&'), G('6'), G('F'), G('V'), G('°'), G('┴')}, {G('\''), G('7'), G('G'), G('W'), G('±'), G('┬')}, {G('('), G('8'), G('H'), G('X'), G('␤'), G('│')}, {G(')'), G('9'), G('I'), G('Y'), G('␋'), G('≤')}, {G('*'), G(':'), G('J'), G('Z'), G('┘'), G('≥')}, {G('+'), G(';'), G('K'), G('['), G('┐'), G('π')}, {G(','), G('<'), G('L'), G('\\'), G('┌'), G('≠')}, {G('-'), G('='), G('M'), G(']'), G('└'), G('£')}, {G('.'), G('>'), G('N'), G('^'), G('┼'), G('·')}, {G('/'), G('?'), G('O'), G('\u2800'), G('⎺'), N(nil)}, } // TODO: Correct to Match docs nrcBritishBase = GraphemeTable{ {G(' '), G('0'), G('@'), G('P'), G('`'), G('p')}, {G('!'), G('1'), G('A'), G('Q'), G('a'), G('q')}, {G('"'), G('2'), G('B'), G('R'), G('b'), G('r')}, {G('#'), G('3'), G('C'), G('S'), G('c'), G('s')}, {G('$'), G('4'), G('D'), G('T'), G('d'), G('t')}, {G('%'), G('5'), G('E'), G('U'), G('e'), G('u')}, {G('&'), G('6'), G('F'), G('V'), G('f'), G('v')}, {G('\''), G('7'), G('G'), G('W'), G('g'), G('w')}, {G('('), G('8'), G('H'), G('X'), G('h'), G('x')}, {G(')'), G('9'), G('I'), G('Y'), G('i'), G('y')}, {G('*'), G(':'), G('J'), G('Z'), G('j'), G('z')}, {G('+'), G(';'), G('K'), G('['), G('k'), G('{')}, {G(','), G('<'), G('L'), G('\\'), G('l'), G('|')}, {G('-'), G('='), G('M'), G(']'), G('m'), G('}')}, {G('.'), G('>'), G('N'), G('^'), G('n'), G('~')}, {G('/'), G('?'), G('O'), G('_'), G('o'), G('\u007F')}, } // TODO: Correct to Match docs nrcDutchBase = GraphemeTable{ {G(' '), G('0'), G('@'), G('P'), G('`'), G('p')}, {G('!'), G('1'), G('A'), G('Q'), G('a'), G('q')}, {G('"'), G('2'), G('B'), G('R'), G('b'), G('r')}, {G('#'), G('3'), G('C'), G('S'), G('c'), G('s')}, {G('$'), G('4'), G('D'), G('T'), G('d'), G('t')}, {G('%'), G('5'), G('E'), G('U'), G('e'), G('u')}, {G('&'), G('6'), G('F'), G('V'), G('f'), G('v')}, {G('\''), G('7'), G('G'), G('W'), G('g'), G('w')}, {G('('), G('8'), G('H'), G('X'), G('h'), G('x')}, {G(')'), G('9'), G('I'), G('Y'), G('i'), G('y')}, {G('*'), G(':'), G('J'), G('Z'), G('j'), G('z')}, {G('+'), G(';'), G('K'), G('['), G('k'), G('{')}, {G(','), G('<'), G('L'), G('\\'), G('l'), G('|')}, {G('-'), G('='), G('M'), G(']'), G('m'), G('}')}, {G('.'), G('>'), G('N'), G('^'), G('n'), G('~')}, {G('/'), G('?'), G('O'), G('_'), G('o'), G('\u007F')}, } // TODO: Correct to Match docs nrcFinnishBase = GraphemeTable{ {G(' '), G('0'), G('@'), G('P'), G('`'), G('p')}, {G('!'), G('1'), G('A'), G('Q'), G('a'), G('q')}, {G('"'), G('2'), G('B'), G('R'), G('b'), G('r')}, {G('#'), G('3'), G('C'), G('S'), G('c'), G('s')}, {G('$'), G('4'), G('D'), G('T'), G('d'), G('t')}, {G('%'), G('5'), G('E'), G('U'), G('e'), G('u')}, {G('&'), G('6'), G('F'), G('V'), G('f'), G('v')}, {G('\''), G('7'), G('G'), G('W'), G('g'), G('w')}, {G('('), G('8'), G('H'), G('X'), G('h'), G('x')}, {G(')'), G('9'), G('I'), G('Y'), G('i'), G('y')}, {G('*'), G(':'), G('J'), G('Z'), G('j'), G('z')}, {G('+'), G(';'), G('K'), G('['), G('k'), G('{')}, {G(','), G('<'), G('L'), G('\\'), G('l'), G('|')}, {G('-'), G('='), G('M'), G(']'), G('m'), G('}')}, {G('.'), G('>'), G('N'), G('^'), G('n'), G('~')}, {G('/'), G('?'), G('O'), G('_'), G('o'), G('\u007F')}, } // TODO: Correct to Match docs nrcFrenchBase = GraphemeTable{ {G(' '), G('0'), G('@'), G('P'), G('`'), G('p')}, {G('!'), G('1'), G('A'), G('Q'), G('a'), G('q')}, {G('"'), G('2'), G('B'), G('R'), G('b'), G('r')}, {G('#'), G('3'), G('C'), G('S'), G('c'), G('s')}, {G('$'), G('4'), G('D'), G('T'), G('d'), G('t')}, {G('%'), G('5'), G('E'), G('U'), G('e'), G('u')}, {G('&'), G('6'), G('F'), G('V'), G('f'), G('v')}, {G('\''), G('7'), G('G'), G('W'), G('g'), G('w')}, {G('('), G('8'), G('H'), G('X'), G('h'), G('x')}, {G(')'), G('9'), G('I'), G('Y'), G('i'), G('y')}, {G('*'), G(':'), G('J'), G('Z'), G('j'), G('z')}, {G('+'), G(';'), G('K'), G('['), G('k'), G('{')}, {G(','), G('<'), G('L'), G('\\'), G('l'), G('|')}, {G('-'), G('='), G('M'), G(']'), G('m'), G('}')}, {G('.'), G('>'), G('N'), G('^'), G('n'), G('~')}, {G('/'), G('?'), G('O'), G('_'), G('o'), G('\u007F')}, } // TODO: Correct to Match docs nrcFrenchCanadianBase = GraphemeTable{ {G(' '), G('0'), G('@'), G('P'), G('`'), G('p')}, {G('!'), G('1'), G('A'), G('Q'), G('a'), G('q')}, {G('"'), G('2'), G('B'), G('R'), G('b'), G('r')}, {G('#'), G('3'), G('C'), G('S'), G('c'), G('s')}, {G('$'), G('4'), G('D'), G('T'), G('d'), G('t')}, {G('%'), G('5'), G('E'), G('U'), G('e'), G('u')}, {G('&'), G('6'), G('F'), G('V'), G('f'), G('v')}, {G('\''), G('7'), G('G'), G('W'), G('g'), G('w')}, {G('('), G('8'), G('H'), G('X'), G('h'), G('x')}, {G(')'), G('9'), G('I'), G('Y'), G('i'), G('y')}, {G('*'), G(':'), G('J'), G('Z'), G('j'), G('z')}, {G('+'), G(';'), G('K'), G('['), G('k'), G('{')}, {G(','), G('<'), G('L'), G('\\'), G('l'), G('|')}, {G('-'), G('='), G('M'), G(']'), G('m'), G('}')}, {G('.'), G('>'), G('N'), G('^'), G('n'), G('~')}, {G('/'), G('?'), G('O'), G('_'), G('o'), G('\u007F')}, } // TODO: Correct to Match docs nrcGermanBase = GraphemeTable{ {G(' '), G('0'), G('@'), G('P'), G('`'), G('p')}, {G('!'), G('1'), G('A'), G('Q'), G('a'), G('q')}, {G('"'), G('2'), G('B'), G('R'), G('b'), G('r')}, {G('#'), G('3'), G('C'), G('S'), G('c'), G('s')}, {G('$'), G('4'), G('D'), G('T'), G('d'), G('t')}, {G('%'), G('5'), G('E'), G('U'), G('e'), G('u')}, {G('&'), G('6'), G('F'), G('V'), G('f'), G('v')}, {G('\''), G('7'), G('G'), G('W'), G('g'), G('w')}, {G('('), G('8'), G('H'), G('X'), G('h'), G('x')}, {G(')'), G('9'), G('I'), G('Y'), G('i'), G('y')}, {G('*'), G(':'), G('J'), G('Z'), G('j'), G('z')}, {G('+'), G(';'), G('K'), G('['), G('k'), G('{')}, {G(','), G('<'), G('L'), G('\\'), G('l'), G('|')}, {G('-'), G('='), G('M'), G(']'), G('m'), G('}')}, {G('.'), G('>'), G('N'), G('^'), G('n'), G('~')}, {G('/'), G('?'), G('O'), G('_'), G('o'), G('\u007F')}, } // TODO: Correct to Match docs nrcItalianBase = GraphemeTable{ {G(' '), G('0'), G('@'), G('P'), G('`'), G('p')}, {G('!'), G('1'), G('A'), G('Q'), G('a'), G('q')}, {G('"'), G('2'), G('B'), G('R'), G('b'), G('r')}, {G('#'), G('3'), G('C'), G('S'), G('c'), G('s')}, {G('$'), G('4'), G('D'), G('T'), G('d'), G('t')}, {G('%'), G('5'), G('E'), G('U'), G('e'), G('u')}, {G('&'), G('6'), G('F'), G('V'), G('f'), G('v')}, {G('\''), G('7'), G('G'), G('W'), G('g'), G('w')}, {G('('), G('8'), G('H'), G('X'), G('h'), G('x')}, {G(')'), G('9'), G('I'), G('Y'), G('i'), G('y')}, {G('*'), G(':'), G('J'), G('Z'), G('j'), G('z')}, {G('+'), G(';'), G('K'), G('['), G('k'), G('{')}, {G(','), G('<'), G('L'), G('\\'), G('l'), G('|')}, {G('-'), G('='), G('M'), G(']'), G('m'), G('}')}, {G('.'), G('>'), G('N'), G('^'), G('n'), G('~')}, {G('/'), G('?'), G('O'), G('_'), G('o'), G('\u007F')}, } // TODO: Correct to Match docs nrcNorwegianDanishBase = GraphemeTable{ {G(' '), G('0'), G('@'), G('P'), G('`'), G('p')}, {G('!'), G('1'), G('A'), G('Q'), G('a'), G('q')}, {G('"'), G('2'), G('B'), G('R'), G('b'), G('r')}, {G('#'), G('3'), G('C'), G('S'), G('c'), G('s')}, {G('$'), G('4'), G('D'), G('T'), G('d'), G('t')}, {G('%'), G('5'), G('E'), G('U'), G('e'), G('u')}, {G('&'), G('6'), G('F'), G('V'), G('f'), G('v')}, {G('\''), G('7'), G('G'), G('W'), G('g'), G('w')}, {G('('), G('8'), G('H'), G('X'), G('h'), G('x')}, {G(')'), G('9'), G('I'), G('Y'), G('i'), G('y')}, {G('*'), G(':'), G('J'), G('Z'), G('j'), G('z')}, {G('+'), G(';'), G('K'), G('['), G('k'), G('{')}, {G(','), G('<'), G('L'), G('\\'), G('l'), G('|')}, {G('-'), G('='), G('M'), G(']'), G('m'), G('}')}, {G('.'), G('>'), G('N'), G('^'), G('n'), G('~')}, {G('/'), G('?'), G('O'), G('_'), G('o'), G('\u007F')}, } // TODO: Correct to Match docs nrcSpanishBase = GraphemeTable{ {G(' '), G('0'), G('@'), G('P'), G('`'), G('p')}, {G('!'), G('1'), G('A'), G('Q'), G('a'), G('q')}, {G('"'), G('2'), G('B'), G('R'), G('b'), G('r')}, {G('#'), G('3'), G('C'), G('S'), G('c'), G('s')}, {G('$'), G('4'), G('D'), G('T'), G('d'), G('t')}, {G('%'), G('5'), G('E'), G('U'), G('e'), G('u')}, {G('&'), G('6'), G('F'), G('V'), G('f'), G('v')}, {G('\''), G('7'), G('G'), G('W'), G('g'), G('w')}, {G('('), G('8'), G('H'), G('X'), G('h'), G('x')}, {G(')'), G('9'), G('I'), G('Y'), G('i'), G('y')}, {G('*'), G(':'), G('J'), G('Z'), G('j'), G('z')}, {G('+'), G(';'), G('K'), G('['), G('k'), G('{')}, {G(','), G('<'), G('L'), G('\\'), G('l'), G('|')}, {G('-'), G('='), G('M'), G(']'), G('m'), G('}')}, {G('.'), G('>'), G('N'), G('^'), G('n'), G('~')}, {G('/'), G('?'), G('O'), G('_'), G('o'), G('\u007F')}, } // TODO: Correct to Match docs nrcSwedishBase = GraphemeTable{ {G(' '), G('0'), G('@'), G('P'), G('`'), G('p')}, {G('!'), G('1'), G('A'), G('Q'), G('a'), G('q')}, {G('"'), G('2'), G('B'), G('R'), G('b'), G('r')}, {G('#'), G('3'), G('C'), G('S'), G('c'), G('s')}, {G('$'), G('4'), G('D'), G('T'), G('d'), G('t')}, {G('%'), G('5'), G('E'), G('U'), G('e'), G('u')}, {G('&'), G('6'), G('F'), G('V'), G('f'), G('v')}, {G('\''), G('7'), G('G'), G('W'), G('g'), G('w')}, {G('('), G('8'), G('H'), G('X'), G('h'), G('x')}, {G(')'), G('9'), G('I'), G('Y'), G('i'), G('y')}, {G('*'), G(':'), G('J'), G('Z'), G('j'), G('z')}, {G('+'), G(';'), G('K'), G('['), G('k'), G('{')}, {G(','), G('<'), G('L'), G('\\'), G('l'), G('|')}, {G('-'), G('='), G('M'), G(']'), G('m'), G('}')}, {G('.'), G('>'), G('N'), G('^'), G('n'), G('~')}, {G('/'), G('?'), G('O'), G('_'), G('o'), G('\u007F')}, } // TODO: Correct to Match docs nrcSwissBase = GraphemeTable{ {G(' '), G('0'), G('@'), G('P'), G('`'), G('p')}, {G('!'), G('1'), G('A'), G('Q'), G('a'), G('q')}, {G('"'), G('2'), G('B'), G('R'), G('b'), G('r')}, {G('#'), G('3'), G('C'), G('S'), G('c'), G('s')}, {G('$'), G('4'), G('D'), G('T'), G('d'), G('t')}, {G('%'), G('5'), G('E'), G('U'), G('e'), G('u')}, {G('&'), G('6'), G('F'), G('V'), G('f'), G('v')}, {G('\''), G('7'), G('G'), G('W'), G('g'), G('w')}, {G('('), G('8'), G('H'), G('X'), G('h'), G('x')}, {G(')'), G('9'), G('I'), G('Y'), G('i'), G('y')}, {G('*'), G(':'), G('J'), G('Z'), G('j'), G('z')}, {G('+'), G(';'), G('K'), G('['), G('k'), G('{')}, {G(','), G('<'), G('L'), G('\\'), G('l'), G('|')}, {G('-'), G('='), G('M'), G(']'), G('m'), G('}')}, {G('.'), G('>'), G('N'), G('^'), G('n'), G('~')}, {G('/'), G('?'), G('O'), G('_'), G('o'), G('\u007F')}, } ) type MSC struct { ASCIIGraphic *GraphemeTable SupplementalGraphic *GraphemeTable } type NRC struct { British *GraphemeTable Dutch *GraphemeTable Finnish *GraphemeTable French *GraphemeTable FrenchCanadian *GraphemeTable German *GraphemeTable Italian *GraphemeTable NorwegianDanish *GraphemeTable Spanish *GraphemeTable Swedish *GraphemeTable Swiss *GraphemeTable } var DEC = struct { MSC MSC SpecialGraphics *GraphemeTable NRC NRC }{ MSC: MSC{ ASCIIGraphic: &mscASCIIGraphic, SupplementalGraphic: &mscSupplementalGraphic, }, SpecialGraphics: &specialGraphics, NRC: NRC{ British: &nrcBritishBase, Dutch: &nrcDutchBase, Finnish: &nrcFinnishBase, French: &nrcFrenchBase, FrenchCanadian: &nrcFrenchCanadianBase, German: &nrcGermanBase, Italian: &nrcItalianBase, NorwegianDanish: &nrcNorwegianDanishBase, Spanish: &nrcSpanishBase, Swedish: &nrcSwedishBase, Swiss: &nrcSwissBase, }, }