paintbrush 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/Rakefile +1 -0
- data/lib/paintbrush/bounded_color_element.rb +49 -0
- data/lib/paintbrush/color_element.rb +27 -0
- data/lib/paintbrush/colorized_string.rb +24 -11
- data/lib/paintbrush/colors.rb +1 -9
- data/lib/paintbrush/element_tree.rb +46 -0
- data/lib/paintbrush/escapes.rb +15 -0
- data/lib/paintbrush/version.rb +1 -1
- data/lib/paintbrush.rb +8 -2
- data/rspec-documentation/bundle/introduction.html +312 -0
- data/rspec-documentation/pages/Introduction.md +36 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb568b4656208e4b1d5e134b9a6982a50be63f9da4a776aa7210a302f65a59ce
|
4
|
+
data.tar.gz: cc92c16814e12eb90e089c5affaa6c4739ecbec1f9121093739c6e776e2aaf0f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dbc3a7c11aedf89c5191e1a538b902235c84e7a540b7d155ee008c1ad58e56a2eb4f139f151d681f06ba93fc7345221130ba0972d7d331ac6e793ef8b7752172
|
7
|
+
data.tar.gz: c2bc6bb3a2e09ec5c9aa2d25c47f1b118cf01e2d10eef340e430806531c05421b11e7292d677d96f12112f1d252d64cb1c673a1f50bcf99d6ac8c0a493a98116
|
data/Gemfile.lock
CHANGED
data/Rakefile
CHANGED
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Paintbrush
|
4
|
+
# Wraps a Paintbrush::ColorElement instance and maps its start and end boundaries within a
|
5
|
+
# compiled escaped string by matching specific unique (indexed) escape codes. Provides
|
6
|
+
# `#surround?` for detecting if another element exists within the current element's boundaries.
|
7
|
+
class BoundedColorElement
|
8
|
+
def initialize(color_element:, escaped_output:)
|
9
|
+
@color_element = color_element
|
10
|
+
@escaped_output = escaped_output
|
11
|
+
end
|
12
|
+
|
13
|
+
def surround?(element)
|
14
|
+
return false if element == self
|
15
|
+
return false unless element.open_index.between?(open_index, close_index)
|
16
|
+
return false unless element.close_index.between?(open_index, close_index)
|
17
|
+
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
def inspect
|
22
|
+
"<#{self.class} boundaries=#{boundaries}>"
|
23
|
+
end
|
24
|
+
|
25
|
+
def index
|
26
|
+
color_element.index
|
27
|
+
end
|
28
|
+
|
29
|
+
def code
|
30
|
+
color_element.code
|
31
|
+
end
|
32
|
+
|
33
|
+
def boundaries
|
34
|
+
@boundaries ||= [open_index, close_index]
|
35
|
+
end
|
36
|
+
|
37
|
+
def open_index
|
38
|
+
@open_index ||= escaped_output.index(Escapes.open(index))
|
39
|
+
end
|
40
|
+
|
41
|
+
def close_index
|
42
|
+
escaped_output.index(Escapes.close(index))
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
attr_reader :escaped_output, :color_element
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Paintbrush
|
4
|
+
# Provides a substring enclosed in unique escape codes for later colorization when the full
|
5
|
+
# string has been created and all interpolation is completed. Adds itself to a provided stack
|
6
|
+
# of ColorElement objects on initialization.
|
7
|
+
class ColorElement
|
8
|
+
attr_reader :stack, :code, :string, :index
|
9
|
+
attr_accessor :open_index, :close_index
|
10
|
+
|
11
|
+
def initialize(stack:, code:, string:)
|
12
|
+
@stack = stack
|
13
|
+
@code = code
|
14
|
+
@string = string
|
15
|
+
@index = stack.size
|
16
|
+
stack << self
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
"#{Escapes.open(index)}#{string}#{Escapes.close(index)}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def inspect
|
24
|
+
"<#{self.class.name} index=#{index} code=#{code}>"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -7,7 +7,7 @@ module Paintbrush
|
|
7
7
|
class ColorizedString
|
8
8
|
def initialize(&block)
|
9
9
|
@block = block
|
10
|
-
@
|
10
|
+
@stack = []
|
11
11
|
end
|
12
12
|
|
13
13
|
# Returns a colorized string by injecting escape codes into the various calls to each color
|
@@ -19,30 +19,43 @@ module Paintbrush
|
|
19
19
|
|
20
20
|
private
|
21
21
|
|
22
|
-
attr_reader :block, :
|
22
|
+
attr_reader :block, :stack
|
23
23
|
|
24
|
-
def colorized_string
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
def colorized_string(string: escaped_output, tree: element_tree)
|
25
|
+
tree[:children].reduce(string) do |output, child|
|
26
|
+
subbed = subbed_string(output, child[:node], tree[:node])
|
27
|
+
next subbed if child[:children].empty?
|
28
|
+
|
29
|
+
colorized_string(string: subbed, tree: child)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def bounded_color_elements
|
34
|
+
@bounded_color_elements ||= stack.map do |color_element|
|
35
|
+
BoundedColorElement.new(color_element: color_element, escaped_output: escaped_output)
|
28
36
|
end
|
29
37
|
end
|
30
38
|
|
31
|
-
def
|
39
|
+
def element_tree
|
40
|
+
@element_tree ||= ElementTree.new(bounded_color_elements: bounded_color_elements).tree
|
41
|
+
end
|
42
|
+
|
43
|
+
def subbed_string(string, color_element, parent_color_element)
|
44
|
+
restored_color_code = parent_color_element.nil? ? '0' : parent_color_element.code
|
32
45
|
string
|
33
|
-
.sub(
|
34
|
-
.sub(
|
46
|
+
.sub(Escapes.open(color_element.index).to_s, "\e[#{color_element.code}m")
|
47
|
+
.sub(Escapes.close(color_element.index).to_s, "\e[0m\e[#{restored_color_code}m")
|
35
48
|
end
|
36
49
|
|
37
50
|
def escaped_output
|
38
|
-
context.instance_eval(&block)
|
51
|
+
@escaped_output ||= context.instance_eval(&block)
|
39
52
|
end
|
40
53
|
|
41
54
|
def context
|
42
55
|
eval('self', block.binding, __FILE__, __LINE__).dup.tap do |context|
|
43
56
|
context.send(:include, Paintbrush::Colors) if context.respond_to?(:include)
|
44
57
|
context.send(:extend, Paintbrush::Colors) if context.respond_to?(:extend)
|
45
|
-
context.send(:instance_variable_set, :@
|
58
|
+
context.send(:instance_variable_set, :@__stack, stack)
|
46
59
|
end
|
47
60
|
end
|
48
61
|
end
|
data/lib/paintbrush/colors.rb
CHANGED
@@ -6,11 +6,6 @@ module Paintbrush
|
|
6
6
|
# string to be reconstituted afterwards with nested strings restoring the previous color once
|
7
7
|
# they have terminated.
|
8
8
|
module Colors
|
9
|
-
ESCAPE_START_OPEN = "\e[3;15;17]OPEN:"
|
10
|
-
ESCAPE_START_CLOSE = "\e[3;15;17]CLOSE:"
|
11
|
-
ESCAPE_END_OPEN = "\e[17;15;3]OPEN:"
|
12
|
-
ESCAPE_END_CLOSE = "\e[17;15;3]CLOSE:"
|
13
|
-
|
14
9
|
COLOR_CODES = {
|
15
10
|
black: '30',
|
16
11
|
red: '31',
|
@@ -25,10 +20,7 @@ module Paintbrush
|
|
25
20
|
|
26
21
|
COLOR_CODES.each do |name, code|
|
27
22
|
define_method name do |string|
|
28
|
-
|
29
|
-
"#{ESCAPE_START_OPEN}#{@__codes.size - 1}#{ESCAPE_START_CLOSE}" \
|
30
|
-
"#{string}" \
|
31
|
-
"#{ESCAPE_END_OPEN}#{@__codes.size - 1}#{ESCAPE_END_CLOSE}"
|
23
|
+
ColorElement.new(stack: @__stack, code: code, string: string).to_s
|
32
24
|
end
|
33
25
|
end
|
34
26
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Paintbrush
|
4
|
+
# A tree of BoundedColorElement objects. Used to build a full tree of colorized substrings in
|
5
|
+
# order to allow discovery of parent substrings and use their color code to restore to when the
|
6
|
+
# substring is terminated. Allows deeply-nested colorized strings.
|
7
|
+
class ElementTree
|
8
|
+
attr_reader :tree
|
9
|
+
|
10
|
+
def initialize(bounded_color_elements:)
|
11
|
+
@bounded_color_elements = bounded_color_elements
|
12
|
+
@tree = { node: nil, children: [] }
|
13
|
+
build_tree(boundary_end: bounded_color_elements.map(&:close_index).max)
|
14
|
+
end
|
15
|
+
|
16
|
+
def build_tree(boundary_end:, root: @tree, elements: bounded_color_elements, boundary_start: 0)
|
17
|
+
root_nodes, non_root_nodes = partitioned_elements(elements, boundary_start, boundary_end)
|
18
|
+
|
19
|
+
root_nodes.each do |node|
|
20
|
+
root[:children] << child_node(node)
|
21
|
+
build_tree(
|
22
|
+
root: root[:children].last,
|
23
|
+
elements: non_root_nodes,
|
24
|
+
boundary_start: node.open_index,
|
25
|
+
boundary_end: node.close_index
|
26
|
+
)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :bounded_color_elements
|
33
|
+
|
34
|
+
def child_node(node)
|
35
|
+
{ node: node, children: [] }
|
36
|
+
end
|
37
|
+
|
38
|
+
def partitioned_elements(elements, boundary_start, boundary_end)
|
39
|
+
elements.partition do |element|
|
40
|
+
next false if elements.any? { |child| child.surround?(element) }
|
41
|
+
|
42
|
+
element.boundaries.all? { |index| index.between?(boundary_start, boundary_end) }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Paintbrush
|
4
|
+
# Provides an authority on escape code generation. Provides `.close` and `.open`, both of which
|
5
|
+
# receive an index (i.e. the current size of the stack). Used for escape code insertion and comparison.
|
6
|
+
module Escapes
|
7
|
+
def self.open(index)
|
8
|
+
"\e[3;15;17]START_OPEN:#{index}:\e[3;15;17]START_CLOSE"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.close(index)
|
12
|
+
"\e[17;15;3]END_OPEN:#{index}:\e[17;15;3]END_CLOSE"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/paintbrush/version.rb
CHANGED
data/lib/paintbrush.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'paintbrush/version'
|
4
|
+
require_relative 'paintbrush/escapes'
|
4
5
|
require_relative 'paintbrush/colors'
|
5
6
|
require_relative 'paintbrush/colorized_string'
|
7
|
+
require_relative 'paintbrush/color_element'
|
8
|
+
require_relative 'paintbrush/bounded_color_element'
|
9
|
+
require_relative 'paintbrush/element_tree'
|
6
10
|
|
7
11
|
# Colorizes a string, provides `#paintbrush`. When included/extended in a class, call
|
8
12
|
# `#paintbrush` and pass a block to use the provided dynamically defined methods, e.g.:
|
@@ -16,9 +20,11 @@ require_relative 'paintbrush/colorized_string'
|
|
16
20
|
# end
|
17
21
|
# ```
|
18
22
|
module Paintbrush
|
19
|
-
|
23
|
+
def self.paintbrush(&block)
|
24
|
+
ColorizedString.new(&block).colorized
|
25
|
+
end
|
20
26
|
|
21
27
|
def paintbrush(&block)
|
22
|
-
|
28
|
+
Paintbrush.paintbrush(&block)
|
23
29
|
end
|
24
30
|
end
|
@@ -0,0 +1,312 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<link rel="stylesheet"
|
4
|
+
href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/css/bootstrap.min.css"
|
5
|
+
integrity="sha512-SbiR/eusphKoMVVXysTKG/7VseWii+Y3FdHrt0EpKgpToZeemhqHeZeLWLhJutz/2ut2Vw1uQEj2MbRF+TVBUA=="
|
6
|
+
crossorigin="anonymous"
|
7
|
+
referrerpolicy="no-referrer" />
|
8
|
+
<style>
|
9
|
+
|
10
|
+
.code {
|
11
|
+
font-family: monospace;
|
12
|
+
max-height: 30rem;
|
13
|
+
overflow-y: auto;
|
14
|
+
}
|
15
|
+
|
16
|
+
h1.title {
|
17
|
+
display: inline;
|
18
|
+
}
|
19
|
+
|
20
|
+
.header .separator {
|
21
|
+
display: inline-block;
|
22
|
+
height: 2.5rem;
|
23
|
+
}
|
24
|
+
|
25
|
+
.version {
|
26
|
+
color: #bbb;
|
27
|
+
font-size: 2rem;
|
28
|
+
}
|
29
|
+
|
30
|
+
.ansi-html {
|
31
|
+
display: inline-block;
|
32
|
+
background-color: #2e2e2e;
|
33
|
+
border: 5px solid #2e2e2e;
|
34
|
+
border-radius: 10px;
|
35
|
+
}
|
36
|
+
|
37
|
+
.ansi-html .ansi-color-0 { color: #555555; }
|
38
|
+
.ansi-html .ansi-color-1 { color: #ff0000; }
|
39
|
+
.ansi-html .ansi-color-2 { color: #47ff47; }
|
40
|
+
.ansi-html .ansi-color-3 { color: #e9e947; }
|
41
|
+
.ansi-html .ansi-color-4 { color: #49a0dd; }
|
42
|
+
.ansi-html .ansi-color-5 { color: #8d7eeb; }
|
43
|
+
.ansi-html .ansi-color-6 { color: #2eecff; }
|
44
|
+
.ansi-html .ansi-color-7 { color: #ffffff; }
|
45
|
+
.ansi-html .ansi-color-9 { color: #606060; }
|
46
|
+
.ansi-html .ansi-color-reset { color: #dddddd; }
|
47
|
+
|
48
|
+
.highlight table td { padding: 5px; }
|
49
|
+
.highlight table pre { margin: 0; }
|
50
|
+
.highlight, .highlight .w {
|
51
|
+
color: #24292f;
|
52
|
+
background-color: #f6f8fa;
|
53
|
+
}
|
54
|
+
.highlight .k, .highlight .kd, .highlight .kn, .highlight .kp, .highlight .kr, .highlight .kt, .highlight .kv {
|
55
|
+
color: #cf222e;
|
56
|
+
}
|
57
|
+
.highlight .gr {
|
58
|
+
color: #f6f8fa;
|
59
|
+
}
|
60
|
+
.highlight .gd {
|
61
|
+
color: #82071e;
|
62
|
+
background-color: #ffebe9;
|
63
|
+
}
|
64
|
+
.highlight .nb {
|
65
|
+
color: #953800;
|
66
|
+
}
|
67
|
+
.highlight .nc {
|
68
|
+
color: #953800;
|
69
|
+
}
|
70
|
+
.highlight .no {
|
71
|
+
color: #953800;
|
72
|
+
}
|
73
|
+
.highlight .nn {
|
74
|
+
color: #953800;
|
75
|
+
}
|
76
|
+
.highlight .sr {
|
77
|
+
color: #116329;
|
78
|
+
}
|
79
|
+
.highlight .na {
|
80
|
+
color: #116329;
|
81
|
+
}
|
82
|
+
.highlight .nt {
|
83
|
+
color: #116329;
|
84
|
+
}
|
85
|
+
.highlight .gi {
|
86
|
+
color: #116329;
|
87
|
+
background-color: #dafbe1;
|
88
|
+
}
|
89
|
+
.highlight .kc {
|
90
|
+
color: #0550ae;
|
91
|
+
}
|
92
|
+
.highlight .l, .highlight .ld, .highlight .m, .highlight .mb, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mx {
|
93
|
+
color: #0550ae;
|
94
|
+
}
|
95
|
+
.highlight .sb {
|
96
|
+
color: #0550ae;
|
97
|
+
}
|
98
|
+
.highlight .bp {
|
99
|
+
color: #0550ae;
|
100
|
+
}
|
101
|
+
.highlight .ne {
|
102
|
+
color: #0550ae;
|
103
|
+
}
|
104
|
+
.highlight .nl {
|
105
|
+
color: #0550ae;
|
106
|
+
}
|
107
|
+
.highlight .py {
|
108
|
+
color: #0550ae;
|
109
|
+
}
|
110
|
+
.highlight .nv, .highlight .vc, .highlight .vg, .highlight .vi, .highlight .vm {
|
111
|
+
color: #0550ae;
|
112
|
+
}
|
113
|
+
.highlight .o, .highlight .ow {
|
114
|
+
color: #0550ae;
|
115
|
+
}
|
116
|
+
.highlight .gh {
|
117
|
+
color: #0550ae;
|
118
|
+
font-weight: bold;
|
119
|
+
}
|
120
|
+
.highlight .gu {
|
121
|
+
color: #0550ae;
|
122
|
+
font-weight: bold;
|
123
|
+
}
|
124
|
+
.highlight .s, .highlight .sa, .highlight .sc, .highlight .dl, .highlight .sd, .highlight .s2, .highlight .se, .highlight .sh, .highlight .sx, .highlight .s1, .highlight .ss {
|
125
|
+
color: #0a3069;
|
126
|
+
}
|
127
|
+
.highlight .nd {
|
128
|
+
color: #8250df;
|
129
|
+
}
|
130
|
+
.highlight .nf, .highlight .fm {
|
131
|
+
color: #8250df;
|
132
|
+
}
|
133
|
+
.highlight .err {
|
134
|
+
color: #f6f8fa;
|
135
|
+
background-color: #82071e;
|
136
|
+
}
|
137
|
+
.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cp, .highlight .cpf, .highlight .c1, .highlight .cs {
|
138
|
+
color: #6e7781;
|
139
|
+
}
|
140
|
+
.highlight .gl {
|
141
|
+
color: #6e7781;
|
142
|
+
}
|
143
|
+
.highlight .gt {
|
144
|
+
color: #6e7781;
|
145
|
+
}
|
146
|
+
.highlight .ni {
|
147
|
+
color: #24292f;
|
148
|
+
}
|
149
|
+
.highlight .si {
|
150
|
+
color: #24292f;
|
151
|
+
}
|
152
|
+
.highlight .ge {
|
153
|
+
color: #24292f;
|
154
|
+
font-style: italic;
|
155
|
+
}
|
156
|
+
.highlight .gs {
|
157
|
+
color: #24292f;
|
158
|
+
font-weight: bold;
|
159
|
+
}
|
160
|
+
|
161
|
+
</style>
|
162
|
+
</head>
|
163
|
+
|
164
|
+
<body>
|
165
|
+
<div class="container m-3 p-3">
|
166
|
+
<div class="header p-3 m-3 w-90 text-end">
|
167
|
+
<h1 class="title">paintbrush</h1>
|
168
|
+
<span class="separator border-end pb-2 ms-2 me-2"></span>
|
169
|
+
<span class="version">0.1.0</span>
|
170
|
+
</div>
|
171
|
+
|
172
|
+
<hr/>
|
173
|
+
|
174
|
+
|
175
|
+
<div class="row">
|
176
|
+
<div class="col-auto page-tree fs-6 mt-1 ms-3 me-3">
|
177
|
+
|
178
|
+
<li>
|
179
|
+
|
180
|
+
<a href='/home/bob/dev/paintbrush/rspec-documentation/bundle/introduction.html'>Introduction</a>
|
181
|
+
|
182
|
+
</li>
|
183
|
+
|
184
|
+
<ul>
|
185
|
+
|
186
|
+
</ul>
|
187
|
+
|
188
|
+
</div>
|
189
|
+
|
190
|
+
<div class="col">
|
191
|
+
<h1 id="paintbrush">Paintbrush</h1>
|
192
|
+
|
193
|
+
<p>Simple and concise string colorization for <em>Ruby</em> without overloading <code>String</code> methods or requiring verbose class/method invocation.</p>
|
194
|
+
|
195
|
+
<p><em>Paintbrush</em> has zero dependencies and does not pollute any namespaces or objects outside of the <code>#paintbrush</code> method wherever you include the <code>Paintbrush</code> module.</p>
|
196
|
+
|
197
|
+
<p>Nesting is supported, allowing you to use multiple colors within the same string. The previous color is automatically restored.</p>
|
198
|
+
|
199
|
+
<div location="9"><button type="button" class="btn btn-primary float-end" data-bs-toggle="modal" data-bs-target="#modal-15cae418-087d-45aa-b936-ea2c34033c01-side-by-side"> View Side-by-side </button> <div class="modal fade" id="modal-15cae418-087d-45aa-b936-ea2c34033c01-side-by-side" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
200
|
+
<div class="modal-dialog modal-xl">
|
201
|
+
<div class="modal-content">
|
202
|
+
<div class="modal-header">
|
203
|
+
<h5 class="modal-title" id="modal-15cae418-087d-45aa-b936-ea2c34033c01-side-by-side-label">Side-by-side view</h5>
|
204
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
205
|
+
</div>
|
206
|
+
<div class="modal-body">
|
207
|
+
<div class="container p-3">
|
208
|
+
<div class="row border">
|
209
|
+
<div class="col border">
|
210
|
+
<div class="p-3 mb-5 code highlight">
|
211
|
+
<span class="nb">require</span> <span class="s1">'paintbrush'</span><br /><br /><span class="kp">extend</span> <span class="no">Paintbrush</span><br /><br /><span class="n">output</span> <span class="o">=</span> <span class="n">paintbrush</span> <span class="p">{</span> <span class="n">purple</span> <span class="s2">"You used </span><span class="si">#{</span><span class="n">green</span> <span class="s1">'four'</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">blue</span> <span class="s2">"(</span><span class="si">#{</span><span class="n">cyan</span> <span class="s1">'4'</span><span class="si">}</span><span class="s2">)"</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">yellow</span> <span class="s1">'colors'</span><span class="si">}</span><span class="s2"> today!"</span> <span class="p">}</span><br /><span class="n">it_documents</span> <span class="n">output</span> <span class="k">do</span><br /> <span class="n">expect</span><span class="p">(</span><span class="n">output</span><span class="p">).</span><span class="nf">to</span> <span class="n">eql</span> <span class="s2">"</span><span class="se">\e</span><span class="s2">[35mYou used </span><span class="se">\e</span><span class="s2">[32mfour</span><span class="se">\e</span><span class="s2">[0m</span><span class="se">\e</span><span class="s2">[35m "</span> <span class="p">\</span><br /> <span class="s2">"</span><span class="se">\e</span><span class="s2">[34m(</span><span class="se">\e</span><span class="s2">[36m4</span><span class="se">\e</span><span class="s2">[0m</span><span class="se">\e</span><span class="s2">[34m)</span><span class="se">\e</span><span class="s2">[0m</span><span class="se">\e</span><span class="s2">[35m "</span> <span class="p">\</span><br /> <span class="s2">"</span><span class="se">\e</span><span class="s2">[33mcolors</span><span class="se">\e</span><span class="s2">[0m</span><span class="se">\e</span><span class="s2">[35m today!</span><span class="se">\e</span><span class="s2">[0m</span><span class="se">\e</span><span class="s2">[0m"</span><br /><span class="k">end</span><br />
|
212
|
+
</div>
|
213
|
+
</div>
|
214
|
+
<div class="col border">
|
215
|
+
<div class="p-3 mb-5 code highlight">
|
216
|
+
<div class="ansi-html border m-1 p-4">
|
217
|
+
<span></span><span class="ansi-color-5">You used </span><span class="ansi-color-2">four</span><span class="ansi-color-reset"></span><span class="ansi-color-5"> </span><span class="ansi-color-4">(</span><span class="ansi-color-6">4</span><span class="ansi-color-reset"></span><span class="ansi-color-4">)</span><span class="ansi-color-reset"></span><span class="ansi-color-5"> </span><span class="ansi-color-3">colors</span><span class="ansi-color-reset"></span><span class="ansi-color-5"> today!</span><span class="ansi-color-reset"></span><span class="ansi-color-reset"></span>
|
218
|
+
</div>
|
219
|
+
</div>
|
220
|
+
</div>
|
221
|
+
</div>
|
222
|
+
</div>
|
223
|
+
</div>
|
224
|
+
<div class="modal-footer">
|
225
|
+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
226
|
+
</div>
|
227
|
+
</div>
|
228
|
+
</div>
|
229
|
+
</div>
|
230
|
+
<ul class="nav nav-tabs" id="html-tabs-15cae418-087d-45aa-b936-ea2c34033c01" role="tablist">
|
231
|
+
<li class="nav-item" role="presentation"><button class="nav-link active" id="code-source-15cae418-087d-45aa-b936-ea2c34033c01-tab" data-bs-toggle="tab" data-bs-target="#code-source-15cae418-087d-45aa-b936-ea2c34033c01" type="button" role="tab" aria-controls="code-source" aria-selected="true">Code</button></li>
|
232
|
+
<li class="nav-item" role="presentation"><button class="nav-link" id="rendered-15cae418-087d-45aa-b936-ea2c34033c01-tab" data-bs-toggle="tab" data-bs-target="#rendered-15cae418-087d-45aa-b936-ea2c34033c01" type="button" role="tab" aria-controls="rendered" aria-selected="false">Output</button></li>
|
233
|
+
</ul>
|
234
|
+
<div class="tab-content" id="html-tab-content-15cae418-087d-45aa-b936-ea2c34033c01">
|
235
|
+
<div class="tab-pane fade show active" id="code-source-15cae418-087d-45aa-b936-ea2c34033c01" role="tabpanel" aria-labelledby="code-source-15cae418-087d-45aa-b936-ea2c34033c01-tab">
|
236
|
+
<div class="p-3 mb-5 code highlight">
|
237
|
+
<span class="nb">require</span> <span class="s1">'paintbrush'</span><br /><br /><span class="kp">extend</span> <span class="no">Paintbrush</span><br /><br /><span class="n">output</span> <span class="o">=</span> <span class="n">paintbrush</span> <span class="p">{</span> <span class="n">purple</span> <span class="s2">"You used </span><span class="si">#{</span><span class="n">green</span> <span class="s1">'four'</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">blue</span> <span class="s2">"(</span><span class="si">#{</span><span class="n">cyan</span> <span class="s1">'4'</span><span class="si">}</span><span class="s2">)"</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">yellow</span> <span class="s1">'colors'</span><span class="si">}</span><span class="s2"> today!"</span> <span class="p">}</span><br /><span class="n">it_documents</span> <span class="n">output</span> <span class="k">do</span><br /> <span class="n">expect</span><span class="p">(</span><span class="n">output</span><span class="p">).</span><span class="nf">to</span> <span class="n">eql</span> <span class="s2">"</span><span class="se">\e</span><span class="s2">[35mYou used </span><span class="se">\e</span><span class="s2">[32mfour</span><span class="se">\e</span><span class="s2">[0m</span><span class="se">\e</span><span class="s2">[35m "</span> <span class="p">\</span><br /> <span class="s2">"</span><span class="se">\e</span><span class="s2">[34m(</span><span class="se">\e</span><span class="s2">[36m4</span><span class="se">\e</span><span class="s2">[0m</span><span class="se">\e</span><span class="s2">[34m)</span><span class="se">\e</span><span class="s2">[0m</span><span class="se">\e</span><span class="s2">[35m "</span> <span class="p">\</span><br /> <span class="s2">"</span><span class="se">\e</span><span class="s2">[33mcolors</span><span class="se">\e</span><span class="s2">[0m</span><span class="se">\e</span><span class="s2">[35m today!</span><span class="se">\e</span><span class="s2">[0m</span><span class="se">\e</span><span class="s2">[0m"</span><br /><span class="k">end</span><br />
|
238
|
+
</div>
|
239
|
+
</div>
|
240
|
+
<div class="tab-pane fade" id="rendered-15cae418-087d-45aa-b936-ea2c34033c01" role="tabpanel" aria-labelledby="rendered-15cae418-087d-45aa-b936-ea2c34033c01-tab">
|
241
|
+
<div class="p-3 mb-5 code highlight">
|
242
|
+
<div class="ansi-html border m-1 p-4">
|
243
|
+
<span></span><span class="ansi-color-5">You used </span><span class="ansi-color-2">four</span><span class="ansi-color-reset"></span><span class="ansi-color-5"> </span><span class="ansi-color-4">(</span><span class="ansi-color-6">4</span><span class="ansi-color-reset"></span><span class="ansi-color-4">)</span><span class="ansi-color-reset"></span><span class="ansi-color-5"> </span><span class="ansi-color-3">colors</span><span class="ansi-color-reset"></span><span class="ansi-color-5"> today!</span><span class="ansi-color-reset"></span><span class="ansi-color-reset"></span>
|
244
|
+
</div>
|
245
|
+
</div>
|
246
|
+
</div>
|
247
|
+
</div>
|
248
|
+
</div>
|
249
|
+
|
250
|
+
<div location="22"><button type="button" class="btn btn-primary float-end" data-bs-toggle="modal" data-bs-target="#modal-c3e2bbb8-9a13-4400-93a1-0e6c9847cba0-side-by-side"> View Side-by-side </button> <div class="modal fade" id="modal-c3e2bbb8-9a13-4400-93a1-0e6c9847cba0-side-by-side" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
251
|
+
<div class="modal-dialog modal-xl">
|
252
|
+
<div class="modal-content">
|
253
|
+
<div class="modal-header">
|
254
|
+
<h5 class="modal-title" id="modal-c3e2bbb8-9a13-4400-93a1-0e6c9847cba0-side-by-side-label">Side-by-side view</h5>
|
255
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
256
|
+
</div>
|
257
|
+
<div class="modal-body">
|
258
|
+
<div class="container p-3">
|
259
|
+
<div class="row border">
|
260
|
+
<div class="col border">
|
261
|
+
<div class="p-3 mb-5 code highlight">
|
262
|
+
<span class="nb">require</span> <span class="s1">'paintbrush'</span><br /><br /><span class="kp">extend</span> <span class="no">Paintbrush</span><br /><br /><span class="n">output</span> <span class="o">=</span> <span class="n">paintbrush</span> <span class="k">do</span><br /> <span class="s2">"</span><span class="si">#{</span><span class="n">blue</span> <span class="s1">'foo'</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">green</span> <span class="s2">"bar </span><span class="si">#{</span><span class="n">cyan</span> <span class="sx">%w[foo bar baz]</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="s1">', '</span><span class="p">)</span><span class="si">}</span><span class="s2"> with </span><span class="si">#{</span><span class="n">cyan</span> <span class="s1">'qux'</span><span class="si">}</span><span class="s2"> and quux"</span><span class="si">}</span><span class="s2"> and corge"</span><br /><span class="k">end</span><br /><br /><span class="n">it_documents</span> <span class="n">output</span> <span class="k">do</span><br /> <span class="n">expect</span><span class="p">(</span><span class="n">output</span><span class="p">).</span><span class="nf">to</span> <span class="n">eql</span> <span class="s2">"</span><span class="se">\e</span><span class="s2">[34mfoo</span><span class="se">\e</span><span class="s2">[0m</span><span class="se">\e</span><span class="s2">[0m </span><span class="se">\e</span><span class="s2">[32mbar </span><span class="se">\e</span><span class="s2">[36mfoo, bar, baz"</span> <span class="p">\</span><br /> <span class="s2">"</span><span class="se">\e</span><span class="s2">[0m</span><span class="se">\e</span><span class="s2">[32m with </span><span class="se">\e</span><span class="s2">[36mqux</span><span class="se">\e</span><span class="s2">[0m</span><span class="se">\e</span><span class="s2">[32m "</span><span class="p">\</span><br /> <span class="s2">"and quux</span><span class="se">\e</span><span class="s2">[0m</span><span class="se">\e</span><span class="s2">[0m and corge"</span><br /><span class="k">end</span><br />
|
263
|
+
</div>
|
264
|
+
</div>
|
265
|
+
<div class="col border">
|
266
|
+
<div class="p-3 mb-5 code highlight">
|
267
|
+
<div class="ansi-html border m-1 p-4">
|
268
|
+
<span></span><span class="ansi-color-4">foo</span><span class="ansi-color-reset"></span><span class="ansi-color-reset"> </span><span class="ansi-color-2">bar </span><span class="ansi-color-6">foo, bar, baz</span><span class="ansi-color-reset"></span><span class="ansi-color-2"> with </span><span class="ansi-color-6">qux</span><span class="ansi-color-reset"></span><span class="ansi-color-2"> and quux</span><span class="ansi-color-reset"></span><span class="ansi-color-reset"> and corge</span>
|
269
|
+
</div>
|
270
|
+
</div>
|
271
|
+
</div>
|
272
|
+
</div>
|
273
|
+
</div>
|
274
|
+
</div>
|
275
|
+
<div class="modal-footer">
|
276
|
+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
277
|
+
</div>
|
278
|
+
</div>
|
279
|
+
</div>
|
280
|
+
</div>
|
281
|
+
<ul class="nav nav-tabs" id="html-tabs-c3e2bbb8-9a13-4400-93a1-0e6c9847cba0" role="tablist">
|
282
|
+
<li class="nav-item" role="presentation"><button class="nav-link active" id="code-source-c3e2bbb8-9a13-4400-93a1-0e6c9847cba0-tab" data-bs-toggle="tab" data-bs-target="#code-source-c3e2bbb8-9a13-4400-93a1-0e6c9847cba0" type="button" role="tab" aria-controls="code-source" aria-selected="true">Code</button></li>
|
283
|
+
<li class="nav-item" role="presentation"><button class="nav-link" id="rendered-c3e2bbb8-9a13-4400-93a1-0e6c9847cba0-tab" data-bs-toggle="tab" data-bs-target="#rendered-c3e2bbb8-9a13-4400-93a1-0e6c9847cba0" type="button" role="tab" aria-controls="rendered" aria-selected="false">Output</button></li>
|
284
|
+
</ul>
|
285
|
+
<div class="tab-content" id="html-tab-content-c3e2bbb8-9a13-4400-93a1-0e6c9847cba0">
|
286
|
+
<div class="tab-pane fade show active" id="code-source-c3e2bbb8-9a13-4400-93a1-0e6c9847cba0" role="tabpanel" aria-labelledby="code-source-c3e2bbb8-9a13-4400-93a1-0e6c9847cba0-tab">
|
287
|
+
<div class="p-3 mb-5 code highlight">
|
288
|
+
<span class="nb">require</span> <span class="s1">'paintbrush'</span><br /><br /><span class="kp">extend</span> <span class="no">Paintbrush</span><br /><br /><span class="n">output</span> <span class="o">=</span> <span class="n">paintbrush</span> <span class="k">do</span><br /> <span class="s2">"</span><span class="si">#{</span><span class="n">blue</span> <span class="s1">'foo'</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">green</span> <span class="s2">"bar </span><span class="si">#{</span><span class="n">cyan</span> <span class="sx">%w[foo bar baz]</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="s1">', '</span><span class="p">)</span><span class="si">}</span><span class="s2"> with </span><span class="si">#{</span><span class="n">cyan</span> <span class="s1">'qux'</span><span class="si">}</span><span class="s2"> and quux"</span><span class="si">}</span><span class="s2"> and corge"</span><br /><span class="k">end</span><br /><br /><span class="n">it_documents</span> <span class="n">output</span> <span class="k">do</span><br /> <span class="n">expect</span><span class="p">(</span><span class="n">output</span><span class="p">).</span><span class="nf">to</span> <span class="n">eql</span> <span class="s2">"</span><span class="se">\e</span><span class="s2">[34mfoo</span><span class="se">\e</span><span class="s2">[0m</span><span class="se">\e</span><span class="s2">[0m </span><span class="se">\e</span><span class="s2">[32mbar </span><span class="se">\e</span><span class="s2">[36mfoo, bar, baz"</span> <span class="p">\</span><br /> <span class="s2">"</span><span class="se">\e</span><span class="s2">[0m</span><span class="se">\e</span><span class="s2">[32m with </span><span class="se">\e</span><span class="s2">[36mqux</span><span class="se">\e</span><span class="s2">[0m</span><span class="se">\e</span><span class="s2">[32m "</span><span class="p">\</span><br /> <span class="s2">"and quux</span><span class="se">\e</span><span class="s2">[0m</span><span class="se">\e</span><span class="s2">[0m and corge"</span><br /><span class="k">end</span><br />
|
289
|
+
</div>
|
290
|
+
</div>
|
291
|
+
<div class="tab-pane fade" id="rendered-c3e2bbb8-9a13-4400-93a1-0e6c9847cba0" role="tabpanel" aria-labelledby="rendered-c3e2bbb8-9a13-4400-93a1-0e6c9847cba0-tab">
|
292
|
+
<div class="p-3 mb-5 code highlight">
|
293
|
+
<div class="ansi-html border m-1 p-4">
|
294
|
+
<span></span><span class="ansi-color-4">foo</span><span class="ansi-color-reset"></span><span class="ansi-color-reset"> </span><span class="ansi-color-2">bar </span><span class="ansi-color-6">foo, bar, baz</span><span class="ansi-color-reset"></span><span class="ansi-color-2"> with </span><span class="ansi-color-6">qux</span><span class="ansi-color-reset"></span><span class="ansi-color-2"> and quux</span><span class="ansi-color-reset"></span><span class="ansi-color-reset"> and corge</span>
|
295
|
+
</div>
|
296
|
+
</div>
|
297
|
+
</div>
|
298
|
+
</div>
|
299
|
+
</div>
|
300
|
+
|
301
|
+
</div>
|
302
|
+
</div>
|
303
|
+
<hr/>
|
304
|
+
|
305
|
+
</div>
|
306
|
+
|
307
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/js/bootstrap.bundle.min.js"
|
308
|
+
integrity="sha512-i9cEfJwUwViEPFKdC1enz4ZRGBj8YQo6QByFTF92YXHi7waCqyexvRD75S5NVTsSiTv7rKWqG9Y5eFxmRsOn0A=="
|
309
|
+
crossorigin="anonymous"
|
310
|
+
referrerpolicy="no-referrer"></script>
|
311
|
+
</body>
|
312
|
+
</html>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Paintbrush
|
2
|
+
|
3
|
+
Simple and concise string colorization for _Ruby_ without overloading `String` methods or requiring verbose class/method invocation.
|
4
|
+
|
5
|
+
_Paintbrush_ has zero dependencies and does not pollute any namespaces or objects outside of the `#paintbrush` method wherever you include the `Paintbrush` module.
|
6
|
+
|
7
|
+
Nesting is supported, allowing you to use multiple colors within the same string. The previous color is automatically restored.
|
8
|
+
|
9
|
+
```rspec:ansi
|
10
|
+
require 'paintbrush'
|
11
|
+
|
12
|
+
extend Paintbrush
|
13
|
+
|
14
|
+
output = paintbrush { purple "You used #{green 'four'} #{blue "(#{cyan '4'})"} #{yellow 'colors'} today!" }
|
15
|
+
it_documents output do
|
16
|
+
expect(output).to eql "\e[35mYou used \e[32mfour\e[0m\e[35m " \
|
17
|
+
"\e[34m(\e[36m4\e[0m\e[34m)\e[0m\e[35m " \
|
18
|
+
"\e[33mcolors\e[0m\e[35m today!\e[0m\e[0m"
|
19
|
+
end
|
20
|
+
```
|
21
|
+
|
22
|
+
```rspec:ansi
|
23
|
+
require 'paintbrush'
|
24
|
+
|
25
|
+
extend Paintbrush
|
26
|
+
|
27
|
+
output = paintbrush do
|
28
|
+
"#{blue 'foo'} #{green "bar #{cyan %w[foo bar baz].join(', ')} with #{cyan 'qux'} and quux"} and corge"
|
29
|
+
end
|
30
|
+
|
31
|
+
it_documents output do
|
32
|
+
expect(output).to eql "\e[34mfoo\e[0m\e[0m \e[32mbar \e[36mfoo, bar, baz" \
|
33
|
+
"\e[0m\e[32m with \e[36mqux\e[0m\e[32m "\
|
34
|
+
"and quux\e[0m\e[0m and corge"
|
35
|
+
end
|
36
|
+
```
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: paintbrush
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bob Farrell
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-26 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Provides a set of encapsulated methods for nested colorization of strings.
|
14
14
|
email:
|
@@ -28,10 +28,16 @@ files:
|
|
28
28
|
- Rakefile
|
29
29
|
- doc/example.png
|
30
30
|
- lib/paintbrush.rb
|
31
|
+
- lib/paintbrush/bounded_color_element.rb
|
32
|
+
- lib/paintbrush/color_element.rb
|
31
33
|
- lib/paintbrush/colorized_string.rb
|
32
34
|
- lib/paintbrush/colors.rb
|
35
|
+
- lib/paintbrush/element_tree.rb
|
36
|
+
- lib/paintbrush/escapes.rb
|
33
37
|
- lib/paintbrush/version.rb
|
34
38
|
- paintbrush.gemspec
|
39
|
+
- rspec-documentation/bundle/introduction.html
|
40
|
+
- rspec-documentation/pages/Introduction.md
|
35
41
|
- sig/paintbrush.rbs
|
36
42
|
homepage: https://github.com/bobf/paintbrush
|
37
43
|
licenses: []
|