-
-
Notifications
You must be signed in to change notification settings - Fork 241
/
UnicodeCodePoints.js
138 lines (130 loc) · 3.46 KB
/
UnicodeCodePoints.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import CharacterBlockEncoder from './CharacterBlock'
import InvalidInputError from '../Error/InvalidInput'
import TextEncoder from '../TextEncoder'
const meta = {
name: 'unicode-code-points',
title: 'Unicode code points',
category: 'Encoding',
type: 'encoder'
}
/**
* Encoder brick for translation between characters and their respective
* Unicode code point values in a given format
*/
export default class UnicodeCodePointsEncoder extends CharacterBlockEncoder {
/**
* Returns brick meta.
* @return {object}
*/
static getMeta () {
return meta
}
/**
* Constructor
*/
constructor () {
super()
this.setCharacterToBlockMode()
this.addSetting({
name: 'format',
type: 'enum',
value: 'unicode',
elements: [
'unicode',
'decimal',
'hexadecimal',
'binary',
'octal',
'ncr-decimal',
'ncr-hexadecimal'
],
labels: [
'Unicode notation',
'Decimal',
'Hexadecimal',
'Binary',
'Octal',
'NCR (Decimal)',
'NCR (Hexadecimal)'
],
randomizable: false,
style: 'radio'
})
}
/**
* Encodes given character to a block.
* @param {number} codePoint Unicode code point
* @param {number} index Unicode code point index
* @param {Chain} content Content to be encoded
* @return {string|Chain} Encoded block
*/
performCharEncodeToBlock (codePoint, index, content) {
switch (this.getSettingValue('format')) {
case 'unicode':
return 'U+' + codePoint.toString(16).toUpperCase()
case 'decimal':
return codePoint.toString(10)
case 'hexadecimal':
return codePoint.toString(16)
case 'binary':
return codePoint.toString(2)
case 'octal':
return codePoint.toString(8)
case 'ncr-decimal':
return `&#${codePoint.toString(10)};`
case 'ncr-hexadecimal':
return `&#x${codePoint.toString(16)};`
}
}
/**
* Decodes given block to a character.
* @param {number} block Block
* @param {number} index Block index
* @param {Chain[]} blocks Blocks to be decoded
* @param {Chain} content Content to be decoded
* @return {number} Decoded code point
*/
performBlockDecodeToChar (block, index, blocks, content) {
let codePoint = 0
let result
switch (this.getSettingValue('format')) {
case 'unicode':
// Interpret unicode notation
result = block.match(/^U\+([0-9A-F]+)$/i)
if (result !== null) {
codePoint = parseInt(result[1], 16)
}
break
case 'decimal':
codePoint = parseInt(block, 10)
break
case 'hexadecimal':
codePoint = parseInt(block, 16)
break
case 'binary':
codePoint = parseInt(block, 2)
break
case 'octal':
codePoint = parseInt(block, 8)
break
case 'ncr-decimal':
case 'ncr-hexadecimal':
// try to interpret hex ncr
result = block.match(/^&#x([0-9A-F]+);$/i)
if (result !== null) {
codePoint = parseInt(result[1], 16)
} else {
// try to interpret decimal ncr
result = block.match(/^&#([0-9]+);$/)
if (result !== null) {
codePoint = parseInt(result[1], 10)
}
}
break
}
if (!TextEncoder.validateCodePoint(codePoint)) {
throw new InvalidInputError(`Invalid code point at index ${index}`)
}
return codePoint
}
}