cloudhead-mutter 0.1.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/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.md +55 -0
- data/Rakefile +73 -0
- data/VERSION +1 -0
- data/lib/defaults.yml +14 -0
- data/lib/mutter.rb +102 -0
- data/mutter.gemspec +49 -0
- data/spec/mutter_spec.rb +103 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/style.yml +8 -0
- metadata +67 -0
data/.document
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 cloudhead
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
mutter
|
2
|
+
======
|
3
|
+
|
4
|
+
> $ my words come out,
|
5
|
+
> in color and style
|
6
|
+
|
7
|
+
mutter is the tiny CLI library, with a focus on style.
|
8
|
+
use it in your apps to have better looking command-line output!
|
9
|
+
|
10
|
+
printing to the command-line
|
11
|
+
----------------------------
|
12
|
+
|
13
|
+
require 'mutter'
|
14
|
+
|
15
|
+
mut = Mutter.new
|
16
|
+
mut.say "hello _world_" # underlines 'world'
|
17
|
+
mut.say "hello world", :bold # bolds the whole string
|
18
|
+
mut.say "hello [world]", :cyan # inverts 'world', and colors the string cyan
|
19
|
+
|
20
|
+
styles
|
21
|
+
------
|
22
|
+
mutter supports these styles:
|
23
|
+
|
24
|
+
:bold, :underline, :inverse
|
25
|
+
|
26
|
+
and these colors:
|
27
|
+
|
28
|
+
:red, :green, :blue, :yellow, :cyan, :purple, :white, :black
|
29
|
+
|
30
|
+
customization
|
31
|
+
-------------
|
32
|
+
|
33
|
+
styles = {
|
34
|
+
:warning => {
|
35
|
+
:match => ['*!', '!*'],
|
36
|
+
:style => ['yellow', 'bold']
|
37
|
+
},
|
38
|
+
:error => {
|
39
|
+
:match => '!!',
|
40
|
+
:style => ['red', 'underline']
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
mut = Mutter.new(styles)
|
45
|
+
mut.say "warning, warning!", :warning
|
46
|
+
mut.say "gosh, we have an !!error!!"
|
47
|
+
|
48
|
+
mutter can also read styles from _YAML_ files, just give it the path, like so:
|
49
|
+
|
50
|
+
Mutter.new("styles.yml")
|
51
|
+
|
52
|
+
There's an example style in `spec/`
|
53
|
+
|
54
|
+
have fun!
|
55
|
+
---------
|
data/Rakefile
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "mutter"
|
8
|
+
gem.summary = %Q{}
|
9
|
+
gem.email = "self@cloudhead.net"
|
10
|
+
gem.homepage = "http://github.com/cloudhead/mutter"
|
11
|
+
gem.authors = ["cloudhead"]
|
12
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
13
|
+
end
|
14
|
+
|
15
|
+
rescue LoadError
|
16
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'rake/testtask'
|
20
|
+
Rake::TestTask.new(:test) do |test|
|
21
|
+
test.libs << 'lib' << 'test'
|
22
|
+
test.pattern = 'test/**/*_test.rb'
|
23
|
+
test.verbose = true
|
24
|
+
end
|
25
|
+
|
26
|
+
begin
|
27
|
+
require 'rcov/rcovtask'
|
28
|
+
Rcov::RcovTask.new do |test|
|
29
|
+
test.libs << 'test'
|
30
|
+
test.pattern = 'test/**/*_test.rb'
|
31
|
+
test.verbose = true
|
32
|
+
end
|
33
|
+
rescue LoadError
|
34
|
+
task :rcov do
|
35
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
task :default => :test
|
41
|
+
|
42
|
+
require 'rake/rdoctask'
|
43
|
+
Rake::RDocTask.new do |rdoc|
|
44
|
+
if File.exist?('VERSION.yml')
|
45
|
+
config = YAML.load(File.read('VERSION.yml'))
|
46
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
47
|
+
else
|
48
|
+
version = ""
|
49
|
+
end
|
50
|
+
|
51
|
+
rdoc.rdoc_dir = 'rdoc'
|
52
|
+
rdoc.title = "mutter #{version}"
|
53
|
+
rdoc.rdoc_files.include('README*')
|
54
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
55
|
+
end
|
56
|
+
|
57
|
+
require 'spec/rake/spectask'
|
58
|
+
|
59
|
+
Spec::Rake::SpecTask.new("spec") do |t|
|
60
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
61
|
+
t.spec_opts = ['--color', '--format=specdoc']
|
62
|
+
end
|
63
|
+
|
64
|
+
task :test do
|
65
|
+
Rake::Task['spec'].invoke
|
66
|
+
end
|
67
|
+
|
68
|
+
Spec::Rake::SpecTask.new("rcov_spec") do |t|
|
69
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
70
|
+
t.spec_opts = ['--color']
|
71
|
+
t.rcov = true
|
72
|
+
t.rcov_opts = ['--exclude', '^spec,/gems/']
|
73
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/lib/defaults.yml
ADDED
data/lib/mutter.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Mutter
|
4
|
+
ANSI = {
|
5
|
+
:bold => [1, 22],
|
6
|
+
:underline => [4, 24],
|
7
|
+
:inverse => [7, 27],
|
8
|
+
|
9
|
+
:black => 30, :red => 31,
|
10
|
+
:green => 32, :yellow => 33,
|
11
|
+
:blue => 34, :purple => 35,
|
12
|
+
:cyan => 36, :white => 37
|
13
|
+
}
|
14
|
+
|
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
|
+
@active << 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
|
+
self.class.stream.write stylize(parse(str), @active + styles).gsub(/\e(\d+)/, "\e[\\1m") + "\n"
|
50
|
+
self.class.stream.flush
|
51
|
+
end
|
52
|
+
alias :print say
|
53
|
+
|
54
|
+
def watch
|
55
|
+
begin
|
56
|
+
yield
|
57
|
+
rescue Interrupt
|
58
|
+
puts
|
59
|
+
exit 0
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def parse string
|
64
|
+
@styles.inject(string) do |str, (name, options)|
|
65
|
+
glyph, styles = options[:match], options[:style]
|
66
|
+
if glyph.is_a? Array
|
67
|
+
str.gsub(/#{Regexp.escape(glyph.first)}(.+?)
|
68
|
+
#{Regexp.escape(glyph.last)}/x) { stylize $1, styles }
|
69
|
+
else
|
70
|
+
str.gsub(/(#{Regexp.escape(glyph)}+)(.+?)\1/) { stylize $2, styles }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def stylize string, styles = []
|
76
|
+
[styles].flatten.inject(string) do |str, style|
|
77
|
+
open, close = ANSI[style.to_sym]
|
78
|
+
"#{esc(open)}#{str}#{esc(close || 0)}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def esc style
|
83
|
+
"\e#{style}"
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.stream
|
87
|
+
@stream
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.stream= io
|
91
|
+
@stream = io
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.say *args
|
96
|
+
new.say *args
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.new *args
|
100
|
+
Mutterer.new(*args)
|
101
|
+
end
|
102
|
+
end
|
data/mutter.gemspec
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{mutter}
|
5
|
+
s.version = "0.1.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["cloudhead"]
|
9
|
+
s.date = %q{2009-07-29}
|
10
|
+
s.email = %q{self@cloudhead.net}
|
11
|
+
s.extra_rdoc_files = [
|
12
|
+
"LICENSE",
|
13
|
+
"README.md"
|
14
|
+
]
|
15
|
+
s.files = [
|
16
|
+
".document",
|
17
|
+
".gitignore",
|
18
|
+
"LICENSE",
|
19
|
+
"README.md",
|
20
|
+
"Rakefile",
|
21
|
+
"VERSION",
|
22
|
+
"lib/defaults.yml",
|
23
|
+
"lib/mutter.rb",
|
24
|
+
"mutter.gemspec",
|
25
|
+
"spec/mutter_spec.rb",
|
26
|
+
"spec/spec_helper.rb",
|
27
|
+
"spec/style.yml"
|
28
|
+
]
|
29
|
+
s.has_rdoc = true
|
30
|
+
s.homepage = %q{http://github.com/cloudhead/mutter}
|
31
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
32
|
+
s.require_paths = ["lib"]
|
33
|
+
s.rubygems_version = %q{1.3.1}
|
34
|
+
s.summary = %q{}
|
35
|
+
s.test_files = [
|
36
|
+
"spec/mutter_spec.rb",
|
37
|
+
"spec/spec_helper.rb"
|
38
|
+
]
|
39
|
+
|
40
|
+
if s.respond_to? :specification_version then
|
41
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
42
|
+
s.specification_version = 2
|
43
|
+
|
44
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
45
|
+
else
|
46
|
+
end
|
47
|
+
else
|
48
|
+
end
|
49
|
+
end
|
data/spec/mutter_spec.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe Mutter do
|
4
|
+
def out
|
5
|
+
File.read("spec/out.txt")
|
6
|
+
end
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
Mutter::Mutterer.stream = File.new("spec/out.txt", 'w')
|
10
|
+
end
|
11
|
+
|
12
|
+
after(:all) do
|
13
|
+
File.delete("spec/out.txt")
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should output strings" do
|
17
|
+
Mutter.say "hello mutter!"
|
18
|
+
out.should == "hello mutter!\n"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should underline" do
|
22
|
+
Mutter.say "_hello mutter!_"
|
23
|
+
out.should == "\e[4mhello mutter!\e[24m\n"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should bold" do
|
27
|
+
Mutter.say "*hello mutter!*"
|
28
|
+
out.should == "\e[1mhello mutter!\e[22m\n"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should inverse" do
|
32
|
+
Mutter.say "[hello mutter!]"
|
33
|
+
out.should == "\e[7mhello mutter!\e[27m\n"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should escape glyphs" do
|
37
|
+
Mutter.say "**hello * world**"
|
38
|
+
out.should == "\e[1mhello * world\e[22m\n"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should set defaults at the instance level" do
|
42
|
+
Mutter.new([:bold, :underline]).say "hello mutter!"
|
43
|
+
out.should == "\e[4m\e[1mhello mutter!\e[22m\e[24m\n"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should set defaults at the method level" do
|
47
|
+
Mutter.say "hello mutter!", :bold, :underline
|
48
|
+
out.should == "\e[4m\e[1mhello mutter!\e[22m\e[24m\n"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should set defaults at both levels" do
|
52
|
+
Mutter.new(:bold).say "hello mutter!", :underline, :yellow
|
53
|
+
out.should == "\e[33m\e[4m\e[1mhello mutter!\e[22m\e[24m\e[0m\n"
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "with custom styles" do
|
57
|
+
it "should work with custom styles" do
|
58
|
+
style = {
|
59
|
+
:alert => {
|
60
|
+
:match => '!',
|
61
|
+
:styles => ['bold', 'red']
|
62
|
+
}
|
63
|
+
}
|
64
|
+
Mutter.new(style).say "alert!", :alert
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should work with shorthand custom styles" do
|
68
|
+
Mutter.new({:bold => '~'}).say "~hello mutter!~"
|
69
|
+
out.should == "\e[1mhello mutter!\e[22m\n"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should color" do
|
73
|
+
Mutter.new({:cyan => ['<', '>']}).say "<hello mutter!>"
|
74
|
+
out.should == "\e[36mhello mutter!\e[0m\n"
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should mix styles" do
|
78
|
+
Mutter.new({:cyan => '~'}).say "_*hello* ~world~_"
|
79
|
+
out.should == "\e[4m\e[1mhello\e[22m \e[36mworld\e[0m\e[24m\n"
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should color backgrounds" do
|
83
|
+
Mutter.new({:cyan => '~'}).say "~[hello mutter!]~"
|
84
|
+
out.should == "\e[36m\e[7mhello mutter!\e[27m\e[0m\n"
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should work with multiple shorthand styles" do
|
88
|
+
Mutter.new({[:cyan, :underline] => '~'}).say "~hello mutter!~"
|
89
|
+
out.should == "\e[4m\e[36mhello mutter!\e[0m\e[24m\n"
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should load styles from a yaml" do
|
93
|
+
Mutter.new("spec/style").say "{important message!}"
|
94
|
+
out.should == "\e[33m\e[4m\e[1mimportant message!\e[22m\e[24m\e[0m\n"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should parse a complex string" do
|
99
|
+
m = Mutter.new({:cyan => ['<','>']})
|
100
|
+
m.say "hello *mutter*, would you _<please be quiet>_ for this <[test]>?"
|
101
|
+
out.should == "hello \e[1mmutter\e[22m, would you \e[4m\e[36mplease be quiet\e[0m\e[24m for this \e[36m\e[7mtest\e[27m\e[0m?\n"
|
102
|
+
end
|
103
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/spec/style.yml
ADDED
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cloudhead-mutter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- cloudhead
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-07-29 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: self@cloudhead.net
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- LICENSE
|
24
|
+
- README.md
|
25
|
+
files:
|
26
|
+
- .document
|
27
|
+
- .gitignore
|
28
|
+
- LICENSE
|
29
|
+
- README.md
|
30
|
+
- Rakefile
|
31
|
+
- VERSION
|
32
|
+
- lib/defaults.yml
|
33
|
+
- lib/mutter.rb
|
34
|
+
- mutter.gemspec
|
35
|
+
- spec/mutter_spec.rb
|
36
|
+
- spec/spec_helper.rb
|
37
|
+
- spec/style.yml
|
38
|
+
has_rdoc: true
|
39
|
+
homepage: http://github.com/cloudhead/mutter
|
40
|
+
licenses:
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options:
|
43
|
+
- --charset=UTF-8
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
version:
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
requirements: []
|
59
|
+
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 1.3.5
|
62
|
+
signing_key:
|
63
|
+
specification_version: 2
|
64
|
+
summary: ""
|
65
|
+
test_files:
|
66
|
+
- spec/mutter_spec.rb
|
67
|
+
- spec/spec_helper.rb
|