tickle 1.2.0 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6c9f24bf840e38c2196e61c1428caa9d84eeb7b5
4
- data.tar.gz: 6e8111fb7b6098f3c285d537b2adb529ede9ad36
3
+ metadata.gz: 1d8b35a7f362cfb13d80ef3236f7f1f036cd7ebc
4
+ data.tar.gz: cec9f257100839052b8ea4e7b7a64fa560eebd01
5
5
  SHA512:
6
- metadata.gz: 84a13f5b64bd9e49327bca5456bbcb197b7d66b90b0f349ea035f842ffe8aa440a263aefc690d163c5023ac24e13b398b395da9e6d7240e9a89220c7c4ca9433
7
- data.tar.gz: 2514f63b04e43ec3610932dc115ad127b29b9a384e9b99fe6c52606982ebb2537cb20ac06beccf2cfcc25630a5c2f7c5021870119ab39395b7fe9f4361af5a1b
6
+ metadata.gz: d3d2636db14e75ce64453d3bf42bfdb4f22fde65af54a01b5113a58447ab46e9530a39f16771265a28e345a16b22417ae6dca699c8828cd9d4825d756db38af0
7
+ data.tar.gz: e972f8974b427bcb5ad3be4333b4ac0951a82ada15f9cc8def342ff7414dd636e4169f757f579a3f17baa9c1578a265bc33865ee596f1e1aee2f2a4123be052b
data/.gitignore CHANGED
@@ -14,8 +14,9 @@ rdoc
14
14
  pkg
15
15
  bin/
16
16
  vendor/
17
+ vendor.noindex/
17
18
  Gemfile.lock
18
- spec/
19
19
  .yardoc/
20
20
  .bundle/
21
21
  .rspec
22
+ *.gem
@@ -1,12 +1,14 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.7
4
- - jruby
5
- - truffleruby
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.1
6
+ - ruby-head
7
+ - jruby-19mode
8
+ # - rbx-2.1.1 # not working right now, will look at later
6
9
 
7
10
  # whitelist
8
11
  branches:
9
12
  only:
10
13
  - master
11
14
  - develop
12
- - v1-branch
data/CHANGES.md CHANGED
@@ -1,39 +1,21 @@
1
1
  # CH CH CH CH CHANGES! #
2
2
 
3
- ## Friday the 18th of September 2020, v1.2.0
3
+ ## Saturday the 7th of November 2015, 2.0.0.rc1 ##
4
4
 
5
- - Changed the dependency from chronic to gitlab-chronic
6
- - Required numerizer explicitly to stop a bug
7
- - Formatted the regex for legibility
8
- - Fixed bug with "today and" in the tests
9
- - Fixed a bug previously fixed on the v2 branch in 2f2a32ce9 with @start
10
- - Added Timecop because we're beyond the date chosen in the tests. Tempus fugit!
5
+ - Rewrite of the internals.
6
+ - API should be pretty much the same from the outside, but enough things on the inside change to warrant the major version bump.
7
+ - Chronic updated to 0.10.2.
11
8
 
12
9
  ----
13
10
 
14
- ## Wednesday the 15th of March 2017, v1.1.1 ##
15
-
16
- * Bit of easier debugging added in.
17
- * Bug fixes, thanks to https://github.com/dodomarocgenex for finding and helping with them.
18
-
19
- ----
20
-
21
- ## Wednesday the 22nd of February 2017, v1.1.0 ##
22
-
23
- * Numerizer duplication removed. Thanks to https://github.com/bjonord.
24
- * Some very minor changes to the project, no other code changes.
25
-
26
- ----
27
-
28
-
29
- ## Monday the 11th of November 2015, v1.0.2 ##
11
+ ## Monday the 11th of November 2013, v1.0.2 ##
30
12
 
31
13
  * Shoulda and simplecov aren't runtime dependencies, fixed that in the gemfile.
32
14
  * Got the version number right this time ;-)
33
15
 
34
16
  ----
35
17
 
36
- ## Monday the 11th of November 2015, v1.0.1 ##
18
+ ## Monday the 11th of November 2013, v1.0.1 ##
37
19
 
