rapydscript-ns 0.9.0 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agignore +1 -1
- package/.github/workflows/ci.yml +38 -38
- package/=template.pyj +5 -5
- package/CHANGELOG.md +10 -0
- package/HACKING.md +103 -103
- package/LICENSE +24 -24
- package/README.md +7 -6
- package/TODO.md +116 -1
- package/add-toc-to-readme +2 -2
- package/bin/export +75 -75
- package/bin/rapydscript +70 -70
- package/bin/web-repl-export +102 -102
- package/build +2 -2
- package/language-service/index.js +9 -9
- package/language-service/language-service.d.ts +1 -1
- package/package.json +6 -2
- package/publish.py +37 -37
- package/release/compiler.js +246 -231
- package/release/signatures.json +23 -23
- package/session.vim +4 -4
- package/setup.cfg +2 -2
- package/src/compiler.pyj +36 -36
- package/src/errors.pyj +30 -30
- package/src/lib/aes.pyj +646 -646
- package/src/lib/contextlib.pyj +379 -0
- package/src/lib/copy.pyj +120 -120
- package/src/lib/datetime.pyj +712 -0
- package/src/lib/elementmaker.pyj +83 -83
- package/src/lib/encodings.pyj +126 -126
- package/src/lib/gettext.pyj +569 -569
- package/src/lib/io.pyj +500 -0
- package/src/lib/itertools.pyj +580 -580
- package/src/lib/json.pyj +227 -0
- package/src/lib/math.pyj +193 -193
- package/src/lib/operator.pyj +11 -11
- package/src/lib/pythonize.pyj +20 -20
- package/src/lib/random.pyj +118 -118
- package/src/lib/react.pyj +74 -74
- package/src/lib/traceback.pyj +63 -63
- package/src/lib/uuid.pyj +77 -77
- package/src/monaco-language-service/diagnostics.js +4 -4
- package/src/monaco-language-service/dts.js +550 -550
- package/src/monaco-language-service/index.js +2 -2
- package/src/output/comments.pyj +45 -45
- package/src/output/exceptions.pyj +201 -201
- package/src/output/jsx.pyj +164 -164
- package/src/output/loops.pyj +9 -0
- package/src/output/treeshake.pyj +182 -182
- package/src/output/utils.pyj +72 -72
- package/src/string_interpolation.pyj +72 -72
- package/src/tokenizer.pyj +1 -1
- package/src/unicode_aliases.pyj +576 -576
- package/src/utils.pyj +192 -192
- package/test/_import_one.pyj +37 -37
- package/test/_import_two/__init__.pyj +11 -11
- package/test/_import_two/level2/deep.pyj +4 -4
- package/test/_import_two/other.pyj +6 -6
- package/test/_import_two/sub.pyj +13 -13
- package/test/aes_vectors.pyj +421 -421
- package/test/annotations.pyj +80 -80
- package/test/contextlib.pyj +362 -0
- package/test/datetime.pyj +500 -0
- package/test/debugger_stmt.pyj +41 -0
- package/test/decorators.pyj +77 -77
- package/test/docstrings.pyj +39 -39
- package/test/elementmaker_test.pyj +45 -45
- package/test/functions.pyj +151 -151
- package/test/generators.pyj +41 -41
- package/test/generic.pyj +370 -370
- package/test/imports.pyj +72 -72
- package/test/internationalization.pyj +73 -73
- package/test/io.pyj +316 -0
- package/test/json.pyj +196 -0
- package/test/lint.pyj +164 -164
- package/test/loops.pyj +85 -85
- package/test/numpy.pyj +734 -734
- package/test/omit_function_metadata.pyj +20 -20
- package/test/repl.pyj +121 -121
- package/test/scoped_flags.pyj +76 -76
- package/test/unit/index.js +66 -0
- package/test/unit/language-service-dts.js +543 -543
- package/test/unit/language-service-hover.js +455 -455
- package/test/unit/language-service.js +1 -1
- package/test/unit/web-repl.js +533 -0
- package/tools/compiler.d.ts +367 -0
- package/tools/completer.js +131 -131
- package/tools/gettext.js +185 -185
- package/tools/ini.js +65 -65
- package/tools/msgfmt.js +187 -187
- package/tools/repl.js +223 -223
- package/tools/test.js +118 -118
- package/tools/utils.js +128 -128
- package/tools/web_repl.js +95 -95
- package/try +41 -41
- package/web-repl/env.js +196 -196
- package/web-repl/index.html +163 -163
- package/web-repl/prism.css +139 -139
- package/web-repl/prism.js +113 -113
- package/web-repl/rapydscript.js +224 -224
- package/web-repl/sha1.js +25 -25
package/src/lib/elementmaker.pyj
CHANGED
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
# vim:fileencoding=utf-8
|
|
2
|
-
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
|
-
|
|
4
|
-
html_elements = {
|
|
5
|
-
'a', 'abbr', 'acronym', 'address', 'area',
|
|
6
|
-
'article', 'aside', 'audio', 'b', 'base', 'big', 'body', 'blockquote', 'br', 'button',
|
|
7
|
-
'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup',
|
|
8
|
-
'command', 'datagrid', 'datalist', 'dd', 'del', 'details', 'dfn',
|
|
9
|
-
'dialog', 'dir', 'div', 'dl', 'dt', 'em', 'event-source', 'fieldset',
|
|
10
|
-
'figcaption', 'figure', 'footer', 'font', 'form', 'header', 'h1',
|
|
11
|
-
'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'head', 'i', 'iframe', 'img', 'input', 'ins',
|
|
12
|
-
'keygen', 'kbd', 'label', 'legend', 'li', 'm', 'map', 'menu', 'meter',
|
|
13
|
-
'multicol', 'nav', 'nextid', 'ol', 'output', 'optgroup', 'option',
|
|
14
|
-
'p', 'pre', 'progress', 'q', 's', 'samp', 'script', 'section', 'select',
|
|
15
|
-
'small', 'sound', 'source', 'spacer', 'span', 'strike', 'strong', 'style',
|
|
16
|
-
'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'time', 'tfoot',
|
|
17
|
-
'th', 'thead', 'tr', 'tt', 'u', 'ul', 'var', 'video'
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
mathml_elements = {
|
|
21
|
-
'maction', 'math', 'merror', 'mfrac', 'mi',
|
|
22
|
-
'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom',
|
|
23
|
-
'mprescripts', 'mroot', 'mrow', 'mspace', 'msqrt', 'mstyle', 'msub',
|
|
24
|
-
'msubsup', 'msup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder',
|
|
25
|
-
'munderover', 'none'
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
svg_elements = {
|
|
29
|
-
'a', 'animate', 'animateColor', 'animateMotion',
|
|
30
|
-
'animateTransform', 'clipPath', 'circle', 'defs', 'desc', 'ellipse',
|
|
31
|
-
'font-face', 'font-face-name', 'font-face-src', 'g', 'glyph', 'hkern',
|
|
32
|
-
'linearGradient', 'line', 'marker', 'metadata', 'missing-glyph',
|
|
33
|
-
'mpath', 'path', 'polygon', 'polyline', 'radialGradient', 'rect',
|
|
34
|
-
'set', 'stop', 'svg', 'switch', 'text', 'title', 'tspan', 'use'
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
html5_tags = html_elements.union(mathml_elements).union(svg_elements)
|
|
38
|
-
|
|
39
|
-
def _makeelement(tag, *args, **kwargs):
|
|
40
|
-
ans = this.createElement(tag)
|
|
41
|
-
|
|
42
|
-
for attr in kwargs:
|
|
43
|
-
vattr = str.replace(str.rstrip(attr, '_'), '_', '-')
|
|
44
|
-
val = kwargs[attr]
|
|
45
|
-
if callable(val):
|
|
46
|
-
if str.startswith(attr, 'on'):
|
|
47
|
-
attr = attr[2:]
|
|
48
|
-
ans.addEventListener(attr, val)
|
|
49
|
-
elif val is True:
|
|
50
|
-
ans.setAttribute(vattr, vattr)
|
|
51
|
-
elif jstype(val) is 'string':
|
|
52
|
-
ans.setAttribute(vattr, val)
|
|
53
|
-
|
|
54
|
-
for arg in args:
|
|
55
|
-
if jstype(arg) is 'string':
|
|
56
|
-
arg = this.createTextNode(arg)
|
|
57
|
-
ans.appendChild(arg)
|
|
58
|
-
return ans
|
|
59
|
-
|
|
60
|
-
def maker_for_document(document):
|
|
61
|
-
# Create an elementmaker to be used with the specified document
|
|
62
|
-
E = _makeelement.bind(document)
|
|
63
|
-
Object.defineProperties(E, {
|
|
64
|
-
tag: {
|
|
65
|
-
'value':_makeelement.bind(document, tag)
|
|
66
|
-
} for tag in html5_tags
|
|
67
|
-
})
|
|
68
|
-
return E
|
|
69
|
-
|
|
70
|
-
if jstype(document) is 'undefined':
|
|
71
|
-
E = maker_for_document({
|
|
72
|
-
'createTextNode': def(value): return value;,
|
|
73
|
-
'createElement': def(name):
|
|
74
|
-
return {
|
|
75
|
-
'name':name,
|
|
76
|
-
'children':[],
|
|
77
|
-
'attributes':{},
|
|
78
|
-
'setAttribute': def(name, val): this.attributes[name] = val;,
|
|
79
|
-
'appendChild': def(child): this.children.push(child);,
|
|
80
|
-
}
|
|
81
|
-
})
|
|
82
|
-
else:
|
|
83
|
-
E = maker_for_document(document)
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
|
+
|
|
4
|
+
html_elements = {
|
|
5
|
+
'a', 'abbr', 'acronym', 'address', 'area',
|
|
6
|
+
'article', 'aside', 'audio', 'b', 'base', 'big', 'body', 'blockquote', 'br', 'button',
|
|
7
|
+
'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup',
|
|
8
|
+
'command', 'datagrid', 'datalist', 'dd', 'del', 'details', 'dfn',
|
|
9
|
+
'dialog', 'dir', 'div', 'dl', 'dt', 'em', 'event-source', 'fieldset',
|
|
10
|
+
'figcaption', 'figure', 'footer', 'font', 'form', 'header', 'h1',
|
|
11
|
+
'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'head', 'i', 'iframe', 'img', 'input', 'ins',
|
|
12
|
+
'keygen', 'kbd', 'label', 'legend', 'li', 'm', 'map', 'menu', 'meter',
|
|
13
|
+
'multicol', 'nav', 'nextid', 'ol', 'output', 'optgroup', 'option',
|
|
14
|
+
'p', 'pre', 'progress', 'q', 's', 'samp', 'script', 'section', 'select',
|
|
15
|
+
'small', 'sound', 'source', 'spacer', 'span', 'strike', 'strong', 'style',
|
|
16
|
+
'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'time', 'tfoot',
|
|
17
|
+
'th', 'thead', 'tr', 'tt', 'u', 'ul', 'var', 'video'
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
mathml_elements = {
|
|
21
|
+
'maction', 'math', 'merror', 'mfrac', 'mi',
|
|
22
|
+
'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom',
|
|
23
|
+
'mprescripts', 'mroot', 'mrow', 'mspace', 'msqrt', 'mstyle', 'msub',
|
|
24
|
+
'msubsup', 'msup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder',
|
|
25
|
+
'munderover', 'none'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
svg_elements = {
|
|
29
|
+
'a', 'animate', 'animateColor', 'animateMotion',
|
|
30
|
+
'animateTransform', 'clipPath', 'circle', 'defs', 'desc', 'ellipse',
|
|
31
|
+
'font-face', 'font-face-name', 'font-face-src', 'g', 'glyph', 'hkern',
|
|
32
|
+
'linearGradient', 'line', 'marker', 'metadata', 'missing-glyph',
|
|
33
|
+
'mpath', 'path', 'polygon', 'polyline', 'radialGradient', 'rect',
|
|
34
|
+
'set', 'stop', 'svg', 'switch', 'text', 'title', 'tspan', 'use'
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
html5_tags = html_elements.union(mathml_elements).union(svg_elements)
|
|
38
|
+
|
|
39
|
+
def _makeelement(tag, *args, **kwargs):
|
|
40
|
+
ans = this.createElement(tag)
|
|
41
|
+
|
|
42
|
+
for attr in kwargs:
|
|
43
|
+
vattr = str.replace(str.rstrip(attr, '_'), '_', '-')
|
|
44
|
+
val = kwargs[attr]
|
|
45
|
+
if callable(val):
|
|
46
|
+
if str.startswith(attr, 'on'):
|
|
47
|
+
attr = attr[2:]
|
|
48
|
+
ans.addEventListener(attr, val)
|
|
49
|
+
elif val is True:
|
|
50
|
+
ans.setAttribute(vattr, vattr)
|
|
51
|
+
elif jstype(val) is 'string':
|
|
52
|
+
ans.setAttribute(vattr, val)
|
|
53
|
+
|
|
54
|
+
for arg in args:
|
|
55
|
+
if jstype(arg) is 'string':
|
|
56
|
+
arg = this.createTextNode(arg)
|
|
57
|
+
ans.appendChild(arg)
|
|
58
|
+
return ans
|
|
59
|
+
|
|
60
|
+
def maker_for_document(document):
|
|
61
|
+
# Create an elementmaker to be used with the specified document
|
|
62
|
+
E = _makeelement.bind(document)
|
|
63
|
+
Object.defineProperties(E, {
|
|
64
|
+
tag: {
|
|
65
|
+
'value':_makeelement.bind(document, tag)
|
|
66
|
+
} for tag in html5_tags
|
|
67
|
+
})
|
|
68
|
+
return E
|
|
69
|
+
|
|
70
|
+
if jstype(document) is 'undefined':
|
|
71
|
+
E = maker_for_document({
|
|
72
|
+
'createTextNode': def(value): return value;,
|
|
73
|
+
'createElement': def(name):
|
|
74
|
+
return {
|
|
75
|
+
'name':name,
|
|
76
|
+
'children':[],
|
|
77
|
+
'attributes':{},
|
|
78
|
+
'setAttribute': def(name, val): this.attributes[name] = val;,
|
|
79
|
+
'appendChild': def(child): this.children.push(child);,
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
else:
|
|
83
|
+
E = maker_for_document(document)
|
package/src/lib/encodings.pyj
CHANGED
|
@@ -1,126 +1,126 @@
|
|
|
1
|
-
# vim:fileencoding=utf-8
|
|
2
|
-
# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
|
-
|
|
4
|
-
def base64encode(bytes, altchars, pad_char):
|
|
5
|
-
# Convert an array of bytes into a base-64 encoded string
|
|
6
|
-
l = bytes.length
|
|
7
|
-
remainder = l % 3
|
|
8
|
-
main_length = l - remainder
|
|
9
|
-
encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + (altchars or '+/')
|
|
10
|
-
pad_char = '=' if pad_char is undefined else pad_char
|
|
11
|
-
ans = v'[]'
|
|
12
|
-
for v'var i = 0; i < main_length; i += 3':
|
|
13
|
-
chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]
|
|
14
|
-
ans.push(encodings[(chunk & 16515072) >> 18], encodings[(chunk & 258048) >> 12], encodings[(chunk & 4032) >> 6], encodings[chunk & 63])
|
|
15
|
-
if remainder is 1:
|
|
16
|
-
chunk = bytes[main_length]
|
|
17
|
-
ans.push(encodings[(chunk & 252) >> 2], encodings[(chunk & 3) << 4], pad_char, pad_char)
|
|
18
|
-
elif remainder is 2:
|
|
19
|
-
chunk = (bytes[main_length] << 8) | bytes[main_length + 1]
|
|
20
|
-
ans.push(encodings[(chunk & 64512) >> 10], encodings[(chunk & 1008) >> 4], encodings[(chunk & 15) << 2], pad_char)
|
|
21
|
-
return ans.join('')
|
|
22
|
-
|
|
23
|
-
def base64decode(string):
|
|
24
|
-
# convert the output of base64encode back into an array of bytes
|
|
25
|
-
# (Uint8Array) only works with the standard altchars and pad_char
|
|
26
|
-
if jstype(window) is not 'undefined':
|
|
27
|
-
chars = window.atob(string)
|
|
28
|
-
else:
|
|
29
|
-
chars = new Buffer(string, 'base64').toString('binary') # noqa: undef
|
|
30
|
-
ans = Uint8Array(chars.length)
|
|
31
|
-
for i in range(ans.length):
|
|
32
|
-
ans[i] = chars.charCodeAt(i)
|
|
33
|
-
return ans
|
|
34
|
-
|
|
35
|
-
def urlsafe_b64encode(bytes, pad_char):
|
|
36
|
-
return base64encode(bytes, '-_', pad_char)
|
|
37
|
-
|
|
38
|
-
def urlsafe_b64decode(string):
|
|
39
|
-
string = String.prototype.replace.call(string, /[_-]/g, def(m): return '+' if m is '-' else '/';)
|
|
40
|
-
return base64decode(string)
|
|
41
|
-
|
|
42
|
-
def hexlify(bytes):
|
|
43
|
-
ans = v'[]'
|
|
44
|
-
for v'var i = 0; i < bytes.length; i++':
|
|
45
|
-
x = bytes[i].toString(16)
|
|
46
|
-
if x.length is 1:
|
|
47
|
-
x = '0' + x
|
|
48
|
-
ans.push(x)
|
|
49
|
-
return ans.join('')
|
|
50
|
-
|
|
51
|
-
def unhexlify(string):
|
|
52
|
-
num = string.length // 2
|
|
53
|
-
if num * 2 is not string.length:
|
|
54
|
-
raise ValueError('string length is not a multiple of two')
|
|
55
|
-
ans = Uint8Array(num)
|
|
56
|
-
for v'var i = 0; i < num; i++':
|
|
57
|
-
x = parseInt(string[i*2:i*2+2], 16)
|
|
58
|
-
if isNaN(x):
|
|
59
|
-
raise ValueError('string is not hex-encoded')
|
|
60
|
-
ans[i] = x
|
|
61
|
-
return ans
|
|
62
|
-
|
|
63
|
-
utf8_decoder_table = v'''[
|
|
64
|
-
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
|
|
65
|
-
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
|
|
66
|
-
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
|
|
67
|
-
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
|
|
68
|
-
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
|
|
69
|
-
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
|
|
70
|
-
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
|
|
71
|
-
0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
|
|
72
|
-
0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
|
|
73
|
-
0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
|
|
74
|
-
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
|
|
75
|
-
1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
|
|
76
|
-
1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
|
|
77
|
-
1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
|
|
78
|
-
]'''
|
|
79
|
-
|
|
80
|
-
def _from_code_point(x):
|
|
81
|
-
if x <= 0xFFFF:
|
|
82
|
-
return String.fromCharCode(x)
|
|
83
|
-
x -= 0x10000
|
|
84
|
-
return String.fromCharCode((x >> 10) + 0xD800, (x % 0x400) + 0xDC00)
|
|
85
|
-
|
|
86
|
-
def utf8_decode(bytes, errors, replacement):
|
|
87
|
-
# Convert an array of UTF-8 encoded bytes into a string
|
|
88
|
-
state = 0
|
|
89
|
-
ans = v'[]'
|
|
90
|
-
|
|
91
|
-
for v'var i = 0, l = bytes.length; i < l; i++': # noqa
|
|
92
|
-
byte = bytes[i]
|
|
93
|
-
typ = utf8_decoder_table[byte]
|
|
94
|
-
codep = (byte & 0x3f) | (codep << 6) if state is not 0 else (0xff >> typ) & (byte)
|
|
95
|
-
state = utf8_decoder_table[256 + state*16 + typ]
|
|
96
|
-
if state is 0:
|
|
97
|
-
ans.push(_from_code_point(codep))
|
|
98
|
-
elif state is 1:
|
|
99
|
-
if not errors or errors is 'strict':
|
|
100
|
-
raise UnicodeDecodeError(str.format('The byte 0x{:02x} at position {} is not valid UTF-8', byte, i))
|
|
101
|
-
elif errors is 'replace':
|
|
102
|
-
ans.push(replacement or '?')
|
|
103
|
-
return ans.join('')
|
|
104
|
-
|
|
105
|
-
def utf8_encode_js(string):
|
|
106
|
-
# Encode a string as an array of UTF-8 bytes
|
|
107
|
-
escstr = encodeURIComponent(string)
|
|
108
|
-
ans = v'[]'
|
|
109
|
-
for v'var i = 0; i < escstr.length; i++':
|
|
110
|
-
ch = escstr[i]
|
|
111
|
-
if ch is '%':
|
|
112
|
-
ans.push(parseInt(escstr[i+1:i+3], 16))
|
|
113
|
-
i += 2
|
|
114
|
-
else:
|
|
115
|
-
ans.push(ch.charCodeAt(0))
|
|
116
|
-
return Uint8Array(ans)
|
|
117
|
-
|
|
118
|
-
if jstype(TextEncoder) is 'function':
|
|
119
|
-
_u8enc = TextEncoder('utf-8')
|
|
120
|
-
utf8_encode = _u8enc.encode.bind(_u8enc)
|
|
121
|
-
_u8enc = undefined
|
|
122
|
-
else:
|
|
123
|
-
utf8_encode = utf8_encode_js
|
|
124
|
-
|
|
125
|
-
def utf8_encode_native(string):
|
|
126
|
-
return _u8enc.encode(string)
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
|
+
|
|
4
|
+
def base64encode(bytes, altchars, pad_char):
|
|
5
|
+
# Convert an array of bytes into a base-64 encoded string
|
|
6
|
+
l = bytes.length
|
|
7
|
+
remainder = l % 3
|
|
8
|
+
main_length = l - remainder
|
|
9
|
+
encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + (altchars or '+/')
|
|
10
|
+
pad_char = '=' if pad_char is undefined else pad_char
|
|
11
|
+
ans = v'[]'
|
|
12
|
+
for v'var i = 0; i < main_length; i += 3':
|
|
13
|
+
chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]
|
|
14
|
+
ans.push(encodings[(chunk & 16515072) >> 18], encodings[(chunk & 258048) >> 12], encodings[(chunk & 4032) >> 6], encodings[chunk & 63])
|
|
15
|
+
if remainder is 1:
|
|
16
|
+
chunk = bytes[main_length]
|
|
17
|
+
ans.push(encodings[(chunk & 252) >> 2], encodings[(chunk & 3) << 4], pad_char, pad_char)
|
|
18
|
+
elif remainder is 2:
|
|
19
|
+
chunk = (bytes[main_length] << 8) | bytes[main_length + 1]
|
|
20
|
+
ans.push(encodings[(chunk & 64512) >> 10], encodings[(chunk & 1008) >> 4], encodings[(chunk & 15) << 2], pad_char)
|
|
21
|
+
return ans.join('')
|
|
22
|
+
|
|
23
|
+
def base64decode(string):
|
|
24
|
+
# convert the output of base64encode back into an array of bytes
|
|
25
|
+
# (Uint8Array) only works with the standard altchars and pad_char
|
|
26
|
+
if jstype(window) is not 'undefined':
|
|
27
|
+
chars = window.atob(string)
|
|
28
|
+
else:
|
|
29
|
+
chars = new Buffer(string, 'base64').toString('binary') # noqa: undef
|
|
30
|
+
ans = Uint8Array(chars.length)
|
|
31
|
+
for i in range(ans.length):
|
|
32
|
+
ans[i] = chars.charCodeAt(i)
|
|
33
|
+
return ans
|
|
34
|
+
|
|
35
|
+
def urlsafe_b64encode(bytes, pad_char):
|
|
36
|
+
return base64encode(bytes, '-_', pad_char)
|
|
37
|
+
|
|
38
|
+
def urlsafe_b64decode(string):
|
|
39
|
+
string = String.prototype.replace.call(string, /[_-]/g, def(m): return '+' if m is '-' else '/';)
|
|
40
|
+
return base64decode(string)
|
|
41
|
+
|
|
42
|
+
def hexlify(bytes):
|
|
43
|
+
ans = v'[]'
|
|
44
|
+
for v'var i = 0; i < bytes.length; i++':
|
|
45
|
+
x = bytes[i].toString(16)
|
|
46
|
+
if x.length is 1:
|
|
47
|
+
x = '0' + x
|
|
48
|
+
ans.push(x)
|
|
49
|
+
return ans.join('')
|
|
50
|
+
|
|
51
|
+
def unhexlify(string):
|
|
52
|
+
num = string.length // 2
|
|
53
|
+
if num * 2 is not string.length:
|
|
54
|
+
raise ValueError('string length is not a multiple of two')
|
|
55
|
+
ans = Uint8Array(num)
|
|
56
|
+
for v'var i = 0; i < num; i++':
|
|
57
|
+
x = parseInt(string[i*2:i*2+2], 16)
|
|
58
|
+
if isNaN(x):
|
|
59
|
+
raise ValueError('string is not hex-encoded')
|
|
60
|
+
ans[i] = x
|
|
61
|
+
return ans
|
|
62
|
+
|
|
63
|
+
utf8_decoder_table = v'''[
|
|
64
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
|
|
65
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
|
|
66
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
|
|
67
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
|
|
68
|
+
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
|
|
69
|
+
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
|
|
70
|
+
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
|
|
71
|
+
0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
|
|
72
|
+
0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
|
|
73
|
+
0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
|
|
74
|
+
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
|
|
75
|
+
1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
|
|
76
|
+
1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
|
|
77
|
+
1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
|
|
78
|
+
]'''
|
|
79
|
+
|
|
80
|
+
def _from_code_point(x):
|
|
81
|
+
if x <= 0xFFFF:
|
|
82
|
+
return String.fromCharCode(x)
|
|
83
|
+
x -= 0x10000
|
|
84
|
+
return String.fromCharCode((x >> 10) + 0xD800, (x % 0x400) + 0xDC00)
|
|
85
|
+
|
|
86
|
+
def utf8_decode(bytes, errors, replacement):
|
|
87
|
+
# Convert an array of UTF-8 encoded bytes into a string
|
|
88
|
+
state = 0
|
|
89
|
+
ans = v'[]'
|
|
90
|
+
|
|
91
|
+
for v'var i = 0, l = bytes.length; i < l; i++': # noqa
|
|
92
|
+
byte = bytes[i]
|
|
93
|
+
typ = utf8_decoder_table[byte]
|
|
94
|
+
codep = (byte & 0x3f) | (codep << 6) if state is not 0 else (0xff >> typ) & (byte)
|
|
95
|
+
state = utf8_decoder_table[256 + state*16 + typ]
|
|
96
|
+
if state is 0:
|
|
97
|
+
ans.push(_from_code_point(codep))
|
|
98
|
+
elif state is 1:
|
|
99
|
+
if not errors or errors is 'strict':
|
|
100
|
+
raise UnicodeDecodeError(str.format('The byte 0x{:02x} at position {} is not valid UTF-8', byte, i))
|
|
101
|
+
elif errors is 'replace':
|
|
102
|
+
ans.push(replacement or '?')
|
|
103
|
+
return ans.join('')
|
|
104
|
+
|
|
105
|
+
def utf8_encode_js(string):
|
|
106
|
+
# Encode a string as an array of UTF-8 bytes
|
|
107
|
+
escstr = encodeURIComponent(string)
|
|
108
|
+
ans = v'[]'
|
|
109
|
+
for v'var i = 0; i < escstr.length; i++':
|
|
110
|
+
ch = escstr[i]
|
|
111
|
+
if ch is '%':
|
|
112
|
+
ans.push(parseInt(escstr[i+1:i+3], 16))
|
|
113
|
+
i += 2
|
|
114
|
+
else:
|
|
115
|
+
ans.push(ch.charCodeAt(0))
|
|
116
|
+
return Uint8Array(ans)
|
|
117
|
+
|
|
118
|
+
if jstype(TextEncoder) is 'function':
|
|
119
|
+
_u8enc = TextEncoder('utf-8')
|
|
120
|
+
utf8_encode = _u8enc.encode.bind(_u8enc)
|
|
121
|
+
_u8enc = undefined
|
|
122
|
+
else:
|
|
123
|
+
utf8_encode = utf8_encode_js
|
|
124
|
+
|
|
125
|
+
def utf8_encode_native(string):
|
|
126
|
+
return _u8enc.encode(string)
|