Skip to content

Commit b897cc9

Browse files
committed
towards crayon removal
1 parent 9cedb34 commit b897cc9

File tree

6 files changed

+71
-105
lines changed

6 files changed

+71
-105
lines changed

Project.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ version = "3.7.0"
99
ColorSchemes = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
1010
ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
1111
Contour = "d38c429a-6771-53c6-b99e-75d170b6e991"
12-
Crayons = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
1312
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
1413
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1514
MarchingCubes = "299715c1-40a9-479a-aaf9-4a633d36f717"
@@ -40,7 +39,6 @@ UnitfulExt = "Unitful"
4039
ColorSchemes = "^3.19"
4140
ColorTypes = "0.11 - 0.12"
4241
Contour = "0.5 - 0.6"
43-
Crayons = "^4.1"
4442
Dates = "1"
4543
FileIO = "1"
4644
FreeType = "4"

src/UnicodePlots.jl

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ using StyledStrings
55
using LinearAlgebra
66
using StaticArrays
77
using ColorTypes
8-
using Crayons
98
using Printf
109
using Dates
1110

@@ -112,19 +111,27 @@ include("interface/boxplot.jl")
112111
include("interface/polarplot.jl")
113112
include("interface/imageplot.jl")
114113

115-
function __init__()
116-
if (terminal_24bit() || forced_24bit()) && !forced_8bit()
117-
truecolors!()
118-
USE_LUT[] ? brightcolors!() : faintcolors!()
119-
else
120-
colors256!()
121-
faintcolors!()
122-
end
114+
function init_24bit()
115+
truecolors!()
116+
USE_LUT[] ? brightcolors!() : faintcolors!()
117+
nothing
118+
end
119+
120+
function init_8bit()
121+
colors256!()
122+
faintcolors!()
123123
nothing
124124
end
125125