38
20
  * Moved library to new maintainer [https://github.com/yb66/tickle](@yb66)
39
21
  * Moved library to [http://semver.org/](semver).
data/Gemfile CHANGED
@@ -2,9 +2,18 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- group :test do
6
- gem "rspec"
5
+ group :development do
6
+ gem "wirble"
7
+ gem "maruku"
8
+ gem "yard"
9
+ gem "pry-byebug"
10
+ gem "activesupport"
7
11
  end
8
12
 
9
- gem "pry-byebug"
10
- gem "pry-state"
13
+ group :test do
14
+ gem "rspec"
15
+ gem "rspec-its"
16
+ gem "timecop"
17
+ gem "simplecov"
18
+ gem "rake"
19
+ end
data/LICENCE CHANGED
@@ -1,5 +1,5 @@
1
1
  Copyright (c) 2010 Joshua Lippiner
2
- Copyright (c) 2013 Iain Barnett
2
+ Copyright (c) 2015 Iain Barnett
3
3
 
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
data/README.md CHANGED
@@ -11,7 +11,7 @@ Take a look at the `develop` branch where all this stuff will be happening.
11
11
 
12
12
  Tickle is a natural language parser for recurring events.
13
13
 
14
- Tickle is designed to be a complement to [Chronic](https://rubygems.org/gems/chronic) and can interpret things such as "every 2 days, every Sunday, Sundays, Weekly, etc."
14
+ Tickle is designed to be a complement to [Chronic](https://rubygems.org/gems/chronic) and can interpret things such as "every 2 days", "every Sunday", Sundays", Weekly", etc.
15
15
 
16
16
  Tickle has one main method, `Tickle.parse`, which returns the next time the event should occur, at which point you simply call `Tickle.parse` again.
17
17
 
@@ -407,7 +407,7 @@ or if you're using Bundler, add this to the Gemfile:
407
407
 
408
408
  Chronic gem:
409
409
 
410
- `gem install gitlab-chronic`
410
+ `gem install chronic`
411
411
 
412
412
  thoughtbot's [shoulda](https://rubygems.org/gems/shoulda):
413
413
 
data/Rakefile CHANGED
@@ -1,11 +1,8 @@
1
- require 'rake/testtask'
2
- Rake::TestTask.new(:test) do |test|
3
- test.libs << 'lib' << 'test'
4
- test.pattern = 'test/**/test_*.rb'
5
- test.verbose = true
6
- end
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new(:spec)
7
4
 
8
- task :default => :test
5
+ task :default => :spec
9
6
 
10
7
 
11
8
  desc "(Re-) generate documentation and place it in the docs/ dir. Open the index.html file in there to read it."
@@ -0,0 +1,71 @@
1
+ require 'benchmark'
2
+ require_relative "../lib/tickle.rb"
3
+ warn Benchmark.measure {
4
+ Tickle.parse('day')
5
+ # Tickle.parse('week')
6
+ Tickle.parse('month')
7
+ Tickle.parse('year')
8
+ Tickle.parse('daily')
9
+ # Tickle.parse('weekly')
10
+ Tickle.parse('monthly')
11
+ Tickle.parse('yearly')
12
+ Tickle.parse('3 days')
13
+ # Tickle.parse('3 weeks')
14
+ Tickle.parse('3 months')
15
+ Tickle.parse('3 years')
16
+ Tickle.parse('other day')
17
+ # Tickle.parse('other week')
18
+ Tickle.parse('other month')
19
+ Tickle.parse('other year')
20
+ Tickle.parse('Monday')
21
+ Tickle.parse('Wednesday')
22
+ Tickle.parse('Friday')
23
+ Tickle.parse('February', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
24
+ Tickle.parse('May', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
25
+ Tickle.parse('june', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
26
+ Tickle.parse('beginning of the week')
27
+ Tickle.parse('middle of the week')
28
+ Tickle.parse('end of the week')
29
+ Tickle.parse('beginning of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
30
+ Tickle.parse('middle of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
31
+ Tickle.parse('end of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
32
+ Tickle.parse('beginning of the year', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
33
+ Tickle.parse('middle of the year', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
34
+ Tickle.parse('end of the year', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
35
+ Tickle.parse('the 3rd of May', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
36
+ Tickle.parse('the 3rd of February', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
37
+ Tickle.parse('the 3rd of February 2022', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
38
+ Tickle.parse('the 3rd of Feb 2022', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
39
+ Tickle.parse('the 4th of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
40
+ Tickle.parse('the 10th of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
41
+ Tickle.parse('the tenth of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
42
+ Tickle.parse('first', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
43
+ Tickle.parse('the first of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
44
+ Tickle.parse('the thirtieth', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
45
+ Tickle.parse('the fifth', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
46
+ Tickle.parse('the 1st Wednesday of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
47
+ Tickle.parse('the 3rd Sunday of May', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
48
+ Tickle.parse('the 3rd Sunday of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
49
+ Tickle.parse('the 23rd of June', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
50
+ Tickle.parse('the twenty third of June', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
51
+ Tickle.parse('the thirty first of July', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
52
+ Tickle.parse('the twenty first', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
53
+ Tickle.parse('the twenty first of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
54
+ Tickle.parse('starting today and ending one week from now')
55
+ Tickle.parse('starting tomorrow and ending one week from now')
56
+ Tickle.parse('starting Monday repeat every month')
57
+ Tickle.parse('starting May 13th repeat every week')
58
+ Tickle.parse('starting May 13th repeat every other day')
59
+ Tickle.parse('every other day starts May 13th')
60
+ Tickle.parse('every other day starts May 13')
61
+ Tickle.parse('every other day starting May 13th')
62
+ Tickle.parse('every other day starting May 13')
63
+ Tickle.parse('every week starts this wednesday')
64
+ Tickle.parse('every week starting this wednesday')
65
+ Tickle.parse('every other day starting May 1st 2021')
66
+ Tickle.parse('every other day starting May 1 2021')
67
+ Tickle.parse('every other week starting this Sunday')
68
+ Tickle.parse('every week starting this wednesday until May 13th')
69
+ Tickle.parse('every week starting this wednesday ends May 13th')
70
+ Tickle.parse('every week starting this wednesday ending May 13th')
71
+ }
@@ -0,0 +1,6 @@
1
+ class Array
2
+ # compares two arrays to determine if they both contain the same elements
3
+ def same?(y)
4
+ self.sort == y.sort
5
+ end
6
+ end
@@ -0,0 +1,64 @@
1
+ class Date
2
+ # returns the days in the sending month
3
+ def days_in_month
4
+ d,m,y = mday,month,year
5
+ d += 1 while Date.valid_civil?(y,m,d)
6
+ d - 1
7
+ end
8
+
9
+
10
+ # no idea what this is for
11
+ def bump(attr, amount=nil)
12
+ amount ||= 1
13
+ case attr
14
+ when :day then
15
+ Date.civil(self.year, self.month, self.day + amount)
16
+ when :wday then
17
+ amount = Date::ABBR_DAYNAMES.index(amount) if amount.is_a?(String)
18
+ raise Exception, "specified day of week invalid. Use #{Date::ABBR_DAYNAMES}" unless amount
19
+ diff = (amount > self.wday) ? (amount - self.wday) : (7 - (self.wday - amount))
20
+ Date.civil(self.year, self.month, self.day + diff)
21
+ when :week then
22
+ Date.civil(self.year, self.month, self.day + (7*amount))
23
+ when :month then
24
+ Date.civil(self.year, self.month+amount, self.day)
25
+ when :year then
26
+ Date.civil(self.year + amount, self.month, self.day)
27
+ when :sec then
28
+ Date.civil(self.year, self.month, self.day, self.hour, self.minute, self.sec + amount)
29
+ else
30
+ raise Exception, "type \"#{attr}\" not supported."
31
+ end
32
+ end
33
+ end
34
+
35
+ class Time
36
+
37
+ # same again, no idea what this is for
38
+ def bump(attr, amount=nil)
39
+ amount ||= 1
40
+ case attr
41
+ when :sec then
42
+ Time.local(self.year, self.month, self.day, self.hour, self.min, self.sec + amount)
43
+ when :min then
44
+ Time.local(self.year, self.month, self.day, self.hour, self.min + amount, self.sec)
45
+ when :hour then
46
+ Time.local(self.year, self.month, self.day, self.hour + amount, self.min, self.sec)
47
+ when :day then
48
+ Time.local(self.year, self.month, self.day + amount, self.hour, self.min, self.sec)
49
+ when :wday then
50
+ amount = Time::RFC2822_DAY_NAME.index(amount) if amount.is_a?(String)
51
+ raise Exception, "specified day of week invalid. Use #{Time::RFC2822_DAY_NAME}" unless amount
52
+ diff = (amount > self.wday) ? (amount - self.wday) : (7 - (self.wday - amount))
53
+ Time.local(self.year, self.month, self.day + diff, self.hour, self.min, self.sec)
54
+ when :week then
55
+ Time.local(self.year, self.month, self.day + (amount * 7), self.hour, self.min, self.sec)
56
+ when :month then
57
+ Time.local(self.year, self.month + amount, self.day, self.hour, self.min, self.sec)
58
+ when :year then
59
+ Time.local(self.year + amount, self.month, self.day, self.hour, self.min, self.sec)
60
+ else
61
+ raise Exception, "type \"#{attr}\" not supported."
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,39 @@
1
+ module Tickle
2
+ class Ordinal < ::String
3
+ # returns true if the sending string is a text or numeric ordinal (e.g. first or 1st)
4
+ def is_ordinal?
5
+ scanner = %w{first second third fourth fifth sixth seventh eighth ninth tenth eleventh twelfth thirteenth fourteenth fifteenth sixteenth seventeenth eighteenth nineteenth twenty thirty thirtieth}
6
+ regex = /\b(\d*)(st|nd|rd|th)\b/
7
+ !(self =~ regex).nil? || scanner.include?(self.downcase)
8
+ end
9
+
10
+ def ordinal_as_number
11
+ return self unless self.is_ordinal?
12
+ scanner = {/first/ => '1st',
13
+ /second/ => '2nd',
14
+ /third/ => '3rd',
15
+ /fourth/ => '4th',
16
+ /fifth/ => '5th',
17
+ /sixth/ => '6th',
18
+ /seventh/ => '7th',
19
+ /eighth/ => '8th',
20
+ /ninth/ => '9th',
21
+ /tenth/ => '10th',
22
+ /eleventh/ => '11th',
23
+ /twelfth/ => '12th',
24
+ /thirteenth/ => '13th',
25
+ /fourteenth/ => '14th',
26
+ /fifteenth/ => '15th',
27
+ /sixteenth/ => '16th',
28
+ /seventeenth/ => '17th',
29
+ /eighteenth/ => '18th',
30
+ /nineteenth/ => '19th',
31
+ /twentieth/ => '20th',
32
+ /thirtieth/ => '30th',
33
+ }
34
+ result = self
35
+ scanner.keys.each {|scanner_item| result = scanner[scanner_item] if scanner_item =~ self}
36
+ return result.gsub(/\b(\d*)(st|nd|rd|th)\b/, '\1')
37
+ end
38
+ end
39
+ end
@@ -9,29 +9,40 @@
9
9
 
10
10
  $LOAD_PATH.unshift(File.dirname(__FILE__)) # For use/testing when no gem is installed
11
11
 
12
- if ENV["DEBUG"]
13
- warn "DEBUG MODE ON"
14
- require 'pry-byebug'
15
- require 'pry-state'
16
- binding.pry
17
- end
18
-
19
12
  require 'date'
20
13
  require 'time'
21
- require 'gitlab-chronic'
14
+ require 'chronic'
22
15
 
23
16
  require 'tickle/tickle'
24
17
  require 'tickle/handler'
25
18
  require 'tickle/repeater'
19
+ require_relative "tickle/tickled.rb"
20
+ require_relative "ext/array.rb"
21
+ require_relative "ext/date_and_time.rb"
22
+ require_relative "ext/string.rb"
23
+
24
+ # these are required not because they're used by the library
25
+ # but because they clobber so much that testing
26
+ # without them will miss possible problems
27
+ require 'active_support/core_ext/string/conversions'
28
+ require 'active_support/core_ext/date/calculations'
29
+ require 'active_support/core_ext/date_time/calculations'
30
+ require 'active_support/core_ext/time/calculations'
26
31
 
27
- module Tickle #:nodoc:
32
+ # Tickle is a natural language parser for recurring events.
33
+ module Tickle
28
34
 
29
- def self.debug=(val); @debug = val; end
35
+ def self.parse(asked, options = {})
36
+ # check to see if a datetime was passed
37
+ # if so, give it back
38
+ # TODO Consider converting to a Tickled
39
+ return asked if asked.respond_to? :day
30
40
 
31
- def self.dwrite(msg, line_feed=nil)
32
- (line_feed ? p(">> #{msg}") : puts(">> #{msg}")) if @debug
41
+ tickled = Tickled.new asked.dup, options
42
+ _parse tickled
33
43
  end
34
44
 
45
+
35
46
  def self.is_date(str)
36
47
  begin
37
48
  Date.parse(str.to_s)
@@ -40,108 +51,4 @@ module Tickle #:nodoc:
40
51
  return false
41
52
  end
42
53
  end
43
- end
44
-
45
- class Date #:nodoc:
46
- # returns the days in the sending month
47
- def days_in_month
48
- d,m,y = mday,month,year
49
- d += 1 while Date.valid_civil?(y,m,d)
50
- d - 1
51
- end
52
-
53
- def bump(attr, amount=nil)
54
- amount ||= 1
55
- case attr
56
- when :day then
57
- Date.civil(self.year, self.month, self.day).next_day(amount)
58
- when :wday then
59
- amount = Date::ABBR_DAYNAMES.index(amount) if amount.is_a?(String)
60
- raise Exception, "specified day of week invalid. Use #{Date::ABBR_DAYNAMES}" unless amount
61
- diff = (amount > self.wday) ? (amount - self.wday) : (7 - (self.wday - amount))
62
- Date.civil(self.year, self.month, self.day).next_day(diff)
63
- when :week then
64
- Date.civil(self.year, self.month, self.day).next_day(7*amount)
65
- when :month then
66
- Date.civil(self.year, self.month, self.day).next_month(amount)
67
- when :year then
68
- Date.civil(self.year, self.month, self.day).next_year(amount)
69
- else
70
- raise Exception, "type \"#{attr}\" not supported."
71
- end
72
- end
73
- end
74
-
75
- class Time #:nodoc:
76
- def bump(attr, amount=nil)
77
- amount ||= 1
78
- case attr
79
- when :sec then
80
- Time.local(self.year, self.month, self.day, self.hour, self.min, self.sec) + amount
81
- when :min then
82
- Time.local(self.year, self.month, self.day, self.hour, self.min, self.sec) + (amount * 60)
83
- when :hour then
84
- Time.local(self.year, self.month, self.day, self.hour, self.min, self.sec) + (amount * 60 * 60)
85
- when :day then
86
- Time.local(self.year, self.month, self.day, self.hour, self.min, self.sec) + (amount * 60 * 60 * 24)
87
- when :wday then
88
- amount = Time::RFC2822_DAY_NAME.index(amount) if amount.is_a?(String)
89
- raise Exception, "specified day of week invalid. Use #{Time::RFC2822_DAY_NAME}" unless amount
90
- diff = (amount > self.wday) ? (amount - self.wday) : (7 - (self.wday - amount))
91
- DateTime.civil(self.year, self.month, self.day, self.hour, self.min, self.sec, self.zone).next_day(diff)
92
- when :week then
93
- DateTime.civil(self.year, self.month, self.day, self.hour, self.min, self.sec, self.zone).next_day(amount * 7)
94
- when :month then
95
- DateTime.civil(self.year, self.month, self.day, self.hour, self.min, self.sec, self.zone).next_month(amount)
96
- when :year then
97
- DateTime.civil(self.year, self.month, self.day, self.hour, self.min, self.sec, self.zone).next_year(amount)
98
- else
99
- raise Exception, "type \"#{attr}\" not supported."
100
- end.to_time.localtime
101
- end
102
- end
103
-
104
- class String #:nodoc:
105
- # returns true if the sending string is a text or numeric ordinal (e.g. first or 1st)
106
- def is_ordinal?
107
- scanner = %w{first second third fourth fifth sixth seventh eighth ninth tenth eleventh twelfth thirteenth fourteenth fifteenth sixteenth seventeenth eighteenth nineteenth twenty thirty thirtieth}
108
- regex = /\b(\d*)(st|nd|rd|th)\b/
109
- !(self =~ regex).nil? || scanner.include?(self.downcase)
110
- end
111
-
112
- def ordinal_as_number
113
- return self unless self.is_ordinal?
114
- scanner = {/first/ => '1st',
115
- /second/ => '2nd',
116
- /third/ => '3rd',
117
- /fourth/ => '4th',
118
- /fifth/ => '5th',
119
- /sixth/ => '6th',
120
- /seventh/ => '7th',
121
- /eighth/ => '8th',
122
- /ninth/ => '9th',
123
- /tenth/ => '10th',
124
- /eleventh/ => '11th',
125
- /twelfth/ => '12th',
126
- /thirteenth/ => '13th',
127
- /fourteenth/ => '14th',
128
- /fifteenth/ => '15th',
129
- /sixteenth/ => '16th',
130
- /seventeenth/ => '17th',
131
- /eighteenth/ => '18th',
132
- /nineteenth/ => '19th',
133
- /twentieth/ => '20th',
134
- /thirtieth/ => '30th',
135
- }
136
- result = self
137
- scanner.keys.each {|scanner_item| result = scanner[scanner_item] if scanner_item =~ self}
138
- return result.gsub(/\b(\d*)(st|nd|rd|th)\b/, '\1')
139
- end
140
- end
141
-
142
- class Array #:nodoc:
143
- # compares two arrays to determine if they both contain the same elements
144
- def same?(y)
145
- self.sort == y.sort
146
- end
147
- end
54
+ end