Skip to content

Commit

Permalink
Merge pull request #2 from ScottPJones/spj/update
Browse files Browse the repository at this point in the history
Further improvements, addition of HTML names for characters, and full Unicode name table.
  • Loading branch information
ScottPJones committed Mar 16, 2016
2 parents 6f53ac3 + 1e46b11 commit 7f09fd4
Show file tree
Hide file tree
Showing 11 changed files with 61,588 additions and 214 deletions.
21 changes: 16 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,28 @@ the $ character in them, which is rather frequent in some applications.
Also, Unicode sequences are represented as in Swift, i.e. as `\u{hexdigits}`, where there
can be from 1 to 6 hex digits. This syntax eliminates having to worry about always outputting
4 or 8 hex digits, to prevent problems with 0-9,A-F,a-f characters immediately following.
Finally, I have added two new ways of representing characters in the literal string,
`\:emojiname:` and `\{latexname}`.
Finally, I have added four ways of representing characters in the literal string,
`\:emojiname:`, `\<latexname>`, `\&htmlname;` and `\N{UnicodeName}`.
This makes life a lot easier when you want to keep the text of a program in ASCII, and
also to be able to write programs using those characters that might not even display
correctly in their editor.

This now has some initial formatting capability, based on Tom Breloff's wonderful PR #10 to the
JuliaLang/Formatting.jl package (by Dahua Lin and other contributors).

`\%(arguments)` is interpolated as a call to fmt(arguments).
This is especially useful when defaults have been set for the type of the first argument.

`fmt_default!{T}(::Type{T}, syms::Symbol...; kwargs...)` sets the defaults for a particular type.
`fmt_default!(syms::Symbol...; kwargs...)` sets the defaults for all types.
Symbols that can currently be used are: `:ljust` or `:left`, `:rjust` or `:right`, `:commas`,
`:zpad` or `:zeropad`, and `:ipre` or `:prefix`.
`reset!{T}(::Type{T})` resets the defaults for a particular type.
`defaultSpec(x)` will return the defaults for the type of x, and
`defaultSpec{T}(::Type{T})` will return the defaults for the given type.

I also plan on adding support for `\%c(arguments)`, where c is a C style formatting character.
I'm debating if I should make it take the full C style syntax, with leading 0, width/precision,
etc, before the single character.
This also adds support for `\%ccc(arguments)`, where ccc is one or more characters of a
single C style format specification, which is interpolated as a call to cfmt("ccc", arguments).

I'm also experimenting with adding Python style syntax (as much as possible), as
u"\{pythonformat}"
29,215 changes: 29,215 additions & 0 deletions data/UnicodeData.txt

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion src/StringUtils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ export s_unescape_string, s_escape_string, s_print_unescaped, s_print_escaped

include("literals.jl")
include("unicodenames.jl")
include("htmlnames.jl")

# From Formatting.jl
import Base.show

export cfmt, fmt, fmt_default, fmt_default!
export FormatSpec, FormatExpr, printfmt, printfmtln, format, generate_formatter
export pyfmt, cfmt, fmt, fmt_default, fmt_default!, reset!, defaultSpec

include("cformat.jl" )
include("fmtspec.jl")
Expand Down
10 changes: 5 additions & 5 deletions src/cformat.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
formatters = Dict{ ASCIIString, Function }()

