riel 1.1.12 → 1.1.13
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.
- data/README.md +41 -0
- data/lib/riel/array.rb +0 -2
- data/lib/riel/command.rb +0 -3
- data/lib/riel/date.rb +0 -4
- data/lib/riel/file.rb +0 -1
- data/lib/riel/pathname.rb +0 -2
- data/lib/riel/setdiff.rb +5 -3
- data/lib/riel/string.rb +4 -20
- data/lib/riel/text/ansi/ansi_color.rb +31 -0
- data/lib/riel/text/ansi/ansi_colors.rb +16 -0
- data/lib/riel/text/ansi/ansi_highlight.rb +111 -0
- data/lib/riel/text/ansi/ansi_list.rb +17 -0
- data/lib/riel/text/ansi/ansi_palette.rb +48 -0
- data/lib/riel/text/ansi/attributes.rb +21 -0
- data/lib/riel/text/ansi/backgrounds.rb +13 -0
- data/lib/riel/text/ansi/color.rb +62 -0
- data/lib/riel/text/ansi/foregrounds.rb +12 -0
- data/lib/riel/text/ansi/grey.rb +30 -0
- data/lib/riel/text/ansi/grey_palette.rb +36 -0
- data/lib/riel/text/ansi/palette.rb +18 -0
- data/lib/riel/text/ansi/rgb_color.rb +28 -0
- data/lib/riel/text/ansi/rgb_palette.rb +49 -0
- data/lib/riel/text/highlight.rb +130 -0
- data/lib/riel/text/highlightable.rb +85 -0
- data/lib/riel/text/html_highlight.rb +98 -0
- data/lib/riel/text/non_highlight.rb +17 -0
- data/lib/riel/text/string.rb +10 -0
- data/lib/riel/text.rb +1 -412
- data/lib/riel.rb +1 -1
- data/test/riel/command_test.rb +11 -10
- data/test/riel/date_test.rb +23 -6
- data/test/riel/file_test.rb +15 -4
- data/test/riel/io_test.rb +2 -2
- data/test/riel/setdiff_test.rb +31 -10
- data/test/riel/string_test.rb +0 -5
- data/test/riel/text/ansi/ansi_highlight_test.rb +125 -0
- data/test/riel/text/ansi/ansi_palette_test.rb +65 -0
- data/test/riel/text/ansi/grey_palette_test.rb +39 -0
- data/test/riel/text/ansi/rgb_palette_test.rb +122 -0
- data/test/riel/text/highlightable_test.rb +27 -0
- data/test/riel/text/string_test.rb +48 -0
- data/test/riel/text_test.rb +1 -1
- metadata +37 -6
- data/README +0 -0
@@ -0,0 +1,130 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
module Text
|
5
|
+
# Highlights text using either ANSI terminal codes, or HTML.
|
6
|
+
|
7
|
+
# Note that the foreground and background sections can have modifiers
|
8
|
+
# (attributes).
|
9
|
+
#
|
10
|
+
# Examples:
|
11
|
+
# black
|
12
|
+
# blue on white
|
13
|
+
# bold green on yellow
|
14
|
+
# underscore bold magenta on cyan
|
15
|
+
# underscore red on cyan
|
16
|
+
|
17
|
+
class Highlighter
|
18
|
+
VERSION = "1.0.4"
|
19
|
+
|
20
|
+
COLORS = %w{ black red green yellow blue magenta cyan white }
|
21
|
+
DECORATIONS = %w{ none reset bold underscore underline blink negative concealed }
|
22
|
+
|
23
|
+
BACKGROUND_COLORS = COLORS.collect { |color| "on_#{color}" }
|
24
|
+
FOREGROUND_COLORS = COLORS
|
25
|
+
|
26
|
+
COLORS_RE = Regexp.new('(?: ' +
|
27
|
+
# background will be in capture 0
|
28
|
+
'on(?:\s+|_) ( ' + COLORS.join(' | ') + ' ) | ' +
|
29
|
+
# foreground will be in capture 1
|
30
|
+
'( ' + (COLORS + DECORATIONS).join(' | ') + ' ) ' +
|
31
|
+
')', Regexp::EXTENDED);
|
32
|
+
|
33
|
+
DEFAULT_COLORS = [
|
34
|
+
"black on yellow",
|
35
|
+
"black on green",
|
36
|
+
"black on magenta",
|
37
|
+
"yellow on black",
|
38
|
+
"magenta on black",
|
39
|
+
"green on black",
|
40
|
+
"cyan on black",
|
41
|
+
"blue on yellow",
|
42
|
+
"blue on magenta",
|
43
|
+
"blue on green",
|
44
|
+
"blue on cyan",
|
45
|
+
"yellow on blue",
|
46
|
+
"magenta on blue",
|
47
|
+
"green on blue",
|
48
|
+
"cyan on blue",
|
49
|
+
]
|
50
|
+
|
51
|
+
attr_reader :colors
|
52
|
+
|
53
|
+
def parse_colors str
|
54
|
+
str.scan(Regexp.new(COLORS_RE)).collect do |color|
|
55
|
+
color[0] ? "on_" + color[0] : color[1]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# returns a list of all color combinations.
|
60
|
+
def self.all_colors
|
61
|
+
all_colors = Array.new
|
62
|
+
([ nil ] + DECORATIONS).each do |dec|
|
63
|
+
([ nil ] + FOREGROUND_COLORS).each do |fg|
|
64
|
+
([ nil ] + BACKGROUND_COLORS).each do |bg|
|
65
|
+
name = [ dec, fg, bg ].compact.join("_")
|
66
|
+
all_colors << name if name && name.length > 0
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
all_colors
|
71
|
+
end
|
72
|
+
|
73
|
+
def highlight str
|
74
|
+
# implemented by subclasses
|
75
|
+
end
|
76
|
+
|
77
|
+
# Colorizes the given object. If a block is passed, its return value is used
|
78
|
+
# and the stream is reset. If a String is provided as the object, it is
|
79
|
+
# colorized and the stream is reset. Otherwise, only the code for the given
|
80
|
+
# color name is returned.
|
81
|
+
|
82
|
+
def color colorstr, obj = nil, &blk
|
83
|
+
colornames = parse_colors colorstr
|
84
|
+
result = names_to_code colornames
|
85
|
+
|
86
|
+
if blk
|
87
|
+
result << blk.call
|
88
|
+
elsif obj.respond_to? :to_s
|
89
|
+
result << obj.to_s
|
90
|
+
end
|
91
|
+
result << names_to_code("reset")
|
92
|
+
result
|
93
|
+
end
|
94
|
+
|
95
|
+
# returns the code for the given color string, which is in the format:
|
96
|
+
# foreground* [on background]?
|
97
|
+
#
|
98
|
+
# Note that the foreground and background sections can have modifiers
|
99
|
+
# (attributes).
|
100
|
+
#
|
101
|
+
# Examples:
|
102
|
+
# black
|
103
|
+
# blue on white
|
104
|
+
# bold green on yellow
|
105
|
+
# underscore bold magenta on cyan
|
106
|
+
# underscore red on cyan
|
107
|
+
def code str
|
108
|
+
fg, bg = str.split(/\s*\bon_?\s*/)
|
109
|
+
(fg ? foreground(fg) : "") + (bg ? background(bg) : "")
|
110
|
+
end
|
111
|
+
|
112
|
+
# Returns the code for the given background color(s).
|
113
|
+
def background bgcolor
|
114
|
+
names_to_code "on_" + bgcolor
|
115
|
+
end
|
116
|
+
|
117
|
+
# Returns the code for the given foreground color(s).
|
118
|
+
def foreground fgcolor
|
119
|
+
fgcolor.split(/\s+/).collect { |fg| names_to_code fg }.join("")
|
120
|
+
end
|
121
|
+
|
122
|
+
# Returns a highlighted (colored) version of the string, applying the regular
|
123
|
+
# expressions in the array, which are paired with the desired color.
|
124
|
+
def gsub str, re, color
|
125
|
+
str.gsub(re) do |match|
|
126
|
+
self.color color, match
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
require 'riel/text/highlight'
|
5
|
+
require 'riel/text/ansi/ansi_highlight'
|
6
|
+
require 'riel/text/html_highlight'
|
7
|
+
require 'riel/text/non_highlight'
|
8
|
+
|
9
|
+
module Text
|
10
|
+
# An object that can be highlighted. This is used by the String class.
|
11
|
+
module Highlightable
|
12
|
+
# The highlighter for the class in which this module is included.
|
13
|
+
@@highlighter = ANSIHighlighter.instance
|
14
|
+
|
15
|
+
# this dynamically adds methods for individual colors.
|
16
|
+
def method_missing(meth, *args, &blk)
|
17
|
+
if has_color? meth.to_s
|
18
|
+
methdecl = Array.new
|
19
|
+
methdecl << "def #{meth}(&blk);"
|
20
|
+
methdecl << " @@highlighter.color(\"#{meth}\", self, &blk);"
|
21
|
+
methdecl << "end"
|
22
|
+
self.class.class_eval methdecl.join("\n")
|
23
|
+
send meth, *args, &blk
|
24
|
+
elsif Text::ANSIHighlighter.instance.has_alias? meth
|
25
|
+
methdecl = Array.new
|
26
|
+
methdecl << "def #{meth}(&blk);"
|
27
|
+
methdecl << " @@highlighter.#{meth}(self, &blk);"
|
28
|
+
methdecl << "end"
|
29
|
+
self.class.class_eval methdecl.join("\n")
|
30
|
+
send meth, *args, &blk
|
31
|
+
else
|
32
|
+
super
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def respond_to? meth
|
37
|
+
has_color?(meth.to_s) || Text::ANSIHighlighter.instance.has_alias?(meth) || super
|
38
|
+
end
|
39
|
+
|
40
|
+
def has_color? color
|
41
|
+
Text::Highlighter::all_colors.include? color
|
42
|
+
end
|
43
|
+
|
44
|
+
# Sets the highlighter for this class. This can be either by type or by
|
45
|
+
# String.
|
46
|
+
def highlighter= hl
|
47
|
+
@@highlighter = case hl
|
48
|
+
when Text::Highlighter
|
49
|
+
hl
|
50
|
+
when :none, "NONE", nil
|
51
|
+
Text::NonHighlighter.new
|
52
|
+
when :html, "HTML"
|
53
|
+
Text::HTMLHighlighter.new
|
54
|
+
when :ansi, "ANSI"
|
55
|
+
Text::ANSIHighlighter.instance
|
56
|
+
else
|
57
|
+
Text::NonHighlighter.new
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
def rgb red, green, blue
|
63
|
+
@@highlighter.rgb self, red, green, blue
|
64
|
+
end
|
65
|
+
|
66
|
+
def on_rgb red, green, blue
|
67
|
+
@@highlighter.on_rgb self, red, green, blue
|
68
|
+
end
|
69
|
+
|
70
|
+
def grey value
|
71
|
+
@@highlighter.grey self, value
|
72
|
+
end
|
73
|
+
|
74
|
+
def on_grey value
|
75
|
+
@@highlighter.on_grey self, value
|
76
|
+
end
|
77
|
+
|
78
|
+
alias_method :gray, :grey
|
79
|
+
alias_method :on_gray, :on_grey
|
80
|
+
|
81
|
+
def self.add_to cls
|
82
|
+
cls.send :include, Text::Highlightable
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
require 'riel/text/highlight'
|
5
|
+
|
6
|
+
module Text
|
7
|
+
# Highlights using HTML. Fonts are highlighted using <span> tags, not <font>.
|
8
|
+
# Also note that negative is translated to white on black.
|
9
|
+
# According to http://www.w3.org/TR/REC-CSS2/syndata.html#value-def-color,
|
10
|
+
# valid color keywords are: aqua, black, blue, fuchsia, gray, green, lime,
|
11
|
+
# maroon, navy, olive, purple, red, silver, teal, white, and yellow.
|
12
|
+
# Thus, no magenta or cyan.
|
13
|
+
|
14
|
+
class HTMLHighlighter < Highlighter
|
15
|
+
def initialize
|
16
|
+
# we need to know what we're resetting from (bold, font, underlined ...)
|
17
|
+
@stack = []
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns the start tag for the given name.
|
21
|
+
|
22
|
+
def start_style name
|
23
|
+
case name
|
24
|
+
when "negative"
|
25
|
+
"<span style=\"color: white; background-color: black\">"
|
26
|
+
when /on_(\w+)/
|
27
|
+
colval = color_value $1
|
28
|
+
"<span style=\"background-color: #{colval}\">"
|
29
|
+
else
|
30
|
+
colval = color_value name
|
31
|
+
"<span style=\"color: #{colval}\">"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns the end tag ("</span>").
|
36
|
+
|
37
|
+
def end_style
|
38
|
+
"</span>"
|
39
|
+
end
|
40
|
+
|
41
|
+
def color_value cname
|
42
|
+
case cname
|
43
|
+
when "cyan"
|
44
|
+
"#00FFFF"
|
45
|
+
when "magenta"
|
46
|
+
"#FF00FF"
|
47
|
+
else
|
48
|
+
cname
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns the code for the given name.
|
53
|
+
def names_to_code names
|
54
|
+
str = ""
|
55
|
+
|
56
|
+
names = [ names ] unless names.kind_of? Array
|
57
|
+
|
58
|
+
names.each do |name|
|
59
|
+
@stack << name
|
60
|
+
|
61
|
+
case name
|
62
|
+
when "none", "reset"
|
63
|
+
@stack.pop
|
64
|
+
if @stack.length > 0
|
65
|
+
begin
|
66
|
+
prev = @stack.pop
|
67
|
+
case prev
|
68
|
+
when "bold"
|
69
|
+
str << "</b>"
|
70
|
+
when "underscore", "underline"
|
71
|
+
str << "</u>"
|
72
|
+
when "blink"
|
73
|
+
str << "</blink>"
|
74
|
+
when "concealed"
|
75
|
+
str << " -->"
|
76
|
+
else
|
77
|
+
str << end_style
|
78
|
+
end
|
79
|
+
end while @stack.length > 0
|
80
|
+
end
|
81
|
+
str
|
82
|
+
when "bold"
|
83
|
+
str << "<b>"
|
84
|
+
when "underscore", "underline"
|
85
|
+
str << "<u>"
|
86
|
+
when "blink"
|
87
|
+
str << "<blink>"
|
88
|
+
when "concealed"
|
89
|
+
str << "<!-- "
|
90
|
+
else
|
91
|
+
str << start_style(name)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
str
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|