joker 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ # 0.0.1 #
2
+
3
+ * Initial release
4
+ * Ability to match Wildcards against strings
5
+ * Ability to quote strings for use in Wildcards
6
+
@@ -0,0 +1,23 @@
1
+ Copyright (c) 2009 Fabian Streitel
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
@@ -0,0 +1,70 @@
1
+ # Joker #
2
+
3
+ <http://karottenreibe.github.com/joker>
4
+
5
+ Joker is a simple Wildcard (a.k.a Glob Pattern) implementition
6
+ for Ruby.
7
+
8
+ ## Features ##
9
+
10
+ * Behaves much like Regexp
11
+ * ` * ` and ` ? ` as wildcard characters
12
+ * ` \ ` for escaping
13
+ * `\a` matches `\a`, but not `a`
14
+ * Wildcards must always match whole string
15
+ * Wildcards can be case insensitive
16
+
17
+ ## Installation ##
18
+
19
+ gem install karottenreibe-joker --source http://gems.github.com
20
+ gem install joker
21
+
22
+ ## Usage ##
23
+
24
+ require 'rubygems'
25
+ require 'joker'
26
+
27
+
28
+ wild = Wildcard['Fairy?ake*']
29
+
30
+ wild =~ 'Fairycake' #=> true
31
+ wild =~ 'Fairyfakes' #=> true
32
+ wild =~ 'Fairylake is a cool place' #=> true
33
+
34
+ wild =~ 'Dairycake' #=> false
35
+ wild =~ 'Fairysteakes' #=> false
36
+ wild =~ 'fairycake' #=> false
37
+
38
+ wildi = Wildcard['Fairy?ake*\?', true]
39
+
40
+ wildi =~ 'FairyCake?' #=> true
41
+ wildi =~ 'fairyfakes?' #=> true
42
+ wildi =~ 'FairyLake IS A COOL Place?' #=> true
43
+
44
+ Wildcard.quote('*?\\') #=> '\\*\\?\\\\'
45
+
46
+ ## License ##
47
+
48
+ Copyright (c) 2009 Fabian Streitel
49
+
50
+ Permission is hereby granted, free of charge, to any person
51
+ obtaining a copy of this software and associated documentation
52
+ files (the "Software"), to deal in the Software without
53
+ restriction, including without limitation the rights to use,
54
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
55
+ copies of the Software, and to permit persons to whom the
56
+ Software is furnished to do so, subject to the following
57
+ conditions:
58
+
59
+ The above copyright notice and this permission notice shall be
60
+ included in all copies or substantial portions of the Software.
61
+
62
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
63
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
64
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
65
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
66
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
67
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
68
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
69
+ OTHER DEALINGS IN THE SOFTWARE.
70
+
@@ -0,0 +1,20 @@
1
+ require 'jeweler'
2
+
3
+ task :build => :gemspec
4
+
5
+ Jeweler::Tasks.new do |gem|
6
+ gem.name = 'joker'
7
+ gem.summary = gem.description =
8
+ 'Joker is a simple wildcard implementation that works much like Regexps'
9
+ gem.email = 'karottenreibe@gmail.com'
10
+ gem.homepage = 'http://karottenreibe.github.com/joker'
11
+ gem.authors = ['Fabian Streitel']
12
+ gem.rubyforge_project = 'k-gems'
13
+ end
14
+
15
+ Jeweler::RubyforgeTasks.new
16
+
17
+ task :test do
18
+ sh 'bacon -Ilib test/test_*.rb'
19
+ end
20
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,179 @@
1
+ #
2
+ # Joker is a simple Wildcard implementation that works much like Regexps.
3
+ #
4
+
5
+ #
6
+ # Implements wildcards for Ruby. Modeled after the Regexp class.
7
+ #
8
+ # This implementation supports the following special characters:
9
+ #
10
+ # - ? matches a single character
11
+ # - * matches any number of characters, including 0
12
+ # - \\* matches a literal '*'
13
+ # - \\? matches a literal '?'
14
+ # - \\\\ matches a literal '\\'
15
+ # - [xyz] matches either 'x', 'y' or 'z'. NOTE that you have
16
+ # to escape ']' in these groups: \\]
17
+ #
18
+ # NOTE that '\\a' will match the literal string '\\a', not 'a' as
19
+ # one might expect.
20
+ #
21
+ # wild = Wildcard['Fairy?ake*']
22
+ # wild =~ 'Fairycake' #=> true
23
+ # wild =~ 'Fairyfakes are mean' #=> true
24
+ # wild =~ 'Fairysteakes are delicious' #=> false
25
+ #
26
+ # Also there is a case sensitivity flag. By default it is set to true,
27
+ # but it can be turned off at construction time:
28
+ #
29
+ # wild = Wildcard['Fairy?ake*', true]
30
+ # wild =~ 'Fairycake'
31
+ # wild =~ 'fairyCAKE'
32
+ # wild =~ 'FaIrYfAkEs, the Movie'
33
+ #
34
+ # Furthermore, any given Wildcard expression must match the whole string:
35
+ #
36
+ # wild = Wildcard['Fairy?ake']
37
+ # wild =~ 'some Fairycake' #=> false
38
+ # wild =~ 'Fairycake is good for you' #=> false
39
+ #
40
+ class Wildcard
41
+
42
+ #
43
+ # Boolean. Determines case sensitivity of the Wildcard.
44
+ #
45
+ # If this is true, the Wildcard will ignore case.
46
+ #
47
+ attr_reader :casefold
48
+
49
+ #
50
+ # The string from which the Wildcard was constructed.
51
+ #
52
+ attr_reader :source
53
+
54
+ #
55
+ # Creates a new Wildcard from the given string.
56
+ # If casefold is true, the Wildcard will ignore case.
57
+ #
58
+ def initialize( wildcard_string, casefold = false )
59
+ @source = wildcard_string
60
+ @casefold = casefold
61
+ @regexp =
62
+ if casefold then Regexp.new(compile, Regexp::IGNORECASE)
63
+ else Regexp.new(compile)
64
+ end
65
+ end
66
+
67
+ class << self
68
+
69
+ #
70
+ # Returns a new string with any characters escaped that would have
71
+ # special meaning in a Wildcard.
72
+ #
73
+ def quote( string )
74
+ string.gsub(%r{[\\?*\[]}) { |char| "\\#{char}" }
75
+ end
76
+
77
+ alias_method :[], :new
78
+ alias_method :compile, :new
79
+ alias_method :escape, :quote
80
+
81
+ end
82
+
83
+ def inspect
84
+ %{Wildcard[#{@source.inspect}]#{@casefold ? 'i' : ''}}
85
+ end
86
+
87
+ #
88
+ # Matches the wildcard against $_:
89
+ #
90
+ # $_ = 'I love fairycakes'
91
+ # ~Wildcard['*fairy*'] #=> true
92
+ #
93
+ def ~
94
+ self =~ $_
95
+ end
96
+
97
+ #
98
+ # Matches the Wildcard against the given string.
99
+ #
100
+ # NOTE: Since a wildcard has to match the whole string,
101
+ # this method only returns true or false, not the position
102
+ # of the match.
103
+ #
104
+ # Wildcard['*fairy*'] =~ 'I love fairycake' #=> true
105
+ # 'I love fairycake' =~ Wildcard['*dairy*'] #=> false
106
+ #
107
+ def =~( string )
108
+ !!(@regexp =~ string)
109
+ end
110
+
111
+ #
112
+ # The case operator. Allows you to use Wildcards in case
113
+ # expressions:
114
+ #
115
+ # case 'I love fairycake'
116
+ # when Wildcard['*fairy*'] then puts 'fairy!'
117
+ # else puts 'no fairy...'
118
+ # end
119
+ #
120
+ def ===( object )
121
+ !!(@regexp =~ object)
122
+ end
123
+
124
+ #
125
+ # Compares to Wildcards for equality.
126
+ #
127
+ # Two wildcards are equal, if they were constructed from the
128
+ # same string and have the same #casefold?().
129
+ #
130
+ def eql?( that )
131
+ return false unless that.is_a?(Wildcard)
132
+ @source == that.source && @casefold == that.casefold
133
+ end
134
+
135
+ alias_method :==, :eql?
136
+ alias_method :casefold?, :casefold
137
+
138
+ private
139
+
140
+ #
141
+ # Converts the wildcard string into a Regexp.
142
+ # A simple parser, I just threw it in there, no
143
+ # optimizations.
144
+ #
145
+ def compile
146
+ ptr = 0
147
+ compiled = '^'
148
+ while ptr < @source.length
149
+ snip = @source[ptr..-1]
150
+ if snip.scan(%r{^\\\\}).first
151
+ compiled << '\\\\'
152
+ ptr += 2
153
+ elsif snip.scan(%r{^\\\?}).first
154
+ compiled << '\\?'
155
+ ptr += 2
156
+ elsif snip.scan(%r{^\\\*}).first
157
+ compiled << '\\*'
158
+ ptr += 2
159
+ elsif snip.scan(%r{^\?}).first
160
+ compiled << '.'
161
+ ptr += 1
162
+ elsif snip.scan(%r{^\*}).first
163
+ compiled << '.*'
164
+ ptr += 1
165
+ elsif group = snip.scan(%r{^\[(?:\\\]|[^\]])+\]}).first
166
+ ptr += group.length
167
+ group = group[1..-2] # remove []
168
+ group = group.gsub(%r{\\\]}) { ']' }
169
+ compiled << '[' << Regexp.quote(group) << ']'
170
+ else
171
+ compiled << Regexp.quote(@source[ptr..ptr])
172
+ ptr += 1
173
+ end
174
+ end
175
+ compiled + '$'
176
+ end
177
+
178
+ end
179
+
@@ -0,0 +1,59 @@
1
+ require 'bacon'
2
+ require 'joker'
3
+
4
+ describe 'A Wildcard' do
5
+
6
+ before do
7
+ @wild ||= Wildcard['Fairy?ake*']
8
+ @wildi ||= Wildcard['Fairy?ake*\?', true]
9
+ @wildc ||= Wildcard['Fairy[cf]ake[!\\]]']
10
+ end
11
+
12
+ it 'should be constructed correctly' do
13
+ @wild.casefold?.should.be.false
14
+ @wildi.casefold?.should.be.true
15
+ @wildc.casefold?.should.be.false
16
+ regexp = @wild.instance_variable_get(:@regexp)
17
+ regexpi = @wildi.instance_variable_get(:@regexp)
18
+ regexpc = @wildc.instance_variable_get(:@regexp)
19
+ regexp.should.be == /^Fairy.ake.*$/
20
+ regexpi.should.be == /^Fairy.ake.*\?$/i
21
+ regexpc.should.be == /^Fairy[cf]ake[!\]]$/
22
+ end
23
+
24
+ it 'should match correct strings' do
25
+ @wild.should =~ 'Fairycake'
26
+ @wild.should =~ 'Fairyfakes'
27
+ @wild.should =~ 'Fairylake is a cool place'
28
+ end
29
+
30
+ it 'should not match incorrcet strings' do
31
+ @wild.should.not =~ 'Dairycake'
32
+ @wild.should.not =~ 'Fairysteakes'
33
+ @wild.should.not =~ 'fairycake'
34
+ end
35
+
36
+ it 'should match case insensitive' do
37
+ @wildi.should =~ 'FairyCake?'
38
+ @wildi.should =~ 'fairyfakes?'
39
+ @wildi.should =~ 'FairyLake IS A COOL Place?'
40
+ end
41
+
42
+ it 'should handle escapes correctly' do
43
+ wild = Wildcard['\\\\a\\?b\\*c\\d.][+'] # \\a\?b\*c\d.][+
44
+ regexp = wild.instance_variable_get(:@regexp)
45
+ regexp.should.be == /^\\a\?b\*c\\d\.\]\[\+$/
46
+ end
47
+
48
+ it 'should quote correctly' do
49
+ Wildcard.quote('*?\\').should.be == '\\*\\?\\\\' # *?\ --> \*\?\\
50
+ Wildcard.quote('\\\\').should.be == '\\\\\\\\' # \\ --> \\\\
51
+ end
52
+
53
+ it 'should know about character classes' do
54
+ @wildc.should =~ 'Fairycake!'
55
+ @wildc.should =~ 'Fairyfake]'
56
+ end
57
+
58
+ end
59
+
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: joker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Fabian Streitel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-15 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Joker is a simple wildcard implementation that works much like Regexps
17
+ email: karottenreibe@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE.txt
24
+ - README.markdown
25
+ files:
26
+ - HISTORY.markdown
27
+ - LICENSE.txt
28
+ - README.markdown
29
+ - Rakefile
30
+ - VERSION
31
+ - lib/joker.rb
32
+ - test/test_joker.rb
33
+ has_rdoc: true
34
+ homepage: http://karottenreibe.github.com/joker
35
+ licenses: []
36
+
37
+ post_install_message:
38
+ rdoc_options:
39
+ - --charset=UTF-8
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ version:
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ requirements: []
55
+
56
+ rubyforge_project: k-gems
57
+ rubygems_version: 1.3.5
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: Joker is a simple wildcard implementation that works much like Regexps
61
+ test_files:
62
+ - test/test_joker.rb