|
1 | 1 | formatters = Dict{ Compat.ASCIIString, Function }()
|
2 | 2 |
|
3 |
| -function sprintf1( fmt::Compat.ASCIIString, x ) |
| 3 | +@static if VERSION >= v"0.6-" |
| 4 | + |
| 5 | +sprintf1( fmt::Compat.ASCIIString, x ) = eval(Expr(:call, generate_formatter( fmt ), x)) |
| 6 | + |
| 7 | +function checkfmt(fmt) |
| 8 | + test = Base.Printf.parse( fmt ) |
| 9 | + (length( test ) == 1 && typeof( test[1] ) <: Tuple) || |
| 10 | + error( "Only one AND undecorated format string is allowed") |
| 11 | +end |
| 12 | + |
| 13 | +function generate_formatter( fmt::Compat.ASCIIString ) |
4 | 14 | global formatters
|
5 |
| - f = generate_formatter( fmt ) |
6 |
| - f( x ) |
| 15 | + |
| 16 | + haskey( formatters, fmt ) && return formatters[fmt] |
| 17 | + |
| 18 | + if !contains( fmt, "'" ) |
| 19 | + checkfmt(fmt) |
| 20 | + return (formatters[ fmt ] = @eval(x->@sprintf( $fmt, x ))) |
| 21 | + end |
| 22 | + |
| 23 | + conversion = fmt[end] |
| 24 | + conversion in "sduifF" || |
| 25 | + error( string("thousand separator not defined for ", conversion, " conversion") ) |
| 26 | + |
| 27 | + fmtactual = replace( fmt, "'", "", 1 ) |
| 28 | + checkfmt( fmtactual ) |
| 29 | + conversion in "sfF" || |
| 30 | + return (formatters[ fmt ] = @eval(x->checkcommas(@sprintf( $fmtactual, x )))) |
| 31 | + |
| 32 | + formatters[ fmt ] = |
| 33 | + if endswith( fmtactual, 's') |
| 34 | + @eval((x::Real)->((eltype(x) <: Rational) |
| 35 | + ? addcommasrat(@sprintf( $fmtactual, x )) |
| 36 | + : addcommasreal(@sprintf( $fmtactual, x )))) |
| 37 | + else |
| 38 | + @eval((x::Real)->addcommasreal(@sprintf( $fmtactual, x ))) |
| 39 | + end |
7 | 40 | end
|
8 | 41 |
|
| 42 | +function addcommasreal(s) |
| 43 | + dpos = findfirst( s, '.' ) |
| 44 | + dpos != 0 && return string(addcommas( s[1:dpos-1] ), s[ dpos:end ]) |
| 45 | + # find the rightmost digit |
| 46 | + for i in length( s ):-1:1 |
| 47 | + isdigit( s[i] ) && return string(addcommas( s[1:i] ), s[i+1:end]) |
| 48 | + end |
| 49 | + s |
| 50 | +end |
| 51 | + |
| 52 | +function addcommasrat(s) |
| 53 | + # commas are added to only the numerator |
| 54 | + spos = findfirst( s, '/' ) |
| 55 | + string(addcommas( s[1:spos-1] ), s[spos:end]) |
| 56 | +end |
| 57 | + |
| 58 | +function checkcommas(s) |
| 59 | + for i in length( s ):-1:1 |
| 60 | + if isdigit( s[i] ) |
| 61 | + s = string(addcommas( s[1:i] ), s[i+1:end]) |
| 62 | + break |
| 63 | + end |
| 64 | + end |
| 65 | + s |
| 66 | +end |
| 67 | + |
| 68 | +else |
| 69 | + |
| 70 | +sprintf1( fmt::Compat.ASCIIString, x ) = (generate_formatter( fmt ))(x) |
| 71 | + |
9 | 72 | function generate_formatter( fmt::Compat.ASCIIString )
|
10 | 73 | global formatters
|
11 | 74 | if haskey( formatters, fmt )
|
12 | 75 | return formatters[fmt]
|
13 | 76 | end
|
| 77 | + |
14 | 78 | func = @compat Symbol("sprintf_", replace(base64encode(fmt), "=", "!"))
|
15 | 79 |
|
16 | 80 | if !contains( fmt, "'" )
|
@@ -77,6 +141,7 @@ function generate_formatter( fmt::Compat.ASCIIString )
|
77 | 141 | formatters[ fmt ] = f
|
78 | 142 | f
|
79 | 143 | end
|
| 144 | +end |
80 | 145 |
|
81 | 146 | function addcommas( s::Compat.ASCIIString )
|
82 | 147 | len = length(s)
|
|
0 commit comments