126+
function __init__()
127+
forced_24bit() && return init_24bit()
128+
forced_8bit() && return init_8bit()
129+
Base.get_have_truecolor() ? init_24bit() : init_8bit()
130+
end
131+
126132
# COV_EXCL_START
127133
function precompile_workload(io::IO = IOContext(devnull, :color => Base.get_have_color()))
134+
__init__()
128135
surf(x, y) = sinc((x^2 + y^2))
129136
for T in ( # most common types
130137
Float64,

src/common.jl

Lines changed: 53 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ const SUPERSCRIPT = Dict(
152152
############################################################################################
153153
# define types
154154
const MarkerType = Union{Symbol,AbstractChar,AbstractString}
155-
const CrayonColorType = Union{Integer,Symbol,NTuple{3,Integer},Nothing}
156-
const UserColorType = Union{Crayon,CrayonColorType} # allowed color type
155+
const StyledStringsColorType = Union{Integer,Symbol,StyledStrings.RGBTuple,UInt32}
156+
const UserColorType = Union{StyledStrings.Face,StyledStringsColorType,NTuple{3,Integer},Nothing} # allowed color type
157157
const ColorType = UInt32 # internal UnicodePlots color type (on canvas), 8bit or 24bit
158158

159159
############################################################################################
@@ -181,20 +181,17 @@ const UnicodeType = UInt32
181181

182182
############################################################################################
183183
# colors
184+
@enum Colormode COLORMODE_24BIT COLORMODE_8BIT
184185
const THRESHOLD = UInt32(256^3) # 8bit - 24bit threshold
185-
const COLORMODE = Ref(Crayons.COLORS_256)
186+
const COLORMODE = Ref(COLORMODE_24BIT)
186187
const INVALID_COLOR = typemax(ColorType)
187188
const USE_LUT = Ref(false)
188189

189-
const CRAYONS_FAST = Ref(true)
190-
const CRAYONS_EMPTY_STYLES = Tuple(Crayons.ANSIStyle() for _ 1:9)
191-
const CRAYONS_RESET = Crayons.CSI * "0" * Crayons.END_ANSI
192-
193190
const COLOR_CYCLE_FAINT = :green, :blue, :red, :magenta, :yellow, :cyan
194-
const COLOR_CYCLE_BRIGHT = map(s -> Symbol("light_", s), COLOR_CYCLE_FAINT) # COV_EXCL_LINE
191+
const COLOR_CYCLE_BRIGHT = map(s -> Symbol("bright_", s), COLOR_CYCLE_FAINT) # COV_EXCL_LINE
195192
const COLOR_CYCLE = Ref(COLOR_CYCLE_FAINT)
196193

197-
const BORDER_COLOR = Ref(:dark_gray)
194+
const BORDER_COLOR = Ref(:gray)
198195

199196
############################################################################################
200197

@@ -214,17 +211,20 @@ const ASPECT_RATIO = Ref(4 / 3)
214211
const DEFAULT_HEIGHT = Ref(15)
215212
const DEFAULT_WIDTH = Ref(round(Int, DEFAULT_HEIGHT[] * 2ASPECT_RATIO[]))
216213

214+
brightcolors!() = COLOR_CYCLE[] = COLOR_CYCLE_BRIGHT
215+
faintcolors!() = COLOR_CYCLE[] = COLOR_CYCLE_FAINT
216+
217217
colormode() =
218-
if (cm = COLORMODE[]) Crayons.COLORS_256
218+
if (cm = COLORMODE[]) COLORMODE_8BIT
219219
8
220-
elseif cm Crayons.COLORS_24BIT
220+
elseif cm COLORMODE_24BIT
221221
24
222222
else
223223
throw(ArgumentError("color mode $cm is unsupported"))
224224
end
225225

226-
colors256!() = COLORMODE[] = Crayons.COLORS_256
227-
truecolors!() = COLORMODE[] = Crayons.COLORS_24BIT
226+
colors256!() = COLORMODE[] = COLORMODE_8BIT
227+
truecolors!() = COLORMODE[] = COLORMODE_24BIT
228228

229229
function colormode!(mode)
230230
if mode 8
@@ -237,11 +237,6 @@ function colormode!(mode)
237237
nothing
238238
end
239239

240-
brightcolors!() = COLOR_CYCLE[] = COLOR_CYCLE_BRIGHT
241-
faintcolors!() = COLOR_CYCLE[] = COLOR_CYCLE_FAINT
242-
243-
# see gist.github.com/XVilka/8346728#checking-for-colorterm
244-
terminal_24bit() = lowercase(get(ENV, "COLORTERM", "")) ("24bit", "truecolor")
245240

246241
# specific to UnicodePlots
247242
forced_24bit() = lowercase(get(ENV, "UP_COLORMODE", "")) ("24", "24bit", "truecolor")
@@ -444,19 +439,8 @@ function sorted_keys_values(dict::Dict; k2s = true)
444439
first.(keys_vals), last.(keys_vals)
445440
end
446441

447-
crayon_color(::Union{Missing,Nothing}) = Crayons.ANSIColor()
448-
crayon_color(color::ColorType) =
449-
if color INVALID_COLOR
450-
Crayons.ANSIColor()
451-
elseif color < THRESHOLD # 24bit
452-
Crayons.ANSIColor(red(color), grn(color), blu(color), Crayons.COLORS_24BIT)
453-
else # 8bit
454-
Crayons.ANSIColor(color - THRESHOLD, Crayons.COLORS_256)
455-
end
456-
457-
458-
ss_color(::Union{Missing,Nothing}) = nothing
459-
ss_color(color::ColorType) =
442+
styledstrings_color(::Union{Missing,Nothing}) = nothing
443+
styledstrings_color(color::ColorType) =
460444
if color INVALID_COLOR
461445
nothing
462446
elseif color < THRESHOLD # 24bit
@@ -465,33 +449,14 @@ ss_color(color::ColorType) =
465449
StyledStrings.Legacy.legacy_color(Int(color - THRESHOLD))
466450
end
467451

468-
# function print_crayons(io, c, args...)
469-
# if CRAYONS_FAST[]
470-
# if Crayons.anyactive(c) # bypass crayons checks (_have_color, _force_color)
471-
# print(io, Crayons.CSI)
472-
# Crayons._print(io, c)
473-
# print(io, Crayons.END_ANSI, args..., CRAYONS_RESET)
474-
# else
475-
# print(io, args...)
476-
# end
477-
# else
478-
# print(io, c, args..., CRAYONS_RESET)
479-
# end
480-
# end
481-
482-
# print_color(io::IO, color::Crayon, args...) = print_crayons(io, color, args...)
452+
print_color(io::IO, face::StyledStrings.Face, args...) = print(io, StyledStrings.face!(Base.annotatedstring(args...), face))
483453
print_color(io::IO, color::UserColorType, args...) =
484454
print_color(io, ansi_color(color), args...)
485455

486456
function print_color(io::IO, color::ColorType, args...; bgcol = missing)
487457
if get(io, :color, false)
488-
face = StyledStrings.Face(; foreground = ss_color(color), background = ss_color(bgcol))
489-
print(io, StyledStrings.face!(Base.annotatedstring(args...), face))
490-
# print_crayons(
491-
# io,
492-
# Crayon(crayon_color(color), crayon_color(bgcol), CRAYONS_EMPTY_STYLES...),
493-
# args...,
494-
# )
458+
face = StyledStrings.Face(foreground = styledstrings_color(color), background = styledstrings_color(bgcol))
459+
print_color(io, face, args...)
495460
else
496461
print(io, args...)
497462
end
@@ -540,34 +505,48 @@ c256(c::Integer) = c
540505
# `ColorType` conversion - colormaps
541506
ansi_color(rgb::AbstractRGB) = ansi_color((c256(rgb.r), c256(rgb.g), c256(rgb.b)))
542507
ansi_color(rgb::NTuple{3,AbstractFloat}) = ansi_color(c256.(rgb))
508+
ansi_color(color::NTuple{3,Integer})::ColorType = r32(color[1]) + g32(color[2]) + b32(color[3])
543509

544510
ansi_color(color::ColorType)::ColorType = color # no-op
545-
ansi_color(crayon::Crayon) = ansi_color(crayon.fg) # ignore bg & styles
546-
ansi_color(::Missing) = INVALID_COLOR # not a CrayonColorType
511+
ansi_color(face::StyledStrings.Face) = ansi_color(face.foreground) # ignore bg & styles
512+
ansi_color(::Union{Nothing,Missing}) = INVALID_COLOR # not a StyledStringsColorType
547513

548-
function ansi_color(color::CrayonColorType)::ColorType
514+
function ansi_color(color::StyledStringsColorType)::ColorType
549515
ignored_color(color) && return INVALID_COLOR
550-
ansi_color(Crayons._parse_color(color))
516+
ansi_color(StyledStrings.SimpleColor(color))
551517
end
552518

553-
ansi_color(c::Crayons.ANSIColor) = if COLORMODE[] Crayons.COLORS_24BIT
554-
if c.style Crayons.COLORS_24BIT
555-
r32(c.r) + g32(c.g) + b32(c.b)
556-
elseif c.style Crayons.COLORS_256
557-
USE_LUT[] ? LUT_8BIT[c.r + 1] : THRESHOLD + c.r
558-
elseif c.style Crayons.COLORS_16
559-
c8 = ansi_4bit_to_8bit(c.r)
560-
USE_LUT[] ? LUT_8BIT[c8 + 1] : THRESHOLD + c8
519+
function to_256_colors(color)
520+
r, g, b = rgb = color.r, color.g, color.b
521+
ansi = if r == g == b && r % 10 == 8
522+
232 + min((r - 8) ÷ 10, 23) # gray level
523+
elseif all(map(c -> (c & 0x1) == 0 && (c > 0 ? c == 128 || c == 192 : true), rgb))
524+
(r >> 7) + 2(g >> 7) + 4(b >> 7) # primary color
525+
else
526+
r6, g6, b6 = map(c -> c < 48 ? 0 : (c < 114 ? 1 : trunc(Int, (c - 35) / 40)), rgb)
527+
16 + 36r6 + 6g6 + b6 # cube 6x6x6
528+
end
529+
return UInt8(ansi)
530+
end
531+
532+
ansi_color(col::StyledStrings.SimpleColor) = let c = col.value
533+
if COLORMODE[] COLORMODE_24BIT
534+
if c isa Symbol
535+
c4 = get(StyledStrings.ANSI_4BIT_COLORS, c, nothing)
536+
c8 = ansi_4bit_to_8bit(UInt8(c4))
537+
return USE_LUT[] ? LUT_8BIT[c8 + 1] : THRESHOLD + c8
538+
elseif c isa StyledStrings.RGBTuple
539+
return r32(c.r) + g32(c.g) + b32(c.b)
540+
end::ColorType
541+
else # 0-255 ansi stored in a UInt32
542+
return THRESHOLD + if c isa Symbol
543+
c4 = get(StyledStrings.ANSI_4BIT_COLORS, c, nothing)
544+
ansi_4bit_to_8bit(UInt8(c4))
545+
elseif c isa StyledStrings.RGBTuple
546+
to_256_colors(c)
547+
end::UInt8
561548
end::ColorType
562-
else # 0-255 ansi stored in a UInt32
563-
THRESHOLD + if c.style Crayons.COLORS_24BIT
564-
Crayons.to_256_colors(c).r
565-
elseif c.style Crayons.COLORS_256
566-
c.r
567-
elseif c.style Crayons.COLORS_16
568-
ansi_4bit_to_8bit(c.r)
569-
end::UInt8
570-
end::ColorType
549+
end
571550

572551
complement(color::UserColorType)::ColorType = complement(ansi_color(color))
573552
complement(color::ColorType)::ColorType = if color INVALID_COLOR

src/show.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ function _show(end_io::IO, print_nocol, print_color, p::Plot)
225225
border_right_cbar_pad * '\n',
226226
🗹;
227227
p_width = p_width,
228-
color = io_color ? Crayon(foreground = :white, bold = true) : nothing,
228+
color = io_color ? StyledStrings.Face(foreground = :white, weight = :bold) : nothing,
229229
)
230230
h_lbl = print_labels(
231231
io,

test/runtests.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ using TestImages
1919
using ColorTypes
2020
using StableRNGs
2121
using StatsBase
22-
using Crayons
2322
using Unitful
2423

2524
Pkg.status(; outdated = true, mode = Pkg.PKGMODE_MANIFEST)

test/tst_common.jl

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,7 @@ end
8888
@test UnicodePlots.c256(0) == 0
8989
@test UnicodePlots.c256(255) == 255
9090

91-
@test_throws ArgumentError UnicodePlots.colormode!(123456789)
92-
93-
_color_mode = UnicodePlots.colormode()
94-
UnicodePlots.COLORMODE[] = Crayons.COLORS_16 # we only support 8bit or 24bit, not 4bit (terminal dependent)
95-
@test_throws ArgumentError UnicodePlots.colormode()
91+
@test_throws ArgumentError UnicodePlots.colormode!(123_456_789)
9692

9793
UnicodePlots.colors256!()
9894
@test UnicodePlots.ansi_color(0x80) == UnicodePlots.THRESHOLD + 0x80 # ansi 128
@@ -136,8 +132,6 @@ end
136132
@test UnicodePlots.ansi_color(:light_blue) == UnicodePlots.THRESHOLD + 0x0c
137133
UnicodePlots.USE_LUT[] = _lut
138134

139-
UnicodePlots.colormode!(_color_mode)
140-
141135
if true # physical average
142136
@test UnicodePlots.blend_colors(UInt32(0), UInt32(255)) == UInt32(180)
143137
@test UnicodePlots.blend_colors(0xff0000, 0x00ff00) == 0xb4b400 # red & green -> yellow
@@ -153,18 +147,7 @@ end
153147
@test UnicodePlots.complement(UnicodePlots.INVALID_COLOR) == UnicodePlots.INVALID_COLOR
154148
@test UnicodePlots.complement(0x003ae1c3) == 0x00c51e3c
155149

156-
io = PipeBuffer()
157-
_cfast = UnicodePlots.CRAYONS_FAST[]
158-
for fast (false, true)
159-
UnicodePlots.CRAYONS_FAST[] = fast
160-
UnicodePlots.print_crayons(io, Crayon(foreground = :red), 123)
161-
UnicodePlots.print_crayons(io, Crayon(), 123)
162-
end
163-
UnicodePlots.CRAYONS_FAST[] = _cfast
164-
165150
@test UnicodePlots.ignored_color(nothing)
166-
@test UnicodePlots.crayon_color(missing) isa Crayons.ANSIColor
167-
@test UnicodePlots.crayon_color(nothing) isa Crayons.ANSIColor
168151
end
169152

170153
@testset "colormaps" begin

0 commit comments

Comments
 (0)