https://github.com/juliastring/format.jl
A Julia package to provide C and Python-like formatting support
https://github.com/juliastring/format.jl
hacktoberfest
Last synced: about 2 months ago
JSON representation
A Julia package to provide C and Python-like formatting support
- Host: GitHub
- URL: https://github.com/juliastring/format.jl
- Owner: JuliaString
- License: other
- Created: 2016-10-06T17:45:32.000Z (over 9 years ago)
- Default Branch: main
- Last Pushed: 2024-03-26T02:37:33.000Z (almost 2 years ago)
- Last Synced: 2024-04-25T18:04:49.523Z (almost 2 years ago)
- Topics: hacktoberfest
- Language: Julia
- Homepage:
- Size: 289 KB
- Stars: 34
- Watchers: 2
- Forks: 8
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# Format
This package offers Python-style general formatting and c-style numerical formatting (for speed).
[pkg-url]: https://github.com/JuliaString/Format.jl.git
[julia-url]: https://github.com/JuliaLang/Julia
[julia-release]:https://img.shields.io/github/release/JuliaLang/julia.svg
[release]: https://img.shields.io/github/release/JuliaString/Format.jl.svg
[release-date]: https://img.shields.io/github/release-date/JuliaString/Format.jl.svg
[license-img]: http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat
[license-url]: LICENSE.md
[gitter-img]: https://badges.gitter.im/Join%20Chat.svg
[gitter-url]: https://gitter.im/JuliaString/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
[travis-url]: https://travis-ci.org/JuliaString/Format.jl
[travis-s-img]: https://travis-ci.org/JuliaString/Format.jl.svg
[travis-m-img]: https://travis-ci.org/JuliaString/Format.jl.svg?branch=master
[codecov-url]: https://codecov.io/gh/JuliaString/Format.jl
[codecov-img]: https://codecov.io/gh/JuliaString/Format.jl/branch/master/graph/badge.svg
[contrib]: https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat
[![][release]][pkg-url] [![][release-date]][pkg-url] [![][license-img]][license-url] [![contributions welcome][contrib]](https://github.com/JuliaString/Format.jl/issues)
| **Julia Version** | **Unit Tests** | **Coverage** |
|:------------------:|:------------------:|:---------------------:|
| [![][julia-release]][julia-url] | [![][travis-s-img]][travis-url] | [![][codecov-img]][codecov-url]
| Julia Latest | [![][travis-m-img]][travis-url] | [![][codecov-img]][codecov-url]
## Getting Started
This package is pure Julia. Setting up this package is like setting up other Julia packages:
```julia
import Pkg; Pkg.add("Format")
```
or
```julia
]add Format
```
It is forked off of [Formatting.jl](https://github.com/JuliaIO/Formatting.jl), and I try to keep the oldmaster branch up to date with the master branch of that, and cherry pick or port all necessary changes to `Format`).
To start using the package, you can simply write
```julia
using Format
```
This package depends on Julia of version 1.4 or above, and. The package is MIT-licensed.
## Python-style Types and Functions
#### Types to Represent Formats
This package has two types `FormatSpec` and `FormatExpr` to represent a format specification.
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
```julia
fspec = FormatSpec("d")
fspec = FormatSpec("<8.4f")
```
Please refer to [Python's format specification language](http://docs.python.org/3/library/string.html#formatspec) for details.
`FormatExpr` captures a formatting expression that may involve multiple items. One can compile a formatting string into a `FormatExpr` instance as
```julia
fe = FormatExpr("{1} + {2}")
fe = FormatExpr("{1:d} + {2:08.4e} + {3|>abs2}")
```
Please refer to [Python's format string syntax](http://docs.python.org/3/library/string.html#format-string-syntax) for details.
**Note:** If the same format is going to be applied for multiple times. It is more efficient to first compile it.
#### Formatted Printing
One can use `printfmt` and `printfmtln` for formatted printing:
- **printfmt**(io, fe, args...)
- **printfmt**(fe, args...)
Print given arguments using given format `fe`. Here `fe` can be a formatting string, an instance of `FormatSpec` or `FormatExpr`.
**Examples**
```julia
printfmt("{1:>4s} + {2:.2f}", "abc", 12) # --> print(" abc + 12.00")
printfmt("{} = {:#04x}", "abc", 12) # --> print("abc = 0x0c")
fs = FormatSpec("#04x")
printfmt(fs, 12) # --> print("0x0c")
fe = FormatExpr("{} = {:#04x}")
printfmt(fe, "abc", 12) # --> print("abc = 0x0c")
```
**Notes**
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.
```julia
printfmt("{1:d}", 10) # OK, "{1:d}" can be compiled into a FormatExpr instance
printfmt("d", 10) # Error, "d" can not be compiled into a FormatExpr instance
# such a string to specify a format specification for single argument
printfmt(FormatSpec("d"), 10) # OK
printfmt(FormatExpr("{1:d}", 10)) # OK
```
- **printfmtln**(io, fe, args...)
- **printfmtln**(fe, args...)
Similar to `printfmt` except that this function print a newline at the end.
#### Formatted String
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.
- **pyfmt**(fspec, a)
Format a single value using a format specification given by `fspec`, where `fspec` can be either a string or an instance of `FormatSpec`.
- **format**(fe, args...)
Format arguments using a format expression given by `fe`, where `fe` can be either a string or an instance of `FormatSpec`.
#### Difference from Python's Format
At this point, this package implements a subset of Python's formatting language (with slight modification). Here is a summary of the differences:
- 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} + {}`).
- 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.
## C-style functions
The c-style part of this package aims to get around the limitation that
`@sprintf` has to take a literal string argument.
The core part is basically a c-style print formatter using the standard
`@sprintf` macro.
It also adds functionalities such as commas separator (thousands), parenthesis for negatives,
stripping trailing zeros, and mixed fractions.
### Usage and Implementation
The idea here is that the package compiles a function only once for each unique
format string within the `Format.*` name space, so repeated use is faster.
Unrelated parts of a session using the same format string would reuse the same
function, avoiding redundant compilation. To avoid the proliferation of
functions, we limit the usage to only 1 argument. Practical consideration
would suggest that only dozens of functions would be created in a session, which
seems manageable.
Usage
```julia
using Format
fmt = "%10.3f"
s = cfmt( fmt, 3.14159 ) # usage 1. Quite performant. Easiest to switch to.
fmtrfunc = generate_formatter( fmt ) # usage 2. This bypass repeated lookup of cached function. Most performant.
s = fmtrfunc( 3.14159 )
s = format( 3.14159, precision=3 ) # usage 3. Most flexible, with some non-printf options. Least performant.
```
### Commas
This package also supplements the lack of thousand separator e.g. `"%'d"`, `"%'f"`, `"%'g"`.
Note: `"%'g"` behavior is that for small enough floating point (but not too small),
thousand separator would be used. If the number needs to be represented by `"%e"`, no
separator is used.
### Flexible `format` function
This package contains a run-time number formatter `format` function, which goes beyond
the standard `sprintf` functionality.
An example:
```julia
s = format( 1234, commas=true ) # 1,234
s = format( -1234, commas=true, parens=true ) # (1,234)
```
The keyword arguments are (Bold keywords are not printf standard)
* width. Integer. Try to fit the output into this many characters. May not be successful.
Sacrifice space first, then commas.
* precision. Integer. How many decimal places.
* leftjustified. Boolean
* zeropadding. Boolean
* commas. Boolean. Thousands-group separator.
* signed. Boolean. Always show +/- sign?
* positivespace. Boolean. Prepend an extra space for positive numbers? (so they align nicely with negative numbers)
* **parens**. Boolean. Use parenthesis instead of "-". e.g. `(1.01)` instead of `-1.01`. Useful in finance. Note that
you cannot use `signed` and `parens` option at the same time.
* **stripzeros**. Boolean. Strip trailing '0' to the right of the decimal (and to the left of 'e', if any ).
* It may strip the decimal point itself if all trailing places are zeros.
* This is true by default if precision is not given, and vice versa.
* alternative. Boolean. See `#` alternative form explanation in standard printf documentation
* conversion. length=1 string. Default is type dependent. It can be one of `aAeEfFoxX`. See standard
printf documentation.
* **mixedfraction**. Boolean. If the number is rational, format it in mixed fraction e.g. `1_1/2` instead of `3/2`
* **mixedfractionsep**. Default `_`
* **fractionsep**. Default `/`
* **fractionwidth**. Integer. Try to pad zeros to the numerator until the fractional part has this width
* **tryden**. Integer. Try to use this denominator instead of a smaller one. No-op if it'd lose precision.
* **suffix**. String. This strings will be appended to the output. Useful for units/%
* **autoscale**. Symbol, default `:none`. It could be `:metric`, `:binary`, or `:finance`.
* `:metric` implements common SI symbols for large and small numbers e.g. `M`, `k`, `μ`, `n`
* `:binary` implements common ISQ symbols for large numbers e.g. `Ti`, `Gi`, `Mi`, `Ki`
* `:finance` implements common finance/news symbols for large numbers e.g. `b` (billion), `m` (millions)
See the test script for more examples.