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
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
2449 lines (2250 sloc)
78.4 KB
8
/*
9
// Copy static methods from unicode
10
var from_unicode = [
11
"isalpha",
12
"isalnum",
13
"isdecimal",
14
"isdigit",
15
"isidentifier",
16
]
17
*/
19
// Polyfill for older browsers
20
// The code does not use a regex to make it a bit faster.
21
// Implementation taken from a comment by Timo on the blog:
22
// http://blog.stevenlevithan.com/archives/faster-trim-javascript
23
String.prototype.trim = function () {
24
var c
25
for(var i = 0; i < this.length; i++){
26
c = this.charCodeAt(i)
27
if([32, 10, 13, 9, 12, 11, 160, 5760, 6158, 8192, 8193, 8194,
28
8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8232,
29
8233, 8239, 8287, 12288, 65279].indexOf(c) > -1){
30
continue
31
}else{break}
32
}
33
for(var j = this.length - 1; j >= i; j--){
34
c = this.charCodeAt(j)
36
8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8232,
37
8233, 8239, 8287, 12288, 65279].indexOf(c) > -1){
38
continue
39
}else{break}
40
}
41
return this.substring(i, j + 1);
42
}
45
// Convenience method for browsers which do not have a native trimLeft
46
// (which is a nonstandard extension in Firefox and Chrome)
47
String.prototype.trimLeft = function () {
48
var c
49
for(var i = 0; i < this.length; i++){
50
c = this.charCodeAt(i)
52
8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8232,
53
8233, 8239, 8287, 12288, 65279].indexOf(c) > -1){
54
continue
55
}else{break}
56
}
57
return this.substring(i)
61
String.prototype.trimRight = function () {
62
// Convenience method for browsers which do not have a native trimRight
63
// (which is a nonstandard extension in Firefox and Chrome)
64
var c
65
for(var j = this.length - 1; j >= 0; j--){
66
c = this.charCodeAt(j)
67
if([32, 10, 13, 9, 12, 11, 160, 5760, 6158, 8192, 8193, 8194,
68
8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8232,
69
8233, 8239, 8287, 12288, 65279].indexOf(c) > -1){
70
continue
71
}else{break}
72
}
73
return this.substring(0, j + 1)
91
if($.start === null || $.start === _b_.None){$.start = 0}
92
else if($.start < 0){
93
$.start += $.self.length
94
$.start = Math.max(0, $.start)
95
}
96
if($.end === null || $.end === _b_.None){$.end = $.self.length}
97
else if($.end < 0){
98
$.end += $.self.length
99
$.end = Math.max(0, $.end)
100
}
102
if(! isinstance($.start, _b_.int) || ! isinstance($.end, _b_.int)){
103
throw _b_.TypeError.$factory("slice indices must be integers " +
104
"or None or have an __index__ method")
105
}
122
if(!(typeof other === "string")){
123
try{return getattr(other, "__radd__")(self)}
124
catch(err){
125
throw _b_.TypeError.$factory("Can't convert " +
131
str.__contains__ = function(self, item){
132
if(!(typeof item == "string")){
133
throw _b_.TypeError.$factory("'in <string>' requires " +
134
"string as left operand, not " + item.__class__)
135
}
137
if(nbcar == 0) {return true} // a string contains the empty string
138
if(self.length == 0){return nbcar == 0}
139
for(var i = 0, len = self.length; i < len; i++){
140
if(self.substr(i, nbcar) == item){return true}
149
// __dir__must be assigned explicitely because attribute resolution for
150
// builtin classes doesn't use __mro__
154
if(other === undefined){ // compare object "self" to class "str"
155
return self === str
165
if(fmt.type && fmt.type != "s"){
166
throw _b_.ValueError.$factory("Unknown format code '" + fmt.type +
174
if(fmt.sign !== undefined){
175
throw _b_.ValueError.$factory(
176
"Sign not allowed in string format specifier")
186
if(arg < 0) {pos += self.length}
187
if(pos >= 0 && pos < self.length){return self.charAt(pos)}
188
throw _b_.IndexError.$factory("string index out of range")
189
}
190
if(isinstance(arg, slice)) {
191
var s = _b_.slice.$conv_for_seq(arg, self.length),
192
start = s.start,
193
stop = s.stop,
194
step = s.step
195
var res = "",
197
if(step > 0){
198
if(stop <= start){return ""}
199
for(var i = start; i < stop; i += step){res += self.charAt(i)}
201
if(stop >= start){return ''}
202
for(var i = start; i > stop; i += step){res += self.charAt(i)}
210
var prefix = 2,
211
suffix = 3,
212
mask = (2 ** 32 - 1)
213
function fnv(p){
214
if(p.length == 0){
215
return 0
216
}
218
var x = prefix
219
x = (x ^ (p.charCodeAt(0) << 7)) & mask
220
for(var i = 0, len = p.length; i < len; i++){
221
x = ((1000003 * x) ^ p.charCodeAt(i)) & mask
222
}
223
x = (x ^ p.length) & mask
224
x = (x ^ suffix) & mask
282
// left adjusted
283
return s + get_char_array(padding - s.length, flags.pad_char)
284
}
285
}
286
294
if(val.__class__ === $B.long_int){
295
s = $B.long_int.to_base(val, 10)
296
}else{
297
s = val.toString()
299
if(s[0] === "-"){
300
return "-" + get_char_array(precision - s.length + 1, "0") + s.slice(1)
311
if(val === Infinity){
312
val = "inf"
313
}else if(val === -Infinity){
314
val = "-inf"
315
}else{
316
val = "nan"
338
var str_format = function(val, flags) {
339
// string format supports left and right padding
340
flags.pad_char = " " // even if 0 padding is defined, don't use it
346
if(val.__class__ === $B.long_int){
347
val = $B.long_int.to_base(val, 10)
348
}else{
349
val = parseInt(val)
367
var repr_format = function(val, flags) {
368
flags.pad_char = " " // even if 0 padding is defined, don't use it
369
return format_padding(repr(val), flags)
370
}
372
var ascii_format = function(val, flags) {
373
flags.pad_char = " " // even if 0 padding is defined, don't use it
374
return format_padding(ascii(val), flags)
375
}
387
flags.precision = parseInt(flags.precision, 10)
388
validate_precision(flags.precision)
389
}
390
return parseFloat(val)
391
}
394
var trailing_zeros = /(.*?)(0+)([eE].*)/,
395
leading_zeros = /\.(0*)/,
396
trailing_dot = /\.$/
398
var validate_precision = function(precision) {
399
// force precision to limits of javascript
404
var floating_point_format = function(val, upper, flags){
405
val = _float_helper(val, flags),
406
v = val.toString(),
407
v_len = v.length,
408
dot_idx = v.indexOf('.')
409
if(dot_idx < 0){dot_idx = v_len}
410
if(val < 1 && val > -1){
411
var zeros = leading_zeros.exec(v),
412
numzeros
413
if(zeros){
418
if(numzeros >= 4){
419
val = format_sign(val, flags) + format_float_precision(val, upper,
420
flags, _floating_g_exp_helper)
421
if(!flags.alternate){
434
return format_padding(format_sign(val, flags) +
435
format_float_precision(val, upper, flags,
436
function(val, precision) {
437
return val.toFixed(min(precision, v_len - dot_idx) +
438
numzeros)
439
}),
440
flags
441
)
442
}
443
444
if(dot_idx > flags.precision){
445
val = format_sign(val, flags) + format_float_precision(val, upper,
446
flags, _floating_g_exp_helper)
447
if(! flags.alternate){
459
return format_padding(format_sign(val, flags) +
460
format_float_precision(val, upper, flags,
461
function(val, precision) {
462
if(!flags.decimal_point){
463
precision = min(v_len - 1, 6)
464
}else if (precision > v_len){
465
if(! flags.alternate){
466
precision = v_len
467
}
469
if(precision < dot_idx){
470
precision = dot_idx
471
}
472
return val.toFixed(precision - dot_idx)
473
}),
474
flags
475
)
478
var _floating_g_exp_helper = function(val, precision, flags, upper){
479
if(precision){--precision}
482
var e_idx = val.lastIndexOf("e")
483
if(e_idx > val.length - 4){
484
val = val.substring(0, e_idx + 2) + "0" + val.substring(e_idx + 2)
487
return val
488
}
489
490
// fF
491
var floating_point_decimal_format = function(val, upper, flags) {
492
val = _float_helper(val, flags)
493
return format_padding(format_sign(val, flags) +
494
format_float_precision(val, upper, flags,
495
function(val, precision, flags) {
496
val = val.toFixed(precision)
497
if(precision === 0 && flags.alternate){
498
val += '.'
499
}
500
return val
501
}),
502
flags
503
)
504
}
505
506
var _floating_exp_helper = function(val, precision, flags, upper) {
507
val = val.toExponential(precision)
508
// pad exponent to two digits
521
return format_padding(format_sign(val, flags) +
522
format_float_precision(val, upper, flags, _floating_exp_helper), flags)
548
if(flags.alternate){
549
if(ret.charAt(0) === "-"){
550
if(upper){ret = "-0X" + ret.slice(1)}
551
else{ret = "-0x" + ret.slice(1)}
552
}else{
553
if(upper){ret = "0X" + ret}
554
else{ret = "0x" + ret}
564
if(val.__class__ === $B.long_int){
565
ret = $B.long_int.to_base(8)
566
}else{
567
ret = parseInt(val)
568
ret = ret.toString(8)
584
if(flags.alternate){
585
if(ret.charAt(0) === "-"){ret = "-0o" + ret.slice(1)}
586
else{ret = "0o" + ret}
591
var single_char_format = function(val, flags){
592
if(isinstance(val, str) && val.length == 1) return val
593
try{
601
var num_flag = function(c, flags){
602
if(c === "0" && ! flags.padding && ! flags.decimal_point && ! flags.left){
603
flags.pad_char = "0"
609
flags.precision = (flags.precision || "") + c
610
}
611
}
612
613
var decimal_point_flag = function(val, flags) {
615
// can only have one decimal point
616
throw new UnsupportedChar()
617
}
618
flags.decimal_point = true
619
}
620
621
var neg_flag = function(val, flags){
622
flags.pad_char = " " // overrides '0' flag
639
"s": str_format,
640
"d": num_format,
641
"i": num_format,
642
"u": num_format,
643
"o": octal_format,
644
"r": repr_format,
645
"a": ascii_format,
646
"g": function(val, flags){
647
return floating_point_format(val, false, flags)
648
},
649
"G": function(val, flags){return floating_point_format(val, true, flags)},
650
"f": function(val, flags){
651
return floating_point_decimal_format(val, false, flags)
652
},
653
"F": function(val, flags){
654
return floating_point_decimal_format(val, true, flags)
655
},
656
"e": function(val, flags){
657
return floating_point_exponential_format(val, false, flags)
658
},
659
"E": function(val, flags){
660
return floating_point_exponential_format(val, true, flags)
661
},
662
"x": function(val, flags){return signed_hex_format(val, false, flags)},
663
"X": function(val, flags){return signed_hex_format(val, true, flags)},
664
"c": single_char_format,
665
"0": function(val, flags){return num_flag("0", flags)},
666
"1": function(val, flags){return num_flag("1", flags)},
667
"2": function(val, flags){return num_flag("2", flags)},
668
"3": function(val, flags){return num_flag("3", flags)},
669
"4": function(val, flags){return num_flag("4", flags)},
670
"5": function(val, flags){return num_flag("5", flags)},
671
"6": function(val, flags){return num_flag("6", flags)},
672
"7": function(val, flags){return num_flag("7", flags)},
673
"8": function(val, flags){return num_flag("8", flags)},
674
"9": function(val, flags){return num_flag("9", flags)},
675
"-": neg_flag,
676
" ": space_flag,
677
"+": sign_flag,
678
".": decimal_point_flag,
679
"#": alternate_flag
680
}
681
682
// exception thrown when an unsupported char is encountered in legacy format
729
if(self === undefined){
730
throw _b_.TypeError.$factory(
731
"not enough arguments for format string")
758
throw _b_.ValueError.$factory(
759
"unsupported format character '" + invalid_char +
760
"' (0x" + invalid_char.charCodeAt(0).toString(16) +
761
") at index " + newpos)
762
}else if(err.name === "NotANumber"){
763
var try_char = s[newpos],
764
cls = self.__class__
765
if(!cls){
766
if(typeof(self) === "string"){
767
cls = "str"
768
}else{
774
throw _b_.TypeError.$factory("%" + try_char +
775
" format: a number is required, not " + cls)
776
}else{
808
}while(pos < length)
809
810
if(argpos !== null){
811
if(args.length > argpos){
812
throw _b_.TypeError.$factory(
813
"not enough arguments for format string")
814
}else if(args.length < argpos){
815
throw _b_.TypeError.$factory(
816
"not all arguments converted during string formatting")
818
}else if(nbph == 0){
819
throw _b_.TypeError.$factory(
820
"not all arguments converted during string formatting")
828
var $ = $B.args("__mul__", 2, {self: null, other: null},
829
["self", "other"], arguments, {}, null, null)
830
if(! isinstance($.other, _b_.int)){throw _b_.TypeError.$factory(
831
"Can't multiply sequence by non-int of type '" +
843
res = self.replace(/\\/g, "\\\\")
844
// special cases
845
res = res.replace(new RegExp("\u0007", "g"), "\\x07").
846
replace(new RegExp("\b", "g"), "\\x08").
847
replace(new RegExp("\f", "g"), "\\x0c").
848
replace(new RegExp("\n", "g"), "\\n").
849
replace(new RegExp("\r", "g"), "\\r").
850
replace(new RegExp("\t", "g"), "\\t")
853
if(res.search('"') == -1 && res.search("'") == -1){
854
return "'" + res + "'"
855
}else if(self.search('"') == -1){
856
return '"' + res + '"'
857
}
858
var qesc = new RegExp("'", "g") // to escape single quote
859
res = "'" + res.replace(qesc, "\\'") + "'"
863
str.__setitem__ = function(self, attr, value){
864
throw _b_.TypeError.$factory(
865
"'str' object does not support item assignment")
867
var combining = []
868
for(var cp = 0x300; cp <= 0x36F; cp++){
869
combining.push(String.fromCharCode(cp))
870
}
871
var combining_re = new RegExp("(" + combining.join("|") + ")")
883
$comp_func += "" // source code
884
var $comps = {">": "gt", ">=": "ge", "<": "lt", "<=": "le"}
893
var $notimplemented = function(self, other){
894
throw NotImplementedError.$factory(
895
"OPERATOR not implemented for class str")
898
str.capitalize = function(self){
899
var $ = $B.args("capitalize", 1, {self}, ["self"],
900
arguments, {}, null, null)
901
if(self.length == 0){return ""}
902
return self.charAt(0).toUpperCase() + self.substr(1)
903
}
904
905
str.casefold = function(self){
906
var $ = $B.args("casefold", 1, {self}, ["self"],
907
arguments, {}, null, null),
908
res = "",
909
char,
910
cf
911
for(var i = 0, len = self.length; i < len; i++){
912
char = self.charCodeAt(i)
913
cf = $B.unicode_casefold[char]
914
if(cf){
915
cf.forEach(function(cp){
916
res += String.fromCharCode(cp)
917
})
918
}else{
919
res += self.charAt(i).toLowerCase()
920
}
921
}
922
return res
923
}
925
str.center = function(){
926
var $ = $B.args("center", 3, {self: null, width: null, fillchar: null},
927
["self", "width", "fillchar"],
928
arguments, {fillchar:" "}, null, null),
929
self = $.self
941
var $ = $B.args("count", 4, {self:null, sub:null, start:null, stop:null},
942
["self", "sub", "start", "stop"], arguments, {start:null, stop:null},
950
if($.stop !== null){_slice = _b_.slice.$factory($.start, $.stop)}
951
else{_slice = _b_.slice.$factory($.start, $.self.length)}
956
if($.sub.length == 0){
957
if($.start == $.self.length){return 1}
958
else if(substr.length == 0){return 0}
959
return substr.length + 1
961
var n = 0,
962
pos = 0
963
while(pos < substr.length){
964
pos = substr.indexOf($.sub, pos)
965
if(pos >= 0){n++; pos += $.sub.length}
966
else{break}
971
str.encode = function(){
972
var $ = $B.args("encode", 3, {self: null, encoding: null, errors: null},
973
["self", "encoding", "errors"], arguments,
974
{encoding: "utf-8", errors: "strict"}, null, null)
975
if($.encoding == "rot13" || $.encoding == "rot_13"){
980
if(("a" <= char && char <= "m") || ("A" <= char && char <= "M")){
981
res += String.fromCharCode(String.charCodeAt(char) + 13)
982
}else if(("m" < char && char <= "z") ||
983
("M" < char && char <= "Z")){
984
res += String.fromCharCode(String.charCodeAt(char) - 13)
993
// Return True if the string ends with the specified suffix, otherwise
994
// return False. suffix can also be a tuple of suffixes to look for.
995
// With optional start, test beginning at that position. With optional
999
["self", "suffix", "start", "end"],
1000
arguments, {start: 0, end: null}, null, null)
1007
var s = $.self.substring($.start, $.end)
1008
for(var i = 0, len = suffixes.length; i < len; i++){
1012
if(suffix.length <= s.length &&
1013
s.substr(s.length - suffix.length) == suffix){return true}
1019
var $ = $B.args("expandtabs", 2, {self: null, tabsize: null},
1020
["self", "tabsize"], arguments, {tabsize: 8}, null, null)
1021
var s = $B.$GetInt($.tabsize),
1022
col = 0,
1023
pos = 0,
1024
res = ""
1025
if(s == 1){return self.replace(/\t/g," ")}
1026
while(pos < self.length){
1034
res += car
1035
col = 0
1036
break
1037
default:
1038
res += car
1039
col++
1040
break
1041
}
1042
pos++
1043
}
1049
// Return the lowest index in the string where substring sub is found,
1050
// such that sub is contained in the slice s[start:end]. Optional
1051
// arguments start and end are interpreted as in slice notation.
1054
{self: null, sub: null, start: null, end: null},
1055
["self", "sub", "start", "end"],
1056
arguments, {start: 0, end: null}, null, null)
1060
if(!isinstance($.start, _b_.int)||!isinstance($.end, _b_.int)){
1061
throw _b_.TypeError.$factory("slice indices must be " +
1062
"integers or None or have an __index__ method")}
1063
// Can't use string.substring(start, end) because if end < start,
1064
// Javascript transforms it into substring(end, start)...
1065
var s = ""
1066
for(var i = $.start; i < $.end; i++){
1067
s += $.self.charAt(i)
1068
}
1070
if($.sub.length == 0 && $.start == $.self.length){return $.self.length}
1071
if(s.length + $.sub.length == 0){return -1}
1073
var last_search = s.length - $.sub.length
1074
for(var i = 0; i <= last_search; i++){
1075
if(s.substr(i, $.sub.length) == $.sub){return $.start + i}
1086
// a.x[z]!r:...
1087
// the object has attributes :
1088
// - name : "a"
1089
// - name_ext : [".x", "[z]"]
1090
// - conv : r
1091
// - spec : rest of string after :
1099
// No : in the string : it only contains a name
1100
name = fmt_string
1101
}else{
1102
// name is before the first ":"
1103
// spec (the format specification) is after
1104
name = elts[0]
1108
var elts = name.split("!")
1109
if(elts.length > 1){
1110
name = elts[0]
1111
conv = elts[1] // conversion flag
1115
// "name' may be a subscription or attribute
1116
// Put these "extensions" in the list "name_ext"
1117
function name_repl(match){
1118
name_ext.push(match)
1120
}
1121
var name_ext_re = /\.[_a-zA-Z][_a-zA-Z0-9]*|\[[_a-zA-Z][_a-zA-Z0-9]*\]|\[[0-9]+\]/g
1122
name = name.replace(name_ext_re, name_repl)
1123
}
1130
// Parse self to detect formatting instructions
1131
// Create a list "parts" made of sections of the string :
1132
// - elements of even rank are literal text
1133
// - elements of odd rank are "format objects", built from the
1134
// format strings in self (of the form {...})
1145
text += "{"
1146
pos += 2
1147
}else if(car == "}" && self.charAt(pos + 1) == "}"){
1154
// Store current literal text
1155
parts.push(text)
1156
1157
// Search the end of the format string, ie the } closing the
1158
// opening {. Since the string can contain other pairs {} for
1159
// nested formatting, an integer nb is incremented for each { and
1160
// decremented for each } ; the end of the format string is
1161
// reached when nb == 0
1162
var end = pos + 1,
1163
nb = 1
1164
while(end < _len){
1165
if(self.charAt(end) == "{"){nb++; end++}
1166
else if(self.charAt(end) == "}"){
1167
nb--; end++
1168
if(nb == 0){
1173
var fmt_obj = $B.parse_format(fmt_string)
1174
fmt_obj.raw_name = fmt_obj.name
1175
fmt_obj.raw_spec = fmt_obj.spec
1210
return parts
1211
}
1212
1213
str.format = function(self) {
1214
var $ = $B.args("format", 1, {self: null}, ["self"],
1215
arguments, {}, "$args", "$kw")
1216
1217
var parts = $B.split_format($.self)
1218
1229
1230
if(fmt.spec !== undefined){
1231
// "spec" may contain "nested replacement fields"
1232
// In this case, evaluate them using the positional
1233
// or keyword arguments passed to format()
1234
function replace_nested(name, key){
1235
if(/\d+/.exec(key)){
1236
// If key is numeric, search in positional
1237
// arguments
1238
return _b_.tuple.__getitem__($.$args,
1239
parseInt(key))
1240
}else{
1241
// Else try in keyword arguments
1242
return _b_.dict.__getitem__($.$kw, key)
1243
}
1244
}
1245
fmt.spec = fmt.spec.replace(/\{(.*?)\}/g,
1246
replace_nested)
1247
}
1249
// Numerical reference : use positional arguments
1250
var pos = parseInt(fmt.name),
1260
// Attribute
1261
value = _b_.getattr(value, ext.substr(1))
1262
}else{
1263
// Subscription
1266
if(key.charAt(0).search(/\d/) > -1){key = parseInt(key)}
1267
value = _b_.getattr(value, "__getitem__")(key)
1271
// If the conversion flag is set, first call a function to convert
1272
// the value
1273
if(fmt.conv == "a"){value = _b_.ascii(value)}
1274
else if(fmt.conv == "r"){value = _b_.repr(value)}
1275
else if(fmt.conv == "s"){value = _b_.str.$factory(value)}
1289
throw NotImplementedError.$factory(
1290
"function format_map not implemented yet")
1301
/* Return true if the string is empty or all characters in the string are
1302
ASCII, false otherwise. ASCII characters have code points in the range
1303
U+0000-U+007F. */
1304
for(var i = 0, len = self.length; i < len; i++){
1305
if(self.charCodeAt(i) > 127){return false}
1306
}
1307
return true
1308
}
1309
1310
str.isalnum = function(self){
1311
/* Return true if all characters in the string are alphanumeric and there
1312
is at least one character, false otherwise. A character c is alphanumeric
1313
if one of the following returns True: c.isalpha(), c.isdecimal(),
1314
c.isdigit(), or c.isnumeric(). */
1315
var $ = $B.args("isalnum", 1, {self: null}, ["self"],
1316
arguments, {}, null, null),
1317
char
1318
for(var i = 0, len = self.length; i < len; i++){
1319
char = self.charCodeAt(i)
1320
if(unicode_tables.Ll[char] ||
1321
unicode_tables.Lu[char] ||
1322
unicode_tables.Lm[char] ||
1323
unicode_tables.Lt[char] ||
1324
unicode_tables.Lo[char] ||
1325
unicode_tables.Nd[char] ||
1326
unicode_tables.digits[char] ||
1327
unicode_tables.numeric[char]){
1328
continue
1329
}
1330
return false
1331
}
1332
return true
1333
}
1334
1335
str.isalpha = function(self){
1336
/* Return true if all characters in the string are alphabetic and there is
1337
at least one character, false otherwise. Alphabetic characters are those
1338
characters defined in the Unicode character database as "Letter", i.e.,
1339
those with general category property being one of "Lm", "Lt", "Lu", "Ll",
1340
or "Lo". */
1341
var $ = $B.args("isalpha", 1, {self: null}, ["self"],
1342
arguments, {}, null, null),
1343
char
1344
for(var i = 0, len = self.length; i < len; i++){
1345
char = self.charCodeAt(i)
1346
if(unicode_tables.Ll[char] ||
1347
unicode_tables.Lu[char] ||
1348
unicode_tables.Lm[char] ||
1349
unicode_tables.Lt[char] ||
1350
unicode_tables.Lo[char]){
1351
continue
1352
}
1353
return false
1354
}
1355
return true
1356
}
1357
1358
str.isdecimal = function(self){
1359
/* Return true if all characters in the string are decimal characters and
1360
there is at least one character, false otherwise. Decimal characters are
1361
those that can be used to form numbers in base 10, e.g. U+0660,
1362
ARABIC-INDIC DIGIT ZERO. Formally a decimal character is a character in
1363
the Unicode General Category "Nd". */
1364
var $ = $B.args("isdecimal", 1, {self: null}, ["self"],
1365
arguments, {}, null, null),
1366
char
1367
for(var i = 0, len = self.length; i < len; i++){
1368
char = self.charCodeAt(i)
1369
if(! unicode_tables.Nd[char]){
1370
return false
1371
}
1372
}
1373
return self.length > 0
1374
}
1375
1376
str.isdigit = function(self){
1377
/* Return true if all characters in the string are digits and there is at
1378
least one character, false otherwise. */
1379
var $ = $B.args("isdigit", 1, {self: null}, ["self"],
1380
arguments, {}, null, null),
1381
char
1382
for(var i = 0, len = self.length; i < len; i++){
1383
char = self.charCodeAt(i)
1384
if(! unicode_tables.digits[char]){
1385
return false
1386
}
1387
}
1388
return self.length > 0
1389
}
1390
1391
str.isidentifier = function(self){
1392
/* Return true if the string is a valid identifier according to the
1393
language definition. */
1394
var $ = $B.args("isidentifier", 1, {self: null}, ["self"],
1395
arguments, {}, null, null),
1396
char
1397
if(self.length == 0){return false}
1398
else if(unicode_tables.XID_Start[self.charCodeAt(0)] === undefined){
1399
return false
1400
}else{
1401
for(var i = 1, len = self.length; i < len; i++){
1402
if(unicode_tables.XID_Continue[self.charCodeAt(i)] === undefined){
1403
return false
1404
}
1405
}
1406
}
1407
return true
1408
}
1409
1410
str.islower = function(self){
1411
/* Return true if all cased characters 4 in the string are lowercase and
1412
there is at least one cased character, false otherwise. */
1413
var $ = $B.args("islower", 1, {self: null}, ["self"],
1414
arguments, {}, null, null),
1415
has_cased = false,
1416
char
1417
1418
for(var i = 0, len = self.length; i < len; i++){
1419
char = self.charCodeAt(i)
1420
if(unicode_tables.Ll[char]){has_cased = true; continue}
1421
else if(unicode_tables.Lu[char] || unicode_tables.Lt[char]){
1422
return false
1423
}
1424
}
1425
return has_cased
1426
}
1427
1428
str.isnumeric = function(self){
1429
/* Return true if all characters in the string are numeric characters, and
1430
there is at least one character, false otherwise. Numeric characters
1431
include digit characters, and all characters that have the Unicode numeric
1432
value property, e.g. U+2155, VULGAR FRACTION ONE FIFTH. Formally, numeric
1433
characters are those with the property value Numeric_Type=Digit,
1434
Numeric_Type=Decimal or Numeric_Type=Numeric.*/
1435
var $ = $B.args("isnumeric", 1, {self: null}, ["self"],
1436
arguments, {}, null, null)
1437
for(var i = 0, len = self.length; i < len; i++){
1438
if(! unicode_tables.numeric[self.charCodeAt(i)]){
1439
return false
1440
}
1441
}
1442
return self.length > 0
1443
}
1444
1445
var printable,
1446
printable_gc = ['Cc', 'Cf', 'Co', 'Cs','Zl', 'Zp', 'Zs']
1447
1448
str.isprintable = function(self){
1449
/* Return true if all characters in the string are printable or the string
1450
is empty, false otherwise. Nonprintable characters are those characters
1451
defined in the Unicode character database as "Other" or "Separator",
1452
excepting the ASCII space (0x20) which is considered printable. */
1453
1454
// Set printable if not set yet
1455
if(printable === undefined){
1456
for(var i = 0; i < printable_gc.length; i++){
1457
var table = unicode_tables[printable_gc[i]]
1458
for(var cp in table){
1459
printable[cp] = true
1460
}
1461
}
1462
printable[32] = true
1463
}
1464
1465
var $ = $B.args("isprintable", 1, {self: null}, ["self"],
1466
arguments, {}, null, null),
1467
char,
1468
flag
1469
for(var i = 0, len = self.length; i < len; i++){
1470
char = self.charCodeAt(i)
1471
if(! printable[char]){
1472
return false
1473
}
1474
}
1475
return true
1476
}
1477
1478
str.isspace = function(self){
1479
/* Return true if there are only whitespace characters in the string and
1480
there is at least one character, false otherwise.
1481
1482
A character is whitespace if in the Unicode character database, either its
1483
general category is Zs ("Separator, space"), or its bidirectional class is
1484
one of WS, B, or S.*/
1485
var $ = $B.args("isspace", 1, {self: null}, ["self"],
1486
arguments, {}, null, null),
1487
char
1488
for(var i = 0, len = self.length; i < len; i++){
1489
char = self.charCodeAt(i)
1490
if(! unicode_tables.Zs[char] &&
1491
$B.unicode_bidi_whitespace.indexOf(char) == -1){
1492
return false
1493
}
1494
}
1495
return self.length > 0
1496
}
1497
1498
str.istitle = function(self){
1499
/* Return true if the string is a titlecased string and there is at least
1500
one character, for example uppercase characters may only follow uncased
1501
characters and lowercase characters only cased ones. Return false
1502
otherwise. */
1503
var $ = $B.args("istitle", 1, {self: null}, ["self"],
1504
arguments, {}, null, null)
1505
return self.length > 0 && str.title(self) == self
1506
}
1507
1508
str.isupper = function(self){
1509
/* Return true if all cased characters 4 in the string are lowercase and
1510
there is at least one cased character, false otherwise. */
1511
var $ = $B.args("islower", 1, {self: null}, ["self"],
1512
arguments, {}, null, null),
1513
has_cased = false,
1514
char
1515
1516
for(var i = 0, len = self.length; i < len; i++){
1517
char = self.charCodeAt(i)
1518
if(unicode_tables.Lu[char]){has_cased = true; continue}
1519
else if(unicode_tables.Ll[char] || unicode_tables.Lt[char]){
1537
if(! isinstance(obj2, str)){throw _b_.TypeError.$factory(
1538
"sequence item " + count + ": expected str instance, " +
1552
var $ = $B.args("ljust", 3, {self: null, width: null, fillchar:null},
1553
["self", "width", "fillchar"],
1554
arguments, {fillchar: " "}, null, null)
1560
str.lower = function(self){
1561
var $ = $B.args("lower", 1, {self: null}, ["self"],
1562
arguments, {}, null, null)
1563
return self.toLowerCase()
1564
}
1565
1567
var $ = $B.args("lstrip", 2, {self: null, chars: null}, ["self", "chars"],
1568
arguments, {chars:_b_.None}, null, null)
1569
if($.chars === _b_.None){return $.self.trimLeft()}
1570
for(var i = 0; i < $.self.length; i++){
1571
if($.chars.indexOf($.self.charAt(i)) === -1){
1572
return $.self.substring(i)
1580
var $ = $B.args("maketrans", 3, {x: null, y: null, z: null},
1581
["x", "y", "z"], arguments, {y: null, z: null}, null, null)
1586
// If there is only one argument, it must be a dictionary mapping
1587
// Unicode ordinals (integers) or characters (strings of length 1) to
1588
// Unicode ordinals, strings (of arbitrary lengths) or None. Character
1590
if(! _b_.isinstance($.x, _b_.dict)){
1591
throw _b_.TypeError.$factory(
1592
"maketrans only argument must be a dict")
1595
for(var i = 0, len = items.length; i < len; i++){
1596
var k = items[i][0],
1597
v = items[i][1]
1598
if(! _b_.isinstance(k, _b_.int)){
1599
if(_b_.isinstance(k, _b_.str) && k.length == 1){
1600
k = _b_.ord(k)
1601
}else{throw _b_.TypeError.$factory("dictionary key " + k +
1604
if(v !== _b_.None && ! _b_.isinstance(v, [_b_.int, _b_.str])){
1605
throw _b_.TypeError.$factory("dictionary value " + v +
1613
// and in the resulting dictionary, each character in x will be mapped
1614
// to the character at the same position in y
1617
}else if($.x.length !== $.y.length){
1618
throw _b_.TypeError.$factory(
1619
"maketrans arguments must be strings or same length")
1625
if(! _b_.isinstance($.z, _b_.str)){
1626
throw _b_.TypeError.$factory(
1627
"maketrans third argument must be a string")
1649
var $ = $B.args("partition", 2, {self: null, sep: null}, ["self", "sep"],
1650
arguments, {}, null, null)
1655
return _b_.tuple.$factory([$.self.substring(0, i), $.sep,
1656
$.self.substring(i + $.sep.length)])
1657
}
1658
1659
function $re_escape(str){
1660
var specials = "[.*+?|()$^"
1661
for(var i = 0, len = specials.length; i < len; i++){
1662
var re = new RegExp("\\"+specials.charAt(i), "g")
1663
str = str.replace(re, "\\"+specials.charAt(i))
1664
}
1665
return str
1672
var $ = $B.args("replace", 4,
1673
{self: null, old: null, $$new: null, count: null},
1674
["self", "old", "$$new", "count"],
1675
arguments, {count: -1}, null, null),
1676
count = $.count,
1677
self = $.self,
1678
old = $.old,
1679
_new = $.$$new
1686
"' object cannot be interpreted as an integer")
1687
}else if(isinstance(count, _b_.float)){
1688
throw _b_.TypeError.$factory("integer argument expected, got float")
1689
}
1690
if(count == 0){return self}
1691
if(count.__class__ == $B.long_int){count = parseInt(count.value)}
1692
if(old == ""){
1693
if(_new == ""){return self}
1694
if(self == ""){return _new}
1695
var elts = self.split("")
1696
if(count > -1 && elts.length >= count){
1697
var rest = elts.slice(count).join("")
1698
return _new + elts.slice(0, count).join(_new) + rest
1699
}else{return _new + elts.join(_new) + _new}
1714
if(count < 0){count = res.length}
1715
while(count > 0){
1716
pos = res.indexOf(old, pos)
1717
if(pos < 0){break}
1718
res = res.substr(0, pos) + _new + res.substr(pos + old.length)
1719
pos = pos + _new.length
1720
count--
1726
// Return the highest index in the string where substring sub is found,
1727
// such that sub is contained within s[start:end]. Optional arguments
1729
if(arguments.length == 2 && typeof substr == "string"){
1730
return self.lastIndexOf(substr)
1731
}
1733
{self: null, sub: null, start: null, end: null},
1734
["self", "sub", "start", "end"],
1735
arguments, {start: 0, end: null}, null, null)
1747
for(var i = $.end - sublen; i >= $.start; i--){
1748
if($.self.substr(i, sublen) == $.sub){return i}
1755
var res = str.rfind.apply(null, arguments)
1756
if(res == -1){throw _b_.ValueError.$factory("substring not found")}
1761
var $ = $B.args("rjust",3,
1762
{self: null, width: null, fillchar: null},
1763
["self", "width", "fillchar"],
1764
arguments, {fillchar: " "}, null, null)
1772
var $ = $B.args("rpartition", 2, {self: null, sep: null}, ["self", "sep"],
1773
arguments, {}, null, null)
1777
var items = str.partition(self, sep).reverse()
1778
for(var i = 0; i < items.length; i++){
1779
items[i] = items[i].split("").reverse().join("")
1785
var $ = $B.args("rsplit", 3, {self: null, sep: null, maxsplit: null},
1786
["self", "sep", "maxsplit"], arguments,
1787
{sep: _b_.None, maxsplit: -1}, null, null),
1788
sep = $.sep
1791
var rev_str = reverse($.self),
1792
rev_sep = sep === _b_.None ? sep : reverse($.sep),
1803
str.rstrip = function(self, x){
1804
var $ = $B.args("rstrip", 2, {self: null, chars: null}, ["self", "chars"],
1805
arguments, {chars: _b_.None}, null, null)
1806
if($.chars === _b_.None){return $.self.trimRight()}
1808
if($.chars.indexOf($.self.charAt(j)) == -1){
1809
return $.self.substring(0, j + 1)
1816
var $ = $B.args("split", 3, {self: null, sep: null, maxsplit: null},
1817
["self", "sep", "maxsplit"], arguments,
1818
{sep: _b_.None, maxsplit: -1}, null, null),
1819
sep = $.sep,
1820
maxsplit = $.maxsplit,
1821
self = $.self,
1822
pos = 0
1823
if(maxsplit.__class__ === $B.long_int){maxsplit = parseInt(maxsplit.value)}
1824
if(sep == ""){throw _b_.ValueError.$factory("empty separator")}
1825
if(sep === _b_.None){
1827
while(pos < self.length && self.charAt(pos).search(/\s/) > -1){pos++}
1828
if(pos === self.length - 1){return [self]}
1829
var name = ""
1831
if(self.charAt(pos).search(/\s/) == -1){
1832
if(name == ""){name = self.charAt(pos)}
1833
else{name += self.charAt(pos)}
1853
var res = [],
1854
s = "",
1855
seplen = sep.length
1856
if(maxsplit == 0){return [self]}
1857
while(pos < self.length){
1858
if(self.substr(pos, seplen) == sep){
1878
["self", "keepends"], arguments, {keepends: false}, null, null)
1879
if(! _b_.isinstance($.keepends, [_b_.bool, _b_.int])){
1880
throw _b_.TypeError.$factory("integer argument expected, got " +
1887
start = pos,
1888
pos = 0,
1889
self = $.self
1890
while(pos < self.length){
1891
if(self.substr(pos, 2) == "\r\n"){
1892
res.push(self.substring(start, pos + 2))
1893
start = pos + 2
1895
}else if(self.charAt(pos) == "\r" || self.charAt(pos) == "\n"){
1896
res.push(self.substring(start, pos + 1))
1897
start = pos + 1
1898
pos = start
1899
}else{pos++}
1900
}
1901
var rest = self.substr(start)
1902
if(rest){res.push(rest)}
1903
return res
1904
}else{
1911
// Return True if string starts with the prefix, otherwise return False.
1912
// prefix can also be a tuple of prefixes to look for. With optional
1913
// start, test string beginning at that position. With optional end,
1915
var $ = $B.args("startswith", 4,
1916
{self: null, prefix: null, start: null, end: null},
1917
["self", "prefix", "start", "end"],
1918
arguments, {start: 0, end: null}, null, null)
1925
var s = $.self.substring($.start, $.end)
1926
for(var i = 0, len = prefixes.length; i < len; i++){
1937
var $ = $B.args("strip", 2, {self: null, chars: null}, ["self", "chars"],
1938
arguments, {chars: _b_.None}, null, null)
1939
if($.chars === _b_.None){return $.self.trim()}
1940
for(var i = 0; i < $.self.length; i++){
1941
if($.chars.indexOf($.self.charAt(i)) == -1){
1942
break
1945
for(var j = $.self.length - 1; j >= i; j--){
1946
if($.chars.indexOf($.self.charAt(j)) == -1){
1947
break
1953
str.swapcase = function(self){
1954
var $ = $B.args("swapcase", 1, {self}, ["self"],
1955
arguments, {}, null, null),
1956
res = "",
1957
char
1958
1959
for(var i = 0, len = self.length; i < len; i++){
1960
char = self.charCodeAt(i)
1961
if(unicode_tables.Ll[char]){
1962
res += self.charAt(i).toUpperCase()
1963
}else if(unicode_tables.Lu[char]){
1964
res += self.charAt(i).toLowerCase()
1965
}else{
1966
res += self.charAt(i)
1967
}
1968
}
1969
return res
1970
}
1971
1972
str.title = function(self){
1973
var $ = $B.args("title", 1, {self}, ["self"],
1974
arguments, {}, null, null),
1975
state,
1976
char,
1977
res = ""
1978
for(var i = 0, len = self.length; i < len; i++){
1979
char = self.charCodeAt(i)
1980
if(unicode_tables.Ll[char]){
1981
if(! state){
1982
res += self.charAt(i).toUpperCase()
1983
state = "word"
1984
}else{
1985
res += self.charAt(i)
1986
}
1987
}else if(unicode_tables.Lu[char] || unicode_tables.Lt[char]){
1988
res += state ? self.charAt(i).toLowerCase() : self.charAt(i)
1989
state = "word"
1990
}else{
1991
state = null
1992
res += self.charAt(i)
1993
}
1994
}
1995
return res
1996
}
1997
2000
getitem = $B.$getattr(table, "__getitem__")
2001
for(var i = 0, len = self.length; i < len; i++){
2002
try{
2003
var repl = getitem(self.charCodeAt(i))
2004
if(repl !== _b_.None){
2014
str.upper = function(self){
2015
var $ = $B.args("upper", 1, {self: null}, ["self"],
2016
arguments, {}, null, null)
2017
return self.toUpperCase()
2018
}
2019
2022
["self", "width"], arguments, {}, null, null)
2023
if($.width <= self.length){return self}
2025
case "+":
2026
case "-":
2027
return self.charAt(0) +
2028
"0".repeat($.width - self.length) + self.substr(1)
2036
if(arg === undefined){
2037
throw _b_.TypeError.$factory("str() argument is undefined")
2038
}
2049
// class or its subclasses, but the attribute __str__ of the
2050
// class metaclass (usually "type") or its subclasses (usually
2051
// "object")
2052
// The metaclass is the attribute __class__ of the class dictionary
2056
if(arg.__class__ && arg.__class__ === _b_.bytes &&
2057
encoding !== undefined){
2058
// str(bytes, encoding, errors) is equal to
2059
// bytes.decode(encoding, errors)
2060
// Arguments may be passed as keywords (cf. issue #1060)
2061
var $ = $B.args("str", 3, {arg: null, encoding: null, errors: null},
2062
["arg", "encoding", "errors"], arguments,
2063
{encoding: "utf-8", errors: "strict"}, null, null)
2064
return _b_.bytes.decode(arg, $.encoding, $.errors)
2066
var f = $B.$getattr(arg, "__str__", null)
2067
if(f === null ||
2068
// if not better than object.__str__, try __repr__
2069
(arg.__class__ && arg.__class__ !== _b_.object &&
2070
f.$infos && f.$infos.__func__ === _b_.object.__str__)){
2071
var f = $B.$getattr(arg, "__repr__")
2072
}
2077
if($B.debug > 1){console.log(err)}
2078
console.log("Warning - no method __str__ or __repr__, " +
2079
"default to toString", arg)
2086
if(cls === undefined){
2087
throw _b_.TypeError.$factory("str.__new__(): not enough arguments")
2111
var args = [],
2112
pos = 0
2113
if(arguments.length > 0){
2114
var args = [arguments[0].valueOf()],
2115
pos = 1
2116
for(var i = 1, len = arguments.length; i < len; i++){
2117
args[pos++] = arguments[i]
2133
// Function to parse the 2nd argument of format()
2134
$B.parse_format_spec = function(spec){
2137
var pos = 0,
2138
aligns = "<>=^",
2139
digits = "0123456789",
2140
types = "bcdeEfFgGnosxX%",
2142
if(align_pos != -1){
2143
if(spec.charAt(1) && aligns.indexOf(spec.charAt(1)) != -1){
2144
// If the second char is also an alignment specifier, the
2145
// first char is the fill value
2146
this.fill = spec.charAt(0)
2147
this.align = spec.charAt(1)
2148
pos = 2
2149
}else{
2150
// The first character defines alignment : fill defaults to ' '
2165
if(car == "+" || car == "-" || car == " "){
2166
this.sign = car
2167
pos++
2168
car = spec.charAt(pos)
2170
if(car == "#"){this.alternate = true; pos++; car = spec.charAt(pos)}
2171
if(car == "0"){
2180
while(car && digits.indexOf(car) > -1){
2181
if(this.width === undefined){this.width = car}
2182
else{this.width += car}
2183
pos++
2184
car = spec.charAt(pos)
2187
if(this.width === undefined && car == "{"){
2188
// Width is determined by a parameter
2189
var end_param_pos = spec.substr(pos).search("}")
2190
this.width = spec.substring(pos, end_param_pos)
2191
console.log("width", "[" + this.width + "]")
2192
pos += end_param_pos + 1
2193
}
2194
if(car == ","){this.comma = true; pos++; car = spec.charAt(pos)}
2195
if(car == "."){
2196
if(digits.indexOf(spec.charAt(pos + 1)) == -1){
2197
throw _b_.ValueError.$factory(
2198
"Missing precision in format spec")
2200
this.precision = spec.charAt(pos + 1)
2201
pos += 2
2202
car = spec.charAt(pos)
2203
while(car && digits.indexOf(car) > -1){
2210
if(car && types.indexOf(car) > -1){
2211
this.type = car
2212
pos++
2213
car = spec.charAt(pos)
2214
}
2215
if(pos !== spec.length){
2221
return (this.fill === undefined ? "" : _b_.str.$factory(this.fill)) +
2222
(this.align || "") +
2223
(this.sign || "") +
2224
(this.alternate ? "#" : "") +
2225
(this.sign_aware ? "0" : "") +
2226
(this.width || "") +
2227
(this.comma ? "," : "") +
2228
(this.precision ? "." + this.precision : "") +
2229
(this.type || "")
2234
if(fmt.width && s.length < fmt.width){
2235
var fill = fmt.fill || " ",
2236
align = fmt.align || "<",
2237
missing = fmt.width - s.length
2239
case "<":
2240
return s + fill.repeat(missing)
2241
case ">":
2242
return fill.repeat(missing) + s
2243
case "=":
2244
if("+-".indexOf(s.charAt(0)) > -1){
2245
return s.charAt(0) + fill.repeat(missing) + s.substr(1)
2249
case "^":
2250
var left = parseInt(missing / 2)
2251
return fill.repeat(left) + s + fill.repeat(missing - left)
2264
$B.parse_fstring = function(string){
2265
// Parse a f-string
2266
var elts = [],
2267
pos = 0,
2291
}else{
2292
throw Error(" f-string: single '}' is not allowed")
2293
}
2294
}else{
2316
current += car
2317
i += 2
2318
}else{
2319
throw Error(" f-string: single '}' is not allowed")
2320
}
2321
}else{
2322
current += car
2323
i++
2324
}
2325
}
2327
}else if(ctype == "debug"){
2328
// after the equal sign, whitespace are ignored and the only
2329
// valid characters are } and :
2330
while(string.charAt(i) == " "){i++}
2331
if(string.charAt(i) == "}"){
2332
// end of debug expression
2333
elts.push(current)
2334
ctype = null
2335
current = ""
2336
pos = i + 1
2337
}
2338
}else{
2339
// End of expression is the } matching the opening {
2340
// There may be nested braces
2341
var i = pos,
2342
nb_braces = 1,
2364
// backslash is not allowed in expressions
2365
throw Error("f-string expression part cannot include a" +
2366
" backslash")
2373
throw Error("f-string: invalid conversion character:" +
2374
" expected 's', 'r', or 'a'")
2375
}else{
2389
if(string.substr(i, 3) == '"""'){
2390
var end = string.indexOf('"""', i + 3)
2391
if(end == -1){
2392
throw Error("f-string: unterminated string")
2393
}else{
2394
var trs = string.substring(i, end + 3)
2395
trs = trs.replace("\n", "\\n\\")
2400
var end = string.indexOf('"', i + 1)
2401
if(end == -1){
2402
throw Error("f-string: unterminated string")
2403
}else{
2404
current.expression += string.substring(i, end + 1)
2405
i = end + 1
2412
}else if(car == "="){
2413
// might be a "debug expression", eg f"{x=}"
2414
var ce = current.expression
2415
if(ce.length == 0 ||
2417
current.expression += car
2418
i++
2419
}else{
2420
// add debug string
2421
tail = car
2422
while(string.charAt(i + 1).match(/\s/)){
2423
tail += string.charAt(i + 1)
2424
i++
2425
}
2426
elts.push(current.expression + tail)
2427
// remove trailing whitespace from expression
2428
while(ce.match(/\s$/)){
2429
ce = ce.substr(0, ce.length - 1)
2430
}
2431
current.expression = ce
2432
ctype = "debug"
2433
i++
2434
}