hizuke 0.0.3 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +37 -1
- data/Gemfile +2 -2
- data/Gemfile.lock +1 -1
- data/README.md +91 -2
- data/Rakefile +6 -6
- data/hizuke.gemspec +39 -0
- data/lib/hizuke/constants.rb +86 -0
- data/lib/hizuke/date_calculator.rb +458 -0
- data/lib/hizuke/parser.rb +83 -411
- data/lib/hizuke/pattern_matcher.rb +495 -0
- data/lib/hizuke/version.rb +2 -2
- data/lib/hizuke.rb +31 -4
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b0d90523e4927c6aeac7e03575aeb0bbb9cc923e6524cf63eacfbcff6115cb8
|
4
|
+
data.tar.gz: b641b880ad5ac8a67a29437702aea3c7f690695d9a560c039b2eead361b4d30f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 788e7bcd5b09046f865771f7b9fc3ef55bab5ed6b1374891ef24006d67db8e3759fadaf34d21fd9ed60bce27331ef1ca6545a0fe9cd8c272ac74265b7f97772f
|
7
|
+
data.tar.gz: c8a4b2c5c5d07cf3c8f3d4233121a0f92c379ff2d8caaa05804e021b19da07271deec84af4ffa2061fa98e3cf84419113a09307ae25ee402fa194e874e607f81
|
data/CHANGELOG.md
CHANGED
@@ -5,7 +5,43 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
-
## [0.0
|
8
|
+
## [0.1.0] - 2025-05-08
|
9
|
+
|
10
|
+
### Added
|
11
|
+
- Support for Christmas date parsing:
|
12
|
+
- "christmas" / "xmas" - returns December 25th of the current year
|
13
|
+
- "last christmas" / "lastchristmas" - returns December 25th of the previous year
|
14
|
+
- "next christmas" / "nextchristmas" - returns December 25th of the next year
|
15
|
+
|
16
|
+
### Changed
|
17
|
+
- Major refactoring of the entire codebase:
|
18
|
+
- Improved code organization and structure
|
19
|
+
- Better error handling and edge case management
|
20
|
+
- Cleaner API design for better developer experience
|
21
|
+
|
22
|
+
## [0.0.4] - 2025-04-29
|
23
|
+
|
24
|
+
### Added
|
25
|
+
- Support for time recognition in text:
|
26
|
+
- "at X" format (e.g., "at 10" for 10:00)
|
27
|
+
- "@ X" alternative syntax
|
28
|
+
- Time with minutes "at X:Y" (e.g., "at 10:30")
|
29
|
+
- Time with seconds "at X:Y:Z" (e.g., "at 10:30:45")
|
30
|
+
- AM/PM format "at Xam/pm" (e.g., "at 10am", "at 7pm")
|
31
|
+
- New attributes in Result class:
|
32
|
+
- `time` attribute to access the extracted time
|
33
|
+
- `datetime` method to get a combined Time object of date and time
|
34
|
+
- Created a dedicated `TimeOfDay` class for better time handling with cleaner display
|
35
|
+
- Support for word-based time expressions:
|
36
|
+
- "at noon" - returns 12:00
|
37
|
+
- "at midnight" - returns 00:00
|
38
|
+
- "in the morning" - returns configurable time (default 08:00)
|
39
|
+
- "in the evening" - returns configurable time (default 20:00)
|
40
|
+
- Configuration system to customize times for "morning" and "evening"
|
41
|
+
- Comprehensive tests for time parsing functionality
|
42
|
+
- Updated documentation with time parsing examples and supported formats
|
43
|
+
|
44
|
+
## [0.0.3] - 2025-04-24
|
9
45
|
|
10
46
|
### Added
|
11
47
|
- Support for quarterly date references:
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Hizuke
|
2
2
|
|
3
|
-
Hizuke is a simple Ruby gem that parses text containing date references like "yesterday", "today", and "tomorrow". It extracts the date and returns the clean text without the date reference.
|
3
|
+
Hizuke is a simple Ruby gem that parses text containing date references like "yesterday", "today", and "tomorrow". It extracts the date and returns the clean text without the date reference. It can also recognize time references like "at 10" or "at 7pm".
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -61,10 +61,76 @@ puts result.date # => <Date: 2024-01-01> (represents the first day of the next
|
|
61
61
|
result = Hizuke.parse("hiking this weekend")
|
62
62
|
puts result.text # => "hiking"
|
63
63
|
puts result.date # => <Date: 2023-04-01> (represents the next Saturday)
|
64
|
+
|
65
|
+
# Parse text with time
|
66
|
+
result = Hizuke.parse("meeting tomorrow at 10")
|
67
|
+
puts result.text # => "meeting"
|
68
|
+
puts result.date # => <Date: 2023-04-01> (represents tomorrow's date)
|
69
|
+
puts result.time # => 10:00 (represents the time)
|
70
|
+
puts result.datetime # => 2023-04-01 10:00:00 (combines date and time)
|
71
|
+
|
72
|
+
# Parse text with time including minutes
|
73
|
+
result = Hizuke.parse("call client today at 14:30")
|
74
|
+
puts result.text # => "call client"
|
75
|
+
puts result.date # => <Date: 2023-03-31> (represents today's date)
|
76
|
+
puts result.time # => 14:30 (represents the time)
|
77
|
+
puts result.datetime # => 2023-03-31 14:30:00 (combines date and time)
|
78
|
+
|
79
|
+
# Parse text with AM/PM time
|
80
|
+
result = Hizuke.parse("lunch meeting tomorrow at 12pm")
|
81
|
+
puts result.text # => "lunch meeting"
|
82
|
+
puts result.date # => <Date: 2023-04-01> (represents tomorrow's date)
|
83
|
+
puts result.time # => 12:00 (represents the time, noon)
|
84
|
+
puts result.datetime # => 2023-04-01 12:00:00 (combines date and time)
|
85
|
+
|
86
|
+
# Parse text with word-based time
|
87
|
+
result = Hizuke.parse("dinner tomorrow at noon")
|
88
|
+
puts result.text # => "dinner"
|
89
|
+
puts result.date # => <Date: 2023-04-01> (represents tomorrow's date)
|
90
|
+
puts result.time # => 12:00 (represents noon)
|
91
|
+
|
92
|
+
result = Hizuke.parse("flight today at midnight")
|
93
|
+
puts result.text # => "flight"
|
94
|
+
puts result.date # => <Date: 2023-03-31> (represents today's date)
|
95
|
+
puts result.time # => 00:00 (represents midnight)
|
96
|
+
|
97
|
+
result = Hizuke.parse("breakfast tomorrow in the morning")
|
98
|
+
puts result.text # => "breakfast"
|
99
|
+
puts result.date # => <Date: 2023-04-01> (represents tomorrow's date)
|
100
|
+
puts result.time # => 08:00 (default morning time)
|
101
|
+
|
102
|
+
result = Hizuke.parse("dinner today in the evening")
|
103
|
+
puts result.text # => "dinner"
|
104
|
+
puts result.date # => <Date: 2023-03-31> (represents today's date)
|
105
|
+
puts result.time # => 20:00 (default evening time)
|
64
106
|
```
|
65
107
|
|
66
108
|
The parser is case-insensitive and can handle date references located anywhere in the text. It also supports date references with or without spaces (e.g., "nextweek" or "next week").
|
67
109
|
|
110
|
+
## Configuration
|
111
|
+
|
112
|
+
You can configure the time values for "in the morning" and "in the evening" expressions:
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
Hizuke.configure do |config|
|
116
|
+
# Set morning time to 9:30
|
117
|
+
config.morning_time = { hour: 9, min: 30 }
|
118
|
+
|
119
|
+
# Set evening time to 7:00 PM
|
120
|
+
config.evening_time = { hour: 19, min: 0 }
|
121
|
+
end
|
122
|
+
|
123
|
+
# Now when parsing "in the morning", it will return 9:30
|
124
|
+
result = Hizuke.parse("breakfast tomorrow in the morning")
|
125
|
+
puts result.time # => 09:30
|
126
|
+
|
127
|
+
# And "in the evening" will return 19:00
|
128
|
+
result = Hizuke.parse("dinner today in the evening")
|
129
|
+
puts result.time # => 19:00
|
130
|
+
```
|
131
|
+
|
132
|
+
By default, "in the morning" is set to 8:00 and "in the evening" is set to 20:00.
|
133
|
+
|
68
134
|
## Supported Date Keywords
|
69
135
|
|
70
136
|
Currently, the following English date keywords are supported:
|
@@ -99,6 +165,29 @@ Currently, the following English date keywords are supported:
|
|
99
165
|
- `mid month` / `midmonth` - returns the date of the 15th day of the current month
|
100
166
|
- `next quarter` / `nextquarter` - returns the first day of the next quarter
|
101
167
|
- `last quarter` / `lastquarter` - returns the first day of the last quarter
|
168
|
+
- `christmas` / `xmas` - returns the date of Christmas (December 25th) of the current year (or next year if Christmas has already passed)
|
169
|
+
- `next christmas` / `nextchristmas` - returns the date of Christmas (December 25th) of the next year
|
170
|
+
- `last christmas` / `lastchristmas` - returns the date of Christmas (December 25th) of the previous year
|
171
|
+
|
172
|
+
## Supported Time Formats
|
173
|
+
|
174
|
+
The following time formats are supported:
|
175
|
+
|
176
|
+
### Numeric time formats
|
177
|
+
- `at X` - where X is a number (e.g., "at 10" for 10:00)
|
178
|
+
- `@ X` - alternative syntax with @ symbol
|
179
|
+
- `at X:Y` - where X is hours and Y is minutes (e.g., "at 10:30")
|
180
|
+
- `at X:Y:Z` - where X is hours, Y is minutes, and Z is seconds
|
181
|
+
- `at Xam/pm` - with AM/PM indicator (e.g., "at 10am", "at 7pm")
|
182
|
+
- `at X:Yam/pm` - with minutes and AM/PM indicator (e.g., "at 10:30am")
|
183
|
+
|
184
|
+
### Word-based time formats
|
185
|
+
- `at noon` - returns 12:00
|
186
|
+
- `at midnight` - returns 00:00
|
187
|
+
- `in the morning` - returns configurable time (default 08:00)
|
188
|
+
- `in the evening` - returns configurable time (default 20:00)
|
189
|
+
|
190
|
+
When time is included, you can access it through the `time` attribute of the result. The time is displayed in the format "HH:MM" or "HH:MM:SS" if seconds are present. Additionally, you can use the `datetime` attribute to get a Time object combining both the date and time information.
|
102
191
|
|
103
192
|
## Development
|
104
193
|
|
@@ -108,7 +197,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
108
197
|
|
109
198
|
## Contributing
|
110
199
|
|
111
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
200
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/majur/hizuke.
|
112
201
|
|
113
202
|
## License
|
114
203
|
|
data/Rakefile
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rake/testtask'
|
5
5
|
|
6
6
|
Rake::TestTask.new(:test) do |t|
|
7
|
-
t.libs <<
|
8
|
-
t.libs <<
|
9
|
-
t.test_files = FileList[
|
7
|
+
t.libs << 'test'
|
8
|
+
t.libs << 'lib'
|
9
|
+
t.test_files = FileList['test/**/test_*.rb']
|
10
10
|
end
|
11
11
|
|
12
|
-
task default: :test
|
12
|
+
task default: :test
|
data/hizuke.gemspec
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/hizuke/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'hizuke'
|
7
|
+
spec.version = Hizuke::VERSION
|
8
|
+
spec.authors = ['Juraj Maťaše']
|
9
|
+
spec.email = ['juraj@hey.com']
|
10
|
+
|
11
|
+
spec.summary = 'A simple date parser for natural language time references'
|
12
|
+
spec.description = 'Hizuke is a lightweight utility that extracts dates from text ' \
|
13
|
+
'by recognizing common time expressions. ' \
|
14
|
+
'It cleans the original text and returns both the parsed date ' \
|
15
|
+
'and the text without the date reference.'
|
16
|
+
spec.homepage = 'https://github.com/majur/hizuke'
|
17
|
+
spec.license = 'MIT'
|
18
|
+
spec.required_ruby_version = '>= 2.6.0'
|
19
|
+
|
20
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
21
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
22
|
+
spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
|
23
|
+
|
24
|
+
# Specify which files should be added to the gem when it is released.
|
25
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
26
|
+
spec.files = Dir.chdir(__dir__) do
|
27
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
28
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
29
|
+
end
|
30
|
+
end
|
31
|
+
spec.bindir = 'exe'
|
32
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
33
|
+
spec.require_paths = ['lib']
|
34
|
+
|
35
|
+
# Add development dependencies here
|
36
|
+
spec.add_development_dependency 'minitest', '~> 5.0'
|
37
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
38
|
+
spec.add_development_dependency 'rubocop', '~> 1.21'
|
39
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hizuke
|
4
|
+
# Module containing constants used throughout Hizuke
|
5
|
+
module Constants
|
6
|
+
# Mapping of day names to their wday values (0-6, Sunday is 0)
|
7
|
+
DAYS_OF_WEEK = {
|
8
|
+
'monday' => 1,
|
9
|
+
'tuesday' => 2,
|
10
|
+
'wednesday' => 3,
|
11
|
+
'thursday' => 4,
|
12
|
+
'friday' => 5,
|
13
|
+
'saturday' => 6,
|
14
|
+
'sunday' => 0
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
# Date keywords mapping
|
18
|
+
DATE_KEYWORDS = {
|
19
|
+
'yesterday' => -1,
|
20
|
+
'today' => 0,
|
21
|
+
'tomorrow' => 1,
|
22
|
+
'dayaftertomorrow' => 2,
|
23
|
+
'day after tomorrow' => 2,
|
24
|
+
'daybeforeyesterday' => -2,
|
25
|
+
'day before yesterday' => -2,
|
26
|
+
'nextweek' => :next_week,
|
27
|
+
'next week' => :next_week,
|
28
|
+
'lastweek' => :last_week,
|
29
|
+
'last week' => :last_week,
|
30
|
+
'nextmonth' => :next_month,
|
31
|
+
'next month' => :next_month,
|
32
|
+
'lastmonth' => :last_month,
|
33
|
+
'last month' => :last_month,
|
34
|
+
'nextyear' => :next_year,
|
35
|
+
'next year' => :next_year,
|
36
|
+
'lastyear' => :last_year,
|
37
|
+
'last year' => :last_year,
|
38
|
+
'nextquarter' => :next_quarter,
|
39
|
+
'next quarter' => :next_quarter,
|
40
|
+
'lastquarter' => :last_quarter,
|
41
|
+
'last quarter' => :last_quarter,
|
42
|
+
'thisweekend' => :this_weekend,
|
43
|
+
'this weekend' => :this_weekend,
|
44
|
+
'endofweek' => :end_of_week,
|
45
|
+
'end of week' => :end_of_week,
|
46
|
+
'endofmonth' => :end_of_month,
|
47
|
+
'end of month' => :end_of_month,
|
48
|
+
'endofyear' => :end_of_year,
|
49
|
+
'end of year' => :end_of_year,
|
50
|
+
'midweek' => :mid_week,
|
51
|
+
'mid week' => :mid_week,
|
52
|
+
'midmonth' => :mid_month,
|
53
|
+
'mid month' => :mid_month,
|
54
|
+
'christmas' => :christmas,
|
55
|
+
'xmas' => :christmas,
|
56
|
+
'nextchristmas' => :next_christmas,
|
57
|
+
'next christmas' => :next_christmas,
|
58
|
+
'lastchristmas' => :last_christmas,
|
59
|
+
'last christmas' => :last_christmas
|
60
|
+
}.freeze
|
61
|
+
|
62
|
+
# Regex patterns for dynamic date references
|
63
|
+
IN_X_DAYS_PATTERN = /in (\d+) days?/i.freeze
|
64
|
+
X_DAYS_AGO_PATTERN = /(\d+) days? ago/i.freeze
|
65
|
+
IN_X_WEEKS_PATTERN = /in (\d+) weeks?/i.freeze
|
66
|
+
X_WEEKS_AGO_PATTERN = /(\d+) weeks? ago/i.freeze
|
67
|
+
IN_X_MONTHS_PATTERN = /in (\d+) months?/i.freeze
|
68
|
+
X_MONTHS_AGO_PATTERN = /(\d+) months? ago/i.freeze
|
69
|
+
IN_X_YEARS_PATTERN = /in (\d+) years?/i.freeze
|
70
|
+
X_YEARS_AGO_PATTERN = /(\d+) years? ago/i.freeze
|
71
|
+
|
72
|
+
# Regex patterns for specific days of the week
|
73
|
+
THIS_DAY_PATTERN = /this (monday|tuesday|wednesday|thursday|friday|saturday|sunday)/i.freeze
|
74
|
+
NEXT_DAY_PATTERN = /next (monday|tuesday|wednesday|thursday|friday|saturday|sunday)/i.freeze
|
75
|
+
LAST_DAY_PATTERN = /last (monday|tuesday|wednesday|thursday|friday|saturday|sunday)/i.freeze
|
76
|
+
|
77
|
+
# Regex patterns for time references
|
78
|
+
TIME_PATTERN = /(?:at|@)\s*(\d{1,2})(?::(\d{1,2}))?(?::(\d{1,2}))?\s*(am|pm)?/i.freeze
|
79
|
+
|
80
|
+
# Regex patterns for word-based time references
|
81
|
+
NOON_PATTERN = /at\s+noon/i.freeze
|
82
|
+
MIDNIGHT_PATTERN = /at\s+midnight/i.freeze
|
83
|
+
MORNING_PATTERN = /in\s+the\s+morning/i.freeze
|
84
|
+
EVENING_PATTERN = /in\s+the\s+evening/i.freeze
|
85
|
+
end
|
86
|
+
end
|