diff --git a/Project.toml b/Project.toml index 9be9af3..ba4afcd 100644 --- a/Project.toml +++ b/Project.toml @@ -5,12 +5,10 @@ version = "0.4.0" [deps] Configurations = "5218b696-f38b-4ac9-8b61-a12ec717816d" -Crayons = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" Preferences = "21216c6a-2e73-6563-6e65-726566657250" [compat] Configurations = "0.16" -Crayons = "4" Preferences = "1" julia = "1" diff --git a/src/GarishPrint.jl b/src/GarishPrint.jl index 077e69b..8e7264e 100644 --- a/src/GarishPrint.jl +++ b/src/GarishPrint.jl @@ -1,8 +1,6 @@ module GarishPrint export pprint, pprint_struct - -using Crayons using Configurations # 1.0 Compat @@ -21,7 +19,6 @@ else end include("color.jl") -include("colorschemes.jl") include("io.jl") include("pprint.jl") include("struct.jl") diff --git a/src/arrays.jl b/src/arrays.jl index 430e546..ce06cb5 100644 --- a/src/arrays.jl +++ b/src/arrays.jl @@ -27,8 +27,7 @@ end # NOTE: modified based on base/arrayshow.jl:show_zero_dim function pprint_zero_dim(io::GarishIO, X::AbstractArray{T, 0}) where T if isassigned(X) - print_token(io, :call, "fill") - print(io, "(") + print(io, "fill(") pprint(io, X[]) else print_token(io, :type, "Array{", T, ", 0}(") diff --git a/src/color.jl b/src/color.jl index 56644ac..b1495dd 100644 --- a/src/color.jl +++ b/src/color.jl @@ -26,182 +26,108 @@ function supports_color256() end end -# NOTE: this type immutable because each object maps to -# an preference file, thus it shouldn't be changed once -# created +const ColorType = Union{Int, Symbol} """ - ColorScheme + ColorPreference -The color scheme type. +The color preference type. """ -@option struct ColorScheme - # struct components - fieldname::Crayon - type::Crayon - - # keyword-like - keyword::Crayon - call::Crayon - +struct ColorPreference + fieldname::ColorType + type::ColorType + operator::ColorType + # literal-like - text::Crayon - number::Crayon - string::Crayon - symbol::Crayon - literal::Crayon - constant::Crayon - op::Crayon + literal::ColorType + constant::ColorType + number::ColorType + string::ColorType # comment-like - comment::Crayon - undef::Crayon - lineno::Crayon + comment::ColorType + undef::ColorType + linenumber::ColorType end -# fancy color names -const semantic_crayons = Dict{Crayon, String}() -const semantic_colornames = [ - "default", "black", "blue", - "cyan", "green", "light_blue", "light_cyan", "light_green", - "light_magenta", "light_red", "light_yellow", "magenta", "nothing", "red", - "white" -] - -const COLORS = Dict( - 0 => "black", - 1 => "red", - 2 => "green", - 3 => "yellow", - 4 => "blue", - 5 => "magenta", - 6 => "cyan", - 7 => "light_gray", - 9 => "default", - 60 => "dark_gray", - 61 => "light_red", - 62 => "light_green", - 63 => "light_yellow", - 64 => "light_blue", - 65 => "light_magenta", - 66 => "light_cyan", - 67 => "white" -) - -for name in semantic_colornames - semantic_crayons[Crayon(foreground = Symbol(name))] = name +struct PreferenceInvalid <: Exception + key::String + type + got end -function Configurations.convert_to_option(::Type{ColorScheme}, ::Type{Crayon}, x::String) - x in semantic_colornames || throw(ArgumentError("invalid color $x")) - return Crayon(foreground = Symbol(x)) +function Base.showerror(io::IO, x::PreferenceInvalid) + print(io, "preference for ") + printstyled(io, x.key; color=:light_blue) + print(io, " is invalid, expect ") + printstyled(io, x.type; color=:green) + print(io, " got: ", repr(x.got)) end -function Configurations.convert_to_option(::Type{ColorScheme}, ::Type{Crayon}, d::Dict) - kwargs = [] - if haskey(d, "foreground") - push!(kwargs, :foreground => parse_color(d["foreground"])) - end +Base.show(io::IO, x::ColorPreference) = pprint_struct(io, x) - if haskey(d, "background") - push!(kwargs, :background => parse_color(d["background"])) - end +""" + ColorPreference(;kw...) - for key in [ - :reset, - :bold, - :faint, - :italics, - :underline, - :blink, - :negative, - :conceal, - :strikethrough, - ] - - if get(d, string(key), false) - push!(kwargs, key => true) - end +See [`pprint`](@ref) for available keyword configurations. +""" +function ColorPreference(;kw...) + colors = supports_color256() ? default_colors_256() : default_colors_ansi() + if color_prefs_toml !== nothing + merge!(colors, color_prefs_toml) end - return Crayon(;kwargs...) -end - -function Configurations.to_dict(::Type{ColorScheme}, x::Crayon) - if haskey(semantic_crayons, x) - return semantic_crayons[x] - else - d = Dict{String, Any}() - if x.fg.active - d["foreground"] = ansi_color_to_dict(x.fg) - end - - if x.bg.active - d["background"] = ansi_color_to_dict(x.bg) + colors = merge!(colors, kw) + + args = map(fieldnames(ColorPreference)) do name + val = colors[string(name)] + if val isa String + return Symbol(val) + elseif val isa Int + return val + else + throw(PreferenceInvalid("GarishPrint.color.$name", Union{String, Int}, val)) end - - for f in fieldnames(Crayon) - if f === :fg || f === :bg - continue - end - - if getfield(x, f).active - d[string(each)] = true - end - end - return d end + return ColorPreference(args...) end -parse_color(s::String) = Symbol(s) - -function parse_color(d::Dict) - haskey(d, "style") || error("field `style` is required for color") - haskey(d, "color") || error("field `color` is required for color") - - if d["style"] == "256" - return Int(d["color"]) - elseif d["style"] == "24bit" - return parse(UInt32, "0x" * d["color"]) - else - error("invalid style: $(d["style"])") - end -end - -function ansi_color_to_dict(x::Crayons.ANSIColor) - if x.style == Crayons.COLORS_16 - return COLORS[x.r] - elseif x.style == Crayons.COLORS_256 - Dict{String, Any}( - "color" => x.r, - "style" => "256", - ) - elseif x.style == Crayons.COLORS_24BIT - Dict{String, Any}( - "color" => rgb_to_hex(x.r, x.g, x.b), - "style" => "24bit", - ) - else - error("invalid color encoding RESET") - end -end +""" + default_colors_ansi() -function rgb_to_hex(r, g, b) - r, g, b = UInt32(r), UInt32(g), UInt32(b) - hex = r << 16 | g << 8 | b - return uppercase(string(hex; base=16)) +The default ANSI color theme. +""" +function default_colors_ansi() + Dict{String, Any}( + "fieldname" => "light_blue", + "type" => "green", + "operator" => "normal", + "literal" => "yellow", + "constant" => "yellow", + "number" => "normal", + "string" => "yellow", + "comment" => "light_black", + "undef" => "normal", + "linenumber" => "light_black", + ) end -Base.show(io::IO, x::ColorScheme) = pprint_struct(io, x) - -function color_scheme(;kw...) - colors = supports_color256() ? monokai_256() : monokai() - d = to_dict(colors, TOMLStyle) - if color_prefs_toml !== nothing - merge!(d, color_prefs_toml) - end +""" + default_colors_256() - if !isempty(kw) - merge!(d, kw) - end - return from_dict(ColorScheme, d) +The default color 256 theme. +""" +function default_colors_256() + Dict{String, Any}( + "fieldname" => 039, + "type" => 037, + "operator" => 196, + "literal" => 140, + "constant" => 099, + "number" => 140, + "string" => 180, + "comment" => 240, + # undef is actually a constant + "undef" => 099, + "linenumber" => 240, + ) end diff --git a/src/colorschemes.jl b/src/colorschemes.jl deleted file mode 100644 index f12de33..0000000 --- a/src/colorschemes.jl +++ /dev/null @@ -1,43 +0,0 @@ -function monokai() - return ColorScheme( - fieldname = Crayon(foreground = :default), - type = Crayon(foreground = :cyan), - - keyword = Crayon(foreground = :light_red), - call = Crayon(foreground = :cyan), - - text = Crayon(foreground = :default), - number = Crayon(foreground = :magenta), - string = Crayon(foreground = :yellow), - symbol = Crayon(foreground = :magenta), - op = Crayon(foreground = :light_red), - literal = Crayon(foreground = :yellow), - constant = Crayon(foreground = :yellow), - - comment = Crayon(foreground = :dark_gray), - undef = Crayon(foreground = :dark_gray), - lineno = Crayon(foreground = :dark_gray), - ) -end - -function monokai_256() - return ColorScheme(; - fieldname = Crayon(foreground = :default), - type = Crayon(foreground = 81), - - keyword = Crayon(foreground = 197), - call = Crayon(foreground = 81), - - text = Crayon(foreground = :default), - number = Crayon(foreground = 141), - string = Crayon(foreground = 208), - symbol = Crayon(foreground = 141), - op = Crayon(foreground = 197), - literal = Crayon(foreground = 140), - constant = Crayon(foreground = 99), - - comment = Crayon(foreground = 60), - undef = Crayon(foreground = 60), - lineno = Crayon(foreground = 60), - ) -end diff --git a/src/io.jl b/src/io.jl index 3b02476..2e7cbdb 100644 --- a/src/io.jl +++ b/src/io.jl @@ -34,7 +34,7 @@ PrintState() = PrintState(Unknown, Any, false, 0, 0) - `compact::Bool`: whether the printing should be compact. - `displaysize::Tuple{Int, Int}`: the terminal displaysize. - `show_indent`: print the indentation hint or not. -- `color`: color preference, either `ColorScheme` or `nothing` for no color. +- `color`: color preference, either `ColorPreference` or `nothing` for no color. - `state`: the state of the printer, see [`PrintState`](@ref). """ struct GarishIO{IO_t <: IO} <: Base.AbstractPipe @@ -48,7 +48,7 @@ struct GarishIO{IO_t <: IO} <: Base.AbstractPipe # option type include_defaults::Bool # use nothing for no color print - color::Union{Nothing, ColorScheme} + color::Union{Nothing, ColorPreference} state::PrintState end @@ -63,17 +63,17 @@ function GarishIO(io::IO; limit::Bool=get(io, :limit, false), displaysize::Tuple{Int, Int}=displaysize(io), color::Bool=get(io, :color, true), - color_prefs::Union{Nothing, ColorScheme} = nothing, # indent is similar to color show_indent::Bool=get(io, :color, true), include_defaults::Bool=get(io, :include_defaults, false), kw... ) - if color && color_prefs === nothing - color_prefs = color_scheme(;kw...) + if color + color_prefs = ColorPreference(;kw...) + else + color_prefs = nothing end - return GarishIO( io, indent, compact, limit, @@ -99,7 +99,7 @@ function GarishIO(io::GarishIO; if isempty(kw) color_prefs = color else - color_prefs = color_scheme(;kw...) + color_prefs = ColorPreference(;kw...) end return GarishIO( @@ -206,7 +206,7 @@ end print_token(io::GarishIO, type::Symbol, xs...) Print `xs` to a `GarishIO` as given token type. The token type -should match the field name of `ColorScheme`. +should match the field name of `ColorPreference`. """ function print_token(io::GarishIO, type::Symbol, xs...) print_token(print, io, type, xs...) @@ -219,16 +219,7 @@ Print `xs` to a `GarishIO` as given token type using `f(io, xs...)` """ function print_token(f, io::GarishIO, type::Symbol, xs...) isnothing(io.color) && return f(io, xs...) - # workaround :color option - get(io, :color, false) || return f(io, xs...) - crayon = getfield(io.color, type) - # Base.with_output_color - buf = IOBuffer() - try f(GarishIO(buf, io), xs...) - finally - str = String(take!(buf)) - return f(io, crayon(str)) - end + Base.with_output_color(f, getfield(io.color, type), io, xs...) end function max_indent_reached(io::GarishIO, offset::Int) diff --git a/src/misc.jl b/src/misc.jl index 40fcd30..eeaeaac 100644 --- a/src/misc.jl +++ b/src/misc.jl @@ -66,6 +66,6 @@ Print an operator, such as `=`, `+`, `=>` etc. This should be only used under `M """ function print_operator(io::GarishIO, op) io.compact || print(io, " ") - print_token(io, :op, op) + print_token(io, :operator, op) io.compact || print(io, " ") end diff --git a/test/Project.toml b/test/Project.toml index 2b76550..d297545 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -2,7 +2,6 @@ Configurations = "5218b696-f38b-4ac9-8b61-a12ec717816d" Preferences = "21216c6a-2e73-6563-6e65-726566657250" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -Crayons = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76" UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/test/colors.jl b/test/colors.jl deleted file mode 100644 index d5700ff..0000000 --- a/test/colors.jl +++ /dev/null @@ -1,15 +0,0 @@ -module TestColors - -using Test -using GarishPrint -using GarishPrint: ColorScheme, monokai_256, monokai -using Configurations -cs = monokai_256() -d = to_dict(cs) -@test from_dict(ColorScheme, d) == cs - -cs = monokai() -d = to_dict(cs) -@test from_dict(ColorScheme, d) == cs - -end diff --git a/test/prefs.jl b/test/prefs.jl index cc6e088..6bf1261 100644 --- a/test/prefs.jl +++ b/test/prefs.jl @@ -1,6 +1,5 @@ using Test using UUIDs -using Crayons using Preferences set_preferences!( UUID("b0ab02a7-8576-43f7-aa76-eaa7c3897c54"), @@ -9,4 +8,4 @@ set_preferences!( ) using GarishPrint -@test GarishPrint.color_scheme().fieldname === Crayon(foreground=:blue) +@test GarishPrint.ColorPreference().fieldname === :blue diff --git a/test/runtests.jl b/test/runtests.jl index cc1ad4a..0339130 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -6,10 +6,6 @@ using Test end end -@testset "colors" begin - include("colors.jl") -end - include("basic.jl") include("configs.jl") include("dataframe.jl")