@@ -15,7 +15,8 @@ function generate_formatter( fmt::ASCIIStr )
15
15
16
16
if ! occursin (" '" , fmt)
17
17
checkfmt (fmt)
18
- return (formatters[ fmt ] = @eval (x-> @sprintf ( $ fmt, x )))
18
+ formatter = @eval (x-> @sprintf ( $ fmt, x ))
19
+ return (formatters[ fmt ] = x-> Base. invokelatest (formatter, x))
19
20
end
20
21
21
22
conversion = fmt[end ]
@@ -24,60 +25,65 @@ function generate_formatter( fmt::ASCIIStr )
24
25
25
26
fmtactual = replace ( fmt, " '" => " " ; count= 1 )
26
27
checkfmt ( fmtactual )
27
- conversion in " sfF" ||
28
- return (formatters[ fmt ] = @eval (x-> checkcommas (@sprintf ( $ fmtactual, x ))))
29
-
30
- formatters[ fmt ] =
31
- if endswith ( fmtactual, ' s' )
28
+ formatter =
29
+ if ! (conversion in " sfF" )
30
+ @eval (x-> checkcommas (@sprintf ( $ fmtactual, x )))
31
+ elseif endswith ( fmtactual, ' s' )
32
32
@eval ((x:: Real )-> ((eltype (x) <: Rational )
33
33
? addcommasrat (@sprintf ( $ fmtactual, x ))
34
34
: addcommasreal (@sprintf ( $ fmtactual, x ))))
35
35
else
36
36
@eval ((x:: Real )-> addcommasreal (@sprintf ( $ fmtactual, x )))
37
37
end
38
+ return (formatters[ fmt ] = x-> Base. invokelatest (formatter, x))
38
39
end
39
40
40
41
function addcommasreal (s)
42
+ len = length (s)
41
43
dpos = findfirst ( isequal (' .' ), s )
42
- dpos != = nothing && return string ( addcommas ( s[ 1 : dpos - 1 ] ), s[ dpos: end ] )
44
+ dpos != = nothing && return addcommas (s, len, dpos- 1 )
43
45
# find the rightmost digit
44
- for i in length ( s ) : - 1 : 1
45
- isdigit ( s[i] ) && return string ( addcommas ( s[ 1 : i] ), s[i + 1 : end ] )
46
+ for i in len : - 1 : 1
47
+ isdigit ( s[i] ) && return addcommas (s, len, i )
46
48
end
47
49
s
48
50
end
49
51
50
- function addcommasrat (s)
51
- # commas are added to only the numerator
52
- spos = findfirst ( isequal (' /' ), s )
53
- string (addcommas ( s[1 : spos- 1 ] ), s[spos: end ])
54
- end
52
+ # commas are added to only the numerator
53
+ addcommasrat (s) = addcommas (s, length (s), findfirst ( isequal (' /' ), s )- 1 )
55
54
56
55
function checkcommas (s)
57
- for i in length ( s ): - 1 : 1
58
- if isdigit ( s[i] )
59
- s = string (addcommas ( s[1 : i] ), s[i+ 1 : end ])
60
- break
61
- end
56
+ len = length (s)
57
+ for i in len: - 1 : 1
58
+ isdigit ( s[i] ) && return addcommas (s, len, i)
62
59
end
63
60
s
64
61
end
65
62
66
- function addcommas ( s:: ASCIIStr )
67
- len = length (s)
68
- t = " "
69
- for i in 1 : 3 : len
70
- subs = s[max (1 ,len- i- 1 ): len- i+ 1 ]
71
- if i == 1
72
- t = subs
73
- elseif match ( r" [0-9]" , subs ) != nothing
74
- t = string (subs, ' ,' , t)
75
- else
76
- t = string (subs, t)
77
- end
63
+ function addcommas (s:: T , len, lst) where {T<: AbstractString }
64
+ lst < 4 && return s
65
+ beg = 1
66
+ while beg < len
67
+ isdigit (s[beg]) && break
68
+ beg += 1
69
+ end
70
+ dig = lst - beg + 1
71
+ dig < 4 && return s
72
+
73
+ commas = div (dig - 1 , 3 )
74
+ sv = Base. StringVector (len + commas)
75
+
76
+ for i = 1 : beg- 1 ; sv[i] = s[i]; end
77
+ cnt = dig - commas* 3
78
+ pos = beg - 1
79
+ for i = beg: lst- 3
80
+ sv[pos += 1 ] = s[i]
81
+ (cnt -= 1 ) == 0 && (cnt = 3 ; sv[pos += 1 ] = ' ,' )
78
82
end
79
- t
83
+ for i = lst- 2 : len; sv[i+ commas] = s[i]; end
84
+ T (sv)
80
85
end
86
+ addcommas (s) = (l = length (s); addcommas (s, l, l))
81
87
82
88
function generate_format_string (;
83
89
width:: Int = - 1 ,
0 commit comments