Permalink
Mar 6, 2021
Mar 19, 2018
Mar 19, 2018
Apr 5, 2021
Mar 6, 2021
Mar 19, 2018
Apr 25, 2020
Mar 6, 2021
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 6, 2021
Mar 19, 2018
Mar 6, 2021
Mar 6, 2021
Mar 30, 2021
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
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
Dec 18, 2019
Dec 18, 2019
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 6, 2021
Mar 19, 2018
Mar 16, 2021
Mar 16, 2021
Mar 19, 2018
Mar 27, 2019
Mar 6, 2021
Mar 19, 2018
Mar 6, 2021
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 19, 2018
Apr 2, 2019
Apr 2, 2019
Mar 19, 2018
Aug 31, 2017
Mar 19, 2018
Mar 6, 2021
Mar 19, 2018
Mar 6, 2021
Aug 31, 2017
Apr 16, 2019
Mar 19, 2018
Apr 16, 2019
Mar 6, 2021
Mar 19, 2018
Mar 6, 2021
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Nov 12, 2018
Nov 22, 2020
Nov 12, 2018
Mar 19, 2018
Nov 22, 2020
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Sep 27, 2020
Sep 27, 2020
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 19, 2018
Mar 6, 2021
Mar 19, 2018
Mar 6, 2021
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 6, 2021
Jun 11, 2020
Mar 19, 2018
Mar 19, 2018
Apr 5, 2021
Mar 6, 2021
Mar 6, 2021
Mar 19, 2018
Mar 19, 2018
Aug 31, 2017
May 24, 2019
Mar 19, 2018
Mar 6, 2021
Mar 6, 2021
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 6, 2021
Mar 19, 2018
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 19, 2018
Feb 27, 2020
Feb 27, 2020
Feb 27, 2020
Aug 31, 2017
Mar 19, 2018
Mar 6, 2021
Mar 19, 2018
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Mar 6, 2021
Jan 26, 2020
Mar 6, 2021
Nov 15, 2019
Jul 28, 2018
Oct 27, 2019
Nov 2, 2018
Oct 27, 2019
Nov 2, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 6, 2021
Nov 12, 2018
Mar 6, 2021
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Dec 12, 2020
Jun 29, 2017
Oct 13, 2019
Jun 29, 2017
Dec 12, 2020
Jul 10, 2017
Jul 10, 2017
Mar 19, 2018
Mar 19, 2018
Jun 20, 2020
Oct 13, 2019
Jan 18, 2021
Jan 18, 2021
Newer
100644
2817 lines (2603 sloc)
85.3 KB
8
9
$B.has_surrogate = function(s){
10
// Check if there are "surrogate pairs" characters in string s
11
for(var i = 0; i < s.length; i++){
12
code = s.charCodeAt(i)
13
if(code >= 0xD800 && code <= 0xDBFF){
14
return true
15
}
16
}
17
return false
18
}
19
32
if($.start === null || $.start === _b_.None){$.start = 0}
33
else if($.start < 0){
34
$.start += $.self.length
35
$.start = Math.max(0, $.start)
36
}
37
if($.end === null || $.end === _b_.None){$.end = $.self.length}
38
else if($.end < 0){
39
$.end += $.self.length
40
$.end = Math.max(0, $.end)
41
}
44
throw _b_.TypeError.$factory("slice indices must be integers " +
45
"or None or have an __index__ method")
46
}
56
throw _b_.TypeError.$factory((prefix || '') +
57
"must be str, not " + $B.class_name(obj))
61
function to_chars(s){
62
// Transform Javascript string s into a list of Python characters
63
// (2 JS chars if surrogate, 1 otherwise)
64
var chars = []
65
for(var i = 0, len = s.length; i < len; i++){
66
var code = s.charCodeAt(i)
67
if(code >= 0xD800 && code <= 0xDBFF){
68
chars.push(s.substr(i, 2))
69
i++
70
}else{
71
chars.push(s.charAt(i))
72
}
73
}
74
return chars
75
}
76
77
function to_codepoints(s){
78
// Transform Javascript string s into a list of codepoints
79
var cps = []
80
for(var i = 0, len = s.length; i < len; i++){
81
var code = s.charCodeAt(i)
82
if(code >= 0xD800 && code <= 0xDBFF){
83
var v = 0x10000
84
v += (code & 0x03FF) << 10
85
v += (s.charCodeAt(i + 1) & 0x03FF)
86
cps.push(v)
87
i++
88
}else{
89
cps.push(code)
90
}
91
}
92
return cps
93
}
94
107
throw _b_.TypeError.$factory("'in <string>' requires " +
108
"string as left operand, not " + item.__class__)
109
}
110
if(typeof item == "string"){
111
var nbcar = item.length
112
}else{
113
var nbcar = _b_.len(item)
114
}
115
if(nbcar == 0){
116
// a string contains the empty string
117
return true
118
}
119
if(self.length == 0){
120
return nbcar == 0
121
}
134
// __dir__must be assigned explicitely because attribute resolution for
135
// builtin classes doesn't use __mro__
147
if(fmt.type && fmt.type != "s"){
148
throw _b_.ValueError.$factory("Unknown format code '" + fmt.type +
156
if(fmt.sign !== undefined){
157
throw _b_.ValueError.$factory(
158
"Sign not allowed in string format specifier")
172
if(arg < 0){
173
pos += self.length
174
}
175
if(pos >= 0 && pos < chars.length){
176
return chars[pos]
177
}
181
var s = _b_.slice.$conv_for_seq(arg, self.length),
182
start = s.start,
183
stop = s.stop,
184
step = s.step
185
var res = "",
188
if(stop <= start){
189
return ""
190
}
191
for(var i = start; i < stop; i += step){
192
res += chars[i]
193
}
195
if(stop >= start){
196
return ''
197
}
198
for(var i = start; i > stop; i += step){
199
res += chars[i]
200
}
261
// found at
262
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length
263
return [...self].length
300
// left adjusted
301
return s + get_char_array(padding - s.length, flags.pad_char)
302
}
303
}
304
312
if(val.__class__ === $B.long_int){
313
s = $B.long_int.to_base(val, 10)
314
}else{
315
s = val.toString()
317
if(s[0] === "-"){
318
return "-" + get_char_array(precision - s.length + 1, "0") + s.slice(1)
329
if(val === Infinity){
330
val = "inf"
331
}else if(val === -Infinity){
332
val = "-inf"
333
}else{
334
val = "nan"
356
var str_format = function(val, flags) {
357
// string format supports left and right padding
358
flags.pad_char = " " // even if 0 padding is defined, don't use it
364
if(val.__class__ === $B.long_int){
365
val = $B.long_int.to_base(val, 10)
366
}else{
367
val = parseInt(val)
385
var repr_format = function(val, flags) {
386
flags.pad_char = " " // even if 0 padding is defined, don't use it
390
var ascii_format = function(val, flags) {
391
flags.pad_char = " " // even if 0 padding is defined, don't use it
405
flags.precision = parseInt(flags.precision, 10)
406
validate_precision(flags.precision)
407
}
408
return parseFloat(val)
409
}
412
var trailing_zeros = /(.*?)(0+)([eE].*)/,
413
leading_zeros = /\.(0*)/,
414
trailing_dot = /\.$/
416
var validate_precision = function(precision) {
417
// force precision to limits of javascript
422
var floating_point_format = function(val, upper, flags){
423
val = _float_helper(val, flags),
424
v = val.toString(),
425
v_len = v.length,
426
dot_idx = v.indexOf('.')
427
if(dot_idx < 0){dot_idx = v_len}
428
if(val < 1 && val > -1){
429
var zeros = leading_zeros.exec(v),
430
numzeros
431
if(zeros){
436
if(numzeros >= 4){
437
val = format_sign(val, flags) + format_float_precision(val, upper,
438
flags, _floating_g_exp_helper)
439
if(!flags.alternate){
452
return format_padding(format_sign(val, flags) +
453
format_float_precision(val, upper, flags,
454
function(val, precision) {
456
numzeros)
457
}),
458
flags
459
)
460
}
461
462
if(dot_idx > flags.precision){
463
val = format_sign(val, flags) + format_float_precision(val, upper,
464
flags, _floating_g_exp_helper)
465
if(! flags.alternate){
477
return format_padding(format_sign(val, flags) +
478
format_float_precision(val, upper, flags,
479
function(val, precision) {
480
if(!flags.decimal_point){
482
}else if (precision > v_len){
483
if(! flags.alternate){
484
precision = v_len
485
}
487
if(precision < dot_idx){
488
precision = dot_idx
489
}
490
return val.toFixed(precision - dot_idx)
491
}),
492
flags
493
)
496
var _floating_g_exp_helper = function(val, precision, flags, upper){
497
if(precision){--precision}
500
var e_idx = val.lastIndexOf("e")
501
if(e_idx > val.length - 4){
502
val = val.substring(0, e_idx + 2) + "0" + val.substring(e_idx + 2)
505
return val
506
}
507
508
// fF
509
var floating_point_decimal_format = function(val, upper, flags) {
510
val = _float_helper(val, flags)
511
return format_padding(format_sign(val, flags) +
512
format_float_precision(val, upper, flags,
513
function(val, precision, flags) {
514
val = val.toFixed(precision)
515
if(precision === 0 && flags.alternate){
516
val += '.'
517
}
518
return val
519
}),
520
flags
521
)
522
}
523
524
var _floating_exp_helper = function(val, precision, flags, upper) {
525
val = val.toExponential(precision)
526
// pad exponent to two digits
539
return format_padding(format_sign(val, flags) +
540
format_float_precision(val, upper, flags, _floating_exp_helper), flags)
566
if(flags.alternate){
567
if(ret.charAt(0) === "-"){
568
if(upper){ret = "-0X" + ret.slice(1)}
569
else{ret = "-0x" + ret.slice(1)}
570
}else{
571
if(upper){ret = "0X" + ret}
572
else{ret = "0x" + ret}
582
if(val.__class__ === $B.long_int){
583
ret = $B.long_int.to_base(8)
584
}else{
585
ret = parseInt(val)
586
ret = ret.toString(8)
602
if(flags.alternate){
603
if(ret.charAt(0) === "-"){ret = "-0o" + ret.slice(1)}
604
else{ret = "0o" + ret}
609
function series_of_bytes(val, flags){
610
if(val.__class__ && val.__class__.$buffer_protocol){
611
var it = _b_.iter(val),
612
ints = []
613
while(true){
614
try{
615
ints.push(_b_.next(it))
616
}catch(err){
617
if(err.__class__ === _b_.StopIteration){
618
var b = _b_.bytes.$factory(ints)
619
return format_padding(_b_.bytes.decode(b, "ascii"), flags)
620
}
621
throw err
622
}
623
}
624
}else{
625
try{
626
bytes_obj = $B.$getattr(val, "__bytes__")
627
return format_padding(_b_.bytes.decode(bytes_obj), flags)
628
}catch(err){
629
if(err.__class__ === _b_.AttributeError){
630
throw _b_.TypeError.$factory("%b does not accept '" +
631
$B.class_name(val) + "'")
632
}
633
throw err
634
}
635
}
636
}
637
642
val = val.source[0]
643
}else{
644
try{
645
val = _b_.int.$factory(val) // yes, floats are valid (they are cast to int)
646
}catch (err){
647
throw _b_.TypeError.$factory("%c requires int or char")
648
}
653
var num_flag = function(c, flags){
654
if(c === "0" && ! flags.padding && ! flags.decimal_point && ! flags.left){
655
flags.pad_char = "0"
661
flags.precision = (flags.precision || "") + c
662
}
663
}
664
665
var decimal_point_flag = function(val, flags) {
667
// can only have one decimal point
668
throw new UnsupportedChar()
669
}
670
flags.decimal_point = true
671
}
672
673
var neg_flag = function(val, flags){
674
flags.pad_char = " " // overrides '0' flag
692
"s": str_format,
693
"d": num_format,
694
"i": num_format,
695
"u": num_format,
696
"o": octal_format,
697
"r": repr_format,
698
"a": ascii_format,
699
"g": function(val, flags){
700
return floating_point_format(val, false, flags)
701
},
702
"G": function(val, flags){return floating_point_format(val, true, flags)},
703
"f": function(val, flags){
704
return floating_point_decimal_format(val, false, flags)
705
},
706
"F": function(val, flags){
707
return floating_point_decimal_format(val, true, flags)
708
},
709
"e": function(val, flags){
710
return floating_point_exponential_format(val, false, flags)
711
},
712
"E": function(val, flags){
713
return floating_point_exponential_format(val, true, flags)
714
},
715
"x": function(val, flags){return signed_hex_format(val, false, flags)},
716
"X": function(val, flags){return signed_hex_format(val, true, flags)},
717
"c": single_char_format,
718
"0": function(val, flags){return num_flag("0", flags)},
719
"1": function(val, flags){return num_flag("1", flags)},
720
"2": function(val, flags){return num_flag("2", flags)},
721
"3": function(val, flags){return num_flag("3", flags)},
722
"4": function(val, flags){return num_flag("4", flags)},
723
"5": function(val, flags){return num_flag("5", flags)},
724
"6": function(val, flags){return num_flag("6", flags)},
725
"7": function(val, flags){return num_flag("7", flags)},
726
"8": function(val, flags){return num_flag("8", flags)},
727
"9": function(val, flags){return num_flag("9", flags)},
728
"-": neg_flag,
729
" ": space_flag,
730
"+": sign_flag,
731
".": decimal_point_flag,
732
"#": alternate_flag
733
}
734
735
// exception thrown when an unsupported char is encountered in legacy format
781
if(self === undefined){
782
throw _b_.TypeError.$factory(
783
"not enough arguments for format string")
810
throw _b_.ValueError.$factory(
811
"unsupported format character '" + invalid_char +
812
"' (0x" + invalid_char.charCodeAt(0).toString(16) +
813
") at index " + newpos)
814
}else if(err.name === "NotANumber"){
815
var try_char = s[newpos],
816
cls = self.__class__
817
if(!cls){
818
if(typeof(self) === "string"){
819
cls = "str"
820
}else{
826
throw _b_.TypeError.$factory("%" + try_char +
827
" format: a number is required, not " + cls)
828
}else{
860
}while(pos < length)
861
862
if(argpos !== null){
863
if(args.length > argpos){
864
throw _b_.TypeError.$factory(
865
"not enough arguments for format string")
866
}else if(args.length < argpos){
867
throw _b_.TypeError.$factory(
868
"not all arguments converted during string formatting")
870
}else if(nbph == 0){
871
throw _b_.TypeError.$factory(
872
"not all arguments converted during string formatting")
880
var $ = $B.args("__mul__", 2, {self: null, other: null},
881
["self", "other"], arguments, {}, null, null)
892
function __newobj__(){
893
// __newobj__ is called with a generator as only argument
894
var $ = $B.args('__newobj__', 0, {}, [], arguments, {}, 'args', null),
895
args = $.args
896
var res = args[1]
897
res.__class__ = args[0]
898
return res
899
}
900
901
str.__reduce_ex__ = function(self){
902
return $B.fast_tuple([
903
__newobj__,
904
$B.fast_tuple([self.__class__ || _b_.str, self]),
905
_b_.None,
906
_b_.None])
907
}
908
911
var t = {
912
8: "\\x08",
913
9: "\\t",
914
10: "\\n",
915
11: "\\x0b",
916
12: "\\x0c",
917
13: "\\r",
918
92: "\\\\"
919
}
920
var repl = '',
921
chars = to_chars(self)
922
for(var i = 0; i < chars.length; i++){
923
var cp = _b_.ord(chars[i])
924
if(t[cp] !== undefined){
925
repl += t[cp]
926
}else if($B.is_unicode_cn(cp)){
945
if(res.search('"') == -1 && res.search("'") == -1){
946
return "'" + res + "'"
947
}else if(self.search('"') == -1){
948
return '"' + res + '"'
949
}
950
var qesc = new RegExp("'", "g") // to escape single quote
951
res = "'" + res.replace(qesc, "\\'") + "'"
955
str.__rmul__ = function(self, other){
956
if(_b_.isinstance(other, _b_.int)){
957
other = _b_.int.numerator(other)
958
var res = ''
959
while(other > 0){
960
res += self
961
other--
962
}
963
return res
964
}
965
return _b_.NotImplemented
966
}
967
968
str.__setattr__ = function(self, attr, value){
969
if(typeof self === "string"){
970
if(str.hasOwnProperty(attr)){
972
attr + "' is read-only")
973
}else{
974
throw _b_.AttributeError.$factory(
975
"'str' object has no attribute '" + attr + "'")
976
}
977
}
978
// str subclass : use __dict__
979
_b_.dict.$setitem(self.__dict__, attr, value)
980
return $N
981
}
982
983
str.__setitem__ = function(self, attr, value){
984
throw _b_.TypeError.$factory(
985
"'str' object does not support item assignment")
988
var combining = []
989
for(var cp = 0x300; cp <= 0x36F; cp++){
990
combining.push(String.fromCharCode(cp))
991
}
995
var repl = '',
996
chars = to_chars(self)
997
if(chars.length == self.length){
998
return self.replace(combining_re, "\u200B$1")
999
}
1000
for(var i = 0; i < chars.length; i++){
1001
var cp = _b_.ord(chars[i])
1002
if(cp >= 0x300 && cp <= 0x36F){
1003
repl += "\u200B" + chars[i]
1004
}else{
1005
repl += chars[i]
1006
}
1007
}
1008
return repl
1018
$comp_func += "" // source code
1019
var $comps = {">": "gt", ">=": "ge", "<": "lt", "<=": "le"}
1030
str.capitalize = function(self){
1031
var $ = $B.args("capitalize", 1, {self}, ["self"],
1032
arguments, {}, null, null)
1036
return self.charAt(0).toUpperCase() + self.substr(1)
1037
}
1038
1039
str.casefold = function(self){
1040
var $ = $B.args("casefold", 1, {self}, ["self"],
1041
arguments, {}, null, null),
1042
res = "",
1043
char,
1044
cf,
1045
chars = to_chars($.self)
1046
1047
for(var i = 0, len = chars.length; i < len; i++){
1048
char = chars[i]
1049
cf = $B.unicode_casefold[char]
1050
if(cf){
1051
cf.forEach(function(cp){
1052
res += String.fromCharCode(cp)
1053
})
1054
}else{
1061
str.center = function(){
1062
var $ = $B.args("center", 3, {self: null, width: null, fillchar: null},
1063
["self", "width", "fillchar"],
1064
arguments, {fillchar:" "}, null, null),
1065
self = $.self
1069
var pad = parseInt(($.width - self.length) / 2),
1070
res = $.fillchar.repeat(pad)
1079
var $ = $B.args("count", 4, {self:null, sub:null, start:null, stop:null},
1080
["self", "sub", "start", "stop"], arguments, {start:null, stop:null},
1082
if(!(typeof $.sub == "string")){
1083
throw _b_.TypeError.$factory("Can't convert '" + $B.class_name($.sub) +
1084
"' object to str implicitly")
1085
}
1089
if($.stop !== null){
1090
_slice = _b_.slice.$factory($.start, $.stop)
1091
}else{
1092
_slice = _b_.slice.$factory($.start, $.self.length)
1093
}
1101
if($.start == $.self.length){
1102
return 1
1103
}else if(substr.length == 0){
1104
return 0
1105
}
1108
var n = 0,
1109
pos = 0
1110
while(pos < substr.length){
1111
pos = substr.indexOf($.sub, pos)
1122
str.encode = function(){
1123
var $ = $B.args("encode", 3, {self: null, encoding: null, errors: null},
1124
["self", "encoding", "errors"], arguments,
1125
{encoding: "utf-8", errors: "strict"}, null, null)
1126
if($.encoding == "rot13" || $.encoding == "rot_13"){
1129
for(var i = 0, len = $.self.length; i < len ; i++){
1130
var char = $.self.charAt(i)
1131
if(("a" <= char && char <= "m") || ("A" <= char && char <= "M")){
1132
res += String.fromCharCode(String.charCodeAt(char) + 13)
1133
}else if(("m" < char && char <= "z") ||
1134
("M" < char && char <= "Z")){
1135
res += String.fromCharCode(String.charCodeAt(char) - 13)
1144
// Return True if the string ends with the specified suffix, otherwise
1145
// return False. suffix can also be a tuple of suffixes to look for.
1146
// With optional start, test beginning at that position. With optional
1150
["self", "suffix", "start", "end"],
1151
arguments, {start: 0, end: null}, null, null)
1164
if(! _b_.isinstance(suffix, str)){
1165
throw _b_.TypeError.$factory(
1166
"endswith first arg must be str or a tuple of str, not int")
1167
}
1177
var $ = $B.args("expandtabs", 2, {self: null, tabsize: null},
1178
["self", "tabsize"], arguments, {tabsize: 8}, null, null)
1179
var s = $B.$GetInt($.tabsize),
1180
col = 0,
1181
pos = 0,
1182
res = "",
1183
chars = to_chars(self)
1184
if(s == 1){
1185
return self.replace(/\t/g," ")
1186
}
1187
while(pos < chars.length){
1188
var car = chars[pos]
1198
res += car
1199
col = 0
1200
break
1201
default:
1202
res += car
1203
col++
1204
break
1205
}
1206
pos++
1207
}
1208
return res
1212
// Return the lowest index in the string where substring sub is found,
1213
// such that sub is contained in the slice s[start:end]. Optional
1214
// arguments start and end are interpreted as in slice notation.
1217
{self: null, sub: null, start: null, end: null},
1218
["self", "sub", "start", "end"],
1219
arguments, {start: 0, end: null}, null, null)
1225
throw _b_.TypeError.$factory("slice indices must be " +
1226
"integers or None or have an __index__ method")}
1227
// Can't use string.substring(start, end) because if end < start,
1228
// Javascript transforms it into substring(end, start)...
1229
var s = ""
1230
for(var i = $.start; i < $.end; i++){
1231
s += $.self.charAt(i)
1232
}
1234
var len = str.__len__($.self)
1235
1236
if($.sub.length == 0 && $.start == len){
1237
return len
1238
}
1239
if(s.length + $.sub.length == 0){
1240
return -1
1241
}
1243
var last_search = s.length - $.sub.length
1244
for(var i = 0; i <= last_search; i++){
1245
if(s.substr(i, $.sub.length) == $.sub){
1246
return $.start + str.__len__(s.substr(0, i))
1247
}
1258
// a.x[z]!r:...
1259
// the object has attributes :
1260
// - name : "a"
1261
// - name_ext : [".x", "[z]"]
1262
// - conv : r
1263
// - spec : rest of string after :
1271
// No : in the string : it only contains a name
1272
name = fmt_string
1273
}else{
1274
// name is before the first ":"
1275
// spec (the format specification) is after
1276
name = elts[0]
1280
var elts = name.split("!")
1281
if(elts.length > 1){
1282
name = elts[0]
1283
conv = elts[1] // conversion flag
1287
// "name' may be a subscription or attribute
1288
// Put these "extensions" in the list "name_ext"
1289
function name_repl(match){
1290
name_ext.push(match)
1292
}
1293
var name_ext_re = /\.[_a-zA-Z][_a-zA-Z0-9]*|\[[_a-zA-Z][_a-zA-Z0-9]*\]|\[[0-9]+\]/g
1294
name = name.replace(name_ext_re, name_repl)
1295
}
1302
// Parse self to detect formatting instructions
1303
// Create a list "parts" made of sections of the string :
1304
// - elements of even rank are literal text
1305
// - elements of odd rank are "format objects", built from the
1306
// format strings in self (of the form {...})
1317
text += "{"
1318
pos += 2
1319
}else if(car == "}" && self.charAt(pos + 1) == "}"){
1326
// Store current literal text
1327
parts.push(text)
1328
1329
// Search the end of the format string, ie the } closing the
1330
// opening {. Since the string can contain other pairs {} for
1331
// nested formatting, an integer nb is incremented for each { and
1332
// decremented for each } ; the end of the format string is
1333
// reached when nb == 0
1334
var end = pos + 1,
1335
nb = 1
1336
while(end < _len){
1337
if(self.charAt(end) == "{"){nb++; end++}
1338
else if(self.charAt(end) == "}"){
1339
nb--; end++
1340
if(nb == 0){
1345
var fmt_obj = $B.parse_format(fmt_string)
1346
fmt_obj.raw_name = fmt_obj.name
1347
fmt_obj.raw_spec = fmt_obj.spec
1381
}else{
1382
text += car
1383
pos++
1384
}
1385
}
1386
if(text){
1387
parts.push(text)
1393
// Special management of keyword arguments if str.format is called by
1394
// str.format_map(mapping) : the argument "mapping" might not be a
1395
// dictionary
1396
var last_arg = $B.last(arguments)
1397
if(last_arg.$nat == "mapping"){
1398
var mapping = last_arg.mapping,
1399
getitem = $B.$getattr(mapping, "__getitem__")
1400
// Get the rest of the arguments
1401
var args = []
1402
for(var i = 0, len = arguments.length - 1; i < len; i++){
1403
args.push(arguments[i])
1404
}
1405
var $ = $B.args("format", 1, {self: null}, ["self"],
1406
args, {}, "$args", null)
1407
}else{
1408
var $ = $B.args("format", 1, {self: null}, ["self"],
1409
arguments, {}, "$args", "$kw"),
1410
mapping = $.$kw, // dictionary
1411
getitem = function(key){
1412
return _b_.dict.$getitem(mapping, key)
1413
}
1414
}
1427
1428
if(fmt.spec !== undefined){
1429
// "spec" may contain "nested replacement fields"
1430
// In this case, evaluate them using the positional
1431
// or keyword arguments passed to format()
1432
function replace_nested(name, key){
1433
if(/\d+/.exec(key)){
1434
// If key is numeric, search in positional
1435
// arguments
1436
return _b_.tuple.__getitem__($.$args,
1437
parseInt(key))
1438
}else{
1439
// Else try in keyword arguments
1440
return _b_.dict.__getitem__($.$kw, key)
1441
}
1442
}
1443
fmt.spec = fmt.spec.replace(/\{(.*?)\}/g,
1444
replace_nested)
1445
}
1447
// Numerical reference : use positional arguments
1448
var pos = parseInt(fmt.name),
1469
// If the conversion flag is set, first call a function to convert
1470
// the value
1471
if(fmt.conv == "a"){value = _b_.ascii(value)}
1472
else if(fmt.conv == "r"){value = _b_.repr(value)}
1473
else if(fmt.conv == "s"){value = _b_.str.$factory(value)}
1486
str.format_map = function(self, mapping){
1487
var $ = $B.args("format_map", 2, {self: null, mapping: null},
1488
['self', 'mapping'], arguments, {}, null, null)
1489
return str.format(self, {$nat: 'mapping', mapping})
1502
/* Return true if the string is empty or all characters in the string are
1503
ASCII, false otherwise. ASCII characters have code points in the range
1504
U+0000-U+007F. */
1513
str.isalnum = function(self){
1514
/* Return true if all characters in the string are alphanumeric and there
1515
is at least one character, false otherwise. A character c is alphanumeric
1516
if one of the following returns True: c.isalpha(), c.isdecimal(),
1517
c.isdigit(), or c.isnumeric(). */
1518
var $ = $B.args("isalnum", 1, {self: null}, ["self"],
1519
arguments, {}, null, null),
1520
cp
1521
for(var char of to_chars(self)){
1522
cp = _b_.ord(char)
1523
if(unicode_tables.Ll[cp] ||
1524
unicode_tables.Lu[cp] ||
1525
unicode_tables.Lm[cp] ||
1526
unicode_tables.Lt[cp] ||
1527
unicode_tables.Lo[cp] ||
1528
unicode_tables.Nd[cp] ||
1529
unicode_tables.digits[cp] ||
1530
unicode_tables.numeric[cp]){
1531
continue
1532
}
1533
return false
1534
}
1535
return true
1536
}
1537
1538
str.isalpha = function(self){
1539
/* Return true if all characters in the string are alphabetic and there is
1540
at least one character, false otherwise. Alphabetic characters are those
1541
characters defined in the Unicode character database as "Letter", i.e.,
1542
those with general category property being one of "Lm", "Lt", "Lu", "Ll",
1543
or "Lo". */
1544
var $ = $B.args("isalpha", 1, {self: null}, ["self"],
1545
arguments, {}, null, null),
1546
cp
1547
for(var char of to_chars(self)){
1548
cp = _b_.ord(char)
1549
if(unicode_tables.Ll[cp] ||
1550
unicode_tables.Lu[cp] ||
1551
unicode_tables.Lm[cp] ||
1552
unicode_tables.Lt[cp] ||
1553
unicode_tables.Lo[cp]){
1554
continue
1555
}
1556
return false
1557
}
1558
return true
1559
}
1560
1561
str.isdecimal = function(self){
1562
/* Return true if all characters in the string are decimal characters and
1563
there is at least one character, false otherwise. Decimal characters are
1564
those that can be used to form numbers in base 10, e.g. U+0660,
1565
ARABIC-INDIC DIGIT ZERO. Formally a decimal character is a character in
1566
the Unicode General Category "Nd". */
1567
var $ = $B.args("isdecimal", 1, {self: null}, ["self"],
1568
arguments, {}, null, null),
1569
cp
1570
for(var char of to_chars(self)){
1571
cp = _b_.ord(char)
1572
if(! unicode_tables.Nd[cp]){
1573
return false
1574
}
1575
}
1576
return self.length > 0
1577
}
1578
1579
str.isdigit = function(self){
1580
/* Return true if all characters in the string are digits and there is at
1581
least one character, false otherwise. */
1582
var $ = $B.args("isdigit", 1, {self: null}, ["self"],
1583
arguments, {}, null, null),
1584
cp
1585
for(var char of to_chars(self)){
1586
cp = _b_.ord(char)
1587
if(! unicode_tables.digits[cp]){
1588
return false
1589
}
1590
}
1591
return self.length > 0
1592
}
1593
1594
str.isidentifier = function(self){
1595
/* Return true if the string is a valid identifier according to the
1596
language definition. */
1597
var $ = $B.args("isidentifier", 1, {self: null}, ["self"],
1601
}
1602
var chars = to_chars(self)
1603
if(unicode_tables.XID_Start[_b_.ord(chars[0])] === undefined){
1606
for(var char of chars){
1607
var cp = _b_.ord(char)
1608
if(unicode_tables.XID_Continue[cp] === undefined){
1609
return false
1610
}
1611
}
1612
}
1613
return true
1614
}
1615
1616
str.islower = function(self){
1617
/* Return true if all cased characters 4 in the string are lowercase and
1618
there is at least one cased character, false otherwise. */
1619
var $ = $B.args("islower", 1, {self: null}, ["self"],
1620
arguments, {}, null, null),
1621
has_cased = false,
1624
for(var char of to_chars(self)){
1625
cp = _b_.ord(char)
1626
if(unicode_tables.Ll[cp]){
1627
has_cased = true
1628
continue
1629
}else if(unicode_tables.Lu[cp] || unicode_tables.Lt[cp]){
1630
return false
1631
}
1632
}
1633
return has_cased
1634
}
1635
1636
str.isnumeric = function(self){
1637
/* Return true if all characters in the string are numeric characters, and
1638
there is at least one character, false otherwise. Numeric characters
1639
include digit characters, and all characters that have the Unicode numeric
1640
value property, e.g. U+2155, VULGAR FRACTION ONE FIFTH. Formally, numeric
1641
characters are those with the property value Numeric_Type=Digit,
1642
Numeric_Type=Decimal or Numeric_Type=Numeric.*/
1643
var $ = $B.args("isnumeric", 1, {self: null}, ["self"],
1644
arguments, {}, null, null)
1653
var unprintable = {},
1654
unprintable_gc = ['Cc', 'Cf', 'Co', 'Cs','Zl', 'Zp', 'Zs']
1655
1656
str.isprintable = function(self){
1657
/* Return true if all characters in the string are printable or the string
1658
is empty, false otherwise. Nonprintable characters are those characters
1659
defined in the Unicode character database as "Other" or "Separator",
1660
excepting the ASCII space (0x20) which is considered printable. */
1661
1662
// Set unprintable if not set yet
1663
if(Object.keys(unprintable).length == 0){
1664
for(var i = 0; i < unprintable_gc.length; i++){
1665
var table = unicode_tables[unprintable_gc[i]]
1676
return false
1677
}
1678
}
1679
return true
1680
}
1681
1682
str.isspace = function(self){
1683
/* Return true if there are only whitespace characters in the string and
1684
there is at least one character, false otherwise.
1685
1686
A character is whitespace if in the Unicode character database, either its
1687
general category is Zs ("Separator, space"), or its bidirectional class is
1688
one of WS, B, or S.*/
1689
var $ = $B.args("isspace", 1, {self: null}, ["self"],
1690
arguments, {}, null, null),
1691
cp
1692
for(var char of to_chars(self)){
1693
cp = _b_.ord(char)
1694
if(! unicode_tables.Zs[cp] &&
1695
$B.unicode_bidi_whitespace.indexOf(cp) == -1){
1696
return false
1697
}
1698
}
1699
return self.length > 0
1700
}
1701
1702
str.istitle = function(self){
1703
/* Return true if the string is a titlecased string and there is at least
1704
one character, for example uppercase characters may only follow uncased
1705
characters and lowercase characters only cased ones. Return false
1706
otherwise. */
1707
var $ = $B.args("istitle", 1, {self: null}, ["self"],
1708
arguments, {}, null, null)
1709
return self.length > 0 && str.title(self) == self
1710
}
1711
1712
str.isupper = function(self){
1713
/* Return true if all cased characters 4 in the string are lowercase and
1714
there is at least one cased character, false otherwise. */
1715
var $ = $B.args("islower", 1, {self: null}, ["self"],
1716
arguments, {}, null, null),
1720
for(var char of to_chars(self)){
1721
cp = _b_.ord(char)
1722
if(unicode_tables.Lu[cp]){
1723
is_upper = true
1724
continue
1725
}else if(unicode_tables.Ll[cp] || unicode_tables.Lt[cp]){
1744
throw _b_.TypeError.$factory("sequence item " + count +
1745
": expected str instance, " + $B.class_name(obj2) +
1746
" found")
1747
}
1760
var $ = $B.args("ljust", 3, {self: null, width: null, fillchar:null},
1761
["self", "width", "fillchar"],
1765
if($.width <= len){
1766
return self
1767
}
1768
return self + $.fillchar.repeat($.width - len)
1771
str.lower = function(self){
1772
var $ = $B.args("lower", 1, {self: null}, ["self"],
1773
arguments, {}, null, null)
1774
return self.toLowerCase()
1775
}
1776
1778
var $ = $B.args("lstrip", 2, {self: null, chars: null}, ["self", "chars"],
1779
arguments, {chars:_b_.None}, null, null)
1780
if($.chars === _b_.None){
1781
return $.self.trimLeft()
1782
}
1783
var chars = to_chars(self)
1784
for(var i = 0, len = chars.length; i < len; i++){
1785
if($.chars.indexOf(chars[i]) === -1){
1786
return chars.slice(i).join('')
1794
var $ = $B.args("maketrans", 3, {x: null, y: null, z: null},
1795
["x", "y", "z"], arguments, {y: null, z: null}, null, null)
1800
// If there is only one argument, it must be a dictionary mapping
1801
// Unicode ordinals (integers) or characters (strings of length 1) to
1802
// Unicode ordinals, strings (of arbitrary lengths) or None. Character
1804
if(! _b_.isinstance($.x, _b_.dict)){
1805
throw _b_.TypeError.$factory(
1806
"maketrans only argument must be a dict")
1809
for(var i = 0, len = items.length; i < len; i++){
1810
var k = items[i][0],
1811
v = items[i][1]
1812
if(! _b_.isinstance(k, _b_.int)){
1813
if(_b_.isinstance(k, _b_.str) && k.length == 1){
1814
k = _b_.ord(k)
1815
}else{throw _b_.TypeError.$factory("dictionary key " + k +
1818
if(v !== _b_.None && ! _b_.isinstance(v, [_b_.int, _b_.str])){
1819
throw _b_.TypeError.$factory("dictionary value " + v +
1827
// and in the resulting dictionary, each character in x will be mapped
1828
// to the character at the same position in y
1831
}else if($.x.length !== $.y.length){
1832
throw _b_.TypeError.$factory(
1833
"maketrans arguments must be strings or same length")
1839
if(! _b_.isinstance($.z, _b_.str)){
1840
throw _b_.TypeError.$factory(
1841
"maketrans third argument must be a string")
1863
var $ = $B.args("partition", 2, {self: null, sep: null}, ["self", "sep"],
1864
arguments, {}, null, null)
1871
if(i == -1){
1872
return _b_.tuple.$factory([$.self, "", ""])
1873
}
1874
return _b_.tuple.$factory([chars.slice(0, i).join(''), $.sep,
1875
chars.slice(i + $.sep.length).join('')])
1878
str.removeprefix = function(){
1879
var $ = $B.args("removeprefix", 2, {self: null, prefix: null},
1880
["self", "prefix"], arguments, {}, null, null)
1881
if(!_b_.isinstance($.prefix, str)){
1882
throw _b_.ValueError.$factory("prefix should be str, not " +
1883
`'${$B.class_name($.prefix)}'`)
1884
}
1885
if(str.startswith($.self, $.prefix)){
1886
return $.self.substr($.prefix.length)
1887
}
1888
return $.self.substr(0)
1889
}
1890
1891
str.removesuffix = function(){
1892
var $ = $B.args("removesuffix", 2, {self: null, prefix: null},
1893
["self", "suffix"], arguments, {}, null, null)
1894
if(!_b_.isinstance($.suffix, str)){
1895
throw _b_.ValueError.$factory("suffix should be str, not " +
1896
`'${$B.class_name($.prefix)}'`)
1897
}
1898
if($.suffix.length > 0 && str.endswith($.self, $.suffix)){
1899
return $.self.substr(0, $.self.length - $.suffix.length)
1900
}
1901
return $.self.substr(0)
1902
}
1903
1904
function $re_escape(str){
1905
var specials = "[.*+?|()$^"
1906
for(var i = 0, len = specials.length; i < len; i++){
1907
var re = new RegExp("\\"+specials.charAt(i), "g")
1908
str = str.replace(re, "\\"+specials.charAt(i))
1909
}
1910
return str
1917
var $ = $B.args("replace", 4,
1918
{self: null, old: null, $$new: null, count: null},
1919
["self", "old", "$$new", "count"],
1920
arguments, {count: -1}, null, null),
1921
count = $.count,
1922
self = $.self,
1923
old = $.old,
1924
_new = $.$$new
1926
check_str(old, "replace() argument 1 ")
1927
check_str(_new, "replace() argument 2 ")
1935
if(count == 0){
1936
return self
1937
}
1938
if(count.__class__ == $B.long_int){
1939
count = parseInt(count.value)
1940
}
1942
if(_new == ""){
1943
return self
1944
}
1945
if(self == ""){
1946
return _new
1947
}
1948
var elts = self.split("")
1949
if(count > -1 && elts.length >= count){
1950
var rest = elts.slice(count).join("")
1951
return _new + elts.slice(0, count).join(_new) + rest
1977
res = res.substr(0, pos) + _new + res.substr(pos + old.length)
1978
pos = pos + _new.length
1979
count--
1985
// Return the highest index in the string where substring sub is found,
1986
// such that sub is contained within s[start:end]. Optional arguments
1988
if(arguments.length == 2 && typeof substr == "string"){
1989
return self.lastIndexOf(substr)
1990
}
1992
{self: null, sub: null, start: null, end: null},
1993
["self", "sub", "start", "end"],
1994
arguments, {start: 0, end: null}, null, null)
2001
if($.start > $.self.length){
2002
return -1
2003
}else{
2004
return str.__len__($.self)
2005
}
2011
if($.self.substr(i, sublen) == $.sub){
2012
return str.__len__($.self.substr(0, i))
2013
}
2028
var $ = $B.args("rjust",3,
2029
{self: null, width: null, fillchar: null},
2030
["self", "width", "fillchar"],
2031
arguments, {fillchar: " "}, null, null)
2041
var $ = $B.args("rpartition", 2, {self: null, sep: null}, ["self", "sep"],
2042
arguments, {}, null, null)
2046
var items = str.partition(self, sep).reverse()
2047
for(var i = 0; i < items.length; i++){
2048
items[i] = items[i].split("").reverse().join("")
2054
var $ = $B.args("rsplit", 3, {self: null, sep: null, maxsplit: null},
2055
["self", "sep", "maxsplit"], arguments,
2056
{sep: _b_.None, maxsplit: -1}, null, null),
2057
sep = $.sep
2060
var rev_str = reverse($.self),
2061
rev_sep = sep === _b_.None ? sep : reverse($.sep),
2072
str.rstrip = function(self, x){
2073
var $ = $B.args("rstrip", 2, {self: null, chars: null}, ["self", "chars"],
2075
if($.chars === _b_.None){
2076
return $.self.trimRight()
2077
}
2078
var chars = to_chars(self)
2079
for(var j = chars.length - 1; j >= 0; j--){
2080
if($.chars.indexOf(chars[j]) == -1){
2081
return chars.slice(0, j + 1).join('')
2088
var $ = $B.args("split", 3, {self: null, sep: null, maxsplit: null},
2089
["self", "sep", "maxsplit"], arguments,
2090
{sep: _b_.None, maxsplit: -1}, null, null),
2091
sep = $.sep,
2092
maxsplit = $.maxsplit,
2093
self = $.self,
2094
pos = 0
2095
if(maxsplit.__class__ === $B.long_int){
2096
maxsplit = parseInt(maxsplit.value)
2097
}
2098
if(sep == ""){
2099
throw _b_.ValueError.$factory("empty separator")
2100
}
2103
while(pos < self.length && self.charAt(pos).search(/\s/) > -1){
2104
pos++
2105
}
2106
if(pos === self.length - 1){
2107
return [self]
2108
}
2112
if(name == ""){
2113
name = self.charAt(pos)
2114
}else{
2115
name += self.charAt(pos)
2116
}
2138
var res = [],
2139
s = "",
2140
seplen = sep.length
2141
if(maxsplit == 0){return [self]}
2142
while(pos < self.length){
2143
if(self.substr(pos, seplen) == sep){
2161
str.splitlines = function(self) {
2162
var $ = $B.args('splitlines', 2, {self: null, keepends: null},
2163
['self','keepends'], arguments, {keepends: false},
2164
null, null)
2165
if(!_b_.isinstance($.keepends,[_b_.bool, _b_.int])){
2166
throw _b_.TypeError('integer argument expected, got '+
2169
var keepends = _b_.int.$factory($.keepends),
2170
res = [],
2171
self = $.self,
2172
start = 0,
2173
pos = 0
2174
if(!self.length){
2178
if(self.substr(pos, 2) == '\r\n'){
2179
res.push(self.slice(start, keepends ? pos + 2 : pos))
2180
start = pos = pos+2
2181
}else if(self[pos] == '\r' || self[pos] == '\n'){
2182
res.push(self.slice(start, keepends ? pos+1 : pos))
2183
start = pos = pos+1
2184
}else{
2185
pos++
2186
}
2187
}
2188
if(start < self.length){
2189
res.push(self.slice(start))
2190
}
2191
return res
2195
// Return True if string starts with the prefix, otherwise return False.
2196
// prefix can also be a tuple of prefixes to look for. With optional
2197
// start, test string beginning at that position. With optional end,
2199
var $ = $B.args("startswith", 4,
2200
{self: null, prefix: null, start: null, end: null},
2201
["self", "prefix", "start", "end"],
2202
arguments, {start: 0, end: null}, null, null)
2214
if(! _b_.isinstance(prefix, str)){
2215
throw _b_.TypeError.$factory("endswith first arg must be str " +
2216
"or a tuple of str, not int")
2217
}
2218
if(s.substr(0, prefix.length) == prefix){
2219
return true
2220
}
2226
var $ = $B.args("strip", 2, {self: null, chars: null}, ["self", "chars"],
2227
arguments, {chars: _b_.None}, null, null)
2228
if($.chars === _b_.None){
2229
return $.self.trim()
2230
}
2231
var chars = to_chars($.self)
2232
for(var i = 0; i < chars.length; i++){
2233
if($.chars.indexOf(chars[i]) == -1){
2237
for(var j = chars.length - 1; j >= i; j--){
2238
if($.chars.indexOf(chars[j]) == -1){
2245
str.swapcase = function(self){
2246
var $ = $B.args("swapcase", 1, {self}, ["self"],
2247
arguments, {}, null, null),
2248
res = "",
2249
cp
2250
2251
for(var char of to_chars(self)){
2252
cp = _b_.ord(char)
2253
if(unicode_tables.Ll[cp]){
2254
res += char.toUpperCase()
2255
}else if(unicode_tables.Lu[cp]){
2256
res += char.toLowerCase()
2259
}
2260
}
2261
return res
2262
}
2263
2264
str.title = function(self){
2265
var $ = $B.args("title", 1, {self}, ["self"],
2266
arguments, {}, null, null),
2267
state,
2270
for(var char of to_chars(self)){
2271
cp = _b_.ord(char)
2272
if(unicode_tables.Ll[cp]){
2279
}else if(unicode_tables.Lu[cp] || unicode_tables.Lt[cp]){
2280
res += state ? char.toLowerCase() : char
2292
getitem = $B.$getattr(table, "__getitem__"),
2293
cp
2294
for(var char of to_chars(self)){
2295
cp = _b_.ord(char)
2299
if(typeof repl == "string"){
2300
res.push(repl)
2301
}else if(typeof repl == "number"){
2302
res.push(String.fromCharCode(repl))
2303
}
2312
str.upper = function(self){
2313
var $ = $B.args("upper", 1, {self: null}, ["self"],
2314
arguments, {}, null, null)
2315
return self.toUpperCase()
2316
}
2317
2320
["self", "width"], arguments, {}, null, null),
2321
len = str.__len__(self)
2322
if($.width <= len){
2323
return self
2324
}
2344
if(encoding !== undefined){
2345
// Arguments may be passed as keywords (cf. issue #1060)
2346
var $ = $B.args("str", 3, {arg: null, encoding: null, errors: null},
2347
["arg", "encoding", "errors"], arguments,
2348
{encoding: "utf-8", errors: "strict"}, null, null),
2349
encoding = $.encoding,
2350
errors = $.errors
2351
}
2362
// class or its subclasses, but the attribute __str__ of the
2363
// class metaclass (usually "type") or its subclasses (usually
2364
// "object")
2365
// The metaclass is the attribute __class__ of the class dictionary
2370
if(arg.__class__ && arg.__class__ === _b_.bytes &&
2371
encoding !== undefined){
2372
// str(bytes, encoding, errors) is equal to
2373
// bytes.decode(encoding, errors)
2376
// Implicit invocation of __str__ uses method __str__ on the class,
2377
// even if arg has an attribute __str__
2378
var klass = arg.__class__ || $B.get_class(arg)
2384
// if not better than object.__str__, try __repr__
2385
(arg.__class__ && arg.__class__ !== _b_.object &&
2386
method.$infos && method.$infos.__func__ === _b_.object.__str__)){
2387
var method = $B.$getattr(klass, "__repr__")
2393
if($B.debug > 1){console.log(err)}
2394
console.log("Warning - no method __str__ or __repr__, " +
2395
"default to toString", arg)
2402
if(cls === undefined){
2403
throw _b_.TypeError.$factory("str.__new__(): not enough arguments")
2427
var args = [],
2428
pos = 0
2429
if(arguments.length > 0){
2430
var args = [arguments[0].valueOf()],
2431
pos = 1
2432
for(var i = 1, len = arguments.length; i < len; i++){
2433
args[pos++] = arguments[i]
2450
// Function to parse the 2nd argument of format()
2451
$B.parse_format_spec = function(spec){
2455
var pos = 0,
2456
aligns = "<>=^",
2457
digits = "0123456789",
2458
types = "bcdeEfFgGnosxX%",
2460
if(align_pos != -1){
2461
if(spec.charAt(1) && aligns.indexOf(spec.charAt(1)) != -1){
2462
// If the second char is also an alignment specifier, the
2463
// first char is the fill value
2464
this.fill = spec.charAt(0)
2465
this.align = spec.charAt(1)
2466
pos = 2
2467
}else{
2468
// The first character defines alignment : fill defaults to ' '
2483
if(car == "+" || car == "-" || car == " "){
2484
this.sign = car
2485
pos++
2486
car = spec.charAt(pos)
2501
if(this.width === undefined){
2502
this.width = car
2503
}else{
2504
this.width += car
2505
}
2512
if(this.width === undefined && car == "{"){
2513
// Width is determined by a parameter
2514
var end_param_pos = spec.substr(pos).search("}")
2515
this.width = spec.substring(pos, end_param_pos)
2516
console.log("width", "[" + this.width + "]")
2517
pos += end_param_pos + 1
2518
}
2519
if(car == ","){
2520
this.comma = true
2521
pos++
2522
car = spec.charAt(pos)
2523
}
2524
if(car == "."){
2525
if(digits.indexOf(spec.charAt(pos + 1)) == -1){
2526
throw _b_.ValueError.$factory(
2527
"Missing precision in format spec")
2529
this.precision = spec.charAt(pos + 1)
2530
pos += 2
2531
car = spec.charAt(pos)
2532
while(car && digits.indexOf(car) > -1){
2539
if(car && types.indexOf(car) > -1){
2540
this.type = car
2541
pos++
2542
car = spec.charAt(pos)
2543
}
2544
if(pos !== spec.length){
2550
return (this.fill === undefined ? "" : _b_.str.$factory(this.fill)) +
2551
(this.align || "") +
2552
(this.sign || "") +
2553
(this.alternate ? "#" : "") +
2554
(this.sign_aware ? "0" : "") +
2555
(this.width || "") +
2556
(this.comma ? "," : "") +
2557
(this.precision ? "." + this.precision : "") +
2558
(this.type || "")
2563
if(fmt.width && s.length < fmt.width){
2564
var fill = fmt.fill || " ",
2565
align = fmt.align || "<",
2566
missing = fmt.width - s.length
2568
case "<":
2569
return s + fill.repeat(missing)
2570
case ">":
2571
return fill.repeat(missing) + s
2572
case "=":
2573
if("+-".indexOf(s.charAt(0)) > -1){
2574
return s.charAt(0) + fill.repeat(missing) + s.substr(1)
2578
case "^":
2579
var left = parseInt(missing / 2)
2580
return fill.repeat(left) + s + fill.repeat(missing - left)
2593
function fstring_error(msg, pos){
2594
error = Error(msg)
2595
error.position = pos
2596
throw error
2597
}
2598
2599
$B.parse_fstring = function(string){
2600
// Parse a f-string
2601
var elts = [],
2602
pos = 0,
2664
}else if(ctype == "debug"){
2665
// after the equal sign, whitespace are ignored and the only
2666
// valid characters are } and :
2667
while(string.charAt(i) == " "){i++}
2668
if(string.charAt(i) == "}"){
2669
// end of debug expression
2670
elts.push(current)
2671
ctype = null
2672
current = ""
2673
pos = i + 1
2674
}
2675
}else{
2676
// End of expression is the } matching the opening {
2677
// There may be nested braces
2678
var i = pos,
2679
nb_braces = 1,
2692
if(current.expression == ""){
2693
fstring_error("f-string: empty expression not allowed",
2694
pos)
2695
}
2705
// backslash is not allowed in expressions
2706
throw Error("f-string expression part cannot include a" +
2707
" backslash")
2714
throw Error("f-string: invalid conversion character:" +
2715
" expected 's', 'r', or 'a'")
2716
}else{
2730
if(string.substr(i, 3) == '"""'){
2731
var end = string.indexOf('"""', i + 3)
2732
if(end == -1){
2734
}else{
2735
var trs = string.substring(i, end + 3)
2736
trs = trs.replace("\n", "\\n\\")
2755
var ce = current.expression,
2756
last_char = ce.charAt(ce.length - 1),
2757
last_char_re = ('()'.indexOf(last_char) > -1 ? "\\" : "") + last_char
2765
}else{
2766
// add debug string
2767
tail = car
2768
while(string.charAt(i + 1).match(/\s/)){
2769
tail += string.charAt(i + 1)
2770
i++
2771
}
2772
elts.push(current.expression + tail)
2773
// remove trailing whitespace from expression
2774
while(ce.match(/\s$/)){
2775
ce = ce.substr(0, ce.length - 1)
2776
}
2777
current.expression = ce
2778
ctype = "debug"
2779
i++
2780
}
2798
if(i >= 0x10000 && i <= 0x10FFFF){
2799
var code = (i - 0x10000)
2800
return String.fromCodePoint(0xD800 | (code >> 10)) +
2801
String.fromCodePoint(0xDC00 | (code & 0x3FF))
2802
}else{
2803
return String.fromCodePoint(i)
2804
}
2805
}
2808
if(c.length == 1){
2809
return c.charCodeAt(0)
2810
}
2811
var code = 0x10000
2812
code += (c.charCodeAt(0) & 0x03FF) << 10
2813
code += (c.charCodeAt(1) & 0x03FF)
2814
return code
2815
}
2816