forked from foliojs/unicode-properties
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.coffee
110 lines (85 loc) · 2.97 KB
/
index.coffee
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
UnicodeTrie = require 'unicode-trie'
data = require './data.json'
# Trie is serialized as a Buffer in node, but here
# we may be running in a browser so we make an Uint8Array
trieBuffer = require './trie.json'
trieData = new Uint8Array trieBuffer.data
trie = new UnicodeTrie trieData
log2 = Math.log2 or (n) ->
Math.log(n) / Math.LN2
bits = (n) ->
(log2(n) + 1) | 0
# compute the number of bits stored for each field
CATEGORY_BITS = bits(data.categories.length - 1)
COMBINING_BITS = bits(data.combiningClasses.length - 1)
SCRIPT_BITS = bits(data.scripts.length - 1)
EAW_BITS = bits(data.eaw.length - 1)
NUMBER_BITS = 10
# compute shift and mask values for each field
CATEGORY_SHIFT = COMBINING_BITS + SCRIPT_BITS + EAW_BITS + NUMBER_BITS
COMBINING_SHIFT = SCRIPT_BITS + EAW_BITS + NUMBER_BITS
SCRIPT_SHIFT = EAW_BITS + NUMBER_BITS
EAW_SHIFT = NUMBER_BITS
CATEGORY_MASK = (1 << CATEGORY_BITS) - 1
COMBINING_MASK = (1 << COMBINING_BITS) - 1
SCRIPT_MASK = (1 << SCRIPT_BITS) - 1
EAW_MASK = (1 << EAW_BITS) - 1
NUMBER_MASK = (1 << NUMBER_BITS) - 1
exports.getCategory = (codePoint) ->
val = trie.get codePoint
data.categories[(val >> CATEGORY_SHIFT) & CATEGORY_MASK]
exports.getCombiningClass = (codePoint) ->
val = trie.get codePoint
data.combiningClasses[(val >> COMBINING_SHIFT) & COMBINING_MASK]
exports.getScript = (codePoint) ->
val = trie.get codePoint
data.scripts[(val >> SCRIPT_SHIFT) & SCRIPT_MASK]
exports.getEastAsianWidth = (codePoint) ->
val = trie.get codePoint
data.eaw[(val >> EAW_SHIFT) & EAW_MASK]
exports.getNumericValue = (codePoint) ->
val = trie.get codePoint
num = val & NUMBER_MASK
if num is 0
return null
else if num <= 50
return num - 1
else if num < 0x1e0
# fraction
numerator = (num >> 4) - 12
denominator = (num & 0xf) + 1
return numerator / denominator
else if num < 0x300
# base 10
val = (num >> 5) - 14
exp = (num & 0x1f) + 2
while exp > 0
val *= 10
exp--
return val
else
# base 60
val = (num >> 2) - 0xbf
exp = (num & 3) + 1
while exp > 0
val *= 60
exp--
return val
exports.isAlphabetic = (codePoint) ->
exports.getCategory(codePoint) in ['Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl']
exports.isDigit = (codePoint) ->
exports.getCategory(codePoint) is 'Nd'
exports.isPunctuation = (codePoint) ->
exports.getCategory(codePoint) in ['Pc', 'Pd', 'Pe', 'Pf', 'Pi', 'Po', 'Ps']
exports.isLowerCase = (codePoint) ->
exports.getCategory(codePoint) is 'Ll'
exports.isUpperCase = (codePoint) ->
exports.getCategory(codePoint) is 'Lu'
exports.isTitleCase = (codePoint) ->
exports.getCategory(codePoint) is 'Lt'
exports.isWhiteSpace = (codePoint) ->
exports.getCategory(codePoint) in ['Zs', 'Zl', 'Zp']
exports.isBaseForm = (codePoint) ->
exports.getCategory(codePoint) in ['Nd', 'No', 'Nl', 'Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Me', 'Mc']
exports.isMark = (codePoint) ->
exports.getCategory(codePoint) in ['Mn', 'Me', 'Mc']