rapydscript-ns 0.9.3 → 0.9.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.
Files changed (98) hide show
  1. package/.agignore +1 -1
  2. package/.github/workflows/ci.yml +38 -38
  3. package/=template.pyj +5 -5
  4. package/CHANGELOG.md +9 -0
  5. package/HACKING.md +103 -103
  6. package/LICENSE +24 -24
  7. package/PYTHON_GAPS.md +48 -116
  8. package/README.md +35 -15
  9. package/TODO.md +1 -26
  10. package/add-toc-to-readme +2 -2
  11. package/bin/export +75 -75
  12. package/bin/rapydscript +0 -0
  13. package/bin/web-repl-export +102 -102
  14. package/build +2 -2
  15. package/language-service/index.js +9 -7
  16. package/package.json +1 -1
  17. package/publish.py +37 -37
  18. package/session.vim +4 -4
  19. package/setup.cfg +2 -2
  20. package/src/ast.pyj +6 -0
  21. package/src/baselib-containers.pyj +23 -1
  22. package/src/baselib-str.pyj +13 -2
  23. package/src/compiler.pyj +36 -36
  24. package/src/errors.pyj +30 -30
  25. package/src/lib/aes.pyj +646 -646
  26. package/src/lib/collections.pyj +227 -3
  27. package/src/lib/copy.pyj +120 -120
  28. package/src/lib/elementmaker.pyj +83 -83
  29. package/src/lib/encodings.pyj +126 -126
  30. package/src/lib/gettext.pyj +569 -569
  31. package/src/lib/itertools.pyj +580 -580
  32. package/src/lib/math.pyj +193 -193
  33. package/src/lib/operator.pyj +11 -11
  34. package/src/lib/pprint.pyj +455 -0
  35. package/src/lib/random.pyj +118 -118
  36. package/src/lib/react.pyj +74 -74
  37. package/src/lib/statistics.pyj +0 -0
  38. package/src/lib/traceback.pyj +63 -63
  39. package/src/lib/uuid.pyj +77 -77
  40. package/src/monaco-language-service/diagnostics.js +2 -2
  41. package/src/monaco-language-service/dts.js +550 -550
  42. package/src/output/codegen.pyj +4 -1
  43. package/src/output/comments.pyj +45 -45
  44. package/src/output/exceptions.pyj +201 -201
  45. package/src/output/jsx.pyj +164 -164
  46. package/src/output/treeshake.pyj +182 -182
  47. package/src/output/utils.pyj +72 -72
  48. package/src/parse.pyj +28 -7
  49. package/src/string_interpolation.pyj +72 -72
  50. package/src/tokenizer.pyj +18 -2
  51. package/src/unicode_aliases.pyj +576 -576
  52. package/src/utils.pyj +192 -192
  53. package/test/_import_one.pyj +37 -37
  54. package/test/_import_two/__init__.pyj +11 -11
  55. package/test/_import_two/level2/deep.pyj +4 -4
  56. package/test/_import_two/other.pyj +6 -6
  57. package/test/_import_two/sub.pyj +13 -13
  58. package/test/aes_vectors.pyj +421 -421
  59. package/test/annotations.pyj +80 -80
  60. package/test/baselib.pyj +23 -0
  61. package/test/chainmap.pyj +185 -0
  62. package/test/decorators.pyj +77 -77
  63. package/test/docstrings.pyj +39 -39
  64. package/test/elementmaker_test.pyj +45 -45
  65. package/test/functions.pyj +151 -151
  66. package/test/generators.pyj +41 -41
  67. package/test/generic.pyj +370 -370
  68. package/test/internationalization.pyj +73 -73
  69. package/test/lint.pyj +164 -164
  70. package/test/loops.pyj +85 -85
  71. package/test/numpy.pyj +734 -734
  72. package/test/pprint.pyj +232 -0
  73. package/test/repl.pyj +121 -121
  74. package/test/scoped_flags.pyj +76 -76
  75. package/test/statistics.pyj +224 -0
  76. package/test/unit/index.js +80 -0
  77. package/test/unit/language-service-completions.js +2 -0
  78. package/test/unit/language-service-dts.js +543 -543
  79. package/test/unit/language-service-hover.js +455 -455
  80. package/test/unit/language-service.js +63 -2
  81. package/test/unit/web-repl.js +323 -0
  82. package/tools/compiler.d.ts +367 -367
  83. package/tools/completer.js +131 -131
  84. package/tools/export.js +4 -2
  85. package/tools/gettext.js +185 -185
  86. package/tools/ini.js +65 -65
  87. package/tools/msgfmt.js +187 -187
  88. package/tools/repl.js +223 -223
  89. package/tools/test.js +118 -118
  90. package/tools/utils.js +128 -128
  91. package/tools/web_repl.js +95 -95
  92. package/try +41 -41
  93. package/web-repl/env.js +196 -196
  94. package/web-repl/index.html +163 -163
  95. package/web-repl/prism.css +139 -139
  96. package/web-repl/prism.js +113 -113
  97. package/web-repl/rapydscript.js +228 -226
  98. package/web-repl/sha1.js +25 -25
