tickle 1.2.0 → 2.0.0.rc1

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.
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