Skip to content

Commit 4bbf367

Browse files
committed
Update README and CI
1 parent e4b2991 commit 4bbf367

5 files changed

Lines changed: 205 additions & 63 deletions

File tree

.travis.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ language: julia
33
os:
44
- linux
55
- osx
6+
- windows
67
julia:
78
- 1.0
8-
- 1.3
9+
- 1
910
- nightly
1011
notifications:
1112
email: false
@@ -18,7 +19,5 @@ matrix:
1819
allow_failures:
1920
- julia: nightly
2021

21-
# uncomment the following lines to override the default test script
22-
2322
after_success:
24-
- julia -e 'using Pkg; cd(Pkg.dir("Format")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder()); Codecov.submit(Codecov.process_folder())'
23+
- julia -e 'using Pkg; cd(Pkg.dir("Format")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'

README.md

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22

33
This package offers Python-style general formatting and c-style numerical formatting (for speed).
44

5-
| **Info** | **Windows** | **Linux & MacOS** | **Package Evaluator** | **CodeCov** | **Coveralls** |
6-
|:------------------:|:------------------:|:---------------------:|:-----------------:|:---------------------:|:-----------------:|
7-
| [![][license-img]][license-url] | [![][app-s-img]][app-s-url] | [![][travis-s-img]][travis-url] | [![][pkg-s-img]][pkg-s-url] | [![][codecov-img]][codecov-url] | [![][coverall-s-img]][coverall-s-url]
8-
| [![][gitter-img]][gitter-url] | [![][app-m-img]][app-m-url] | [![][travis-m-img]][travis-url] | [![][pkg-m-img]][pkg-m-url] | [![][codecov-img]][codecov-url] | [![][coverall-m-img]][coverall-m-url]
5+
[pkg-url]: https://github.com/JuliaString/Format.jl.git
6+
7+
[julia-url]: https://github.com/JuliaLang/Julia
8+
[julia-release]:https://img.shields.io/github/release/JuliaLang/julia.svg
9+
10+
[release]: https://img.shields.io/github/release/JuliaString/Format.jl.svg
11+
[release-date]: https://img.shields.io/github/release-date/JuliaString/Format.jl.svg
912

1013
[license-img]: http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat
1114
[license-url]: LICENSE.md
@@ -17,23 +20,17 @@ This package offers Python-style general formatting and c-style numerical format
1720
[travis-s-img]: https://travis-ci.org/JuliaString/Format.jl.svg
1821
[travis-m-img]: https://travis-ci.org/JuliaString/Format.jl.svg?branch=master
1922

20-
[app-s-url]: https://ci.appveyor.com/project/ScottPJones/format-jl
21-
[app-m-url]: https://ci.appveyor.com/project/ScottPJones/format-jl/branch/master
22-
[app-s-img]: https://ci.appveyor.com/api/projects/status/9wb580eyjv4k3iej?svg=true
23-
[app-m-img]: https://ci.appveyor.com/api/projects/status/9wb580eyjv4k3iej/branch/master?svg=true
24-
25-
[pkg-s-url]: http://pkg.julialang.org/?pkg=Format
26-
[pkg-m-url]: http://pkg.julialang.org/?pkg=Format
27-
[pkg-s-img]: http://pkg.julialang.org/badges/Format_0.6.svg
28-
[pkg-m-img]: http://pkg.julialang.org/badges/Format_0.7.svg
29-
3023
[codecov-url]: https://codecov.io/gh/JuliaString/Format.jl
3124
[codecov-img]: https://codecov.io/gh/JuliaString/Format.jl/branch/master/graph/badge.svg
3225

