rapydscript-ns 0.8.2 → 0.8.4
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 +39 -0
- package/HACKING.md +103 -103
- package/LICENSE +24 -24
- package/PYTHON_DIFFERENCES_REPORT.md +291 -0
- package/PYTHON_FEATURE_COVERAGE.md +106 -15
- package/README.md +831 -52
- package/TODO.md +4 -286
- 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 +4623 -0
- package/language-service/language-service.d.ts +40 -0
- package/package.json +9 -7
- package/publish.py +37 -37
- package/release/baselib-plain-pretty.js +2006 -229
- package/release/baselib-plain-ugly.js +70 -3
- package/release/compiler.js +11554 -3870
- package/release/signatures.json +31 -29
- package/session.vim +4 -4
- package/setup.cfg +2 -2
- package/src/ast.pyj +93 -1
- package/src/baselib-builtins.pyj +99 -2
- package/src/baselib-containers.pyj +107 -4
- package/src/baselib-errors.pyj +44 -0
- package/src/baselib-internal.pyj +124 -5
- package/src/baselib-itertools.pyj +97 -97
- package/src/baselib-str.pyj +32 -1
- package/src/compiler.pyj +36 -36
- package/src/errors.pyj +30 -30
- package/src/lib/aes.pyj +646 -646
- package/src/lib/collections.pyj +1 -1
- package/src/lib/copy.pyj +120 -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/itertools.pyj +580 -580
- package/src/lib/math.pyj +193 -193
- package/src/lib/numpy.pyj +10 -10
- package/src/lib/operator.pyj +11 -11
- package/src/lib/pythonize.pyj +20 -20
- package/src/lib/random.pyj +118 -118
- package/src/lib/re.pyj +470 -470
- package/src/lib/react.pyj +74 -0
- package/src/lib/traceback.pyj +63 -63
- package/src/lib/uuid.pyj +77 -77
- package/src/monaco-language-service/analyzer.js +131 -9
- package/src/monaco-language-service/builtins.js +17 -2
- package/src/monaco-language-service/completions.js +170 -1
- package/src/monaco-language-service/diagnostics.js +25 -3
- package/src/monaco-language-service/dts.js +550 -550
- package/src/monaco-language-service/index.js +17 -0
- package/src/monaco-language-service/scope.js +3 -0
- package/src/output/classes.pyj +128 -11
- package/src/output/codegen.pyj +17 -3
- package/src/output/comments.pyj +45 -45
- package/src/output/exceptions.pyj +201 -105
- package/src/output/functions.pyj +13 -16
- package/src/output/jsx.pyj +164 -0
- package/src/output/literals.pyj +28 -2
- package/src/output/loops.pyj +0 -9
- package/src/output/modules.pyj +2 -5
- package/src/output/operators.pyj +22 -2
- package/src/output/statements.pyj +2 -2
- package/src/output/stream.pyj +1 -13
- package/src/output/treeshake.pyj +182 -182
- package/src/output/utils.pyj +72 -72
- package/src/parse.pyj +434 -114
- package/src/string_interpolation.pyj +72 -72
- package/src/tokenizer.pyj +29 -0
- 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/baselib.pyj +4 -4
- package/test/classes.pyj +56 -17
- package/test/collections.pyj +5 -5
- 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/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/python_compat.pyj +326 -0
- package/test/python_features.pyj +129 -29
- package/test/regexp.pyj +55 -55
- package/test/repl.pyj +121 -121
- package/test/scoped_flags.pyj +76 -76
- package/test/slice.pyj +105 -0
- package/test/str.pyj +25 -0
- package/test/unit/fixtures/fibonacci_expected.js +1 -1
- package/test/unit/index.js +2296 -71
- package/test/unit/language-service-builtins.js +70 -0
- package/test/unit/language-service-bundle.js +5 -5
- package/test/unit/language-service-completions.js +180 -0
- package/test/unit/language-service-dts.js +543 -543
- package/test/unit/language-service-hover.js +455 -455
- package/test/unit/language-service-index.js +350 -0
- package/test/unit/language-service-scope.js +255 -0
- package/test/unit/language-service.js +625 -4
- package/test/unit/run-language-service.js +1 -0
- package/test/unit/web-repl.js +437 -0
- package/tools/build-language-service.js +2 -2
- package/tools/cli.js +547 -547
- package/tools/compile.js +219 -219
- package/tools/compiler.js +0 -24
- package/tools/completer.js +131 -131
- package/tools/embedded_compiler.js +251 -251
- package/tools/export.js +3 -37
- 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 -74
- package/web-repl/index.html +163 -163
- package/web-repl/main.js +252 -254
- package/web-repl/prism.css +139 -139
- package/web-repl/prism.js +113 -113
- package/web-repl/rapydscript.js +227 -139
- package/web-repl/sha1.js +25 -25
- package/hack_demo.pyj +0 -112
- package/web-repl/language-service.js +0 -4187
package/src/lib/collections.pyj
CHANGED
|
@@ -353,7 +353,7 @@ class Counter:
|
|
|
353
353
|
|
|
354
354
|
def most_common(self, n=None):
|
|
355
355
|
items = [[k, self._data[k]] for k in self._data]
|
|
356
|
-
items.
|
|
356
|
+
items.sort(key=def(pair): return -pair[1];)
|
|
357
357
|
if n is not None:
|
|
358
358
|
return items[:n]
|
|
359
359
|
return items
|
package/src/lib/copy.pyj
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: BSD
|
|
3
|
+
# RapydScript implementation of Python's copy standard library.
|
|
4
|
+
#
|
|
5
|
+
# Supported: copy, deepcopy
|
|
6
|
+
# Classes may define __copy__() and __deepcopy__(memo) for custom behaviour.
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _is_primitive(x):
|
|
10
|
+
t = jstype(x)
|
|
11
|
+
return x is None or t is 'number' or t is 'boolean' or t is 'string' or t is 'undefined'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def copy(x):
|
|
15
|
+
"""Return a shallow copy of x.
|
|
16
|
+
|
|
17
|
+
For immutable primitives (numbers, strings, booleans, None) the object
|
|
18
|
+
itself is returned unchanged. For containers a new container of the same
|
|
19
|
+
type is created whose top-level items are the same objects as in the
|
|
20
|
+
original.
|
|
21
|
+
|
|
22
|
+
Dispatch order:
|
|
23
|
+
1. Primitive → return as-is.
|
|
24
|
+
2. ``__copy__`` method → call and return.
|
|
25
|
+
3. list → ``list(x)`` (slice).
|
|
26
|
+
4. set → ``set(x)``.
|
|
27
|
+
5. frozenset → ``frozenset(x)``.
|
|
28
|
+
6. dict (ρσ_dict) → ``x.copy()``.
|
|
29
|
+
7. Plain JS object (constructor is Object or null-proto) → Object.assign.
|
|
30
|
+
8. Other object (class instance) → Object.create + Object.assign.
|
|
31
|
+
"""
|
|
32
|
+
if _is_primitive(x):
|
|
33
|
+
return x
|
|
34
|
+
if jstype(x.__copy__) is 'function':
|
|
35
|
+
return x.__copy__()
|
|
36
|
+
if Array.isArray(x):
|
|
37
|
+
return list(x)
|
|
38
|
+
if isinstance(x, set):
|
|
39
|
+
return set(x)
|
|
40
|
+
if isinstance(x, frozenset):
|
|
41
|
+
return frozenset(x)
|
|
42
|
+
if isinstance(x, dict):
|
|
43
|
+
return x.copy()
|
|
44
|
+
proto = Object.getPrototypeOf(x)
|
|
45
|
+
if x.constructor is Object or proto is None:
|
|
46
|
+
return Object.assign({}, x)
|
|
47
|
+
# Class instance: create a same-prototype object and copy own properties.
|
|
48
|
+
result = Object.create(proto)
|
|
49
|
+
Object.assign(result, x)
|
|
50
|
+
return result
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def deepcopy(x, memo=None):
|
|
54
|
+
"""Return a deep (recursive) copy of x.
|
|
55
|
+
|
|
56
|
+
Circular references are handled via the *memo* mapping (a JS Map), which
|
|
57
|
+
stores already-copied objects so that they are only copied once.
|
|
58
|
+
|
|
59
|
+
Dispatch order (same structure as ``copy`` but recursive):
|
|
60
|
+
1. Primitive → return as-is.
|
|
61
|
+
2. Memo hit → return the previously copied object.
|
|
62
|
+
3. ``__deepcopy__(memo)`` method → call and return.
|
|
63
|
+
4. list → recurse into elements.
|
|
64
|
+
5. set → recurse into elements, build new set.
|
|
65
|
+
6. frozenset → recurse into elements, build new frozenset.
|
|
66
|
+
7. dict → recurse into keys and values.
|
|
67
|
+
8. Plain JS object → recurse into own-enumerable properties.
|
|
68
|
+
9. Class instance → recurse into own-enumerable properties.
|
|
69
|
+
"""
|
|
70
|
+
if memo is None:
|
|
71
|
+
memo = v'new Map()'
|
|
72
|
+
if _is_primitive(x):
|
|
73
|
+
return x
|
|
74
|
+
if memo.has(x):
|
|
75
|
+
return memo.get(x)
|
|
76
|
+
if jstype(x.__deepcopy__) is 'function':
|
|
77
|
+
result = x.__deepcopy__(memo)
|
|
78
|
+
memo.set(x, result)
|
|
79
|
+
return result
|
|
80
|
+
if Array.isArray(x):
|
|
81
|
+
result = []
|
|
82
|
+
memo.set(x, result)
|
|
83
|
+
for i in range(x.length):
|
|
84
|
+
result.push(deepcopy(x[i], memo))
|
|
85
|
+
return result
|
|
86
|
+
if isinstance(x, set):
|
|
87
|
+
result = set()
|
|
88
|
+
memo.set(x, result)
|
|
89
|
+
iterator = x[ρσ_iterator_symbol]()
|
|
90
|
+
r = iterator.next()
|
|
91
|
+
while not r.done:
|
|
92
|
+
result.add(deepcopy(r.value, memo))
|
|
93
|
+
r = iterator.next()
|
|
94
|
+
return result
|
|
95
|
+
if isinstance(x, frozenset):
|
|
96
|
+
items = []
|
|
97
|
+
iterator = x[ρσ_iterator_symbol]()
|
|
98
|
+
r = iterator.next()
|
|
99
|
+
while not r.done:
|
|
100
|
+
items.push(deepcopy(r.value, memo))
|
|
101
|
+
r = iterator.next()
|
|
102
|
+
result = frozenset(items)
|
|
103
|
+
memo.set(x, result)
|
|
104
|
+
return result
|
|
105
|
+
if isinstance(x, dict):
|
|
106
|
+
result = dict()
|
|
107
|
+
memo.set(x, result)
|
|
108
|
+
iterator = x.items()
|
|
109
|
+
r = iterator.next()
|
|
110
|
+
while not r.done:
|
|
111
|
+
result.set(deepcopy(r.value[0], memo), deepcopy(r.value[1], memo))
|
|
112
|
+
r = iterator.next()
|
|
113
|
+
return result
|
|
114
|
+
proto = Object.getPrototypeOf(x)
|
|
115
|
+
result = Object.create(proto)
|
|
116
|
+
memo.set(x, result)
|
|
117
|
+
keys = Object.keys(x)
|
|
118
|
+
for i in range(keys.length):
|
|
119
|
+
result[keys[i]] = deepcopy(x[keys[i]], memo)
|
|
120
|
+
return result
|
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)
|