kristofferc / crayons.jl Goto Github PK
View Code? Open in Web Editor NEWColored and styled strings for terminals.
License: Other
Colored and styled strings for terminals.
License: Other
I know uppercase(str)
works fine, but it would be nice to support it with the syntax in this package.
currently precompile gives the following warning of this package
WARNING: Method definition Any(Union{AbstractString, Crayons.CrayonWrapper}...) in module Crayons at /home/roger/.julia/packages/Crayons/7tJDU/src/crayon_wrapper.jl:6 overwritten on the same line (check for duplicate calls to `include`).
** incremental compilation may be fatally broken for this module **
This may be a feature or a quirk, rather than a bug, but perhaps could be noted in the docs. Also, while the code below that demonstrates the issue only illustrates it with inv(), perhaps it's applicable to any ANSI color setting strings.
The observed behavior (on an Ubuntu 20.04, Linux 5.4.0 system) is that if say Crayon(background = :green)
has been in effect, and an inv() for it is printed after a println() instead of before, then there's a green background for the tail of the upcoming line (which I didn't expect).
#!/usr/bin/env julia
# -*- mode: julia; coding: utf-8 -*-
# Tues 11 Jan 2022 - j-waldby
module testcrayoninv
using Crayons
green = Crayon(background = :green)
blue = Crayon(background = :blue)
function plines(nlines, befor, flu)
perline, lex, c = 1:5, 4, 'a'
println("\nbefor is ", befor, " flu is ", flu)
for l in 1:nlines
print("Line ", l)
if l%4<1 print(green) end
if l%5<1 print(blue) end
for p in perline
lex = (lex+5)%9
c = c<'z' ? c+1 : 'a'
print(" ", join([c for i in 1:lex]))
end
if befor
if l%4<1 print(inv(green)) end
if l%5<1 print(inv(blue)) end
if flu flush(stdout) end
end
println() # Print the inv's before or after this println()
if !befor
if l%4<1 print(inv(green)) end
if l%5<1 print(inv(blue)) end
if flu flush(stdout) end
end
end
end
plines(11, false, true)
plines(11, false, false)
plines(11, true, false)
plines(11, true, true)
end # module
currently the show
method overloaded in this package doesn't respect the :color option in julia IO, which as a result will print extra ASCII chars in Pluto.
This issue is used to trigger TagBot; feel free to unsubscribe.
If you haven't already, you should update your TagBot.yml
to include issue comment triggers.
Please see this post on Discourse for instructions and more details.
If you'd like for me to do this for you, comment TagBot fix
on this issue.
I'll open a PR within a few hours, please be patient!
Those variables are exported but not being defined in Crayons.jl/src/consts.jl
. I guess it is a typo.
LIGHT_YELLOW_F,
LIGHT_MAGENTA_,
LIGHT_YELLOW_B,
LIGHT_MAGENTA_,
Is it possible to define a new name color supported by Crayons.jl
like orange for instance?
Thanks!
The Solarized Dark color scheme is very popular because of it’s eye-friendlyness – but sadly it violates the terminal color specification, because some bright color variants contain very dark tones and the grey tones being too near to the background color tone. This is due to Solarized’s color logic which doesn’t align well with the terminal color palette definition.
Here’s it’s color palette (in German, but I’m sure you get it):
This leads to text parts in Julia not being readable, especially visible in stack traces, see the difference here:
There’s a big Julia thread here JuliaLang/julia#38730, and we already discussed to quite some extent in the DataFrames issue JuliaData/DataFrames.jl#3400.
The best solution seems to let Solarized be broken, because e.g. hard-coding that color would negatively impact all other themes. But because of Solarized’s enormous popularity, it would be nice if we could have a handy manual solution – e.g. being able to define an ENV or execute a config function to alter that color tone. And as it affects whole Julia, it seems to be best implemented in Crayons.
So: Is it possible to implement something like an ENV SOLARIZED_DARK_FIX[=<COLOR>]
which alters that color to a predefined color (terminal colors 242-246 are quite usable, see JuliaData/DataFrames.jl#3400)? Best if a custom color could optionally be specified.
Hello, just wonder if or why this is not implemented:
crayon"red" * "Foo"
Of corse also the other way around and maybe also for Box.
Hello there,
Currently the definition of the ANSIColor struct (in src/crayon.jl) has three fields of type Int
, and an inner constructor that checks the bounds of the values passed to these fields.
I'd like to propose changing the type of these fields to UInt8
. I think using a smaller integer type would:
An alternative would be to parametrize these fields, allowing ANSIColor structs of different sizes.
I'm still new to the Julia language, so if there's a good reason for defining the struct like that, It'd be good to know. I noticed this while setting up OhMyREPL, very cool project, thanks for working on this.
I'm setting colours with Crayons.Box constants. Because the thing being displayed is via show rather than a string literal, I can't use the function application syntax. So I need to manually handle resetting formatting. However, there's no Crayons.Box.RESET crayon to use.
Crayons.test_256_colors(shownumbers::Bool=true)
Crayons.test_24bit_colors(shownumbers::Bool=false)
should probably be codes
, but, also, shouldn't include ::Bool
unless I'm missing something, and also also, it isn't a named argument anyway so it can't even be named regardless.
julia> Crayons.test_256_colors(shownumbers::Bool=true)
ERROR: syntax: invalid keyword argument name "shownumbers::Bool" around REPL[55]:1
The test_256_colors
example above appears in the Readme section "The foreground and background argument can be of three types:". It appears that Crayons.test_256_colors(true) and Crayons.test_256_colors(false) work ok. Same problem applies to Crayons.test_24bit_colors
I get the following message on Julia nightly:
WARNING: Method definition Any(Union{AbstractString, Crayons.CrayonWrapper}...) in module Crayons at /home/bkamins/.julia/packages/Crayons/7tJDU/src/crayon_wrapper.jl:6 overwritten on the same line (check for duplicate calls to `include`).
** incremental compilation may be fatally broken for this module **
on Linux:
Version 1.8.0-DEV.31 (2021-06-14)
Commit 2f1a958826
Is it possible to attach a color to a string without printing it directly?
Or what is the best way to print something like:
a table line A B C D E F
and have the C in green sometimes and sometimes in red?
At the moment it looks like I have do activate it before the C and deactivate it afterwards but can't figure out how to do it with string concatenation.
The tag name "v0.4" is not of the appropriate SemVer form (vX.Y.Z).
cc: @KristofferC
According to https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit:
In the 6x6x6
cube, if I take #ff8700
= rgb(255, 135, 0)
I should land on the ANSI color code 208
.
julia> using Crayons
julia> Crayon(foreground = (255, 135, 0)).fg |> Crayons.to_256_colors |> Crayons.val |> Int
214 # NOK
If instead I use the following :
julia> using Crayons
julia> function cubecolor(c) # see stackoverflow.com/a/27165165
tc = [0, 95, 135, 175, 215, 255]
argmin(abs.(c .- tc)) - 1
end
julia> function to_256_colors(color)
r, g, b = color.r, color.g, color.b
r24, g24, b24 = map(c->round(Int, c * 23 / 256), (r, g, b))
if r24 == g24 == b24
return Crayons.ANSIColor(UInt8(232 + r24), Crayons.COLORS_256, color.active)
else
# r6, g6, b6 = map(c->round(Int, c * 5 / 256), (r, g, b))
r6, g6, b6 = map(c->cubecolor(c), (r, g, b)) # <== note the change
return Crayons.ANSIColor(UInt8(16 + 36 * r6 + 6 * g6 + b6), Crayons.COLORS_256, color.active)
end
end
julia> Crayon(foreground = (255, 135, 0)).fg |> to_256_colors |> Crayons.val |> Int
208 # OK, expected value
Is this a bug ?
I designed that API when I was young and naive (... or something). What I am talking about is:
Alternatively, if the environment variable FORCE_COLOR exist, or Crayons.force_color(::Bool) has been enabled, color sequences are printed no matter what. Also, since relatively few terminals support full 24-bit colors, it is possible to activate 256 color mode which converts the 24-bit crayon to a 256 color crayon when printed. This is done by either defining the variable environment FORCE_256_COLORS or by calling Crayons.force_256_colors(::Bool). In addition, some systems have problems even with 256 colors, it is possible to convert to one of the 16 system colors by defining the variable FORCE_SYSTEM_COLORS or by calling Crayons.force_system_colors(::Bool).
These env variables are checked every time a Crayon is printed which is a system call etc. Should probablt deprecate these and figure out some other way of doing it.
Not sure if this is subject to type piracy, but quite puzzling when I first saw a Crayon popping out of nowhere.
Normal behavior of Base.merge()
before Crayons got imported:
julia> merge()
ERROR: MethodError: no method matching merge()
Closest candidates are:
merge(::AbstractDict, ::AbstractDict...) at abstractdict.jl:286
merge(::Function, ::AbstractDict, ::AbstractDict...) at abstractdict.jl:316
merge(::NamedTuple{(),T} where T<:Tuple, ::NamedTuple) at namedtuple.jl:233
...
Stacktrace:
[1] top-level scope at REPL[1]:1
After:
julia> import Crayons
julia> merge()
julia> ans |> typeof
Crayons.Crayon
It comes from splatting Base.merge(toks::Crayon...)
.
Line 278 in 5950d1d
This was what I've been doing
using Printf
struct Foo
val
end
function Base.show(io::IO, x::Foo)
print(io, "Foo=")
printstyled(io,x.val; color=:yellow)
end
julia>string(Foo(10))
"Foo=10"
And I tired to replace printstyled
with Crayons
using Crayons
struct Foo
val
end
function Base.show(io::IO, x::Foo)
print(io, "Foo=", Crayon(forecround=:yellow), x.val)
end
julia>string(Foo(10))
"Foo=\e[33m10"
Is there way for me to make string
conversion work as before? without overriding the string
method
Hi!
Using Julia-1.8, I am getting some inference problems when calling this function:
write(buf_line, string(crayon))
The relevant information obtained from SnoopCompile is:
││││││││││┌ @ /Users/ronan.arraes/.julia/dev/PrettyTables/src/backends/text/display.jl:326 PrettyTables.string(crayon)
│││││││││││┌ @ strings/io.jl:185 Base.print_to_string(xs...)
││││││││││││┌ @ strings/io.jl:144 Base.print(s, x)
│││││││││││││┌ @ /Users/ronan.arraes/.julia/packages/Crayons/u3AH8/src/crayon.jl:110 Crayons._have_color()
││││││││││││││┌ @ /Users/ronan.arraes/.julia/packages/Crayons/u3AH8/src/crayon.jl:104 Base.get_have_color()
│││││││││││││││┌ @ ttyhascolor.jl:21 Base.ttyhascolor()
││││││││││││││││┌ @ ttyhascolor.jl:7 #self#(Base.get(Base.ENV, "TERM", ""))
│││││││││││││││││┌ @ ttyhascolor.jl:12 Base.success(Base.cmd_gen(Core.tuple(Core.tuple("tput"), Core.tuple("setaf"), Core.tuple("0"))))
││││││││││││││││││┌ @ process.jl:522 Base.success(Base._spawn(cmd))
│││││││││││││││││││┌ @ process.jl:510 Base.test_success(x)
││││││││││││││││││││┌ @ process.jl:503 Base.repr(Base.getproperty(proc, :cmd))
│││││││││││││││││││││┌ @ strings/io.jl:282 Base.#repr#453(Base.nothing, #self#, x)
││││││││││││││││││││││┌ @ strings/io.jl:282 Core.kwfunc(Base.sprint)(Core.apply_type(Core.NamedTuple, (:context,))(Core.tuple(context)), Base.sprint, Base.show, x)
│││││││││││││││││││││││┌ @ strings/io.jl:108 Base.#sprint#450(Core.tuple(context, sizehint, _3, f), args...)
││││││││││││││││││││││││┌ @ strings/io.jl:114 f(Core.tuple(s), args...)
│││││││││││││││││││││││││┌ @ cmd.jl:133 Base.collect(Base.Int, Base.getproperty(cmd, :cpus))
││││││││││││││││││││││││││┌ @ array.jl:647 Base._collect(_, itr, Base.IteratorSize(itr))
│││││││││││││││││││││││││││┌ @ array.jl:649 Base._similar_shape(itr, isz)
││││││││││││││││││││││││││││┌ @ array.jl:663 Base.length(itr)
│││││││││││││││││││││││││││││ no matching method found for call signature (Tuple{typeof(length), Nothing}): Base.length(itr::Nothing)
││││││││││││││││││││││││││││└────────────────
The problem seems related to the function have_color()
. If I change the code to:
write(buf_line, Crayons.CSI)
Crayons._print(buf_line, crayon)
write(buf_line, Crayons.END_ANSI)
The problem is gone and I can see a gain in allocations at first call:
Before: 0.702563 seconds (758.04 k allocations: 41.054 MiB, 1.56% gc time, 99.89% compilation time)
After: 0.645968 seconds (698.16 k allocations: 37.900 MiB, 2.14% gc time, 99.88% compilation time)
Since I am checking if display has colors, is it possible to provide a function to convert a crayon to string without checking if Base has colors?
Note: I can make a PR as soon as you accept this and we select a name (I am terrible in naming things... :D)
I have a package where I show numbers with a red->green color gradient. Is there a function that returns whether 24-bit color is supported?
Alternatively, it would be neat if I could write Crayon(foreground=nearest_ansi_color(121,0,40))
BTW, the README needs to be updated, Crayons.test_256_colors(shownumbers::Bool=true)
doesn't support keyword arguments.
I noticed that Crayons.jl recently bumped the min Julia to 1.6. We have a dependency on Crayons in the VS Code extension (via JuliaFormatter.jl), and our plan is to keep supporting Julia 1.0 for the foreseeable future [*]. Was there a specific reason to drop Julia 1.0 support, or was it just done because why-not? Is there a chance that we could keep supporting Julia 1.0?
[*] The long term plan is that once static compilation can produce small enough binaries that we ship a compiled version of the language server in the VS Code extension, and at that point the code in the LS will no longer have to run on legacy Julia versions, it will then just need to be able to consume legacy Julia code.
I really like crayons but it adds a bit of bloat syntactically. Would it be reasonable to suggest something like the following below?
using Crayons
cols = "black, red, green, yellow, blue, magenta, cyan, light_gray, default, dark_gray, light_red, light_green, light_yellow, light_blue, light_magenta, light_cyan, white"
fxs = "reset, bold, faint, italics, underline, blink, negative, conceal, strikethrough"
for (col, fx) in Iterators.product( split(cols, ", "), split(fxs, ", ") )
name = Symbol(col * "_" * fx)
global colsym = Symbol( col )
global fxsym = Symbol( fx )
@eval $colsym = colsym
@eval $fxsym = fxsym
@eval $name() = Crayon( foreground = $colsym, $fxsym = true)
end
print( magenta_italics(), "woah", cyan_underline(), " wooooo" )
Basically just make it a little less verbose so you don't end up with really long lines of code to print text?
AFAIK, you need to be using print
to get strings with multiple styles. Something like the following doesn't work:
@assert false "This is an " * Crayon(foreground=:red)("error")
This throws an error:
no method matching *(::String, ::Crayons.CrayonWrapper)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.