Class: Mutter::Mutterer
Class Method Summary collapse
- .color ⇒ Object
- .color=(bool) ⇒ Object
-
.stream ⇒ Object
Output stream (defaults to STDOUT) mostly for test purposes.
- .stream=(io) ⇒ Object
Instance Method Summary collapse
- #+(style) ⇒ Object
- #-(style) ⇒ Object
-
#<<(style) ⇒ Object
Add and remove styles from the active styles.
- #>>(style) ⇒ Object
- #clear(opt = :all) ⇒ Object (also: #reset)
- #color? ⇒ Boolean
-
#esc(str, open, close) ⇒ Object
Escape a string, for later replacement.
-
#initialize(obj = {}) ⇒ Mutterer
constructor
Initialize the styles, and load the defaults from
styles.yml
. -
#load(styles) ⇒ Object
Loads styles from a YAML style-sheet, and converts the keys to symbols.
-
#parse(string) ⇒ Object
Parse a string to ANSI codes.
-
#process(msg, *styles) ⇒ Object
(also: #[])
Parse the message, but also apply a style on the whole thing.
-
#say(msg, *styles) ⇒ Object
(also: #print)
Output to @stream.
- #styles ⇒ Object
-
#stylize(string, styles = []) ⇒ Object
Apply styles to a string.
-
#table(*args, &blk) ⇒ Object
Create a table.
-
#unstyle(msg) ⇒ Object
Remove all tags from string.
-
#write(str) ⇒ Object
Write to the out stream, and flush it.
Constructor Details
#initialize(obj = {}) ⇒ Mutterer
Initialize the styles, and load the defaults from styles.yml
@active: currently active styles, which apply to the whole string @styles: contains all the user + default styles
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 |
# File 'lib/mutter/mutterer.rb', line 11 def initialize obj = {} self.reset @defaults = load 'default' case obj when Hash # A style definition: expand quick-styles and merge with @styles @styles = obj.inject({}) do |h, (k, v)| h.merge k => (v.is_a?(Hash) ? v : { :match => v, :style => [k].flatten }) end when Array # An array of styles to be activated @active = obj when Symbol # A single style to be activated self << obj when String # The path of a yaml style-sheet @styles = load obj else raise ArgumentError end # # Create an instance method for each style # self.styles.keys.each do |style| (class << self; self end).class_eval do define_method style do |msg| say msg, style end end if style.is_a? Symbol end end |
Class Method Details
.color ⇒ Object
202 203 204 |
# File 'lib/mutter/mutterer.rb', line 202 def self.color @color end |
.color=(bool) ⇒ Object
206 207 208 |
# File 'lib/mutter/mutterer.rb', line 206 def self.color= bool @color = bool end |
.stream ⇒ Object
Output stream (defaults to STDOUT)
mostly for test purposes
194 195 196 |
# File 'lib/mutter/mutterer.rb', line 194 def self.stream @stream end |
.stream=(io) ⇒ Object
198 199 200 |
# File 'lib/mutter/mutterer.rb', line 198 def self.stream= io @stream = io end |
Instance Method Details
#+(style) ⇒ Object
132 133 134 |
# File 'lib/mutter/mutterer.rb', line 132 def + style dup.tap {|m| m << style } end |
#-(style) ⇒ Object
136 137 138 |
# File 'lib/mutter/mutterer.rb', line 136 def - style dup.tap {|m| m >> style } end |
#<<(style) ⇒ Object
Add and remove styles from the active styles
124 125 126 |
# File 'lib/mutter/mutterer.rb', line 124 def << style @active << style end |
#>>(style) ⇒ Object
128 129 130 |
# File 'lib/mutter/mutterer.rb', line 128 def >> style @active.delete style end |
#clear(opt = :all) ⇒ Object Also known as: reset
46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/mutter/mutterer.rb', line 46 def clear opt = :all case opt when :user then @styles = {} when :styles then @styles, @defaults = {}, {} when :active then @active = [] when :all then @active, @styles, @defaults = [], {}, {} when :default, :defaults then @defaults = {} else raise ArgumentError, "[:user, :default, :active, :all] only" end self end |
#color? ⇒ Boolean
73 74 75 |
# File 'lib/mutter/mutterer.rb', line 73 def color? (ENV['TERM'].include?('color') && self.class.stream.tty?) || self.class.color end |
#esc(str, open, close) ⇒ Object
Escape a string, for later replacement
186 187 188 |
# File 'lib/mutter/mutterer.rb', line 186 def esc str, open, close "\e#{open}\e" + str + "\e#{close}\e" end |
#load(styles) ⇒ Object
Loads styles from a YAML style-sheet,
and converts the keys to symbols
64 65 66 67 68 69 70 71 |
# File 'lib/mutter/mutterer.rb', line 64 def load styles styles += '.yml' unless styles =~ /\.ya?ml$/ styles = File.join(File.dirname(__FILE__), "styles", styles) unless File.exist? styles YAML.load_file(styles).inject({}) do |h, (key, value)| value = { :match => value['match'], :style => value['style'] } h.merge key.to_sym => value end end |
#parse(string) ⇒ Object
Parse a string to ANSI codes
if the glyph is a pair, we match [0] as the start
and [1] as the end marker.
the matches are sent to +stylize+
147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/mutter/mutterer.rb', line 147 def parse string self.styles.inject(string) do |str, (name, )| glyph, style = [:match], [:style] if glyph.is_a? Array str.gsub(/#{Regexp.escape(glyph.first)}(.*?) #{Regexp.escape(glyph.last)}/x) { stylize $1, style } else str.gsub(/(#{Regexp.escape(glyph)}+)(.*?)\1/) { stylize $2, style } end end end |
#process(msg, *styles) ⇒ Object Also known as: []
Parse the message, but also apply a style on the whole thing
99 100 101 |
# File 'lib/mutter/mutterer.rb', line 99 def process msg, *styles stylize(parse(msg), @active + styles).gsub(/\e(\d+)\e/, "\e[\\1m") end |
#say(msg, *styles) ⇒ Object Also known as: print
Output to @stream
80 81 82 |
# File 'lib/mutter/mutterer.rb', line 80 def say msg, *styles self.write((color?? process(msg, *styles) : unstyle(msg)) + "\n") ; nil end |
#styles ⇒ Object
42 43 44 |
# File 'lib/mutter/mutterer.rb', line 42 def styles @defaults.merge @styles end |
#stylize(string, styles = []) ⇒ Object
Apply styles to a string
if the style is a default ANSI style, we add the start
and end sequence to the string.
if the style is a custom style, we recurse, sending
the list of ANSI styles contained in the custom style.
TODO: use ';' delimited codes instead of multiple \e sequences
170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/mutter/mutterer.rb', line 170 def stylize string, styles = [] [styles].flatten.inject(string) do |str, style| style = style.to_sym if ANSI[:transforms].include? style esc str, *ANSI[:transforms][style] elsif ANSI[:colors].include? style esc str, ANSI[:colors][style], ANSI[:colors][:reset] else stylize(str, @styles[style][:style]) end end end |
#table(*args, &blk) ⇒ Object
Create a table
117 118 119 |
# File 'lib/mutter/mutterer.rb', line 117 def table *args, &blk Table.new(*args, &blk) end |
#unstyle(msg) ⇒ Object
Remove all tags from string
88 89 90 91 92 93 94 |
# File 'lib/mutter/mutterer.rb', line 88 def unstyle msg styles.map do |_,v| v[:match] end.flatten.inject(msg) do |m, tag| m.gsub(tag, '') end end |
#write(str) ⇒ Object
Write to the out stream, and flush it
107 108 109 110 111 112 |
# File 'lib/mutter/mutterer.rb', line 107 def write str self.class.stream.tap do |stream| stream.write str stream.flush end ; nil end |