Permalink
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Dec 20, 2018
Dec 20, 2018
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jan 14, 2015
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 27, 2019
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Apr 2, 2019
Apr 2, 2019
Mar 19, 2018
Aug 31, 2017
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Aug 31, 2017
Apr 16, 2019
Mar 19, 2018
Apr 16, 2019
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Nov 12, 2018
Nov 12, 2018
Nov 12, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Apr 2, 2019
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Aug 31, 2017
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jan 6, 2016
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Aug 31, 2017
May 24, 2019
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Aug 31, 2017
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Nov 14, 2018
Mar 19, 2018
Mar 19, 2018
Jul 28, 2018
Mar 19, 2019
Nov 2, 2018
Nov 2, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Nov 12, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jun 29, 2017
Jun 29, 2017
Jun 29, 2017
Oct 13, 2019
Jun 29, 2017
Jul 10, 2017
Jul 10, 2017
Mar 19, 2018
Mar 19, 2018
Oct 13, 2019
Oct 13, 2019
Newer
100644
2476 lines (2275 sloc)
79.1 KB
6
// build tables from data in unicode_data.js
7
var unicode_tables = {}
8
for(var gc in $B.unicode){
9
unicode_tables[gc] = {}
10
$B.unicode[gc].forEach(function(item){
11
if(Array.isArray(item)){
12
var step = item[2] || 1
13
for(var i = 0, nb = item[1]; i < nb; i += 1){
14
unicode_tables[gc][item[0] + i * step] = true
15
}
16
}else{
17
unicode_tables[gc][item] = true
18
}
19
})
20
}
21
22
for(var key in $B.unicode_identifiers){
23
unicode_tables[key] = {}
24
for(const item of $B.unicode_identifiers[key]){
25
if(Array.isArray(item)){
26
for(var i = 0; i < item[1]; i++){
27
unicode_tables[key][item[0] + i] = true
28
}
29
}else{
30
unicode_tables[key][item] = true
31
}
32
}
33
}
34
35
/*
36
// Copy static methods from unicode
37
var from_unicode = [
38
"isalpha",
39
"isalnum",
40
"isdecimal",
41
"isdigit",
42
"isidentifier",
43
]
44
*/
46
// Polyfill for older browsers
47
// The code does not use a regex to make it a bit faster.
48
// Implementation taken from a comment by Timo on the blog:
49
// http://blog.stevenlevithan.com/archives/faster-trim-javascript
50
String.prototype.trim = function () {
51
var c
52
for(var i = 0; i < this.length; i++){
53
c = this.charCodeAt(i)
54
if([32, 10, 13, 9, 12, 11, 160, 5760, 6158, 8192, 8193, 8194,
55
8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8232,
56
8233, 8239, 8287, 12288, 65279].indexOf(c) > -1){
57
continue
58
}else{break}
59
}
60
for(var j = this.length - 1; j >= i; j--){
61
c = this.charCodeAt(j)
63
8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8232,
64
8233, 8239, 8287, 12288, 65279].indexOf(c) > -1){
65
continue
66
}else{break}
67
}
68
return this.substring(i, j + 1);
69
}
72
// Convenience method for browsers which do not have a native trimLeft
73
// (which is a nonstandard extension in Firefox and Chrome)
74
String.prototype.trimLeft = function () {
75
var c
76
for(var i = 0; i < this.length; i++){
77
c = this.charCodeAt(i)
79
8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8232,
80
8233, 8239, 8287, 12288, 65279].indexOf(c) > -1){
81
continue
82
}else{break}
83
}
84
return this.substring(i)
88
String.prototype.trimRight = function () {
89
// Convenience method for browsers which do not have a native trimRight
90
// (which is a nonstandard extension in Firefox and Chrome)
91
var c
92
for(var j = this.length - 1; j >= 0; j--){
93
c = this.charCodeAt(j)
94
if([32, 10, 13, 9, 12, 11, 160, 5760, 6158, 8192, 8193, 8194,
95
8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8232,
96
8233, 8239, 8287, 12288, 65279].indexOf(c) > -1){
97
continue
98
}else{break}
99
}
100
return this.substring(0, j + 1)
118
if($.start === null || $.start === _b_.None){$.start = 0}
119
else if($.start < 0){
120
$.start += $.self.length
121
$.start = Math.max(0, $.start)
122
}
123
if($.end === null || $.end === _b_.None){$.end = $.self.length}
124
else if($.end < 0){
125
$.end += $.self.length
126
$.end = Math.max(0, $.end)
127
}
129
if(! isinstance($.start, _b_.int) || ! isinstance($.end, _b_.int)){
130
throw _b_.TypeError.$factory("slice indices must be integers " +
131
"or None or have an __index__ method")
132
}
149
if(!(typeof other === "string")){
150
try{return getattr(other, "__radd__")(self)}
151
catch(err){
152
throw _b_.TypeError.$factory("Can't convert " +
158
str.__contains__ = function(self, item){
159
if(!(typeof item == "string")){
160
throw _b_.TypeError.$factory("'in <string>' requires " +
161
"string as left operand, not " + item.__class__)
162
}
164
if(nbcar == 0) {return true} // a string contains the empty string
165
if(self.length == 0){return nbcar == 0}
166
for(var i = 0, len = self.length; i < len; i++){
167
if(self.substr(i, nbcar) == item){return true}
176
// __dir__must be assigned explicitely because attribute resolution for
177
// builtin classes doesn't use __mro__
181
if(other === undefined){ // compare object "self" to class "str"
182
return self === str
192
if(fmt.type && fmt.type != "s"){
193
throw _b_.ValueError.$factory("Unknown format code '" + fmt.type +
201
if(fmt.sign !== undefined){
202
throw _b_.ValueError.$factory(
203
"Sign not allowed in string format specifier")
213
if(arg < 0) {pos += self.length}
214
if(pos >= 0 && pos < self.length){return self.charAt(pos)}
215
throw _b_.IndexError.$factory("string index out of range")
216
}
217
if(isinstance(arg, slice)) {
218
var s = _b_.slice.$conv_for_seq(arg, self.length),
219
start = s.start,
220
stop = s.stop,
221
step = s.step
222
var res = "",
224
if(step > 0){
225
if(stop <= start){return ""}
226
for(var i = start; i < stop; i += step){res += self.charAt(i)}
228
if(stop >= start){return ''}
229
for(var i = start; i > stop; i += step){res += self.charAt(i)}
237
var prefix = 2,
238
suffix = 3,
239
mask = (2 ** 32 - 1)
240
function fnv(p){
241
if(p.length == 0){
242
return 0
243
}
245
var x = prefix
246
x = (x ^ (p.charCodeAt(0) << 7)) & mask
247
for(var i = 0, len = p.length; i < len; i++){
248
x = ((1000003 * x) ^ p.charCodeAt(i)) & mask
249
}
250
x = (x ^ p.length) & mask
251
x = (x ^ suffix) & mask
309
// left adjusted
310
return s + get_char_array(padding - s.length, flags.pad_char)
311
}
312
}
313
321
if(val.__class__ === $B.long_int){
322
s = $B.long_int.to_base(val, 10)
323
}else{
324
s = val.toString()
326
if(s[0] === "-"){
327
return "-" + get_char_array(precision - s.length + 1, "0") + s.slice(1)
338
if(val === Infinity){
339
val = "inf"
340
}else if(val === -Infinity){
341
val = "-inf"
342
}else{
343
val = "nan"
365
var str_format = function(val, flags) {
366
// string format supports left and right padding
367
flags.pad_char = " " // even if 0 padding is defined, don't use it
373
if(val.__class__ === $B.long_int){
374
val = $B.long_int.to_base(val, 10)
375
}else{
376
val = parseInt(val)
394
var repr_format = function(val, flags) {
395
flags.pad_char = " " // even if 0 padding is defined, don't use it
396
return format_padding(repr(val), flags)
397
}
399
var ascii_format = function(val, flags) {
400
flags.pad_char = " " // even if 0 padding is defined, don't use it
401
return format_padding(ascii(val), flags)
402
}
414
flags.precision = parseInt(flags.precision, 10)
415
validate_precision(flags.precision)
416
}
417
return parseFloat(val)
418
}
421
var trailing_zeros = /(.*?)(0+)([eE].*)/,
422
leading_zeros = /\.(0*)/,
423
trailing_dot = /\.$/
425
var validate_precision = function(precision) {
426
// force precision to limits of javascript
431
var floating_point_format = function(val, upper, flags){
432
val = _float_helper(val, flags),
433
v = val.toString(),
434
v_len = v.length,
435
dot_idx = v.indexOf('.')
436
if(dot_idx < 0){dot_idx = v_len}
437
if(val < 1 && val > -1){
438
var zeros = leading_zeros.exec(v),
439
numzeros
440
if(zeros){
445
if(numzeros >= 4){
446
val = format_sign(val, flags) + format_float_precision(val, upper,
447
flags, _floating_g_exp_helper)
448
if(!flags.alternate){
461
return format_padding(format_sign(val, flags) +
462
format_float_precision(val, upper, flags,
463
function(val, precision) {
464
return val.toFixed(min(precision, v_len - dot_idx) +
465
numzeros)
466
}),
467
flags
468
)
469
}
470
471
if(dot_idx > flags.precision){
472
val = format_sign(val, flags) + format_float_precision(val, upper,
473
flags, _floating_g_exp_helper)
474
if(! flags.alternate){
486
return format_padding(format_sign(val, flags) +
487
format_float_precision(val, upper, flags,
488
function(val, precision) {
489
if(!flags.decimal_point){
490
precision = min(v_len - 1, 6)
491
}else if (precision > v_len){
492
if(! flags.alternate){
493
precision = v_len
494
}
496
if(precision < dot_idx){
497
precision = dot_idx
498
}
499
return val.toFixed(precision - dot_idx)
500
}),
501
flags
502
)
505
var _floating_g_exp_helper = function(val, precision, flags, upper){
506
if(precision){--precision}
509
var e_idx = val.lastIndexOf("e")
510
if(e_idx > val.length - 4){
511
val = val.substring(0, e_idx + 2) + "0" + val.substring(e_idx + 2)
514
return val
515
}
516
517
// fF
518
var floating_point_decimal_format = function(val, upper, flags) {
519
val = _float_helper(val, flags)
520
return format_padding(format_sign(val, flags) +
521
format_float_precision(val, upper, flags,
522
function(val, precision, flags) {
523
val = val.toFixed(precision)
524
if(precision === 0 && flags.alternate){
525
val += '.'
526
}
527
return val
528
}),
529
flags
530
)
531
}
532
533
var _floating_exp_helper = function(val, precision, flags, upper) {
534
val = val.toExponential(precision)
535
// pad exponent to two digits
548
return format_padding(format_sign(val, flags) +
549
format_float_precision(val, upper, flags, _floating_exp_helper), flags)
575
if(flags.alternate){
576
if(ret.charAt(0) === "-"){
577
if(upper){ret = "-0X" + ret.slice(1)}
578
else{ret = "-0x" + ret.slice(1)}
579
}else{
580
if(upper){ret = "0X" + ret}
581
else{ret = "0x" + ret}
591
if(val.__class__ === $B.long_int){
592
ret = $B.long_int.to_base(8)
593
}else{
594
ret = parseInt(val)
595
ret = ret.toString(8)
611
if(flags.alternate){
612
if(ret.charAt(0) === "-"){ret = "-0o" + ret.slice(1)}
613
else{ret = "0o" + ret}
618
var single_char_format = function(val, flags){
619
if(isinstance(val, str) && val.length == 1) return val
620
try{
628
var num_flag = function(c, flags){
629
if(c === "0" && ! flags.padding && ! flags.decimal_point && ! flags.left){
630
flags.pad_char = "0"
636
flags.precision = (flags.precision || "") + c
637
}
638
}
639
640
var decimal_point_flag = function(val, flags) {
642
// can only have one decimal point
643
throw new UnsupportedChar()
644
}
645
flags.decimal_point = true
646
}
647
648
var neg_flag = function(val, flags){
649
flags.pad_char = " " // overrides '0' flag
666
"s": str_format,
667
"d": num_format,
668
"i": num_format,
669
"u": num_format,
670
"o": octal_format,
671
"r": repr_format,
672
"a": ascii_format,
673
"g": function(val, flags){
674
return floating_point_format(val, false, flags)
675
},
676
"G": function(val, flags){return floating_point_format(val, true, flags)},
677
"f": function(val, flags){
678
return floating_point_decimal_format(val, false, flags)
679
},
680
"F": function(val, flags){
681
return floating_point_decimal_format(val, true, flags)
682
},
683
"e": function(val, flags){
684
return floating_point_exponential_format(val, false, flags)
685
},
686
"E": function(val, flags){
687
return floating_point_exponential_format(val, true, flags)
688
},
689
"x": function(val, flags){return signed_hex_format(val, false, flags)},
690
"X": function(val, flags){return signed_hex_format(val, true, flags)},
691
"c": single_char_format,
692
"0": function(val, flags){return num_flag("0", flags)},
693
"1": function(val, flags){return num_flag("1", flags)},
694
"2": function(val, flags){return num_flag("2", flags)},
695
"3": function(val, flags){return num_flag("3", flags)},
696
"4": function(val, flags){return num_flag("4", flags)},
697
"5": function(val, flags){return num_flag("5", flags)},
698
"6": function(val, flags){return num_flag("6", flags)},
699
"7": function(val, flags){return num_flag("7", flags)},
700
"8": function(val, flags){return num_flag("8", flags)},
701
"9": function(val, flags){return num_flag("9", flags)},
702
"-": neg_flag,
703
" ": space_flag,
704
"+": sign_flag,
705
".": decimal_point_flag,
706
"#": alternate_flag
707
}
708
709
// exception thrown when an unsupported char is encountered in legacy format
756
if(self === undefined){
757
throw _b_.TypeError.$factory(
758
"not enough arguments for format string")
785
throw _b_.ValueError.$factory(
786
"unsupported format character '" + invalid_char +
787
"' (0x" + invalid_char.charCodeAt(0).toString(16) +
788
") at index " + newpos)
789
}else if(err.name === "NotANumber"){
790
var try_char = s[newpos],
791
cls = self.__class__
792
if(!cls){
793
if(typeof(self) === "string"){
794
cls = "str"
795
}else{
801
throw _b_.TypeError.$factory("%" + try_char +
802
" format: a number is required, not " + cls)
803
}else{
835
}while(pos < length)
836
837
if(argpos !== null){
838
if(args.length > argpos){
839
throw _b_.TypeError.$factory(
840
"not enough arguments for format string")
841
}else if(args.length < argpos){
842
throw _b_.TypeError.$factory(
843
"not all arguments converted during string formatting")
845
}else if(nbph == 0){
846
throw _b_.TypeError.$factory(
847
"not all arguments converted during string formatting")
855
var $ = $B.args("__mul__", 2, {self: null, other: null},
856
["self", "other"], arguments, {}, null, null)
857
if(! isinstance($.other, _b_.int)){throw _b_.TypeError.$factory(
858
"Can't multiply sequence by non-int of type '" +
870
res = self.replace(/\\/g, "\\\\")
871
// special cases
872
res = res.replace(new RegExp("\u0007", "g"), "\\x07").
873
replace(new RegExp("\b", "g"), "\\x08").
874
replace(new RegExp("\f", "g"), "\\x0c").
875
replace(new RegExp("\n", "g"), "\\n").
876
replace(new RegExp("\r", "g"), "\\r").
877
replace(new RegExp("\t", "g"), "\\t")
880
if(res.search('"') == -1 && res.search("'") == -1){
881
return "'" + res + "'"
882
}else if(self.search('"') == -1){
883
return '"' + res + '"'
884
}
885
var qesc = new RegExp("'", "g") // to escape single quote
886
res = "'" + res.replace(qesc, "\\'") + "'"
890
str.__setitem__ = function(self, attr, value){
891
throw _b_.TypeError.$factory(
892
"'str' object does not support item assignment")
894
var combining = []
895
for(var cp = 0x300; cp <= 0x36F; cp++){
896
combining.push(String.fromCharCode(cp))
897
}
898
var combining_re = new RegExp("(" + combining.join("|") + ")")
910
$comp_func += "" // source code
911
var $comps = {">": "gt", ">=": "ge", "<": "lt", "<=": "le"}
920
var $notimplemented = function(self, other){
921
throw NotImplementedError.$factory(
922
"OPERATOR not implemented for class str")
925
str.capitalize = function(self){
926
var $ = $B.args("capitalize", 1, {self}, ["self"],
927
arguments, {}, null, null)
928
if(self.length == 0){return ""}
929
return self.charAt(0).toUpperCase() + self.substr(1)
930
}
931
932
str.casefold = function(self){
933
var $ = $B.args("casefold", 1, {self}, ["self"],
934
arguments, {}, null, null),
935
res = "",
936
char,
937
cf
938
for(var i = 0, len = self.length; i < len; i++){
939
char = self.charCodeAt(i)
940
cf = $B.unicode_casefold[char]
941
if(cf){
942
cf.forEach(function(cp){
943
res += String.fromCharCode(cp)
944
})
945
}else{
946
res += self.charAt(i).toLowerCase()
947
}
948
}
949
return res
950
}
952
str.center = function(){
953
var $ = $B.args("center", 3, {self: null, width: null, fillchar: null},
954
["self", "width", "fillchar"],
955
arguments, {fillchar:" "}, null, null),
956
self = $.self
968
var $ = $B.args("count", 4, {self:null, sub:null, start:null, stop:null},
969
["self", "sub", "start", "stop"], arguments, {start:null, stop:null},
977
if($.stop !== null){_slice = _b_.slice.$factory($.start, $.stop)}
978
else{_slice = _b_.slice.$factory($.start, $.self.length)}
983
if($.sub.length == 0){
984
if($.start == $.self.length){return 1}
985
else if(substr.length == 0){return 0}
986
return substr.length + 1
988
var n = 0,
989
pos = 0
990
while(pos < substr.length){
991
pos = substr.indexOf($.sub, pos)
992
if(pos >= 0){n++; pos += $.sub.length}
993
else{break}
998
str.encode = function(){
999
var $ = $B.args("encode", 3, {self: null, encoding: null, errors: null},
1000
["self", "encoding", "errors"], arguments,
1001
{encoding: "utf-8", errors: "strict"}, null, null)
1002
if($.encoding == "rot13" || $.encoding == "rot_13"){
1005
for(var i = 0, len = $.self.length; i < len ; i++){
1006
var char = $.self.charAt(i)
1007
if(("a" <= char && char <= "m") || ("A" <= char && char <= "M")){
1008
res += String.fromCharCode(String.charCodeAt(char) + 13)
1009
}else if(("m" < char && char <= "z") ||
1010
("M" < char && char <= "Z")){
1011
res += String.fromCharCode(String.charCodeAt(char) - 13)
1020
// Return True if the string ends with the specified suffix, otherwise
1021
// return False. suffix can also be a tuple of suffixes to look for.
1022
// With optional start, test beginning at that position. With optional
1026
["self", "suffix", "start", "end"],
1027
arguments, {start: 0, end: null}, null, null)
1034
var s = $.self.substring($.start, $.end)
1035
for(var i = 0, len = suffixes.length; i < len; i++){
1039
if(suffix.length <= s.length &&
1040
s.substr(s.length - suffix.length) == suffix){return true}
1046
var $ = $B.args("expandtabs", 2, {self: null, tabsize: null},
1047
["self", "tabsize"], arguments, {tabsize: 8}, null, null)
1048
var s = $B.$GetInt($.tabsize),
1049
col = 0,
1050
pos = 0,
1051
res = ""
1052
if(s == 1){return self.replace(/\t/g," ")}
1053
while(pos < self.length){
1061
res += car
1062
col = 0
1063
break
1064
default:
1065
res += car
1066
col++
1067
break
1068
}
1069
pos++
1070
}
1076
// Return the lowest index in the string where substring sub is found,
1077
// such that sub is contained in the slice s[start:end]. Optional
1078
// arguments start and end are interpreted as in slice notation.
1081
{self: null, sub: null, start: null, end: null},
1082
["self", "sub", "start", "end"],
1083
arguments, {start: 0, end: null}, null, null)
1087
if(!isinstance($.start, _b_.int)||!isinstance($.end, _b_.int)){
1088
throw _b_.TypeError.$factory("slice indices must be " +
1089
"integers or None or have an __index__ method")}
1090
// Can't use string.substring(start, end) because if end < start,
1091
// Javascript transforms it into substring(end, start)...
1092
var s = ""
1093
for(var i = $.start; i < $.end; i++){
1094
s += $.self.charAt(i)
1095
}
1097
if($.sub.length == 0 && $.start == $.self.length){return $.self.length}
1098
if(s.length + $.sub.length == 0){return -1}
1100
var last_search = s.length - $.sub.length
1101
for(var i = 0; i <= last_search; i++){
1102
if(s.substr(i, $.sub.length) == $.sub){return $.start + i}
1113
// a.x[z]!r:...
1114
// the object has attributes :
1115
// - name : "a"
1116
// - name_ext : [".x", "[z]"]
1117
// - conv : r
1118
// - spec : rest of string after :
1126
// No : in the string : it only contains a name
1127
name = fmt_string
1128
}else{
1129
// name is before the first ":"
1130
// spec (the format specification) is after
1131
name = elts[0]
1135
var elts = name.split("!")
1136
if(elts.length > 1){
1137
name = elts[0]
1138
conv = elts[1] // conversion flag
1142
// "name' may be a subscription or attribute
1143
// Put these "extensions" in the list "name_ext"
1144
function name_repl(match){
1145
name_ext.push(match)
1147
}
1148
var name_ext_re = /\.[_a-zA-Z][_a-zA-Z0-9]*|\[[_a-zA-Z][_a-zA-Z0-9]*\]|\[[0-9]+\]/g
1149
name = name.replace(name_ext_re, name_repl)
1150
}
1157
// Parse self to detect formatting instructions
1158
// Create a list "parts" made of sections of the string :
1159
// - elements of even rank are literal text
1160
// - elements of odd rank are "format objects", built from the
1161
// format strings in self (of the form {...})
1172
text += "{"
1173
pos += 2
1174
}else if(car == "}" && self.charAt(pos + 1) == "}"){
1181
// Store current literal text
1182
parts.push(text)
1183
1184
// Search the end of the format string, ie the } closing the
1185
// opening {. Since the string can contain other pairs {} for
1186
// nested formatting, an integer nb is incremented for each { and
1187
// decremented for each } ; the end of the format string is
1188
// reached when nb == 0
1189
var end = pos + 1,
1190
nb = 1
1191
while(end < _len){
1192
if(self.charAt(end) == "{"){nb++; end++}
1193
else if(self.charAt(end) == "}"){
1194
nb--; end++
1195
if(nb == 0){
1200
var fmt_obj = $B.parse_format(fmt_string)
1201
fmt_obj.raw_name = fmt_obj.name
1202
fmt_obj.raw_spec = fmt_obj.spec
1237
return parts
1238
}
1239
1240
str.format = function(self) {
1241
var $ = $B.args("format", 1, {self: null}, ["self"],
1242
arguments, {}, "$args", "$kw")
1243
1244
var parts = $B.split_format($.self)
1245
1256
1257
if(fmt.spec !== undefined){
1258
// "spec" may contain "nested replacement fields"
1259
// In this case, evaluate them using the positional
1260
// or keyword arguments passed to format()
1261
function replace_nested(name, key){
1262
if(/\d+/.exec(key)){
1263
// If key is numeric, search in positional
1264
// arguments
1265
return _b_.tuple.__getitem__($.$args,
1266
parseInt(key))
1267
}else{
1268
// Else try in keyword arguments
1269
return _b_.dict.__getitem__($.$kw, key)
1270
}
1271
}
1272
fmt.spec = fmt.spec.replace(/\{(.*?)\}/g,
1273
replace_nested)
1274
}
1276
// Numerical reference : use positional arguments
1277
var pos = parseInt(fmt.name),
1287
// Attribute
1288
value = _b_.getattr(value, ext.substr(1))
1289
}else{
1290
// Subscription
1293
if(key.charAt(0).search(/\d/) > -1){key = parseInt(key)}
1294
value = _b_.getattr(value, "__getitem__")(key)
1298
// If the conversion flag is set, first call a function to convert
1299
// the value
1300
if(fmt.conv == "a"){value = _b_.ascii(value)}
1301
else if(fmt.conv == "r"){value = _b_.repr(value)}
1302
else if(fmt.conv == "s"){value = _b_.str.$factory(value)}
1316
throw NotImplementedError.$factory(
1317
"function format_map not implemented yet")
1328
/* Return true if the string is empty or all characters in the string are
1329
ASCII, false otherwise. ASCII characters have code points in the range
1330
U+0000-U+007F. */
1331
for(var i = 0, len = self.length; i < len; i++){
1332
if(self.charCodeAt(i) > 127){return false}
1333
}
1334
return true
1335
}
1336
1337
str.isalnum = function(self){
1338
/* Return true if all characters in the string are alphanumeric and there
1339
is at least one character, false otherwise. A character c is alphanumeric
1340
if one of the following returns True: c.isalpha(), c.isdecimal(),
1341
c.isdigit(), or c.isnumeric(). */
1342
var $ = $B.args("isalnum", 1, {self: null}, ["self"],
1343
arguments, {}, null, null),
1344
char
1345
for(var i = 0, len = self.length; i < len; i++){
1346
char = self.charCodeAt(i)
1347
if(unicode_tables.Ll[char] ||
1348
unicode_tables.Lu[char] ||
1349
unicode_tables.Lm[char] ||
1350
unicode_tables.Lt[char] ||
1351
unicode_tables.Lo[char] ||
1352
unicode_tables.Nd[char] ||
1353
unicode_tables.digits[char] ||
1354
unicode_tables.numeric[char]){
1355
continue
1356
}
1357
return false
1358
}
1359
return true
1360
}
1361
1362
str.isalpha = function(self){
1363
/* Return true if all characters in the string are alphabetic and there is
1364
at least one character, false otherwise. Alphabetic characters are those
1365
characters defined in the Unicode character database as "Letter", i.e.,
1366
those with general category property being one of "Lm", "Lt", "Lu", "Ll",
1367
or "Lo". */
1368
var $ = $B.args("isalpha", 1, {self: null}, ["self"],
1369
arguments, {}, null, null),
1370
char
1371
for(var i = 0, len = self.length; i < len; i++){
1372
char = self.charCodeAt(i)
1373
if(unicode_tables.Ll[char] ||
1374
unicode_tables.Lu[char] ||
1375
unicode_tables.Lm[char] ||
1376
unicode_tables.Lt[char] ||
1377
unicode_tables.Lo[char]){
1378
continue
1379
}
1380
return false
1381
}
1382
return true
1383
}
1384
1385
str.isdecimal = function(self){
1386
/* Return true if all characters in the string are decimal characters and
1387
there is at least one character, false otherwise. Decimal characters are
1388
those that can be used to form numbers in base 10, e.g. U+0660,
1389
ARABIC-INDIC DIGIT ZERO. Formally a decimal character is a character in
1390
the Unicode General Category "Nd". */
1391
var $ = $B.args("isdecimal", 1, {self: null}, ["self"],
1392
arguments, {}, null, null),
1393
char
1394
for(var i = 0, len = self.length; i < len; i++){
1395
char = self.charCodeAt(i)
1396
if(! unicode_tables.Nd[char]){
1397
return false
1398
}
1399
}
1400
return self.length > 0
1401
}
1402
1403
str.isdigit = function(self){
1404
/* Return true if all characters in the string are digits and there is at
1405
least one character, false otherwise. */
1406
var $ = $B.args("isdigit", 1, {self: null}, ["self"],
1407
arguments, {}, null, null),
1408
char
1409
for(var i = 0, len = self.length; i < len; i++){
1410
char = self.charCodeAt(i)
1411
if(! unicode_tables.digits[char]){
1412
return false
1413
}
1414
}
1415
return self.length > 0
1416
}
1417
1418
str.isidentifier = function(self){
1419
/* Return true if the string is a valid identifier according to the
1420
language definition. */
1421
var $ = $B.args("isidentifier", 1, {self: null}, ["self"],
1422
arguments, {}, null, null),
1423
char
1424
if(self.length == 0){return false}
1425
else if(unicode_tables.XID_Start[self.charCodeAt(0)] === undefined){
1426
return false
1427
}else{
1428
for(var i = 1, len = self.length; i < len; i++){
1429
if(unicode_tables.XID_Continue[self.charCodeAt(i)] === undefined){
1430
return false
1431
}
1432
}
1433
}
1434
return true
1435
}
1436
1437
str.islower = function(self){
1438
/* Return true if all cased characters 4 in the string are lowercase and
1439
there is at least one cased character, false otherwise. */
1440
var $ = $B.args("islower", 1, {self: null}, ["self"],
1441
arguments, {}, null, null),
1442
has_cased = false,
1443
char
1444
1445
for(var i = 0, len = self.length; i < len; i++){
1446
char = self.charCodeAt(i)
1447
if(unicode_tables["Ll"][char]){has_cased = true; continue}
1448
else if(unicode_tables["Lu"][char] || unicode_tables["Lt"][char]){
1449
return false
1450
}
1451
}
1452
return has_cased
1453
}
1454
1455
str.isnumeric = function(self){
1456
/* Return true if all characters in the string are numeric characters, and
1457
there is at least one character, false otherwise. Numeric characters
1458
include digit characters, and all characters that have the Unicode numeric
1459
value property, e.g. U+2155, VULGAR FRACTION ONE FIFTH. Formally, numeric
1460
characters are those with the property value Numeric_Type=Digit,
1461
Numeric_Type=Decimal or Numeric_Type=Numeric.*/
1462
var $ = $B.args("isnumeric", 1, {self: null}, ["self"],
1463
arguments, {}, null, null)
1464
for(var i = 0, len = self.length; i < len; i++){
1465
if(! unicode_tables.numeric[self.charCodeAt(i)]){
1466
return false
1467
}
1468
}
1469
return self.length > 0
1470
}
1471
1472
var printable,
1473
printable_gc = ['Cc', 'Cf', 'Co', 'Cs','Zl', 'Zp', 'Zs']
1474
1475
str.isprintable = function(self){
1476
/* Return true if all characters in the string are printable or the string
1477
is empty, false otherwise. Nonprintable characters are those characters
1478
defined in the Unicode character database as "Other" or "Separator",
1479
excepting the ASCII space (0x20) which is considered printable. */
1480
1481
// Set printable if not set yet
1482
if(printable === undefined){
1483
for(var i = 0; i < printable_gc.length; i++){
1484
var table = unicode_tables[printable_gc[i]]
1485
for(var cp in table){
1486
printable[cp] = true
1487
}
1488
}
1489
printable[32] = true
1490
}
1491
1492
var $ = $B.args("isprintable", 1, {self: null}, ["self"],
1493
arguments, {}, null, null),
1494
char,
1495
flag
1496
for(var i = 0, len = self.length; i < len; i++){
1497
char = self.charCodeAt(i)
1498
if(! printable[char]){
1499
return false
1500
}
1501
}
1502
return true
1503
}
1504
1505
str.isspace = function(self){
1506
/* Return true if there are only whitespace characters in the string and
1507
there is at least one character, false otherwise.
1508
1509
A character is whitespace if in the Unicode character database, either its
1510
general category is Zs ("Separator, space"), or its bidirectional class is
1511
one of WS, B, or S.*/
1512
var $ = $B.args("isspace", 1, {self: null}, ["self"],
1513
arguments, {}, null, null),
1514
char
1515
for(var i = 0, len = self.length; i < len; i++){
1516
char = self.charCodeAt(i)
1517
if(! unicode_tables.Zs[char] &&
1518
$B.unicode_bidi_whitespace.indexOf(char) == -1){
1519
return false
1520
}
1521
}
1522
return self.length > 0
1523
}
1524
1525
str.istitle = function(self){
1526
/* Return true if the string is a titlecased string and there is at least
1527
one character, for example uppercase characters may only follow uncased
1528
characters and lowercase characters only cased ones. Return false
1529
otherwise. */
1530
var $ = $B.args("istitle", 1, {self: null}, ["self"],
1531
arguments, {}, null, null)
1532
return self.length > 0 && str.title(self) == self
1533
}
1534
1535
str.isupper = function(self){
1536
/* Return true if all cased characters 4 in the string are lowercase and
1537
there is at least one cased character, false otherwise. */
1538
var $ = $B.args("islower", 1, {self: null}, ["self"],
1539
arguments, {}, null, null),
1540
has_cased = false,
1541
char
1542
1543
for(var i = 0, len = self.length; i < len; i++){
1544
char = self.charCodeAt(i)
1545
if(unicode_tables["Lu"][char]){has_cased = true; continue}
1546
else if(unicode_tables["Ll"][char] || unicode_tables["Lt"][char]){
1547
return false
1548
}
1549
}
1550
return has_cased
1551
}
1552
1553
1564
if(! isinstance(obj2, str)){throw _b_.TypeError.$factory(
1565
"sequence item " + count + ": expected str instance, " +
1579
var $ = $B.args("ljust", 3, {self: null, width: null, fillchar:null},
1580
["self", "width", "fillchar"],
1581
arguments, {fillchar: " "}, null, null)
1587
str.lower = function(self){
1588
var $ = $B.args("lower", 1, {self: null}, ["self"],
1589
arguments, {}, null, null)
1590
return self.toLowerCase()
1591
}
1592
1594
var $ = $B.args("lstrip", 2, {self: null, chars: null}, ["self", "chars"],
1595
arguments, {chars:_b_.None}, null, null)
1596
if($.chars === _b_.None){return $.self.trimLeft()}
1597
for(var i = 0; i < $.self.length; i++){
1598
if($.chars.indexOf($.self.charAt(i)) === -1){
1599
return $.self.substring(i)
1607
var $ = $B.args("maketrans", 3, {x: null, y: null, z: null},
1608
["x", "y", "z"], arguments, {y: null, z: null}, null, null)
1613
// If there is only one argument, it must be a dictionary mapping
1614
// Unicode ordinals (integers) or characters (strings of length 1) to
1615
// Unicode ordinals, strings (of arbitrary lengths) or None. Character
1617
if(! _b_.isinstance($.x, _b_.dict)){
1618
throw _b_.TypeError.$factory(
1619
"maketrans only argument must be a dict")
1622
for(var i = 0, len = items.length; i < len; i++){
1623
var k = items[i][0],
1624
v = items[i][1]
1625
if(! _b_.isinstance(k, _b_.int)){
1626
if(_b_.isinstance(k, _b_.str) && k.length == 1){
1627
k = _b_.ord(k)
1628
}else{throw _b_.TypeError.$factory("dictionary key " + k +
1631
if(v !== _b_.None && ! _b_.isinstance(v, [_b_.int, _b_.str])){
1632
throw _b_.TypeError.$factory("dictionary value " + v +
1640
// and in the resulting dictionary, each character in x will be mapped
1641
// to the character at the same position in y
1644
}else if($.x.length !== $.y.length){
1645
throw _b_.TypeError.$factory(
1646
"maketrans arguments must be strings or same length")
1652
if(! _b_.isinstance($.z, _b_.str)){
1653
throw _b_.TypeError.$factory(
1654
"maketrans third argument must be a string")
1676
var $ = $B.args("partition", 2, {self: null, sep: null}, ["self", "sep"],
1677
arguments, {}, null, null)
1682
return _b_.tuple.$factory([$.self.substring(0, i), $.sep,
1683
$.self.substring(i + $.sep.length)])
1684
}
1685
1686
function $re_escape(str){
1687
var specials = "[.*+?|()$^"
1688
for(var i = 0, len = specials.length; i < len; i++){
1689
var re = new RegExp("\\"+specials.charAt(i), "g")
1690
str = str.replace(re, "\\"+specials.charAt(i))
1691
}
1692
return str
1699
var $ = $B.args("replace", 4,
1700
{self: null, old: null, $$new: null, count: null},
1701
["self", "old", "$$new", "count"],
1702
arguments, {count: -1}, null, null),
1703
count = $.count,
1704
self = $.self,
1705
old = $.old,
1706
_new = $.$$new
1713
"' object cannot be interpreted as an integer")
1714
}else if(isinstance(count, _b_.float)){
1715
throw _b_.TypeError.$factory("integer argument expected, got float")
1716
}
1717
if(count == 0){return self}
1718
if(count.__class__ == $B.long_int){count = parseInt(count.value)}
1719
if(old == ""){
1720
if(_new == ""){return self}
1721
if(self == ""){return _new}
1722
var elts = self.split("")
1723
if(count > -1 && elts.length >= count){
1724
var rest = elts.slice(count).join("")
1725
return _new + elts.slice(0, count).join(_new) + rest
1726
}else{return _new + elts.join(_new) + _new}
1741
if(count < 0){count = res.length}
1742
while(count > 0){
1743
pos = res.indexOf(old, pos)
1744
if(pos < 0){break}
1745
res = res.substr(0, pos) + _new + res.substr(pos + old.length)
1746
pos = pos + _new.length
1747
count--
1753
// Return the highest index in the string where substring sub is found,
1754
// such that sub is contained within s[start:end]. Optional arguments
1756
if(arguments.length == 2 && typeof substr == "string"){
1757
return self.lastIndexOf(substr)
1758
}
1760
{self: null, sub: null, start: null, end: null},
1761
["self", "sub", "start", "end"],
1762
arguments, {start: 0, end: null}, null, null)
1774
for(var i = $.end - sublen; i >= $.start; i--){
1775
if($.self.substr(i, sublen) == $.sub){return i}
1782
var res = str.rfind.apply(null, arguments)
1783
if(res == -1){throw _b_.ValueError.$factory("substring not found")}
1788
var $ = $B.args("rjust",3,
1789
{self: null, width: null, fillchar: null},
1790
["self", "width", "fillchar"],
1791
arguments, {fillchar: " "}, null, null)
1799
var $ = $B.args("rpartition", 2, {self: null, sep: null}, ["self", "sep"],
1800
arguments, {}, null, null)
1804
var items = str.partition(self, sep).reverse()
1805
for(var i = 0; i < items.length; i++){
1806
items[i] = items[i].split("").reverse().join("")
1812
var $ = $B.args("rsplit", 3, {self: null, sep: null, maxsplit: null},
1813
["self", "sep", "maxsplit"], arguments,
1814
{sep: _b_.None, maxsplit: -1}, null, null),
1815
sep = $.sep
1818
var rev_str = reverse($.self),
1819
rev_sep = sep === _b_.None ? sep : reverse($.sep),
1830
str.rstrip = function(self, x){
1831
var $ = $B.args("rstrip", 2, {self: null, chars: null}, ["self", "chars"],
1832
arguments, {chars: _b_.None}, null, null)
1833
if($.chars === _b_.None){return $.self.trimRight()}
1835
if($.chars.indexOf($.self.charAt(j)) == -1){
1836
return $.self.substring(0, j + 1)
1843
var $ = $B.args("split", 3, {self: null, sep: null, maxsplit: null},
1844
["self", "sep", "maxsplit"], arguments,
1845
{sep: _b_.None, maxsplit: -1}, null, null),
1846
sep = $.sep,
1847
maxsplit = $.maxsplit,
1848
self = $.self,
1849
pos = 0
1850
if(maxsplit.__class__ === $B.long_int){maxsplit = parseInt(maxsplit.value)}
1851
if(sep == ""){throw _b_.ValueError.$factory("empty separator")}
1852
if(sep === _b_.None){
1854
while(pos < self.length && self.charAt(pos).search(/\s/) > -1){pos++}
1855
if(pos === self.length - 1){return [self]}
1856
var name = ""
1858
if(self.charAt(pos).search(/\s/) == -1){
1859
if(name == ""){name = self.charAt(pos)}
1860
else{name += self.charAt(pos)}
1880
var res = [],
1881
s = "",
1882
seplen = sep.length
1883
if(maxsplit == 0){return [self]}
1884
while(pos < self.length){
1885
if(self.substr(pos, seplen) == sep){
1905
["self", "keepends"], arguments, {keepends: false}, null, null)
1906
if(! _b_.isinstance($.keepends, [_b_.bool, _b_.int])){
1907
throw _b_.TypeError.$factory("integer argument expected, got " +
1914
start = pos,
1915
pos = 0,
1916
self = $.self
1917
while(pos < self.length){
1918
if(self.substr(pos, 2) == "\r\n"){
1919
res.push(self.substring(start, pos + 2))
1920
start = pos + 2
1922
}else if(self.charAt(pos) == "\r" || self.charAt(pos) == "\n"){
1923
res.push(self.substring(start, pos + 1))
1924
start = pos + 1
1925
pos = start
1926
}else{pos++}
1927
}
1928
var rest = self.substr(start)
1929
if(rest){res.push(rest)}
1930
return res
1931
}else{
1938
// Return True if string starts with the prefix, otherwise return False.
1939
// prefix can also be a tuple of prefixes to look for. With optional
1940
// start, test string beginning at that position. With optional end,
1942
var $ = $B.args("startswith", 4,
1943
{self: null, prefix: null, start: null, end: null},
1944
["self", "prefix", "start", "end"],
1945
arguments, {start: 0, end: null}, null, null)
1952
var s = $.self.substring($.start, $.end)
1953
for(var i = 0, len = prefixes.length; i < len; i++){
1964
var $ = $B.args("strip", 2, {self: null, chars: null}, ["self", "chars"],
1965
arguments, {chars: _b_.None}, null, null)
1966
if($.chars === _b_.None){return $.self.trim()}
1967
for(var i = 0; i < $.self.length; i++){
1968
if($.chars.indexOf($.self.charAt(i)) == -1){
1969
break
1972
for(var j = $.self.length - 1; j >= i; j--){
1973
if($.chars.indexOf($.self.charAt(j)) == -1){
1974
break
1980
str.swapcase = function(self){
1981
var $ = $B.args("swapcase", 1, {self}, ["self"],
1982
arguments, {}, null, null),
1983
res = "",
1984
char
1985
1986
for(var i = 0, len = self.length; i < len; i++){
1987
char = self.charCodeAt(i)
1988
if(unicode_tables.Ll[char]){
1989
res += self.charAt(i).toUpperCase()
1990
}else if(unicode_tables.Lu[char]){
1991
res += self.charAt(i).toLowerCase()
1992
}else{
1993
res += self.charAt(i)
1994
}
1995
}
1996
return res
1997
}
1998
1999
str.title = function(self){
2000
var $ = $B.args("title", 1, {self}, ["self"],
2001
arguments, {}, null, null),
2002
state,
2003
char,
2004
res = ""
2005
for(var i = 0, len = self.length; i < len; i++){
2006
char = self.charCodeAt(i)
2007
if(unicode_tables.Ll[char]){
2008
if(! state){
2009
res += self.charAt(i).toUpperCase()
2010
state = "word"
2011
}else{
2012
res += self.charAt(i)
2013
}
2014
}else if(unicode_tables.Lu[char] || unicode_tables.Lt[char]){
2015
res += state ? self.charAt(i).toLowerCase() : self.charAt(i)
2016
state = "word"
2017
}else{
2018
state = null
2019
res += self.charAt(i)
2020
}
2021
}
2022
return res
2023
}
2024
2027
getitem = $B.$getattr(table, "__getitem__")
2028
for(var i = 0, len = self.length; i < len; i++){
2029
try{
2030
var repl = getitem(self.charCodeAt(i))
2031
if(repl !== _b_.None){
2041
str.upper = function(self){
2042
var $ = $B.args("upper", 1, {self: null}, ["self"],
2043
arguments, {}, null, null)
2044
return self.toUpperCase()
2045
}
2046
2049
["self", "width"], arguments, {}, null, null)
2050
if($.width <= self.length){return self}
2052
case "+":
2053
case "-":
2054
return self.charAt(0) +
2055
"0".repeat($.width - self.length) + self.substr(1)
2063
if(arg === undefined){
2064
throw _b_.TypeError.$factory("str() argument is undefined")
2065
}
2076
// class or its subclasses, but the attribute __str__ of the
2077
// class metaclass (usually "type") or its subclasses (usually
2078
// "object")
2079
// The metaclass is the attribute __class__ of the class dictionary
2083
if(arg.__class__ && arg.__class__ === _b_.bytes &&
2084
encoding !== undefined){
2085
// str(bytes, encoding, errors) is equal to
2086
// bytes.decode(encoding, errors)
2087
// Arguments may be passed as keywords (cf. issue #1060)
2088
var $ = $B.args("str", 3, {arg: null, encoding: null, errors: null},
2089
["arg", "encoding", "errors"], arguments,
2090
{encoding: "utf-8", errors: "strict"}, null, null)
2091
return _b_.bytes.decode(arg, $.encoding, $.errors)
2093
var f = $B.$getattr(arg, "__str__", null)
2094
if(f === null ||
2095
// if not better than object.__str__, try __repr__
2096
(arg.__class__ && arg.__class__ !== _b_.object &&
2097
f.$infos && f.$infos.__func__ === _b_.object.__str__)){
2098
var f = $B.$getattr(arg, "__repr__")
2099
}
2104
if($B.debug > 1){console.log(err)}
2105
console.log("Warning - no method __str__ or __repr__, " +
2106
"default to toString", arg)
2113
if(cls === undefined){
2114
throw _b_.TypeError.$factory("str.__new__(): not enough arguments")
2138
var args = [],
2139
pos = 0
2140
if(arguments.length > 0){
2141
var args = [arguments[0].valueOf()],
2142
pos = 1
2143
for(var i = 1, len = arguments.length; i < len; i++){
2144
args[pos++] = arguments[i]
2160
// Function to parse the 2nd argument of format()
2161
$B.parse_format_spec = function(spec){
2164
var pos = 0,
2165
aligns = "<>=^",
2166
digits = "0123456789",
2167
types = "bcdeEfFgGnosxX%",
2169
if(align_pos != -1){
2170
if(spec.charAt(1) && aligns.indexOf(spec.charAt(1)) != -1){
2171
// If the second char is also an alignment specifier, the
2172
// first char is the fill value
2173
this.fill = spec.charAt(0)
2174
this.align = spec.charAt(1)
2175
pos = 2
2176
}else{
2177
// The first character defines alignment : fill defaults to ' '
2192
if(car == "+" || car == "-" || car == " "){
2193
this.sign = car
2194
pos++
2195
car = spec.charAt(pos)
2197
if(car == "#"){this.alternate = true; pos++; car = spec.charAt(pos)}
2198
if(car == "0"){
2207
while(car && digits.indexOf(car) > -1){
2208
if(this.width === undefined){this.width = car}
2209
else{this.width += car}
2210
pos++
2211
car = spec.charAt(pos)
2214
if(this.width === undefined && car == "{"){
2215
// Width is determined by a parameter
2216
var end_param_pos = spec.substr(pos).search("}")
2217
this.width = spec.substring(pos, end_param_pos)
2218
console.log("width", "[" + this.width + "]")
2219
pos += end_param_pos + 1
2220
}
2221
if(car == ","){this.comma = true; pos++; car = spec.charAt(pos)}
2222
if(car == "."){
2223
if(digits.indexOf(spec.charAt(pos + 1)) == -1){
2224
throw _b_.ValueError.$factory(
2225
"Missing precision in format spec")
2227
this.precision = spec.charAt(pos + 1)
2228
pos += 2
2229
car = spec.charAt(pos)
2230
while(car && digits.indexOf(car) > -1){
2237
if(car && types.indexOf(car) > -1){
2238
this.type = car
2239
pos++
2240
car = spec.charAt(pos)
2241
}
2242
if(pos !== spec.length){
2248
return (this.fill === undefined ? "" : _b_.str.$factory(this.fill)) +
2249
(this.align || "") +
2250
(this.sign || "") +
2251
(this.alternate ? "#" : "") +
2252
(this.sign_aware ? "0" : "") +
2253
(this.width || "") +
2254
(this.comma ? "," : "") +
2255
(this.precision ? "." + this.precision : "") +
2256
(this.type || "")
2261
if(fmt.width && s.length < fmt.width){
2262
var fill = fmt.fill || " ",
2263
align = fmt.align || "<",
2264
missing = fmt.width - s.length
2266
case "<":
2267
return s + fill.repeat(missing)
2268
case ">":
2269
return fill.repeat(missing) + s
2270
case "=":
2271
if("+-".indexOf(s.charAt(0)) > -1){
2272
return s.charAt(0) + fill.repeat(missing) + s.substr(1)
2276
case "^":
2277
var left = parseInt(missing / 2)
2278
return fill.repeat(left) + s + fill.repeat(missing - left)
2291
$B.parse_fstring = function(string){
2292
// Parse a f-string
2293
var elts = [],
2294
pos = 0,
2318
}else{
2319
throw Error(" f-string: single '}' is not allowed")
2320
}
2321
}else{
2343
current += car
2344
i += 2
2345
}else{
2346
throw Error(" f-string: single '}' is not allowed")
2347
}
2348
}else{
2349
current += car
2350
i++
2351
}
2352
}
2354
}else if(ctype == "debug"){
2355
// after the equal sign, whitespace are ignored and the only
2356
// valid characters are } and :
2357
while(string.charAt(i) == " "){i++}
2358
if(string.charAt(i) == "}"){
2359
// end of debug expression
2360
elts.push(current)
2361
ctype = null
2362
current = ""
2363
pos = i + 1
2364
}
2365
}else{
2366
// End of expression is the } matching the opening {
2367
// There may be nested braces
2368
var i = pos,
2369
nb_braces = 1,
2391
// backslash is not allowed in expressions
2392
throw Error("f-string expression part cannot include a" +
2393
" backslash")
2400
throw Error("f-string: invalid conversion character:" +
2401
" expected 's', 'r', or 'a'")
2402
}else{
2416
if(string.substr(i, 3) == '"""'){
2417
var end = string.indexOf('"""', i + 3)
2418
if(end == -1){
2419
throw Error("f-string: unterminated string")
2420
}else{
2421
var trs = string.substring(i, end + 3)
2422
trs = trs.replace("\n", "\\n\\")
2427
var end = string.indexOf('"', i + 1)
2428
if(end == -1){
2429
throw Error("f-string: unterminated string")
2430
}else{
2431
current.expression += string.substring(i, end + 1)
2432
i = end + 1
2439
}else if(car == "="){
2440
// might be a "debug expression", eg f"{x=}"
2441
var ce = current.expression
2442
if(ce.length == 0 ||
2444
current.expression += car
2445
i++
2446
}else{
2447
// add debug string
2448
tail = car
2449
while(string.charAt(i + 1).match(/\s/)){
2450
tail += string.charAt(i + 1)
2451
i++
2452
}
2453
elts.push(current.expression + tail)
2454
// remove trailing whitespace from expression
2455
while(ce.match(/\s$/)){
2456
ce = ce.substr(0, ce.length - 1)
2457
}
2458
current.expression = ce
2459
ctype = "debug"
2460
i++
2461
}