Permalink
Jan 14, 2015
Jan 14, 2015
Jan 1, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 1, 2015
Jan 1, 2015
Newer
100644
1703 lines (1526 sloc)
53.6 KB
13
function normalize_start_end($){
14
if($.start===null||$.start===_b_.None){$.start = 0}
15
else if($.start<0){$.start += $.self.length; $.start=Math.max(0, $.start)}
16
if($.end===null||$.end===_b_.None){$.end = $.self.length}
17
else if($.end<0){$.end += $.self.length; $.end=Math.max(0, $.end)}
18
19
if(!isinstance($.start,_b_.int)||!isinstance($.end,_b_.int)){
20
throw _b_.TypeError(
21
"slice indices must be integers or None or have an __index__ method")}
22
23
}
24
25
function norm_pos(pos, s, default_if_None){
26
// For a string s, return a position >=0 is pos is negative or None
27
if(pos>=0){return pos}
28
else if(pos===_b_.None||pos===null){return default_if_None}
29
else{pos+=s.lengh;return Math.max(0, pos)}
30
}
31
32
$StringDict.__add__ = function(self,other){
33
if(!(typeof other==="string")){
34
try{return getattr(other,'__radd__')(self)}
35
catch(err){throw _b_.TypeError(
36
"Can't convert "+$B.get_class(other).__name__+" to str implicitely")}
37
}
38
return self+other
39
}
40
41
$StringDict.__contains__ = function(self,item){
42
if(!(typeof item==="string")){throw _b_.TypeError(
43
"'in <string>' requires string as left operand, not "+item.__class__)}
44
var nbcar = item.length
45
if(nbcar==0) return true // a string contains the empty string
46
if(self.length==0) return nbcar==0
48
if(self.substr(i,nbcar)==item) return true
49
}
50
return false
51
}
52
53
$StringDict.__delitem__ = function(){
54
throw _b_.TypeError("'str' object doesn't support item deletion")
55
}
56
57
// __dir__must be assigned explicitely because attribute resolution for builtin
58
// classes doesn't use __mro__
59
$StringDict.__dir__ = $ObjectDict.__dir__
60
61
$StringDict.__eq__ = function(self,other){
62
if(other===undefined){ // compare object "self" to class "str"
63
return self===str
64
}
65
if (_b_.isinstance(other, _b_.str)) {
66
return other.valueOf() == self.valueOf()
67
}
71
function preformat(self, fmt){
72
if(fmt.empty){return _b_.str(self)}
73
if(fmt.type && fmt.type!='s'){
74
throw _b_.ValueError("Unknown format code '"+fmt.type+
75
"' for object of type 'str'")
76
}
77
return self
78
}
79
80
$StringDict.__format__ = function(self, format_spec) {
81
var fmt = new $B.parse_format_spec(format_spec)
82
// For strings, alignment default to left
83
fmt.align = fmt.align || '<'
84
return $B.format_width(preformat(self, fmt), fmt)
85
}
86
87
$StringDict.__getitem__ = function(self,arg){
88
if(isinstance(arg,_b_.int)){
89
var pos = arg
90
if(arg<0) pos+=self.length
91
if(pos>=0 && pos<self.length) return self.charAt(pos)
92
throw _b_.IndexError('string index out of range')
93
}
94
if(isinstance(arg,slice)) {
95
var step = arg.step===None ? 1 : arg.step
96
if(step>0){
97
var start = arg.start===None ? 0 : arg.start
98
var stop = arg.stop===None ? getattr(self,'__len__')() : arg.stop
99
}else{
100
var start = arg.start===None ? getattr(self,'__len__')()-1 : arg.start
105
var res = '',i=null
106
if(step>0){
107
if(stop<=start) return ''
108
for(var i=start;i<stop;i+=step) res += self.charAt(i)
109
} else {
110
if(stop>=start) return ''
112
}
113
return res
114
}
115
if(isinstance(arg,bool)) return self.__getitem__(_b_.int(arg))
120
if (self === undefined) {
121
return $StringDict.__hashvalue__ || $B.$py_next_hash-- // for hash of string type (not instance of string)
122
}
123
124
//http://stackoverflow.com/questions/2909106/python-whats-a-correct-and-good-way-to-implement-hash
125
// this implementation for strings maybe good enough for us..
126
127
var hash=1;
129
hash=(101*hash + self.charCodeAt(i)) & 0xFFFFFFFF
130
}
131
132
return hash
133
}
134
135
$StringDict.__init__ = function(self,arg){
136
self.valueOf = function(){return arg}
137
self.toString = function(){return arg}
139
}
140
141
var $str_iterator = $B.$iterator_class('str_iterator')
142
$StringDict.__iter__ = function(self){
143
var items = self.split('') // list of all characters in string
144
return $B.$iterator(items,$str_iterator)
145
}
146
147
$StringDict.__len__ = function(self){return self.length}
148
151
var kwarg_key = new RegExp('([^\\)]*)\\)')
152
153
var NotANumber = function() {
154
this.name = 'NotANumber'
155
}
156
157
var number_check=function(s) {
158
if(!isinstance(s,[_b_.int,_b_.float])){
159
throw new NotANumber()
160
}
161
}
162
163
var get_char_array = function(size, char) {
164
if (size <= 0)
165
return ''
166
return new Array(size + 1).join(char)
167
}
168
169
var format_padding = function(s, flags, minus_one) {
170
var padding = flags.padding
171
if (!padding) { // undefined
172
return s
173
}
174
s = s.toString()
175
padding = parseInt(padding, 10)
176
if (minus_one) { // numeric formatting where sign goes in front of padding
177
padding -= 1
178
}
179
if (!flags.left) {
180
return get_char_array(padding - s.length, flags.pad_char) + s
181
} else {
182
// left adjusted
183
return s + get_char_array(padding - s.length, flags.pad_char)
184
}
185
}
186
187
var format_int_precision = function(val, flags) {
188
var precision = flags.precision
189
if (!precision) {
190
return val.toString()
191
}
192
precision = parseInt(precision, 10)
193
var s
194
if (val.__class__ === $B.LongInt.$dict) {
195
s=$B.LongInt.$dict.to_base(val, 10)
196
} else {
197
s=val.toString()
198
}
199
var sign = s[0]
200
if (s[0] === '-') {
201
return '-' + get_char_array(precision - s.length + 1, '0') + s.slice(1)
202
}
203
return get_char_array(precision - s.length, '0') + s
204
}
205
206
var format_float_precision = function(val, upper, flags, modifier) {
207
var precision = flags.precision
208
// val is a float
209
if (isFinite(val)) {
210
val = modifier(val, precision, flags, upper)
211
return val
212
}
213
if (val === Infinity) {
214
val = 'inf'
215
} else if (val === -Infinity) {
216
val = '-inf'
217
} else {
218
val = 'nan'
219
}
220
if (upper) {
221
return val.toUpperCase()
222
}
223
return val
225
}
226
227
var format_sign = function(val, flags) {
228
if (flags.sign) {
229
if (val >= 0) {
230
return "+"
232
} else if (flags.space) {
233
if (val >= 0) {
234
return " "
235
}
236
}
237
return ""
238
}
240
var str_format = function(val, flags) {
241
// string format supports left and right padding
242
flags.pad_char = " " // even if 0 padding is defined, don't use it
243
return format_padding(str(val), flags)
244
}
248
if (val.__class__ === $B.LongInt.$dict) {
249
val = $B.LongInt.$dict.to_base(val, 10)
250
} else {
251
val = parseInt(val)
252
}
253
254
var s = format_int_precision(val, flags)
255
if (flags.pad_char === '0') {
256
if (val < 0) {
257
s = s.substring(1)
258
return '-' + format_padding(s, flags, true)
259
}
260
var sign = format_sign(val, flags)
261
if (sign !== '') {
262
return sign + format_padding(s, flags, true)
263
}
264
}
265
266
return format_padding(format_sign(val, flags) + s, flags)
267
}
269
var repr_format = function(val, flags) {
270
flags.pad_char = " " // even if 0 padding is defined, don't use it
271
return format_padding(repr(val), flags)
272
}
274
var ascii_format = function(val, flags) {
275
flags.pad_char = " " // even if 0 padding is defined, don't use it
276
return format_padding(ascii(val), flags)
277
}
279
// converts to val to float and sets precision if missing
280
var _float_helper = function(val, flags) {
281
number_check(val)
282
if (!flags.precision) {
283
if (!flags.decimal_point) {
284
flags.precision = 6
285
} else {
286
flags.precision = 0
287
}
288
} else {
289
flags.precision = parseInt(flags.precision, 10)
290
validate_precision(flags.precision)
291
}
292
return parseFloat(val)
293
}
295
// used to capture and remove trailing zeroes
296
var trailing_zeros = /(.*?)(0+)([eE].*)/
297
var leading_zeros = /\.(0*)/
298
var trailing_dot = /\.$/
300
var validate_precision = function(precision) {
301
// force precision to limits of javascript
302
if (precision > 20) {
303
throw _b_.ValueError("precision too big")
304
}
305
}
306
307
// gG
308
var floating_point_format = function(val, upper, flags) {
309
val = _float_helper(val, flags)
310
var v = val.toString()
311
var v_len = v.length
312
var dot_idx = v.indexOf('.')
313
if (dot_idx < 0) {
314
dot_idx = v_len
315
}
316
if (val < 1 && val > -1) {
317
var zeros = leading_zeros.exec(v)
318
var numzeros
319
if (zeros) {
320
numzeros = zeros[1].length
321
} else {
322
numzeros = 0
323
}
324
if (numzeros >= 4) {
325
val = format_sign(val, flags) + format_float_precision(val, upper, flags, _floating_g_exp_helper)
326
if (!flags.alternate) {
327
var trl = trailing_zeros.exec(val)
328
if (trl) {
329
val = trl[1].replace(trailing_dot, '') + trl[3] // remove trailing
335
}
336
return format_padding(val, flags)
337
}
338
flags.precision += numzeros
339
return format_padding(format_sign(val, flags) + format_float_precision(val, upper, flags,
340
function(val, precision) {
341
val = val.toFixed(min(precision, v_len - dot_idx) + numzeros)
342
}), flags)
343
}
344
345
if (dot_idx > flags.precision) {
346
val = format_sign(val, flags) + format_float_precision(val, upper, flags, _floating_g_exp_helper)
347
if (!flags.alternate) {
348
var trl = trailing_zeros.exec(val)
349
if (trl) {
350
val = trl[1].replace(trailing_dot, '') + trl[3] // remove trailing
351
}
352
} else {
353
if (flags.precision <= 1) {
354
val = val[0] + '.' + val.substring(1)
355
}
356
}
357
return format_padding(val, flags)
358
}
359
return format_padding(format_sign(val, flags) + format_float_precision(val, upper, flags,
360
function(val, precision) {
361
if (!flags.decimal_point) {
362
precision = min(v_len - 1, 6)
363
} else if (precision > v_len) {
364
if (!flags.alternate) {
365
precision = v_len
367
}
368
if (precision < dot_idx) {
369
precision = dot_idx
370
}
371
return val.toFixed(precision - dot_idx)
372
}), flags)
373
}
375
var _floating_g_exp_helper = function(val, precision, flags, upper) {
376
if (precision) {
377
--precision
378
}
379
val = val.toExponential(precision)
380
// pad exponent to two digits
381
var e_idx = val.lastIndexOf('e')
382
if (e_idx > val.length - 4) {
383
val = val.substring(0, e_idx + 2) + '0' + val.substring(e_idx + 2)
384
}
385
if (upper) {
386
return val.toUpperCase()
387
}
388
return val
389
}
390
391
// fF
392
var floating_point_decimal_format = function(val, upper, flags) {
393
val = _float_helper(val, flags)
394
return format_padding(format_sign(val, flags) + format_float_precision(val, upper, flags,
395
function(val, precision, flags) {
396
val = val.toFixed(precision)
397
if (precision === 0 && flags.alternate) {
398
val += '.'
399
}
400
return val
401
}), flags)
402
}
403
404
var _floating_exp_helper = function(val, precision, flags, upper) {
405
val = val.toExponential(precision)
406
// pad exponent to two digits
407
var e_idx = val.lastIndexOf('e')
408
if (e_idx > val.length - 4) {
409
val = val.substring(0, e_idx + 2) + '0' + val.substring(e_idx + 2)
410
}
411
if (upper) {
412
return val.toUpperCase()
413
}
414
return val
415
}
416
417
// eE
418
var floating_point_exponential_format = function(val, upper, flags) {
419
val = _float_helper(val, flags)
420
421
return format_padding(format_sign(val, flags) + format_float_precision(val, upper, flags, _floating_exp_helper), flags)
422
}
423
424
var signed_hex_format = function(val, upper, flags) {
427
428
if (val.__class__ === $B.LongInt.$dict) {
429
ret=$B.LongInt.$dict.to_base(val, 16)
430
} else {
431
ret = parseInt(val)
432
ret = ret.toString(16)
433
}
434
ret = format_int_precision(ret, flags)
435
if (upper) {
436
ret = ret.toUpperCase()
437
}
438
if (flags.pad_char === '0') {
439
if (val < 0) {
440
ret = ret.substring(1)
441
ret = '-' + format_padding(ret, flags, true)
442
}
443
var sign = format_sign(val, flags)
444
if (sign !== '') {
445
ret = sign + format_padding(ret, flags, true)
447
}
448
449
if (flags.alternate) {
450
if (ret.charAt(0) === '-') {
451
if (upper) {
452
ret = "-0X" + ret.slice(1)
453
} else {
454
ret = "-0x" + ret.slice(1)
455
}
456
} else {
457
if (upper) {
458
ret = "0X" + ret
459
} else {
460
ret = "0x" + ret
461
}
462
}
463
}
464
return format_padding(format_sign(val, flags) + ret, flags)
465
}
469
var ret
470
471
if (val.__class__ === $B.LongInt.$dict) {
472
ret = $B.LongInt.$dict.to_base(8)
473
} else {
474
ret = parseInt(val)
475
ret = ret.toString(8)
476
}
477
480
if (flags.pad_char === '0') {
481
if (val < 0) {
482
ret = ret.substring(1)
483
ret = '-' + format_padding(ret, flags, true)
484
}
485
var sign = format_sign(val, flags)
486
if (sign !== '') {
487
ret = sign + format_padding(ret, flags, true)
488
}
490
491
if (flags.alternate) {
492
if (ret.charAt(0) === '-') {
493
ret = "-0o" + ret.slice(1)
494
} else {
495
ret = "0o" + ret
496
}
498
return format_padding(ret, flags)
499
}
500
501
var single_char_format = function(val, flags) {
502
if(isinstance(val,str) && val.length==1) return val
503
try {
504
val = _b_.int(val) // yes, floats are valid (they are cast to int)
505
} catch (err) {
506
throw _b_.TypeError('%c requires int or char')
507
}
508
return format_padding(chr(val), flags)
509
}
510
511
var num_flag = function(c, flags) {
512
if (c === '0' && !flags.padding && !flags.decimal_point && !flags.left) {
513
flags.pad_char = '0'
514
return
515
}
516
if (!flags.decimal_point) {
517
flags.padding = (flags.padding || "") + c
518
} else {
519
flags.precision = (flags.precision || "") + c
520
}
521
}
522
523
var decimal_point_flag = function(val, flags) {
524
if (flags.decimal_point) {
525
// can only have one decimal point
526
throw new UnsupportedChar()
527
}
528
flags.decimal_point = true
529
}
530
531
var neg_flag = function(val, flags) {
532
flags.pad_char = ' ' // overrides '0' flag
533
flags.left = true
534
}
535
536
var space_flag = function(val, flags) {
537
flags.space = true
538
}
539
540
var sign_flag = function(val, flags) {
541
flags.sign = true
542
}
543
544
var alternate_flag = function(val, flags) {
545
flags.alternate = true
546
}
547
549
's': str_format,
550
'd': num_format,
551
'i': num_format,
552
'u': num_format,
553
'o': octal_format,
554
'r': repr_format,
555
'a': ascii_format,
556
'g': function(val, flags) {return floating_point_format(val, false, flags)},
557
'G': function(val, flags) {return floating_point_format(val, true, flags)},
558
'f': function(val, flags) {return floating_point_decimal_format(val, false, flags)},
559
'F': function(val, flags) {return floating_point_decimal_format(val, true, flags)},
560
'e': function(val, flags) {return floating_point_exponential_format(val, false, flags)},
561
'E': function(val, flags) {return floating_point_exponential_format(val, true, flags)},
562
'x': function(val, flags) {return signed_hex_format(val, false, flags)},
563
'X': function(val, flags) {return signed_hex_format(val, true, flags)},
564
'c': single_char_format,
565
'0': function(val, flags) {return num_flag('0', flags)},
566
'1': function(val, flags) {return num_flag('1', flags)},
567
'2': function(val, flags) {return num_flag('2', flags)},
568
'3': function(val, flags) {return num_flag('3', flags)},
569
'4': function(val, flags) {return num_flag('4', flags)},
570
'5': function(val, flags) {return num_flag('5', flags)},
571
'6': function(val, flags) {return num_flag('6', flags)},
572
'7': function(val, flags) {return num_flag('7', flags)},
573
'8': function(val, flags) {return num_flag('8', flags)},
574
'9': function(val, flags) {return num_flag('9', flags)},
575
'-': neg_flag,
576
' ': space_flag,
577
'+': sign_flag,
578
'.': decimal_point_flag,
579
'#': alternate_flag
580
}
581
582
// exception thrown when an unsupported char is encountered in legacy format
583
var UnsupportedChar = function() {
584
this.name = "UnsupportedChar"
585
}
586
598
++pos
599
var rslt = kwarg_key.exec(s.substring(newpos))
600
if (!rslt) {
601
throw _b_.ValueError("incomplete format key")
602
}
603
var key = rslt[1]
604
newpos += rslt[0].length
605
try {
607
} catch(err) {
608
if (err.name === "KeyError") {
609
throw err
610
}
611
throw _b_.TypeError("format requires a mapping")
612
}
627
}
628
catch(err) {
629
if (err.name === "IndexError") {
630
throw _b_.TypeError("not enough arguments for format string")
631
} else {
632
throw err
633
}
639
// todo: get flags, type
640
// todo: string value based on flags, type, value
641
var flags = {'pad_char': ' '}
642
do {
649
if (ret !== undefined) {
650
return ret
651
}
652
++newpos
653
}
654
} catch (err) {
655
if (err.name === "UnsupportedChar") {
656
invalid_char = s[newpos]
657
if (invalid_char === undefined) {
658
throw _b_.ValueError("incomplete format")
659
}
660
throw _b_.ValueError("unsupported format character '" + invalid_char +
661
"' (0x" + invalid_char.charCodeAt(0).toString(16) + ") at index " + newpos)
662
} else if (err.name === "NotANumber") {
663
var try_char = s[newpos]
670
}
671
} else {
672
cls = cls.__name__
673
}
674
throw _b_.TypeError("%" + try_char + " format: a number is required, not " + cls)
675
} else {
676
throw err
677
}
699
}
700
}
701
} else {
702
// % at end of string
703
throw _b_.ValueError("incomplete format")
704
}
705
pos = newpos + 1
706
} while (pos < length)
707
710
711
$StringDict.__mro__ = [$StringDict,$ObjectDict]
712
713
$StringDict.__mul__ = function(self,other){
714
if(!isinstance(other,_b_.int)){throw _b_.TypeError(
715
"Can't multiply sequence by non-int of type '"+
716
$B.get_class(other).__name__+"'")}
717
$res = ''
718
for(var i=0;i<other;i++){$res+=self.valueOf()}
719
return $res
720
}
721
722
$StringDict.__ne__ = function(self,other){return other!==self.valueOf()}
723
724
$StringDict.__repr__ = function(self){
725
var res = self.replace(/\n/g,'\\\\n')
726
// escape the escape char
727
res = res.replace(/\\/g, '\\\\')
728
if(res.search('"')==-1 && res.search("'")==-1){
729
return "'"+res+"'"
738
$StringDict.__setattr__ = function(self,attr,value){return setattr(self,attr,value)}
739
740
$StringDict.__setitem__ = function(self,attr,value){
741
throw _b_.TypeError("'str' object does not support item assignment")
742
}
743
$StringDict.__str__ = function(self){
744
if(self===undefined) return "<class 'str'>"
745
return self.toString()
746
}
747
$StringDict.toString = function(){return 'string!'}
748
749
// generate comparison methods
750
var $comp_func = function(self,other){
751
if(typeof other !=="string"){throw _b_.TypeError(
752
"unorderable types: 'str' > "+$B.get_class(other).__name__+"()")}
753
return self > other
754
}
755
$comp_func += '' // source code
756
var $comps = {'>':'gt','>=':'ge','<':'lt','<=':'le'}
757
for(var $op in $comps){
758
eval("$StringDict.__"+$comps[$op]+'__ = '+$comp_func.replace(/>/gm,$op))
759
}
760
761
// add "reflected" methods
762
$B.make_rmethods($StringDict)
763
764
// unsupported operations
765
var $notimplemented = function(self,other){
766
throw NotImplementedError("OPERATOR not implemented for class str")
767
}
768
769
$StringDict.capitalize = function(self){
770
if(self.length==0) return ''
771
return self.charAt(0).toUpperCase()+self.substr(1).toLowerCase()
772
}
773
774
$StringDict.casefold = function(self) {
775
throw _b_.NotImplementedError("function casefold not implemented yet");
776
}
777
778
$StringDict.center = function(self,width,fillchar){
779
var $=$B.args("center",3,
780
{self:null, width:null, fillchar:null},
781
['self', 'width', 'fillchar'],
782
arguments,{fillchar:' '},null,null)
783
784
if($.width<=self.length) return self
793
$StringDict.count = function(){
794
var $ = $B.args('count', 4, {self:null, sub:null, start:null, stop:null},
799
var substr = $.self
800
if($.start!==null){
801
var _slice
802
if($.stop!==null){_slice = _b_.slice($.start, $.stop)}
803
else{_slice = _b_.slice($.start,$.self.length)}
804
substr = $StringDict.__getitem__.apply(null, [$.self].concat(_slice))
805
}else{
806
if($.self.length+$.sub.length==0){return 1} // ''.count('') = 1
807
}
808
if($.sub.length==0){
809
if($.start==$.self.length){return 1} // 'aaa'.count('',3) = 1
810
else if(substr.length==0){return 0} // 'aaa'.count('',4) = 0
811
return substr.length+1
812
}
813
var n=0, pos=0
814
while(pos<substr.length){
815
pos=substr.indexOf($.sub,pos)
817
}
818
return n
819
}
820
821
$StringDict.encode = function(self, encoding) {
822
if (encoding === undefined) encoding='utf-8'
823
if(encoding=='rot13' || encoding=='rot_13'){
824
// Special case : returns a string
825
var res = ''
826
for(var i=0, _len = self.length; i<_len ; i++){
827
var char = self.charAt(i)
828
if(('a'<=char && char<='m') || ('A'<=char && char<='M')){
829
res += String.fromCharCode(String.charCodeAt(char)+13)
830
}else if(('m'<char && char<='z') || ('M'<char && char<='Z')){
831
res += String.fromCharCode(String.charCodeAt(char)-13)
832
}else{res += char}
833
}
834
return res
835
}
837
}
838
839
$StringDict.endswith = function(self){
840
// Return True if the string ends with the specified suffix, otherwise
841
// return False. suffix can also be a tuple of suffixes to look for.
842
// With optional start, test beginning at that position. With optional
843
// end, stop comparing at that position.
845
{self:null, suffix:null, start:null, end:null},
846
['self', 'suffix', 'start', 'end'],
847
arguments,{start:0, end:self.length-1},null,null)
848
var suffixes = $ns['suffix']
849
if(!isinstance(suffixes,_b_.tuple)){suffixes=[suffixes]}
854
suffix = suffixes[i]
855
if(suffix.length<=s.length &&
856
s.substr(s.length-suffix.length)==suffix) return true
857
}
858
return false
859
}
860
861
$StringDict.expandtabs = function(self, tabsize) {
862
var $ = $B.args('expandtabs', 2, {self:null, tabsize:null},
863
['self', 'tabsize'], arguments, {tabsize:8}, null, null)
864
var s=$B.$GetInt($.tabsize), col=0,pos=0,res=''
865
if(s==1){return self.replace(/\t/g,' ')}
866
while(pos<self.length){
867
var car = self.charAt(pos)
868
switch(car){
869
case '\t':
870
while(col%s > 0){res += ' ';col++}
871
break
872
case '\r':
873
case '\n':
874
res += car
875
col = 0
876
break
877
default:
878
res += car
879
col++
880
break
881
}
882
pos++
883
}
884
885
return res
889
// Return the lowest index in the string where substring sub is found,
890
// such that sub is contained in the slice s[start:end]. Optional
891
// arguments start and end are interpreted as in slice notation.
892
// Return -1 if sub is not found.
896
arguments,{start:0,end:null},null,null)
897
if(!isinstance($.sub,str)){throw _b_.TypeError(
898
"Can't convert '"+$B.get_class($.sub).__name__+
899
"' object to str implicitly")}
903
throw _b_.TypeError(
904
"slice indices must be integers or None or have an __index__ method")}
905
var s = $.self.substring($.start,$.end)
906
907
if($.sub.length==0 && $.start==$.self.length){return $.self.length}
908
if(s.length+$.sub.length==0){return -1}
909
910
var last_search = s.length-$.sub.length
911
for(var i=0;i<=last_search;i++){
912
if(s.substr(i, $.sub.length)==$.sub){return $.start+i}
921
// Parse a "format string", as described in the Python documentation
922
// Return a format object. For the format string
923
// a.x[z]!r:...
924
// the object has attributes :
925
// - name : "a"
926
// - name_ext : [".x", "[z]"]
927
// - conv : r
928
// - spec : rest of string after :
930
var elts = fmt_string.split(':'), name, conv, spec, name_ext=[]
931
if(elts.length==1){
932
// No : in the string : it only contains a name
933
name = fmt_string
934
}else{
935
// name is before the first ":"
936
// spec (the format specification) is after
937
name = elts[0]
938
spec = elts.splice(1).join(':')
939
}
940
941
var elts = name.split('!')
942
if(elts.length>1){
943
name=elts[0]
944
conv=elts[1] // conversion flag
945
if(conv.length!==1 || 'ras'.search(conv)==-1){
946
throw _b_.ValueError('wrong conversion flag '+conv)
947
}
948
}
950
if(name!==undefined){
951
// "name' may be a subscription or attribute
952
// Put these "extensions" in the list "name_ext"
953
function name_repl(match){
954
name_ext.push(match)
955
return ''
956
}
957
var name_ext_re = /\.[_a-zA-Z][_a-zA-Z0-9]*|\[[_a-zA-Z][_a-zA-Z0-9]*\]|\[[0-9]+\]/g
958
name = name.replace(name_ext_re, name_repl)
959
}
968
arguments, {}, 'args', 'kw')
969
970
// Parse self to detect formatting instructions
971
// Create a list "parts" made of sections of the string :
972
// - elements of even rank are literal text
973
// - elements of odd rank are "format objects", built from the
974
// format strings in self (of the form {...})
975
var pos=0, _len=self.length, car, text='', parts=[], rank=0, defaults={}
976
977
while(pos<_len){
978
car = self.charAt(pos)
979
if(car=='{' && self.charAt(pos+1)=='{'){
980
// replace {{ by literal {
981
text += '{'
982
pos+=2
983
}else if(car=='}' && self.charAt(pos+1)=='}'){
984
// replace }} by literal }
985
text += '}'
986
pos+=2
987
}else if(car=='{'){
988
// Start of a format string
989
990
// Store current literal text
991
parts.push(text)
992
993
// Search the end of the format string, ie the } closing the
994
// opening {. Since the string can contain other pairs {} for
995
// nested formatting, an integer nb is incremented for each { and
996
// decremented for each } ; the end of the format string is
997
// reached when nb==0
998
var end = pos+1, nb=1
999
while(end<_len){
1000
if(self.charAt(end)=='{'){nb++;end++}
1001
else if(self.charAt(end)=='}'){
1002
nb--;end++
1003
if(nb==0){
1004
// End of format string
1005
var fmt_string = self.substring(pos+1, end-1)
1006
1007
// Create a format object, by function parse_format
1008
var fmt_obj = parse_format(fmt_string)
1009
1010
// If no name is explicitely provided, use the rank
1011
if(!fmt_obj.name){
1012
fmt_obj.name=rank+''
1013
rank++
1014
}
1017
// "spec" may contain "nested replacement fields"
1018
// In this case, evaluate them using the keyword
1019
// arguments passed to format()
1020
function replace_nested(name, key){
1023
}
1024
fmt_obj.spec = fmt_obj.spec.replace(/\{(.+?)\}/g,
1025
replace_nested)
1026
}
1027
1028
// Store format object in list "parts"
1029
parts.push(fmt_obj)
1030
text = ''
1031
break
1032
}
1033
}else{end++}
1035
if(nb>0){throw ValueError("wrong format "+self)}
1036
pos = end
1037
}else{text += car;pos++}
1041
// Apply formatting to the values passed to format()
1042
var res = '', fmt
1043
for(var i=0;i<parts.length;i++){
1044
// Literal text is added unchanged
1045
if(typeof parts[i]=='string'){res += parts[i];continue}
1046
1047
// Format objects
1048
fmt = parts[i]
1049
if(fmt.name.charAt(0).search(/\d/)>-1){
1050
// Numerical reference : use positional arguments
1051
var pos = parseInt(fmt.name),
1052
value = _b_.tuple.$dict.__getitem__($.args, pos)
1053
}else{
1054
// Use keyword arguments
1055
var value = _b_.dict.$dict.__getitem__($.kw, fmt.name)
1056
}
1057
// If name has extensions (attributes or subscriptions)
1058
for(var j=0;j<fmt.name_ext.length;j++){
1059
var ext = fmt.name_ext[j]
1060
if(ext.charAt(0)=='.'){
1061
// Attribute
1062
value = _b_.getattr(value, ext.substr(1))
1063
}else{
1064
// Subscription
1065
var key = ext.substr(1, ext.length-2)
1066
// An index made of digits is transformed into an integer
1067
if(key.charAt(0).search(/\d/)>-1){key = parseInt(key)}
1068
value = _b_.getattr(value, '__getitem__')(key)
1069
}
1070
}
1071
// If the conversion flag is set, first call a function to convert
1072
// the value
1073
if(fmt.conv=='a'){value = _b_.ascii(value)}
1074
else if(fmt.conv=='r'){value = _b_.repr(value)}
1075
else if(fmt.conv=='s'){value = _b_.str(value)}
1076
1077
// Call attribute __format__ to perform the actual formatting
1078
res += _b_.getattr(value, '__format__')(fmt.spec)
1081
}
1082
1083
$StringDict.format_map = function(self) {
1084
throw NotImplementedError("function format_map not implemented yet");
1085
}
1086
1087
$StringDict.index = function(self){
1088
// Like find(), but raise ValueError when the substring is not found.
1090
if(res===-1) throw _b_.ValueError("substring not found")
1091
return res
1092
}
1093
1094
$StringDict.isalnum = function(self) {return /^[a-z0-9]+$/i.test(self)}
1095
1096
$StringDict.isalpha = function(self) {return /^[a-z]+$/i.test(self)}
1097
1098
$StringDict.isdecimal = function(self) {
1099
// this is not 100% correct
1100
return /^[0-9]+$/.test(self)
1101
}
1102
1103
$StringDict.isdigit = function(self) { return /^[0-9]+$/.test(self)}
1104
1105
$StringDict.isidentifier = function(self) {
1106
1107
switch(self) {
1108
case 'False':
1109
case 'None':
1110
case 'True':
1111
case 'and':
1112
case 'as':
1113
case 'assert':
1114
case 'break':
1115
case 'class':
1116
case 'continue':
1117
case 'def':
1118
case 'del':
1119
case 'elif':
1120
case 'else':
1121
case 'except':
1122
case 'finally':
1123
case 'for':
1124
case 'from':
1125
case 'global':
1126
case 'if':
1127
case 'import':
1128
case 'in':
1129
case 'is':
1130
case 'lambda':
1131
case 'nonlocal':
1132
case 'not':
1133
case 'or':
1134
case 'pass':
1135
case 'raise':
1136
case 'return':
1137
case 'try':
1138
case 'while':
1139
case 'with':
1140
case 'yield':
1141
return true
1142
}
1143
1144
// fixme.. this isn't complete but should be a good start
1145
return /^[a-z][0-9a-z_]+$/i.test(self)
1146
}
1147
1149
1150
// not sure how to handle unicode variables
1151
$StringDict.isnumeric = function(self) {return /^[0-9]+$/.test(self)}
1152
1153
// inspired by http://www.codingforums.com/archive/index.php/t-17925.html
1154
$StringDict.isprintable = function(self) {return !/[^ -~]/.test(self)}
1155
1156
$StringDict.isspace = function(self) {return /^\s+$/i.test(self)}
1157
1158
$StringDict.istitle = function(self) {return /^([A-Z][a-z]+)(\s[A-Z][a-z]+)$/i.test(self)}
1159
1161
1162
$StringDict.join = function(self,obj){
1163
var iterable=iter(obj)
1164
var res = '',count=0
1165
while(1){
1166
try{
1167
var obj2 = next(iterable)
1168
if(!isinstance(obj2,str)){throw _b_.TypeError(
1169
"sequence item "+count+": expected str instance, "+$B.get_class(obj2).__name__+" found")}
1170
res += obj2+self
1171
count++
1172
}catch(err){
1174
else{throw err}
1175
}
1176
}
1177
if(count==0) return ''
1178
return res.substr(0,res.length-self.length)
1179
}
1180
1181
$StringDict.ljust = function(self) {
1182
var $=$B.args('ljust',3,{self:null,width:null,fillchar:null},
1183
['self','width','fillchar'],arguments,{fillchar:' '},null,null)
1184
1185
if ($.width <= self.length) return self
1186
return self + $.fillchar.repeat($.width - self.length)
1189
$StringDict.lower = function(){
1190
var $=$B.args('lower',1,{self:null},['self'],arguments,{},null,null)
1191
return $.self.toLowerCase()
1192
}
1195
var $=$B.args('lstrip',2,{self:null,chars:null},['self','chars'],
1196
arguments,{chars:_b_.None},null,null)
1197
if($.chars===_b_.None){return $.self.replace(/^\s+/,'')}
1198
return $.self.replace(new RegExp("^["+$.chars+"]*"),"")
1199
}
1200
1201
// note, maketrans should be a static function.
1202
$StringDict.maketrans = function(from, to) {
1203
var _t=[]
1204
// make 'default' translate table
1205
for(var i=0; i < 256; i++) _t[i]=String.fromCharCode(i)
1206
1207
// make substitution in the translation table
1209
var _ndx=from.source[i].charCodeAt(0) //retrieve ascii code of char
1210
_t[_ndx]=to.source[i]
1211
}
1212
1213
// create a data structure that string.translate understands
1217
}
1218
return _d
1219
}
1220
1221
$StringDict.partition = function(self,sep) {
1222
if (sep === undefined) {
1223
throw Error("sep argument is required");
1224
return
1225
}
1226
var i=self.indexOf(sep)
1227
if (i== -1) return _b_.tuple([self, '', ''])
1228
return _b_.tuple([self.substring(0,i), sep, self.substring(i+sep.length)])
1229
}
1230
1231
function $re_escape(str)
1232
{
1233
var specials = "[.*+?|()$^"
1235
var re = new RegExp('\\'+specials.charAt(i),'g')
1236
str = str.replace(re, "\\"+specials.charAt(i))
1237
}
1238
return str
1239
}
1240
1241
$StringDict.replace = function(self, old, _new, count) {
1242
// Replaces occurrences of 'old' by '_new'. Count references
1243
// the number of times to replace. In CPython, negative or undefined
1244
// values of count means replace all.
1245
var $ = $B.args('replace', 4, {self:null,old:null,$$new:null,count:null},
1246
['self','old','$$new','count'], arguments, {count:-1},null,null),
1247
count=$.count,self=$.self,old=$.old,_new=$.$$new
1250
throw _b_.TypeError("Can't convert '" + $B.get_class(old).__name__ +
1251
"' object to str implicitly");
1252
}
1253
if (!isinstance(_new,_b_.str)) {
1254
throw _b_.TypeError("Can't convert '" + $B.get_class(_new).__name__ +
1255
"' object to str implicitly");
1256
}
1257
// Validate instance type of 'count'
1258
if (!isinstance(count,[_b_.int,_b_.float])) {
1259
throw _b_.TypeError("'" + $B.get_class(count).__name__ +
1260
"' object cannot be interpreted as an integer");
1261
} else if (isinstance(count, _b_.float)) {
1262
throw _b_.TypeError("integer argument expected, got float");
1263
}
1264
if(count==0){return self}
1265
if(count.__class__==$B.LongInt.$dict){count=parseInt(count.value)}
1266
if(old==''){
1267
if(_new==''){return self}
1268
if(self==''){return _new}
1269
var elts=self.split('')
1270
if(count>-1 && elts.length>=count){
1271
var rest = elts.slice(count).join('')
1272
return _new+elts.slice(0, count).join(_new)+rest
1273
}else{return _new+elts.join(_new)+_new}
1274
}else{
1275
var elts = $StringDict.split(self,old,count)
1278
var res = self, pos = -1
1279
if(old.length==0){
1280
var res = _new
1281
for(var i=0;i<elts.length;i++){
1282
res += elts[i]+_new
1283
}
1284
return res+rest
1285
}
1286
1287
if (count < 0) count = res.length;
1288
while (count > 0) {
1289
pos = res.indexOf(old, pos);
1290
if (pos < 0)
1291
break;
1292
res = res.substr(0, pos) + _new + res.substr(pos + old.length);
1293
pos = pos + _new.length;
1294
count--;
1295
}
1296
return res;
1297
}
1298
1299
$StringDict.rfind = function(self){
1300
// Return the highest index in the string where substring sub is found,
1301
// such that sub is contained within s[start:end]. Optional arguments
1302
// start and end are interpreted as in slice notation. Return -1 on failure.
1308
normalize_start_end($)
1309
1310
if(!isinstance($.sub,str)){throw _b_.TypeError(
1311
"Can't convert '"+$B.get_class($.sub).__name__+"' object to str implicitly")}
1313
if($.sub.length==0){
1314
if($.start>$.self.length){return -1}
1315
else{return $.self.length}
1316
}
1317
var sublen = $.sub.length
1318
1319
for(var i=$.end-sublen;i>=$.start;i--){
1320
if($.self.substr(i, sublen)==$.sub){return i}
1321
}
1322
return -1
1323
}
1324
1325
$StringDict.rindex = function(){
1326
// Like rfind() but raises ValueError when the substring sub is not found
1328
if(res==-1){throw _b_.ValueError("substring not found")}
1329
return res
1330
}
1331
1332
$StringDict.rjust = function(self) {
1334
{self:null, width:null, fillchar:null},
1335
['self', 'width', 'fillchar'],
1336
arguments,{fillchar:' '},null,null)
1341
}
1342
1343
$StringDict.rpartition = function(self,sep) {
1344
if (sep === undefined) {
1345
throw Error("sep argument is required");
1346
return
1347
}
1348
var pos=self.length-sep.length
1349
while(1){
1350
if(self.substr(pos,sep.length)==sep){
1351
return _b_.tuple([self.substr(0,pos),sep,self.substr(pos+sep.length)])
1352
}else{
1353
pos--
1354
if(pos<0){return _b_.tuple(['','',self])}
1355
}
1356
}
1357
}
1358
1359
$StringDict.rsplit = function(self) {
1360
var $=$B.args("rsplit",3,{self:null,sep:null,maxsplit:null},
1361
['self','sep','maxsplit'],arguments,
1362
{sep:_b_.None, maxsplit:-1},null,null),
1363
sep=$.sep,maxsplit=$.maxsplit,self=$.self
1364
1365
// Use split on the reverse of the string and of separator
1366
var rev_str = $.self.split('').reverse().join(''),
1367
rev_sep = sep === _b_.None ? sep : $.sep.split('').reverse().join(''),
1368
rev_res = $StringDict.split(rev_str, rev_sep, $.maxsplit)
1370
// Reverse the list, then each string inside the list
1371
rev_res.reverse()
1372
for(var i=0;i<rev_res.length;i++){
1373
rev_res[i] = rev_res[i].split('').reverse().join('')
1374
}
1375
return rev_res
1379
var $=$B.args('rstrip',2,{self:null,chars:null},['self','chars'],
1380
arguments,{chars:_b_.None},null,null)
1381
if($.chars===_b_.None){return $.self.replace(/\s+$/,'')}
1382
return $.self.replace(new RegExp("["+$.chars+"]*$"),"")
1387
var $=$B.args("split",3,{self:null,sep:null,maxsplit:null},
1388
['self','sep','maxsplit'],arguments,
1389
{sep:_b_.None, maxsplit:-1},null,null)
1390
var sep=$.sep,maxsplit=$.maxsplit,self=$.self
1391
if(maxsplit.__class__===$B.LongInt.$dict){maxsplit=parseInt(maxsplit.value)}
1394
var res = []
1395
var pos = 0
1396
while(pos<self.length&&self.charAt(pos).search(/\s/)>-1){pos++}
1398
var name = ''
1399
while(1){
1400
if(self.charAt(pos).search(/\s/)===-1){
1401
if(name===''){name=self.charAt(pos)}
1402
else{name+=self.charAt(pos)}
1403
}else{
1404
if(name!==''){
1405
res.push(name)
1406
if(maxsplit!==-1&&res.length===maxsplit+1){
1407
res.pop()
1408
res.push(name+self.substr(pos))
1409
return res
1410
}
1411
name=''
1412
}
1413
}
1414
pos++
1415
if(pos>self.length-1){
1416
if(name){res.push(name)}
1417
break
1418
}
1419
}
1420
return res
1421
}else{
1422
var res = [],s='',pos=0,seplen=sep.length
1423
if(maxsplit==0){return [self]}
1424
while(pos<self.length){
1425
if(self.substr(pos,seplen)==sep){
1426
res.push(s)
1427
pos += seplen
1428
if(maxsplit>-1 && res.length>=maxsplit){
1429
res.push(self.substr(pos))
1430
return res
1431
}
1432
s= ''
1433
}else{
1434
s += self.charAt(pos)
1435
pos++
1440
}
1441
}
1442
1443
$StringDict.splitlines = function(self){return $StringDict.split(self,'\n')}
1444
1445
$StringDict.startswith = function(self){
1446
// Return True if string starts with the prefix, otherwise return False.
1447
// prefix can also be a tuple of prefixes to look for. With optional
1448
// start, test string beginning at that position. With optional end,
1449
// stop comparing string at that position.
1451
{self:null, prefix:null, start:null, end:null},
1452
['self', 'prefix', 'start', 'end'],
1453
arguments,{start:0, end:self.length-1},null,null)
1454
var prefixes = $ns['prefix']
1455
if(!isinstance(prefixes,_b_.tuple)){prefixes=[prefixes]}
1466
$StringDict.strip = function(){
1467
var $=$B.args('strip',2,{self:null,chars:null},['self','chars'],
1468
arguments,{chars:_b_.None},null,null)
1469
return $StringDict.rstrip($StringDict.lstrip($.self,$.chars),$.chars)
1475
//inspired by http://www.geekpedia.com/code69_Swap-string-case-using-JavaScript.html
1477
{ return ($1) ? $0.toUpperCase() : $0.toLowerCase()
1478
})
1479
}
1480
1481
$StringDict.title = function(self) {
1482
//inspired from http://stackoverflow.com/questions/196972/convert-string-to-title-case-with-javascript
1483
return self.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
1484
}
1485
1486
$StringDict.translate = function(self,table) {
1491
if(repl==-1){res[pos++]=self.charAt(i)}
1492
else if(repl!==None){res[pos++]=repl}
1498
$StringDict.upper = function(){
1499
var $=$B.args('lower',1,{self:null},['self'],arguments,{},null,null)
1500
return $.self.toUpperCase()
1501
}
1504
var $=$B.args('zfill',2,{self:null,width:null},
1505
['self','width'],arguments,{},null,null)
1506
if ($.width <= self.length) {return self}
1507
switch(self.charAt(0)){
1508
case '+':
1509
case '-':
1510
return self.charAt(0)+'0'.repeat($.width-self.length)+self.substr(1)
1511
default:
1512
return '0'.repeat(width - self.length)+self
1513
}
1518
switch(typeof arg) {
1519
case 'string': return arg
1520
case 'number': return arg.toString()
1521
}
1527
// class or its subclasses, but the attribute __str__ of the
1528
// class metaclass (usually "type") or its subclasses (usually
1529
// "object")
1530
// The metaclass is the attribute __class__ of the class dictionary
1531
var func = $B.$type.__getattribute__(arg.$dict.__class__,'__str__')
1536
var f = getattr(arg,'__str__')
1537
// XXX fix : if not better than object.__str__, try __repr__
1538
return f()
1539
}
1540
catch(err){
1546
if($B.debug>1){console.log(err)}
1547
console.log('Warning - no method __str__ or __repr__, default to toString', arg)
1549
}
1550
}
1551
}
1552
str.__class__ = $B.$factory
1553
str.$dict = $StringDict
1554
$StringDict.$factory = str
1555
$StringDict.__new__ = function(cls){
1556
if(cls===undefined){
1557
throw _b_.TypeError('str.__new__(): not enough arguments')
1558
}
1559
return {__class__:cls.$dict}
1560
}
1561
1564
// dictionary and factory for subclasses of string
1565
var $StringSubclassDict = {
1566
__class__:$B.$type,
1567
__name__:'str'
1568
}
1569
1570
// the methods in subclass apply the methods in $StringDict to the
1571
// result of instance.valueOf(), which is a Javascript string
1572
for(var $attr in $StringDict){
1573
if(typeof $StringDict[$attr]=='function'){
1574
$StringSubclassDict[$attr]=(function(attr){
1575
return function(){
1581
}
1582
}
1583
return $StringDict[attr].apply(null,args)
1584
}
1585
})($attr)
1586
}
1587
}
1588
$StringSubclassDict.__mro__ = [$StringSubclassDict,$ObjectDict]
1589
1590
// factory for str subclasses
1591
$B.$StringSubclassFactory = {
1592
__class__:$B.$factory,
1593
$dict:$StringSubclassDict
1594
}
1595
1596
_b_.str = str
1597
1598
// Function to parse the 2nd argument of format()
1599
$B.parse_format_spec = function(spec){
1609
if(spec.charAt(1) && aligns.indexOf(spec.charAt(1))!=-1){
1610
// If the second char is also an alignment specifier, the
1611
// first char is the fill value
1612
this.fill = spec.charAt(0)
1613
this.align = spec.charAt(1)
1614
pos = 2
1615
}else{
1616
// The first character defines alignment : fill defaults to ' '
1617
this.align=aligns[align_pos];
1618
this.fill=' ';
1619
pos++
1620
}
1621
}else{
1622
align_pos = aligns.indexOf(spec.charAt(1))
1623
if(spec.charAt(1) && align_pos!=-1){
1624
// The second character defines alignment : fill is the first one
1625
this.align=aligns[align_pos]
1626
this.fill=spec.charAt(0)
1627
pos = 2
1628
}
1629
}
1630
var car = spec.charAt(pos)
1631
if(car=='+'||car=='-'||car==' '){
1632
this.sign=car;
1633
pos++;
1634
car=spec.charAt(pos);
1637
if(car=='0'){
1638
// sign-aware : equivalent to fill=0 and align=='='
1639
this.fill='0'
1640
this.align = '='
1641
pos++;car=spec.charAt(pos)
1642
}
1644
if(this.width===undefined){this.width=car}
1645
else{this.width+=car}
1646
pos++;car=spec.charAt(pos)
1648
if(this.width!==undefined){this.width=parseInt(this.width)}
1649
if(car==','){this.comma=true;pos++;car=spec.charAt(pos)}
1650
if(car=='.'){
1651
if(digits.indexOf(spec.charAt(pos+1))==-1){
1652
throw _b_.ValueError("Missing precision in format spec")
1653
}
1654
this.precision = spec.charAt(pos+1)
1655
pos+=2;car=spec.charAt(pos)
1656
while(car && digits.indexOf(car)>-1){
1657
this.precision+=car;pos++;car=spec.charAt(pos)
1658
}
1659
this.precision = parseInt(this.precision)
1660
}
1661
if(car && types.indexOf(car)>-1){this.type=car;pos++;car=spec.charAt(pos)}
1662
if(pos!==spec.length){
1663
console.log('error', spec, this, pos, spec.charAt(pos))
1664
throw _b_.ValueError("Invalid format specifier")
1665
}
1666
}
1667
this.toString = function(){
1668
return (this.fill===undefined ? '' : _b_.str(this.fill))+
1669
(this.align||'')+
1670
(this.sign||'')+
1671
(this.alternate ? '#' : '')+
1672
(this.sign_aware ? '0' : '')+
1673
(this.width || '')+
1674
(this.comma ? ',' : '')+
1675
(this.precision ? '.'+this.precision : '')+
1676
(this.type || '')
1677
}
1678
}
1679
1680
$B.format_width = function(s, fmt){
1681
if(fmt.width && s.length<fmt.width){
1682
var fill=fmt.fill || ' ', align = fmt.align || '<',
1683
missing = fmt.width-s.length
1684
switch(align){
1685
case '<':
1686
return s+fill.repeat(missing)
1687
case '>':
1688
return fill.repeat(missing)+s
1689
case '=':
1690
if('+-'.indexOf(s.charAt(0))>-1){
1691
return s.charAt(0)+fill.repeat(missing)+s.substr(1)
1692
}else{
1693
return fill.repeat(missing)+s
1694
}
1695
case '^':
1696
left = parseInt(missing/2)