elliottcable-stringray 2

Sign up to get free protection for your applications and to get access to all the features.
data/.manifest ADDED
@@ -0,0 +1,5 @@
1
+ lib/stringray.rb
2
+ Rakefile
3
+ README.mkdn
4
+ spec/stringray_spec.rb
5
+ .manifest
data/README.mkdn ADDED
@@ -0,0 +1,41 @@
1
+ StringRay
2
+ =========
3
+
4
+ **StringRay** exposes a powerful method to split a `String` into an `Array` of words,
5
+ and further allows you to include `Enumerable`, thus exposing many of the
6
+ most useful `Array` methods on your `String`s.
7
+
8
+ Usage
9
+ -----
10
+
11
+ class String; include StringRay; end
12
+
13
+ "Oi! I'm a string, do something fun with me!".each do |word|
14
+ p word
15
+ end
16
+
17
+ Getting
18
+ -------
19
+
20
+ The authoritative source for this project is available at
21
+ <http://github.com/elliottcable/stringray>. You can clone your own copy with the
22
+ following command:
23
+
24
+ git clone git://github.com/elliottcable/stringray.git
25
+
26
+ If you want to make changes to the codebase, you need to fork your own GitHub
27
+ repository for said changes. Send a pullrequest to [elliottcable](http://github.com/elliottcable "elliottcable on GitHub")
28
+ when you've got something ready for the master branch that you think should be
29
+ merged.
30
+
31
+ Requirements
32
+ ------------
33
+
34
+ To run git-blog, you need... nothing!
35
+
36
+ To develop and contribute to git-blog, you also need:
37
+
38
+ * `gem install rake`
39
+ * `gem install rspec`
40
+ * `gem install rcov`
41
+ * `gem install echoe`
data/Rakefile ADDED
@@ -0,0 +1,93 @@
1
+ ($:.unshift File.expand_path(File.join( File.dirname(__FILE__), 'lib' ))).uniq!
2
+ require 'stringray'
3
+ require 'extlib/string' # String#/, because I'm a lazy fuck.
4
+ require 'rake'
5
+ require 'rake/rdoctask'
6
+ require 'spec/rake/spectask'
7
+ require 'spec/rake/verify_rcov'
8
+
9
+ begin
10
+ require 'echoe'
11
+
12
+ namespace :echoe do
13
+ Echoe.new('StringRay', StringRay::VERSION) do |g|
14
+ g.name = 'stringray'
15
+ g.author = ['elliottcable']
16
+ g.email = ['StringRay@elliottcable.com']
17
+ g.summary = 'Combining many of the benefits of Arrays and Strings, StringRay allows you to treat a String as an Array of words in many cases.'
18
+ g.url = 'http://github.com/elliottcable/stringray'
19
+ g.dependencies = []
20
+ g.manifest_name = '.manifest'
21
+ g.ignore_pattern = ['.git', 'meta', 'stringray.gemspec']
22
+ end
23
+
24
+ desc 'tests packaged files to ensure they are all present'
25
+ task :verify => :package do
26
+ # An error message will be displayed if files are missing
27
+ if system %(ruby -e "require 'rubygems'; require 'pkg/merb_strokedb-#{StringRay::VERSION}/lib/stringray'")
28
+ puts "\nThe library files are present"
29
+ end
30
+ end
31
+
32
+ task :copy_gemspec => [:package] do
33
+ pkg = Dir['pkg/*'].select {|dir| File.directory? dir}.last
34
+ mv File.join(pkg, pkg.gsub(/^pkg\//,'').gsub(/\-\d+$/,'.gemspec')), './'
35
+ end
36
+
37
+ desc 'builds a gemspec as GitHub wants it'
38
+ task :gemspec => [:package, :copy_gemspec, :clobber_package]
39
+
40
+ # desc 'Run specs, clean tree, update manifest, run coverage, and install gem!'
41
+ desc 'Clean tree, update manifest, and install gem!'
42
+ task :magic => [:clean, :manifest, :install]
43
+ end
44
+
45
+ task :manifest => [:'echoe:manifest']
46
+
47
+ rescue LoadError => boom
48
+ puts "You are missing a dependency required for meta-operations on this gem."
49
+ puts "#{boom.to_s.capitalize}."
50
+ ensure
51
+ task :default # No effect # Invisible
52
+
53
+ # Runs specs, generates rcov, and opens rcov in your browser.
54
+ namespace :rcov do
55
+ Spec::Rake::SpecTask.new(:run) do |t|
56
+ t.spec_opts = ["--format", "specdoc", "--colour"]
57
+ t.spec_files = Dir['spec/**/*_spec.rb'].sort
58
+ t.libs = ['lib']
59
+ t.rcov = true
60
+ t.rcov_dir = 'meta' / 'coverage'
61
+ end
62
+
63
+ Spec::Rake::SpecTask.new(:plain) do |t|
64
+ t.spec_opts = ["--format", "specdoc"]
65
+ t.spec_files = Dir['spec/**/*_spec.rb'].sort
66
+ t.libs = ['lib']
67
+ t.rcov = true
68
+ t.rcov_opts = ['--exclude-only', '".*"', '--include-file', '^lib']
69
+ t.rcov_dir = 'meta' / 'coverage'
70
+ end
71
+
72
+ RCov::VerifyTask.new(:verify) do |t|
73
+ t.threshold = 100
74
+ t.index_html = 'meta' / 'coverage' / 'index.html'
75
+ end
76
+
77
+ task :open do
78
+ system 'open ' + 'meta' / 'coverage' / 'index.html' if PLATFORM['darwin']
79
+ end
80
+ end
81
+
82
+ namespace :git do
83
+ task :status do
84
+ `git status`
85
+ end
86
+ end
87
+
88
+ desc 'Check everything over before commiting'
89
+ task :aok => [:'echoe:manifest', :'rcov:run', :'rcov:verify', :'rcov:ratio', :'rcov:open', :'git:status']
90
+
91
+ # desc 'Task run during continuous integration' # Invisible
92
+ task :cruise => [:'rcov:plain', :'rcov:verify', :'rcov:ratio']
93
+ end
data/lib/stringray.rb ADDED
@@ -0,0 +1,136 @@
1
+ module StringRay
2
+ VERSION = 2
3
+
4
+ # Splits a string into words. Not using the obvious names (+#split+, +#words+)
5
+ # because I want compatibility for inclusion into +String+.
6
+ def enumerate
7
+ ray = []
8
+
9
+ self.each_byte do |byte|
10
+ char = byte.chr
11
+
12
+ if Delimiter::Characters.include? char
13
+ ray << Delimiter.new(char)
14
+
15
+ elsif Whitespace::Characters.include? char
16
+ if ray.last.is_a? Whitespace
17
+ ray.last << char
18
+ else
19
+ ray << Whitespace.new(char)
20
+ end
21
+
22
+ else
23
+ if ray.last.is_a? Word
24
+ ray.last << char
25
+ else
26
+ ray << Word.new(char)
27
+ end
28
+
29
+ end
30
+ end
31
+
32
+ ray
33
+ end
34
+
35
+ # More sensible than +String#each+, this uses +#enumerate+ to enumerate on
36
+ # words. Accepts options as a hash, determining whether :whitespace and
37
+ # :delemiters will :attach_before, :standalone, or :attach_after. Default is
38
+ # for both to :attach_before.
39
+ def each_word opts = {}, &block
40
+ {:whitespace => :attach_before, :delemiters => :attach_before}.merge! opts
41
+
42
+ # First, we create a two-dimensional array of words with any whitespace or
43
+ # delemiters that should attach to them.
44
+ words = self.enumerate
45
+ mapped = []
46
+ attach_before_next = []
47
+
48
+ words.each do |item|
49
+ case item
50
+ when Delimiter
51
+ case opts[:delemiters]
52
+ when :standalone
53
+ mapped << [item]
54
+ when :attach_after
55
+ attach_before_next << item
56
+ else
57
+ if attach_before_next.empty?
58
+ if mapped.last
59
+ mapped.last << item
60
+ else
61
+ attach_before_next << item
62
+ end
63
+ else
64
+ attach_before_next << item
65
+ end
66
+ end
67
+
68
+ when Whitespace
69
+ case opts[:whitespace]
70
+ when :standalone
71
+ mapped << [item]
72
+ when :attach_after
73
+ attach_before_next << item
74
+ else
75
+ if attach_before_next.empty?
76
+ if mapped.last
77
+ mapped.last << item
78
+ else
79
+ attach_before_next << item
80
+ end
81
+ else
82
+ attach_before_next << item
83
+ end
84
+ end
85
+
86
+ when Word
87
+ if not attach_before_next.empty?
88
+ mapped << [attach_before_next, item].flatten
89
+ attach_before_next = []
90
+ else
91
+ mapped << [item]
92
+ end
93
+
94
+ end
95
+ end
96
+ (mapped.last << attach_before_next).flatten! if not attach_before_next.empty?
97
+
98
+ # Next, we yield each group of (word plus delimiters and whitespace) as a
99
+ # normal string to the block
100
+ mapped.each do |arr|
101
+ yield arr.map{|w|w.to_s}.join
102
+ end
103
+ end
104
+
105
+ class Word < String
106
+ def inspect
107
+ "(#{self})"
108
+ end
109
+ end
110
+
111
+ class Whitespace < String
112
+ Characters = [" ", "\t", "\n"]
113
+ def inspect
114
+ "#{self}"
115
+ end
116
+ end
117
+
118
+ class Delimiter < String
119
+ Characters = ['-', ',', '.', '?', '!', ':', ';', '/', '\\', '|']
120
+
121
+ def inspect
122
+ "<#{self}>"
123
+ end
124
+ end
125
+
126
+ # This overrides +String#each+ with +StringRay#each_word+, thus allowing us
127
+ # to include +Enumerable+.
128
+ def self.included klass
129
+ klass.class_eval do
130
+ alias_method :each_at, :each
131
+ alias_method :each, :each_word
132
+
133
+ include Enumerable
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,108 @@
1
+ ($:.unshift File.expand_path(File.join( File.dirname(__FILE__), '..', 'lib' ))).uniq!
2
+ require 'stringray'
3
+
4
+ describe 'a String including StringRay' do
5
+ before :all do
6
+ String.send :include, StringRay
7
+ end
8
+
9
+ describe '#enumerate' do
10
+ it 'should split a string into an array' do
11
+ string = 'The time has come to talk of many things - of sailing ' +
12
+ 'ships and sealing wax, of cabbages and kings!'
13
+ string.inject([]) {|a, i| a << i }.should ==
14
+ ['The ','time ','has ','come ','to ','talk ','of ',
15
+ 'many ','things - ','of ','sailing ','ships ','and ','sealing ',
16
+ 'wax, ','of ','cabbages ','and ','kings!']
17
+ end
18
+
19
+ it 'should correctly treat commas and lists' do
20
+ string = 'I have commas, periods, and other punctuation'
21
+ string.inject([]) {|a, i| a << i }.should ==
22
+ ['I ','have ','commas, ','periods, ','and ','other ','punctuation']
23
+ end
24
+
25
+ it 'should correctly treat periods and end-of-sentance demarcators' do
26
+ string = 'Periods. Cool right? Yah!'
27
+ string.inject([]) {|a, i| a << i }.should ==
28
+ ['Periods. ','Cool ','right? ','Yah!']
29
+ end
30
+
31
+ it 'should correctly treat dahses' do
32
+ string = 'I have - uh - dashes!'
33
+ string.inject([]) {|a, i| a << i }.should ==
34
+ ['I ','have - ','uh - ','dashes!']
35
+ end
36
+
37
+ it 'should correctly treat ellipses' do
38
+ string = 'Where are we... going?'
39
+ string.inject([]) {|a, i| a << i }.should ==
40
+ ['Where ','are ','we... ','going?']
41
+ end
42
+
43
+ it 'should correctly treat a delimated word' do
44
+ string = 'String and Array, sitting in a tree - K-I-S-S-I-N-G!'
45
+ string.inject([]) {|a, i| a << i }.should ==
46
+ ['String ','and ','Array, ','sitting ','in ','a ','tree - ','K-','I-','S-','S-','I-','N-','G!']
47
+ end
48
+
49
+ it 'should correctly treat inline line returns' do
50
+ string = "This has\na line return!"
51
+ string.inject([]) {|a, i| a << i }.should ==
52
+ ["This ","has\n","a ","line ","return!"]
53
+ end
54
+
55
+ it 'should correctly treat prefacing line returns and whitespace' do
56
+ string = "\n Now it starts!\n\n"
57
+ string.inject([]) {|a, i| a << i }.should ==
58
+ ["\n Now ","it ","starts!\n\n"]
59
+ end
60
+ end
61
+
62
+ describe '#each_word' do
63
+ it 'should be able to attach delimeters to the beginning of the next word' do
64
+ string = 'The time has come to talk of many things - of sailing ' +
65
+ 'ships and sealing wax, of cabbages and kings!'
66
+ array = []
67
+ string.each(:delemiters => :attach_after) {|i| array << i }
68
+ array.should == ['The ','time ','has ','come ','to ','talk ','of ',
69
+ 'many ','things ','- of ','sailing ','ships ','and ','sealing ',
70
+ 'wax',', of ','cabbages ','and ','kings!']
71
+ end
72
+
73
+ it 'should be able to let delimeters stand alone' do
74
+ string = 'The time has come to talk of many things - of sailing ' +
75
+ 'ships and sealing wax, of cabbages and kings!'
76
+ array = []
77
+ string.each(:delemiters => :standalone) {|i| array << i }
78
+ array.should == ['The ','time ','has ','come ','to ','talk ','of ',
79
+ 'many ','things ','- ', 'of ','sailing ','ships ','and ','sealing ',
80
+ 'wax',', ','of ','cabbages ','and ','kings','!']
81
+ end
82
+
83
+ it 'should be able to attach whitespace to the beginning of the next word' do
84
+ string = 'The time has come to talk of many things - of sailing ' +
85
+ 'ships and sealing wax, of cabbages and kings!'
86
+ array = []
87
+ string.each(:whitespace => :attach_after) {|i| array << i }
88
+ array.should == ['The',' time',' has',' come',' to',' talk',' of',
89
+ ' many',' things',' - of',' sailing',' ships',' and',' sealing',
90
+ ' wax,',' of',' cabbages',' and',' kings!']
91
+ end
92
+
93
+ it 'should be able to let whitespace stand alone' do
94
+ string = 'The time has come to talk of many things - of sailing ' +
95
+ 'ships and sealing wax, of cabbages and kings!'
96
+ array = []
97
+ string.each(:whitespace => :standalone) {|i| array << i }
98
+ array.should == ['The',' ','time',' ','has',' ','come',' ','to',' ','talk',' ','of',
99
+ ' ','many',' ','things',' -',' ','of',' ','sailing',' ','ships',' ','and',' ','sealing',
100
+ ' ','wax,',' ','of',' ','cabbages',' ','and',' ','kings!']
101
+ end
102
+ end
103
+
104
+ # TODO: Figure out a better way to say 'should be_include(Enumerable)'
105
+ it 'should also include enumerable' do
106
+ String.ancestors.should be_include(Enumerable)
107
+ end
108
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: elliottcable-stringray
3
+ version: !ruby/object:Gem::Version
4
+ version: "2"
5
+ platform: ruby
6
+ authors:
7
+ - elliottcable
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ date: 2008-08-12 01:00:00 -07:00
12
+ default_executable:
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: echoe
16
+ type: :development
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ version:
24
+ description: Combining many of the benefits of Arrays and Strings, StringRay allows you to treat a String as an Array of words in many cases.
25
+ email:
26
+ - StringRay@elliottcable.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - lib/stringray.rb
33
+ - README.mkdn
34
+ files:
35
+ - lib/stringray.rb
36
+ - Rakefile
37
+ - README.mkdn
38
+ - spec/stringray_spec.rb
39
+ - .manifest
40
+ - StringRay.gemspec
41
+ has_rdoc: true
42
+ homepage: http://github.com/elliottcable/stringray
43
+ post_install_message:
44
+ rdoc_options:
45
+ - --line-numbers
46
+ - --inline-source
47
+ - --title
48
+ - StringRay
49
+ - --main
50
+ - README.mkdn
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - "="
62
+ - !ruby/object:Gem::Version
63
+ version: "1.2"
64
+ version:
65
+ requirements: []
66
+
67
+ rubyforge_project: stringray
68
+ rubygems_version: 1.2.0
69
+ signing_key:
70
+ specification_version: 2
71
+ summary: Combining many of the benefits of Arrays and Strings, StringRay allows you to treat a String as an Array of words in many cases.
72
+ test_files: []
73
+