@@ -2,10 +2,11 @@
2
2
  # License: BSD
3
3
  # RapydScript implementation of Python's collections standard library.
4
4
  #
5
- # Supported: namedtuple, deque, Counter, OrderedDict, defaultdict
5
+ # Supported: namedtuple, deque, Counter, OrderedDict, defaultdict, ChainMap
6
6
  #
7
- # Note: Counter, OrderedDict, and defaultdict use __getitem__/__setitem__.
8
- # For Python-compatible subscript syntax (obj[key]) in user code, add:
7
+ # Note: Counter, OrderedDict, defaultdict, and ChainMap use
8
+ # __getitem__/__setitem__. For Python-compatible subscript syntax (obj[key])
9
+ # in user code, add:
9
10
  # from __python__ import overload_getitem
10
11
 
11
12
 
@@ -693,3 +694,226 @@ class defaultdict:
693
694
  if self._data[k] != src[k]:
694
695
  return False
695
696
  return True
697
+
698
+
699
+ class ChainMap:
700
+ """Combine several mappings into a single, updateable view.
701
+
702
+ Lookups search the underlying mappings in order, so the first mapping
703
+ wins. Writes, updates, and deletions affect only the first mapping.
704
+ Mirrors Python's collections.ChainMap.
705
+ """
706
+
707
+ def __init__(self, *maps):
708
+ if maps.length == 0:
709
+ self.maps = [{}]
710
+ else:
711
+ self.maps = list(maps)
712
+
713
+ # ── internal mapping-access helpers ───────────────────────────────────
714
+ # A "map" may be a plain JS object, a RapydScript dict (ρσ_dict, used for
715
+ # {...} literals in the web-repl), or any RapydScript mapping defining
716
+ # __getitem__/__setitem__/__contains__ (OrderedDict, defaultdict, Counter,
717
+ # or a nested ChainMap).
718
+
719
+ def _is_rdict(self, m):
720
+ return v'!!(m && m.jsmap && typeof m.jsmap.get === "function")'
721
+
722
+ def _is_mapping(self, m):
723
+ return v'!!(m && typeof m.__getitem__ === "function" && typeof m.__contains__ === "function")'
724
+
725
+ def _mkeys(self, m):
726
+ if self._is_rdict(m):
727
+ return v'Array.from(m.jsmap.keys())'
728
+ if self._is_mapping(m):
729
+ return list(m.keys())
730
+ return Object.keys(m)
731
+
732
+ def _mhas(self, m, key):
733
+ if self._is_rdict(m):
734
+ return v'm.jsmap.has(key)'
735
+ if self._is_mapping(m):
736
+ return m.__contains__(key)
737
+ return v'Object.prototype.hasOwnProperty.call(m, key)'
738
+
739
+ def _mget(self, m, key):
740
+ if self._is_rdict(m):
741
+ return v'm.jsmap.get(key)'
742
+ if self._is_mapping(m):
743
+ return m.__getitem__(key)
744
+ return v'm[key]'
745
+
746
+ def _mset(self, m, key, value):
747
+ if self._is_rdict(m):
748
+ v'm.jsmap.set(key, value)'
749
+ elif self._is_mapping(m):
750
+ m.__setitem__(key, value)
751
+ else:
752
+ v'm[key] = value'
753
+
754
+ def _mdel(self, m, key):
755
+ if self._is_rdict(m):
756
+ v'm.jsmap["delete"](key)'
757
+ elif self._is_mapping(m):
758
+ m.__delitem__(key)
759
+ else:
760
+ v'delete m[key]'
761
+
762
+ def _all_keys(self):
763
+ # Unique keys across every map. Maps are scanned last-to-first so that
764
+ # earlier maps keep their key positions, matching Python's iteration.
765
+ seen = {}
766
+ result = []
767
+ i = self.maps.length - 1
768
+ while i >= 0:
769
+ for k in self._mkeys(self.maps[i]):
770
+ if k not in seen:
771
+ seen[k] = True
772
+ result.push(k)
773
+ i -= 1
774
+ return result
775
+
776
+ def __getitem__(self, key):
777
+ for m in self.maps:
778
+ if self._mhas(m, key):
779
+ return self._mget(m, key)
780
+ raise KeyError(repr(key))
781
+
782
+ def __setitem__(self, key, value):
783
+ self._mset(self.maps[0], key, value)
784
+
785
+ def __delitem__(self, key):
786
+ if not self._mhas(self.maps[0], key):
787
+ raise KeyError('Key not found in the first mapping: ' + repr(key))
788
+ self._mdel(self.maps[0], key)
789
+
790
+ def __contains__(self, key):
791
+ for m in self.maps:
792
+ if self._mhas(m, key):
793
+ return True
794
+ return False
795
+
796
+ def __len__(self):
797
+ return self._all_keys().length
798
+
799
+ def __iter__(self):
800
+ return iter(self._all_keys())
801
+
802
+ def __bool__(self):
803
+ for m in self.maps:
804
+ if self._mkeys(m).length > 0:
805
+ return True
806
+ return False
807
+
808
+ def _map_repr(self, m):
809
+ pairs = [repr(k) + ': ' + repr(self._mget(m, k)) for k in self._mkeys(m)]
810
+ return '{' + pairs.join(', ') + '}'
811
+
812
+ def __repr__(self):
813
+ parts = [self._map_repr(m) for m in self.maps]
814
+ return 'ChainMap(' + parts.join(', ') + ')'
815
+
816
+ def __eq__(self, other):
817
+ if other is None:
818
+ return False
819
+ is_mapish = self._is_rdict(other) or self._is_mapping(other) or (jstype(other) is 'object' and not Array.isArray(other))
820
+ if not is_mapish:
821
+ return False
822
+ a = self._all_keys()
823
+ b = self._mkeys(other)
824
+ if a.length != b.length:
825
+ return False
826
+ for k in a:
827
+ if not self._mhas(other, k):
828
+ return False
829
+ if self.__getitem__(k) != self._mget(other, k):
830
+ return False
831
+ return True
832
+
833
+ def get(self, key, dflt=None):
834
+ if self.__contains__(key):
835
+ return self.__getitem__(key)
836
+ return dflt
837
+
838
+ def keys(self):
839
+ return self._all_keys()
840
+
841
+ def values(self):
842
+ return [self.__getitem__(k) for k in self._all_keys()]
843
+
844
+ def items(self):
845
+ return [[k, self.__getitem__(k)] for k in self._all_keys()]
846
+
847
+ @property
848
+ def parents(self):
849
+ cm = ChainMap()
850
+ cm.maps = self.maps.slice(1)
851
+ return cm
852
+
853
+ def new_child(self, m=None):
854
+ if m is None:
855
+ m = {}
856
+ cm = ChainMap()
857
+ cm.maps = [m].concat(self.maps)
858
+ return cm
859
+
860
+ def _copy_map(self, m):
861
+ if jstype(m.copy) is 'function':
862
+ return m.copy()
863
+ result = {}
864
+ for k in Object.keys(m):
865
+ result[k] = m[k]
866
+ return result
867
+
868
+ def copy(self):
869
+ cm = ChainMap()
870
+ cm.maps = [self._copy_map(self.maps[0])].concat(self.maps.slice(1))
871
+ return cm
872
+
873
+ def pop(self, key, *rest):
874
+ first = self.maps[0]
875
+ if self._mhas(first, key):
876
+ val = self._mget(first, key)
877
+ self._mdel(first, key)
878
+ return val
879
+ if len(rest) > 0:
880
+ return rest[0]
881
+ raise KeyError('Key not found in the first mapping: ' + repr(key))
882
+
883
+ def popitem(self):
884
+ first = self.maps[0]
885
+ keys = self._mkeys(first)
886
+ if keys.length == 0:
887
+ raise KeyError('No keys found in the first mapping.')
888
+ k = keys[keys.length - 1]
889
+ val = self._mget(first, k)
890
+ self._mdel(first, k)
891
+ return [k, val]
892
+
893
+ def setdefault(self, key, dflt=None):
894
+ if not self.__contains__(key):
895
+ self._mset(self.maps[0], key, dflt)
896
+ return self.__getitem__(key)
897
+
898
+ def clear(self):
899
+ first = self.maps[0]
900
+ if jstype(first.clear) is 'function':
901
+ first.clear()
902
+ else:
903
+ for k in Object.keys(first):
904
+ v'delete first[k]'
905
+
906
+ def update(self, other=None, **kwargs):
907
+ first = self.maps[0]
908
+ if other is not None:
909
+ if self._is_rdict(other) or self._is_mapping(other):
910
+ for k in self._mkeys(other):
911
+ self._mset(first, k, self._mget(other, k))
912
+ elif jstype(other) is 'object' and not Array.isArray(other):
913
+ for k in Object.keys(other):
914
+ self._mset(first, k, other[k])
915
+ else:
916
+ for pair in other:
917
+ self._mset(first, pair[0], pair[1])
918
+ for k in kwargs:
919
+ self._mset(first, k, kwargs[k])
package/src/lib/copy.pyj CHANGED
@@ -1,120 +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
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
@@ -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)