33-
[coverall-s-url]: https://coveralls.io/github/JuliaString/Format.jl
34-
[coverall-m-url]: https://coveralls.io/github/JuliaString/Format.jl?branch=master
35-
[coverall-s-img]: https://coveralls.io/repos/github/JuliaString/Format.jl/badge.svg
36-
[coverall-m-img]: https://coveralls.io/repos/github/JuliaString/Format.jl/badge.svg?branch=master
26+
[contrib]: https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat
27+
28+
[![][release]][pkg-url] [![][release-date]][pkg-url] [![][license-img]][license-url] [![contributions welcome][contrib]](https://github.com/JuliaString/Format.jl/issues)
29+
30+
| **Julia Version** | **Unit Tests** | **Coverage** |
31+
|:------------------:|:------------------:|:---------------------:|
32+
| [![][julia-release]][julia-url] | [![][travis-s-img]][travis-url] | [![][codecov-img]][codecov-url]
33+
| Julia Latest | [![][travis-m-img]][travis-url] | [![][codecov-img]][codecov-url]
3734

3835
## Getting Started
3936

appveyor.yml

Lines changed: 0 additions & 37 deletions
This file was deleted.

src/Format.jl

Lines changed: 186 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,195 @@
1-
__precompile__(true)
1+
"""
2+
Format.jl
23
4+
This package provides various functions to provide formatted output,
5+
either in a fashion similar to C printf or Python format strings.
6+
7+
## Python-style Types and Functions
8+
9+
#### Types to Represent Formats
10+
11+
This package has two types ``FormatSpec`` and ``FormatExpr`` to represent a format specification.
12+
13+
In particular, ``FormatSpec`` is used to capture the specification of a single entry. One can compile a format specification string into a ``FormatSpec`` instance as
14+
15+
```julia
16+
fspec = FormatSpec("d")
17+
fspec = FormatSpec("<8.4f")
18+
```
19+
Please refer to [Python's format specification language](http://docs.python.org/2/library/string.html#formatspec) for details.
20+
21+
22+
``FormatExpr`` captures a formatting expression that may involve multiple items. One can compile a formatting string into a ``FormatExpr`` instance as
23+
24+
```julia
25+
fe = FormatExpr("{1} + {2}")
26+
fe = FormatExpr("{1:d} + {2:08.4e} + {3|>abs2}")
27+
```
28+
Please refer to [Python's format string syntax](http://docs.python.org/2/library/string.html#format-string-syntax) for details.
29+
30+
31+
**Note:** If the same format is going to be applied for multiple times. It is more efficient to first compile it.
32+
33+
34+
#### Formatted Printing
35+
36+
One can use ``printfmt`` and ``printfmtln`` for formatted printing:
37+
38+
- **printfmt**(io, fe, args...)
39+
40+
- **printfmt**(fe, args...)
41+
42+
Print given arguments using given format ``fe``. Here ``fe`` can be a formatting string, an instance of ``FormatSpec`` or ``FormatExpr``.
43+
44+
**Examples**
45+
46+
```julia
47+
printfmt("{1:>4s} + {2:.2f}", "abc", 12) # --> print(" abc + 12.00")
48+
printfmt("{} = {:#04x}", "abc", 12) # --> print("abc = 0x0c")
49+
50+
fs = FormatSpec("#04x")
51+
printfmt(fs, 12) # --> print("0x0c")
52+
53+
fe = FormatExpr("{} = {:#04x}")
54+
printfmt(fe, "abc", 12) # --> print("abc = 0x0c")
55+
```
56+
57+
**Notes**
58+
59+
If the first argument is a string, it will be first compiled into a ``FormatExpr``, which implies that you can not use specification-only string in the first argument.
60+
61+
```julia
62+
printfmt("{1:d}", 10) # OK, "{1:d}" can be compiled into a FormatExpr instance
63+
printfmt("d", 10) # Error, "d" can not be compiled into a FormatExpr instance
64+
# such a string to specify a format specification for single argument
65+
66+
printfmt(FormatSpec("d"), 10) # OK
67+
printfmt(FormatExpr("{1:d}", 10)) # OK
68+
```
69+
70+
71+
- **printfmtln**(io, fe, args...)
72+
73+
- **printfmtln**(fe, args...)
74+
75+
Similar to ``printfmt`` except that this function print a newline at the end.
76+
77+
#### Formatted String
78+
79+
One can use ``pyfmt`` to format a single value into a string, or ``format`` to format one to multiple arguments into a string using an format expression.
80+
81+
- **pyfmt**(fspec, a)
82+
83+
Format a single value using a format specification given by ``fspec``, where ``fspec`` can be either a string or an instance of ``FormatSpec``.
84+
85+
- **format**(fe, args...)
86+
87+
Format arguments using a format expression given by ``fe``, where ``fe`` can be either a string or an instance of ``FormatSpec``.
88+
89+
90+
#### Difference from Python's Format
91+
92+
At this point, this package implements a subset of Python's formatting language (with slight modification). Here is a summary of the differences:
93+
94+
- ``g`` and ``G`` for floating point formatting have not been supported yet. Please use ``f``, ``e``, or ``E`` instead.
95+
96+
- The package currently provides default alignment, left alignment ``<`` and right alignment ``>``. Other form of alignment such as centered alignment ``^`` has not been supported yet.
97+
98+
- In terms of argument specification, it supports natural ordering (e.g. ``{} + {}``), explicit position (e.g. ``{1} + {2}``). It hasn't supported named arguments or fields extraction yet. Note that mixing these two modes is not allowed (e.g. ``{1} + {}``).
99+
100+
- The package provides support for filtering (for explicitly positioned arguments), such as ``{1|>lowercase}`` by allowing one to embed the ``|>`` operator, which the Python counter part does not support.
101+
102+
## C-style functions
103+
104+
The c-style part of this package aims to get around the limitation that
105+
`@sprintf` has to take a literal string argument.
106+
The core part is basically a c-style print formatter using the standard
107+
`@sprintf` macro.
108+
It also adds functionalities such as commas separator (thousands), parenthesis for negatives,
109+
stripping trailing zeros, and mixed fractions.
110+
111+
### Usage and Implementation
112+
113+
The idea here is that the package compiles a function only once for each unique
114+
format string within the `Format.*` name space, so repeated use is faster.
115+
Unrelated parts of a session using the same format string would reuse the same
116+
function, avoiding redundant compilation. To avoid the proliferation of
117+
functions, we limit the usage to only 1 argument. Practical consideration
118+
would suggest that only dozens of functions would be created in a session, which
119+
seems manageable.
120+
121+
Usage
122+
```julia
123+
using Format
124+
125+
fmt = "%10.3f"
126+
s = cfmt( fmt, 3.14159 ) # usage 1. Quite performant. Easiest to switch to.
127+
128+
fmtrfunc = generate_formatter( fmt ) # usage 2. This bypass repeated lookup of cached function. Most performant.
129+
s = fmtrfunc( 3.14159 )
130+
131+
s = format( 3.14159, precision=3 ) # usage 3. Most flexible, with some non-printf options. Least performant.
132+
```
133+
### Speed
134+
135+
`cfmt`: Speed penalty is about 20% for floating point and 30% for integers.
136+
137+
If the formatter is stored and used instead (see the example using `generate_formatter` above),
138+
the speed penalty reduces to 10% for floating point and 15% for integers.
139+
140+
### Commas
141+
142+
This package also supplements the lack of thousand separator e.g. `"%'d"`, `"%'f"`, `"%'s"`.
143+
144+
Note: `"%'s"` behavior is that for small enough floating point (but not too small),
145+
thousand separator would be used. If the number needs to be represented by `"%e"`, no
146+
separator is used.
147+
148+
### Flexible `format` function
149+
150+
This package contains a run-time number formatter `format` function, which goes beyond
151+
the standard `sprintf` functionality.
152+
153+
An example:
154+
```julia
155+
s = format( 1234, commas=true ) # 1,234
156+
s = format( -1234, commas=true, parens=true ) # (1,234)
157+
```
158+
159+
The keyword arguments are (Bold keywards are not printf standard)
160+
161+
* width. Integer. Try to fit the output into this many characters. May not be successful.
162+
Sacrifice space first, then commas.
163+
* precision. Integer. How many decimal places.
164+
* leftjustified. Boolean
165+
* zeropadding. Boolean
166+
* commas. Boolean. Thousands-group separator.
167+
* signed. Boolean. Always show +/- sign?
168+
* positivespace. Boolean. Prepend an extra space for positive numbers? (so they align nicely with negative numbers)
169+
* **parens**. Boolean. Use parenthesis instead of "-". e.g. `(1.01)` instead of `-1.01`. Useful in finance. Note that
170+
you cannot use `signed` and `parens` option at the same time.
171+
* **stripzeros**. Boolean. Strip trailing '0' to the right of the decimal (and to the left of 'e', if any ).
172+
* It may strip the decimal point itself if all trailing places are zeros.
173+
* This is true by default if precision is not given, and vice versa.
174+
* alternative. Boolean. See `#` alternative form explanation in standard printf documentation
175+
* conversion. length=1 string. Default is type dependent. It can be one of `aAeEfFoxX`. See standard
176+
printf documentation.
177+
* **mixedfraction**. Boolean. If the number is rational, format it in mixed fraction e.g. `1_1/2` instead of `3/2`
178+
* **mixedfractionsep**. Default `_`
179+
* **fractionsep**. Default `/`
180+
* **fractionwidth**. Integer. Try to pad zeros to the numerator until the fractional part has this width
181+
* **tryden**. Integer. Try to use this denominator instead of a smaller one. No-op if it'd lose precision.
182+
* **suffix**. String. This strings will be appended to the output. Useful for units/%
183+
* **autoscale**. Symbol, default `:none`. It could be `:metric`, `:binary`, or `:finance`.
184+
* `:metric` implements common SI symbols for large and small numbers e.g. `M`, `k`, `μ`, `n`
185+
* `:binary` implements common ISQ symbols for large numbers e.g. `Ti`, `Gi`, `Mi`, `Ki`
186+
* `:finance` implements common finance/news symbols for large numbers e.g. `b` (billion), `m` (millions)
187+
"""
3188
module Format
4189

5190
import Base.show
6191

7192
using Printf
8-
const PF = @static VERSION >= v"1.4.0-DEV.180" ? Printf : Base.Printf
9193

10194
_stdout() = stdout
11195
_codeunits(s) = Vector{UInt8}(codeunits(s))
@@ -19,7 +203,6 @@ export fmt_default, fmt_default!, reset!, default_spec, default_spec!
19203
# Later, use Strs package!
20204
isdefined(Main, :ASCIIStr) || (const ASCIIStr = String)
21205
isdefined(Main, :UTF8Str) || (const UTF8Str = String)
22-
isdefined(Main, :AbstractChar) || (const AbstractChar = Char)
23206

24207
include("cformat.jl" )
25208
include("fmtspec.jl")

src/cformat.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ formatters = Dict{ ASCIIStr, Function }()
33
cfmt( fmt::ASCIIStr, x ) = m_eval(Expr(:call, generate_formatter( fmt ), x))
44

55
function checkfmt(fmt)
6-
test = PF.parse( fmt )
6+
test = Printf.parse( fmt )
77
(length( test ) == 1 && typeof( test[1] ) <: Tuple) ||
88
error( "Only one AND undecorated format string is allowed")
99
end

0 commit comments

Comments
 (0)