function sprintf1( fmt::ASCIIString, x )
function cfmt( fmt::ASCIIString, x )
global formatters
f = generate_formatter( fmt )
f( x )
Expand Down Expand Up @@ -159,7 +159,7 @@ function format{T<:Real}( x::T;
)
checkwidth = commas
if conversion == ""
if T <: FloatingPoint || T <: Rational && precision != -1
if T <: AbstractFloat || T <: Rational && precision != -1
actualconv = "f"
elseif T <: Unsigned
actualconv = "x"
Expand All @@ -178,7 +178,7 @@ function format{T<:Real}( x::T;
if T <: Rational && conversion == "s"
stripzeros = false
end
if ( T <: FloatingPoint && actualconv == "f" || T <: Integer ) && autoscale != :none
if ( T <: AbstractFloat && actualconv == "f" || T <: Integer ) && autoscale != :none
actualconv = "f"
if autoscale == :metric
scales = [
Expand All @@ -198,7 +198,7 @@ function format{T<:Real}( x::T;
break
end
end
elseif T <: FloatingPoint
elseif T <: AbstractFloat
smallscales = [
( 1e-12, "p" ),
( 1e-9, "n" ),
Expand Down Expand Up @@ -254,7 +254,7 @@ function format{T<:Real}( x::T;
actualx = x
end
end
s = sprintf1( generate_format_string( width=width,
s = cfmt( generate_format_string( width=width,
precision=precision,
leftjustified=leftjustified,
zeropadding=zeropadding,
Expand Down
10 changes: 5 additions & 5 deletions src/fmt.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

# interface proposal by Tom Breloff (@tbreloff)... comments welcome
# This uses the more basic formatting based on FormatSpec and the cfmt method (formerly called fmt, which I repurposed)
# This uses the more basic formatting based on FormatSpec and the pyfmt method
# (formerly called fmt, which I repurposed)

# TODO: swap out FormatSpec for something that is able to use the "format" method, which has more options for units, prefixes, etc
# TODO: support rational numbers, autoscale, etc as in "format"
Expand Down Expand Up @@ -112,7 +112,7 @@ end

# --------------------------------------------------------------------------------------------------

# TODO: get rid of this entire hack by moving commas into cfmt
# TODO: get rid of this entire hack by moving commas into pyfmt

function optionalCommas(x::Real, s::AbstractString, fspec::FormatSpec)
dpos = findfirst(s, '.')
Expand Down Expand Up @@ -146,12 +146,12 @@ optionalCommas(x, s::AbstractString, fspec::FormatSpec) = s

# TODO: do more caching to optimize repeated calls

# creates a new FormatSpec by overriding the defaults and passes it to cfmt
# creates a new FormatSpec by overriding the defaults and passes it to pyfmt
# note: adding kwargs is only appropriate for one-off formatting.
# normally it will be much faster to change the fmt_default formatting as needed
function fmt(x; kwargs...)
fspec = isempty(kwargs) ? fmt_default(x) : FormatSpec(fmt_default(x); kwargs...)
s = cfmt(fspec, x)
s = pyfmt(fspec, x)

# add the commas now... I was confused as to when this is done currently
if fspec.tsep
Expand Down
10 changes: 7 additions & 3 deletions src/fmtspec.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ immutable FormatSpec
tsep::Bool # whether to use thousand-separator

function FormatSpec(typ::Char;
fill::Char=' ',
fill::Char=' ',
align::Char='\0',
sign::Char='-',
width::Int=-1,
Expand Down Expand Up @@ -181,6 +181,10 @@ _srepr(x) = repr(x)
_srepr(x::AbstractString) = x
_srepr(x::Char) = string(x)

if isdefined(:Enum)
_srepr(x::Enum) = string(x)
end

function printfmt(io::IO, fs::FormatSpec, x)
cls = fs.cls
ty = fs.typ
Expand Down Expand Up @@ -209,5 +213,5 @@ end

printfmt(fs::FormatSpec, x) = printfmt(STDOUT, fs, x)

cfmt(fs::FormatSpec, x) = (buf = IOBuffer(); printfmt(buf, fs, x); bytestring(buf))
cfmt(spec::AbstractString, x) = cfmt(FormatSpec(spec), x)
pyfmt(fs::FormatSpec, x) = (buf = IOBuffer(); printfmt(buf, fs, x); bytestring(buf))
pyfmt(spec::AbstractString, x) = pyfmt(FormatSpec(spec), x)
5 changes: 1 addition & 4 deletions src/formatexpr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ immutable ArgSpec
end
end

getarg(args, sp::ArgSpec) =
getarg(args, sp::ArgSpec) =
(a = args[sp.argidx]; sp.hasfilter ? sp.filter(a) : a)

# pos > 0: must not have iarg in expression (use pos+1), return (entry, pos + 1)
Expand Down Expand Up @@ -166,6 +166,3 @@ printfmt(fe::StringOrFE, args...) = printfmt(STDOUT, fe, args...)
printfmtln(io::IO, fe::StringOrFE, args...) = (printfmt(io, fe, args...); println(io))
printfmtln(fe::StringOrFE, args...) = printfmtln(STDOUT, fe, args...)

format(fe::StringOrFE, args...) =
(buf = IOBuffer(); printfmt(buf, fe, args...); bytestring(buf))

Loading

0 comments on commit 7f09fd4

Please sign in to comment.