-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathcrayon_stack.jl
More file actions
100 lines (89 loc) · 4.88 KB
/
Copy pathcrayon_stack.jl
File metadata and controls
100 lines (89 loc) · 4.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# Type for pushing and popping text states
struct CrayonStack
incremental::Bool
crayons::Vector{Crayon}
end
Base.print(io::IO, cs::CrayonStack) = print(io, cs.crayons[end])
Base.show(io::IO, ::MIME"text/plain", cs::CrayonStack) = show(io, MIME("text/plain"), cs.crayons[end])
function CrayonStack(; incremental::Bool = false)
CrayonStack(incremental, [Crayon(ANSIColor(0x9, COLORS_16, !incremental),
ANSIColor(0x9, COLORS_16, !incremental),
ANSIStyle(false, !incremental),
ANSIStyle(false, !incremental),
ANSIStyle(false, !incremental),
ANSIStyle(false, !incremental),
ANSIStyle(false, !incremental),
ANSIStyle(false, !incremental),
ANSIStyle(false, !incremental),
ANSIStyle(false, !incremental),
ANSIStyle(false, !incremental))])
end
# Checks if equal disregarding active or not
_equal(a::ANSIColor, b::ANSIColor) = a.r == b.r && a.g == b.g && a.b == b.b && a.style == b.style
_equal(a::ANSIStyle, b::ANSIStyle) = a.on == b.on
# Currently we have the crayon a on the stack.
# We now want to push the crayon b.
# If in incremental mode we compute the changes needed to achive the state of b.
function _incremental_add(a::ANSIColor, b::ANSIColor, incremental::Bool)
if b.active
return ANSIColor(b.r, b.g, b.b, b.style, !_equal(a, b) || !incremental)
else
return ANSIColor(a.r, a.g, a.b, a.style, !incremental)
end
end
# Similar to above
_incremental_add(a::ANSIStyle, b::ANSIStyle, incremental::Bool) = b.active ? ANSIStyle(b.on, !_equal(a, b) || !incremental) : ANSIStyle(a.on, !incremental)
# Have a, going to b
# State should be exactly as b!
# However, we only want to activate those that are needed, that is
# those that are active in a AND are different from b
_incremental_sub(a::ANSIColor, b::ANSIColor, incremental::Bool) = ANSIColor(b.r, b.g, b.b, b.style, !_equal(a, b) || !incremental)
_incremental_sub(a::ANSIStyle, b::ANSIStyle, incremental::Bool) = ANSIStyle(b.on, !_equal(a, b) || !incremental)
function Base.push!(cs::CrayonStack, c::Crayon)
pc = cs.crayons[end]
push!(cs.crayons, Crayon(
_incremental_add(pc.fg , c.fg , cs.incremental),
_incremental_add(pc.bg , c.bg , cs.incremental),
_incremental_add(pc.reset , c.reset , cs.incremental),
_incremental_add(pc.bold , c.bold , cs.incremental),
_incremental_add(pc.faint , c.faint , cs.incremental),
_incremental_add(pc.italics , c.italics , cs.incremental),
_incremental_add(pc.underline , c.underline , cs.incremental),
_incremental_add(pc.blink , c.blink , cs.incremental),
_incremental_add(pc.negative , c.negative , cs.incremental),
_incremental_add(pc.conceal , c.conceal , cs.incremental),
_incremental_add(pc.strikethrough, c.strikethrough, cs.incremental)))
return cs
end
function Base.pop!(cs::CrayonStack)
length(cs.crayons) == 1 && throw(ArgumentError("no more Crayons left in stack"))
c = pop!(cs.crayons)
pc = cs.crayons[end]
if length(cs.crayons) == 1
pc = Crayon(ANSIColor(0x9, COLORS_16, true),
ANSIColor(0x9, COLORS_16, true),
ANSIStyle(false, true),
ANSIStyle(false, true),
ANSIStyle(false, true),
ANSIStyle(false, true),
ANSIStyle(false, true),
ANSIStyle(false, true),
ANSIStyle(false, true),
ANSIStyle(false, true),
ANSIStyle(false, true))
end
cs.crayons[end] = Crayon(
_incremental_sub(c.fg , pc.fg , cs.incremental),
_incremental_sub(c.bg , pc.bg , cs.incremental),
_incremental_sub(c.reset , pc.reset , cs.incremental),
_incremental_sub(c.bold , pc.bold , cs.incremental),
_incremental_sub(c.faint , pc.faint , cs.incremental),
_incremental_sub(c.italics , pc.italics , cs.incremental),
_incremental_sub(c.underline , pc.underline , cs.incremental),
_incremental_sub(c.blink , pc.blink , cs.incremental),
_incremental_sub(c.negative , pc.negative , cs.incremental),
_incremental_sub(c.conceal , pc.conceal , cs.incremental),
_incremental_sub(c.strikethrough, pc.strikethrough, cs.incremental))
# Return the currently active crayon so we can use print(pop!(crayonstack), "bla")
return cs
end