cloudhead-mutter 0.1.2 → 0.2.0

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 CHANGED
@@ -6,8 +6,7 @@ mutter
6
6
  style
7
7
 
8
8
  > mutter is the tiny CLI library, with a focus on style.
9
-
10
- use it in your apps to have _gorgeous_ command-line output!
9
+ > use it in your apps to have _gorgeous_ command-line output!
11
10
 
12
11
  usage (command-line output)
13
12
  ---------------------------
@@ -19,6 +18,7 @@ usage (command-line output)
19
18
  mut.say "hello world", :bold # bolds the whole string
20
19
  mut.say "hello [world]", :cyan # inverts 'world', and colors the string cyan
21
20
  mut.print "bonjour!" # alias of `say`
21
+ mut["hola"] # yet another way to print
22
22
 
23
23
  styles
24
24
  ------
@@ -45,8 +45,9 @@ customization
45
45
  }
46
46
 
47
47
  mut = Mutter.new(styles)
48
- mut.say "warning, warning!", :warning
49
- mut.say "gosh, we have an !!error!!"
48
+ mut.say "warning, warning!", :warning
49
+ mut.warning "warning, warning!"
50
+ mut.say "gosh, we have an !!error!!"
50
51
 
51
52
  ### quick styles
52
53
 
@@ -70,3 +71,8 @@ That's it!
70
71
  ----------
71
72
 
72
73
  _have fun_
