Class: Col::Formatter
- Inherits:
-
Object
- Object
- Col::Formatter
- Defined in:
- lib/col.rb
Overview
————————————————————————— #
Instance Method Summary collapse
-
#check_correct_number_of_arguments(strings, *spec) ⇒ Object
In general, there should be the same number of arguments as there are strings:.
-
#decorated_string(string, spec) ⇒ Object
e.g.
-
#extract(string) ⇒ Object
Extracts color, style and background color.
-
#initialize(strings, *spec) ⇒ Formatter
constructor
A new instance of Formatter.
-
#normalise_array(array) ⇒ Object
Input: array of symbols Result: array of symbols, each of which is a legitimate ANSIColor method Note: underscores and nil items are removed from the array.
-
#normalise_format_spec(*spec) ⇒ Object
Each spec in the following groups is equivalent.
-
#normalise_item(item) ⇒ Object
Examples Item Normalised item :r [:red] “r” [:red] :red [:red] [:red] [:red] “rb” [:red, :bold] :rb [:red, :bold] [:red, :bold] [:red, :bold] :b [:blue] :_b [:bold] :__b error :__ob [:on_blue] “gsow” [:green, :strikethrough, :on_white] “_noB” [:negative, :on_black] :_ [] [:_] [] [:_, :_] [] (etc.).
-
#normalise_string(string) ⇒ Object
Examples Input Output r [:red] b [:blue] rb [:red, :bold] red [:red] bold [:bold] gsow [:green, :strikethrough, :on_white] _b [:bold] __ob [:on_blue] _ [].
- #render(spec) ⇒ Object
- #result ⇒ Object
Constructor Details
#initialize(strings, *spec) ⇒ Formatter
Returns a new instance of Formatter.
90 91 92 93 94 |
# File 'lib/col.rb', line 90 def initialize(strings, *spec) check_correct_number_of_arguments(strings, *spec) @strings = strings @format_spec = normalise_format_spec(*spec) end |
Instance Method Details
#check_correct_number_of_arguments(strings, *spec) ⇒ Object
In general, there should be the same number of arguments as there are strings:
Col["one"].fmt( :b )
Col["one", "two"].fmt( [:red, :on_white], [:bold, :negative] )
Col["one", "two", "three"].fmt( :yellow, [:green, :bold], :italic )
Col["one", "two", "three", "four"].fmt(:rb, :y, :cb, :m)
Col["one", "two", "three", "four"].fmt "rb,y,cb,m"
As a special case, if there is only one string, it can have any number of arguments:
Col["string"].fmt( :yellow, :bold, :italic, :blink, :negative, :on_magenta )
If the number of arguments is incorrect, a Col::Error is thrown.
135 136 137 138 139 140 141 142 143 |
# File 'lib/col.rb', line 135 def check_correct_number_of_arguments(strings, *spec) nargs = spec.size if nargs == 1 and spec.first.is_a? String nargs = spec.first.split(/,/).size end if strings.size > 1 and nargs != strings.size raise Col::Error, "incorrect number of arguments: #{render(spec)}" end end |
#decorated_string(string, spec) ⇒ Object
e.g.
string = "hello"
spec = [:yellow, :bold, :on_red]
result = "hello".send(:yellow).send(:bold).send(:on_red)
112 113 114 115 116 |
# File 'lib/col.rb', line 112 def decorated_string(string, spec) raise Col::Error unless string.is_a? String and spec.is_a? Array \ and spec.all? { |e| e.is_a? Symbol } spec.inject(string) { |str, symbol| Term::ANSIColor.send(symbol, str) } end |
#extract(string) ⇒ Object
Extracts color, style and background color.
"gbow" -> ["g", "b", "ow"]
"g" -> ["g", nil, nil]
"_b" -> [nil, "b", nil]
258 259 260 261 262 263 264 265 |
# File 'lib/col.rb', line 258 def extract(string) string += " " color, style, backg = /^(.)(.)(..)/.match(string).captures color = nil if [' ', '_'].include? color style = nil if [' ', '_'].include? style backg = nil if [' ', '__'].include? backg [color, style, backg] end |
#normalise_array(array) ⇒ Object
Input: array of symbols Result: array of symbols, each of which is a legitimate ANSIColor method Note: underscores and nil items are removed from the array
214 215 216 217 218 219 220 221 222 |
# File 'lib/col.rb', line 214 def normalise_array(array) array.reject! { |x| x.nil? or x == :_ or x == '_' } invalid_items = array.select { |item| not Col::DB.method? item } case invalid_items.size when 0 then return array when 1 then raise Col::Error, "Invalid item: #{invalid_items.first.inspect}" else raise Col::Error, "Invalid items: #{invalid_items.inspect}" end end |
#normalise_format_spec(*spec) ⇒ Object
Each spec in the following groups is equivalent. The last one is normalised.
[ :rb ]
[ "rb" ]
[ [:red, :bold] ]
[ :rb, :_n, :y ]
[ "rb", "_n", "y" ]
[ [:red, :bold], [:negative], [:yellow] ]
[ [:green, :concealed], :blue, :bold ]
[ [:green, :concealed], [:blue], [:bold] ]
[ "rb,y,_i,g_ow" ]
[ "rb", "y", "_i", "g_ow" ]
[ [:red, :bold], [:yellow], [:italic], [:green, :on_white] ]
spec is definitely an array because it was gathered like this:
def fmt(*spec)
“Normalised” means an array with one element for each string. Each element is itself an array of all the properties that apply to that string.
171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/col.rb', line 171 def normalise_format_spec(*spec) if spec.size == 1 and spec.first.is_a? String and spec.first.index(',') # ^^^ "rb,y,_n" spec = spec.first.split(',') # ['rb', 'y', '_n'] normalise_format_spec(*spec) else # We have an array of items. We need to treat each item individually and # put the items together. We remove nil elements. spec.map { |item| normalise_item(item) }.compact end end |
#normalise_item(item) ⇒ Object
Examples
Item Normalised item
:r [:red]
"r" [:red]
:red [:red]
[:red] [:red]
"rb" [:red, :bold]
:rb [:red, :bold]
[:red, :bold] [:red, :bold]
:b [:blue]
:_b [:bold]
:__b error
:__ob [:on_blue]
"gsow" [:green, :strikethrough, :on_white]
"_noB" [:negative, :on_black]
:_ []
[:_] []
[:_, :_] []
(etc.)
202 203 204 205 206 207 208 209 |
# File 'lib/col.rb', line 202 def normalise_item(item) case item when Symbol then normalise_string(item.to_s) when Array then normalise_array(item) when String then normalise_string(item) else raise Col::Error, "Invalid item type: #{item.class}" end end |
#normalise_string(string) ⇒ Object
Examples
Input Output
r [:red]
b [:blue]
rb [:red, :bold]
red [:red]
bold [:bold]
gsow [:green, :strikethrough, :on_white]
_b [:bold]
__ob [:on_blue]
_ []
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/col.rb', line 235 def normalise_string(string) # Is it already one of the methods? If so, easy. If not, split and parse. if string == "_" [] elsif Col::DB.method? string [ string.intern ] elsif (1..4).include? string.size # say: "g", "gb", "gbow" color, style, backg = extract(string) color = Col::DB.color(color) # 'g' -> :green style = Col::DB.style(style) # 'b' -> :bold backg = Col::DB.background(backg) # 'ow' -> :on_white [ color, style, backg ].compact # remove nil elements else raise Col::Error, "Invalid item: #{string.inspect}" end rescue Col::Error => e raise Col::Error, "Invalid item: #{string.inspect} (#{e.})" end |
#render(spec) ⇒ Object
267 268 269 |
# File 'lib/col.rb', line 267 def render(spec) ( (spec.size == 1) ? spec.first : spec ).inspect end |
#result ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/col.rb', line 96 def result unless @strings.size == @format_spec.size raise Col::Error, "mismatching strings and specs" end result = String.new @strings.zip(@format_spec).each do |string, spec| d = decorated_string(string, spec) result << d end result end |