74
+
75
+ Footnote
76
+ --------
77
+
78
+ This code is _highly experimental_, don't try this at home!
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.2.0
data/lib/ext.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'mutter'
2
+
3
+ class String
4
+ def examine depth = 0
5
+ inspect
6
+ end
7
+ end
8
+
9
+ class Array
10
+ def examine depth = 0
11
+ end
12
+ end
13
+
14
+ class Hash
15
+ def examine depth = 0
16
+ end
17
+ end
18
+
19
+ class Symbol
20
+ def examine depth = 0
21
+ Mutter.stylize inspect, :purple
22
+ end
23
+ end
24
+
25
+ class Numeric
26
+ def examine depth = 0
27
+ Mutter.stylize inspect, :cyan
28
+ end
29
+ end
30
+
31
+ class Object
32
+ def tap
33
+ yield self
34
+ self
35
+ end
36
+ end
@@ -0,0 +1,11 @@
1
+ module Mutter
2
+ class Indenter
3
+ def initialize tab = 2
4
+ @tab = tab
5
+ end
6
+
7
+ def [] n, obj = nil
8
+ ' ' * (n * @tab)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,157 @@
1
+ module Mutter
2
+ class Mutterer
3
+ @stream = STDOUT
4
+
5
+ # Initialize the styles, and load the defaults from +defaults.yml+
6
+ #
7
+ # @active: currently active styles, which apply to the whole string
8
+ # @styles: contains all the user + default styles
9
+ #
10
+ def initialize obj = {}
11
+ @active, @styles = [], {}
12
+ load File.dirname(__FILE__) + "/styles"
13
+
14
+ case obj
15
+ when Hash # A style definition: expand quick-styles and merge with @styles
16
+ obj = obj.inject({}) do |h, (k, v)|
17
+ h.merge k =>
18
+ (v.is_a?(Hash) ? v : { :match => v, :style => [k].flatten })
19
+ end
20
+ @styles.merge! obj
21
+ when Array # An array of styles to be activated
22
+ @active = obj
23
+ when Symbol # A single style to be activated
24
+ self.<< obj
25
+ when String # The path of a yaml style-sheet
26
+ load obj
27
+ else raise ArgumentError
28
+ end
29
+
30
+ #
31
+ # Create an instance method for each style
32
+ #
33
+ @styles.keys.each do |style|
34
+ (class << self; self end).class_eval do
35
+ define_method style do |msg|
36
+ say msg, style
37
+ end
38
+ end if style.is_a? Symbol
39
+ end
40
+ end
41
+
42
+ #
43
+ # Loads styles from a YAML style-sheet,
44
+ # and converts the keys to symbols
45
+ #
46
+ def load styles
47
+ styles += '.yml' unless styles =~ /\.ya?ml/
48
+ @defaults = YAML.load_file(styles).inject({}) do |h, (key, value)|
49
+ value = { :match => value['match'], :style => value['style'] }
50
+ h.merge key.to_sym => value
51
+ end
52
+ @styles.merge! @defaults
53
+ end
54
+
55
+ #
56
+ # Output to the command-line
57
+ # we parse the string, but also apply a style on the whole string,
58
+ #
59
+ def say obj, *styles
60
+ stylize(parse(obj), @active + styles).tap do |out|
61
+ self.write out.gsub(/\e(\d+)\e/, "\e[\\1m") + "\n"
62
+ end
63
+ end
64
+
65
+ alias :print say
66
+ alias :[] say
67
+
68
+ #
69
+ # Write to the out stream, and flush it
70
+ #
71
+ def write str
72
+ self.class.stream.tap do |stream|
73
+ stream.write str
74
+ stream.flush
75
+ end
76
+ end
77
+
78
+ #
79
+ # Utility function, to make a block interruptible
80
+ #
81
+ def watch
82
+ begin
83
+ yield
84
+ rescue Interrupt
85
+ puts
86
+ exit 0
87
+ end
88
+ end
89
+ alias :oo watch
90
+
91
+ #
92
+ # Add a style to the active styles
93
+ #
94
+ def << style
95
+ @active << style
96
+ end
97
+
98
+ #
99
+ # Parse a string to ANSI codes
100
+ #
101
+ # if the glyph is a pair, we match [0] as the start
102
+ # and [1] as the end marker.
103
+ # the matches are sent to +stylize+
104
+ #
105
+ def parse string
106
+ @styles.inject(string) do |str, (name, options)|
107
+ glyph, styles = options[:match], options[:style]
108
+ if glyph.is_a? Array
109
+ str.gsub(/#{Regexp.escape(glyph.first)}(.+?)
110
+ #{Regexp.escape(glyph.last)}/x) { stylize $1, styles }
111
+ else
112
+ str.gsub(/(#{Regexp.escape(glyph)}+)(.+?)\1/) { stylize $2, styles }
113
+ end
114
+ end
115
+ end
116
+
117
+ #
118
+ # Apply styles to a string
119
+ #
120
+ # if the style is a default ANSI style, we add the start
121
+ # and end sequence to the string.
122
+ #
123
+ # if the style is a custom style, we recurse, sending
124
+ # the list of ANSI styles contained in the custom style.
125
+ #
126
+ def stylize string, styles = []
127
+ [styles].flatten.inject(string) do |str, style|
128
+ style = style.to_sym
129
+ if ANSI.include? style
130
+ open, close = ANSI[style]
131
+ "#{esc(open)}#{str}#{esc(close || 0)}"
132
+ else
133
+ stylize(str, @styles[style][:style])
134
+ end
135
+ end
136
+ end
137
+
138
+ #
139
+ # Escape a string, for later replacement
140
+ #
141
+ def esc style
142
+ "\e#{style}\e"
143
+ end
144
+
145
+ #
146
+ # Output stream (defaults to STDOUT)
147
+ # mostly for test purposes
148
+ #
149
+ def self.stream
150
+ @stream
151
+ end
152
+
153
+ def self.stream= io
154
+ @stream = io
155
+ end
156
+ end
157
+ end
File without changes
data/lib/mutter.rb CHANGED
@@ -1,6 +1,26 @@
1
- require 'yaml'
1
+ #
2
+ # Mutter — the tiny command-line interface library with lots of style~
3
+ #
4
+
5
+ require 'yaml'
6
+
7
+ $:.unshift File.dirname(__FILE__) + '/mutter'
8
+
9
+ require 'mutterer'
10
+ require 'indenter'
11
+ require 'ext'
2
12
 
3
13
  module Mutter
14
+ #
15
+ # ANSI color & style codes
16
+ #
17
+ # if the value's an array, it
18
+ # represents [0] is the start code
19
+ # and [1] is the end code.
20
+ #
21
+ # if the value is an int, it represents
22
+ # the start code, and the end code will be 0
23
+ #
4
24
  ANSI = {
5
25
  :bold => [1, 22],
6
26
  :underline => [4, 24],
@@ -12,100 +32,18 @@ module Mutter
12
32
  :cyan => 36, :white => 37
13
33
  }
14
34
 
15
- class Mutterer
16
- @stream = STDOUT
17
-
18
- def initialize obj = {}
19
- @active, @styles = [], {}
20
- load File.dirname(__FILE__) + "/defaults"
21
-
22
- case obj
23
- when Hash
24
- obj = obj.inject({}) do |h, (k, v)|
25
- h.merge k =>
26
- (v.is_a?(Hash) ? v : { :match => v, :style => [k].flatten })
27
- end
28
- @styles.merge! obj
29
- when Array
30
- @active = obj
31
- when Symbol
32
- self.<< obj
33
- when String
34
- load obj
35
- else raise ArgumentError
36
- end
37
- end
38
-
39
- def load styles
40
- styles += '.yml' unless styles =~ /\.ya?ml/
41
- styles = YAML.load_file(styles).inject({}) do |h, (key, value)|
42
- value = { :match => value['match'], :style => value['style'] }
43
- h.merge key.to_sym => value
44
- end
45
- @styles.merge! styles
46
- end
47
-
48
- def say str, *styles
49
- out = stylize(parse(str), @active + styles)
50
- self.class.stream.write out.gsub(/\e(\d+)\e/, "\e[\\1m") + "\n"
51
- self.class.stream.flush
52
- end
53
- alias :print say
54
-
55
- def watch
56
- begin
57
- yield
58
- rescue Interrupt
59
- puts
60
- exit 0
61
- end
62
- end
63
-
64
- def << style
65
- @active << style
66
- end
67
-
68
- def parse string
69
- @styles.inject(string) do |str, (name, options)|
70
- glyph, styles = options[:match], options[:style]
71
- if glyph.is_a? Array
72
- str.gsub(/#{Regexp.escape(glyph.first)}(.+?)
73
- #{Regexp.escape(glyph.last)}/x) { stylize $1, styles }
74
- else
75
- str.gsub(/(#{Regexp.escape(glyph)}+)(.+?)\1/) { stylize $2, styles }
76
- end
77
- end
78
- end
79
-
80
- def stylize string, styles = []
81
- [styles].flatten.inject(string) do |str, style|
82
- style = style.to_sym
83
- if ANSI.include? style
84
- open, close = ANSI[style]
85
- "#{esc(open)}#{str}#{esc(close || 0)}"
86
- else
87
- stylize(str, @styles[style][:style])
88
- end
89
- end
90
- end
91
-
92
- def esc style
93
- "\e#{style}\e"
94
- end
95
-
96
- def self.stream
97
- @stream
98
- end
99
-
100
- def self.stream= io
101
- @stream = io
102
- end
35
+ def self.indenter tab
36
+ Indenter.new tab
103
37
  end
104
38
 
105
39
  def self.say *args
106
40
  new.say *args
107
41
  end
108
42
 
43
+ def self.stylize *args
44
+ new.stylize *args
45
+ end
46
+
109
47
  def self.new *args
110
48
  Mutterer.new(*args)
111
49
  end
data/mutter.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{mutter}
5
- s.version = "0.1.2"
5
+ s.version = "0.2.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["cloudhead"]
9
- s.date = %q{2009-07-30}
9
+ s.date = %q{2009-07-31}
10
10
  s.email = %q{self@cloudhead.net}
11
11
  s.extra_rdoc_files = [
12
12
  "LICENSE",
@@ -19,8 +19,11 @@ Gem::Specification.new do |s|
19
19
  "README.md",
20
20
  "Rakefile",
21
21
  "VERSION",
22
- "lib/defaults.yml",
22
+ "lib/ext.rb",
23
23
  "lib/mutter.rb",
24
+ "lib/mutter/indenter.rb",
25
+ "lib/mutter/mutterer.rb",
26
+ "lib/mutter/styles.yml",
24
27
  "mutter.gemspec",
25
28
  "spec/mutter_spec.rb",
26
29
  "spec/spec_helper.rb",
data/spec/mutter_spec.rb CHANGED
@@ -94,6 +94,11 @@ describe Mutter do
94
94
  Mutter.new("spec/style").say "{important message!}"
95
95
  out.should == "\e[33m\e[4m\e[1mimportant message!\e[22m\e[24m\e[0m\n"
96
96
  end
97
+
98
+ it "should be able to call styles as methods" do
99
+ Mutter.new("spec/style").important "important message!"
100
+ out.should == "\e[33m\e[4m\e[1mimportant message!\e[22m\e[24m\e[0m\n"
101
+ end
97
102
  end
98
103
 
99
104
  it "should parse a complex string" do
data/spec/style.yml CHANGED
@@ -5,4 +5,10 @@ important:
5
5
  style:
6
6
  - bold
7
7
  - underline
8
- - yellow
8
+ - yellow
9
+
10
+ warning:
11
+ match: '@'
12
+ style:
13
+ - red
14
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudhead-mutter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - cloudhead
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-07-30 00:00:00 -07:00
12
+ date: 2009-07-31 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -29,8 +29,11 @@ files:
29
29
  - README.md
30
30
  - Rakefile
31
31
  - VERSION
32
- - lib/defaults.yml
32
+ - lib/ext.rb
33
33
  - lib/mutter.rb
34
+ - lib/mutter/indenter.rb
35
+ - lib/mutter/mutterer.rb
36
+ - lib/mutter/styles.yml
34
37
  - mutter.gemspec
35
38
  - spec/mutter_spec.rb
36
39
  - spec/spec_helper.rb