Mon, 19 Mar 2012 22:26:07 +0000
Add MIT/X11 licence
28 | 1 | -- ndp - Natural Date Parser library for Lua |
2 | -- Copyright (C) 2009 Matthew Wild <mwild1@gmail.com> | |
3 | -- | |
4 | -- This project is MIT/X11 licensed. Please see the | |
5 | -- COPYING file in the source package for more information. | |
6 | -- | |
7 | ||
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 | module(..., package.seeall); |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
9 | |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
10 | require "luarocks.require" |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
11 | require "lpeg" |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
12 | |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
13 | -- Add case-insensitive string matching to Lpeg |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
14 | function lpeg.Pi(s) |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
15 | local patt = lpeg.P(true); |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
16 | for c in s:gmatch(".") do |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
17 | patt = patt * (lpeg.P(c:lower()) + lpeg.P(c:upper())); |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
18 | end |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
19 | return patt; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
20 | end |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
21 | |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
22 | function lpeg.one_of(list) |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
23 | local patt = lpeg.P(false); |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
24 | for _, match in ipairs(list) do |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
25 | patt = patt + lpeg.Pi(match); |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
26 | end |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
27 | return patt; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
28 | end |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
29 | |
12
a127265f3257
Match only at word boundaries
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
30 | local wordsep = lpeg.S" "; |
a127265f3257
Match only at word boundaries
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
31 | |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
32 | local ordinal = lpeg.P{ lpeg.C(lpeg.R("09")^-2) * (lpeg.Pi("st") + lpeg.Pi("nd") + lpeg.Pi("rd") + lpeg.Pi("th")) + 1 * lpeg.V(1) }; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
33 | local number = lpeg.R "09"^1 |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
34 | |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
35 | local day_name = lpeg.one_of {'monday', 'tuesday', 'wednesday', |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
36 | 'thursday', 'friday', 'saturday', 'sunday'} |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
37 | |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
38 | local month_name = lpeg.one_of {'january', 'february', 'march', 'april', 'may', 'june', |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
39 | 'july', 'august', 'september', 'october', 'november', 'december' } |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
40 | |
5
3eee607e57e8
Add support for specifying a year in the input
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
41 | local year = lpeg.R("09") * lpeg.R("09") * lpeg.R("09") * lpeg.R("09"); |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
42 | |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
43 | local unit_of_time = lpeg.one_of { 'second', 'minute', 'hour', 'day', 'week', 'month', 'year' } |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
44 | |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
45 | local time_of_day = lpeg.one_of { 'morning', 'noon', 'afternoon', 'evening', 'night', 'midnight' } |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
46 | local time_of_days = { morning = 09, noon = 12, afternoon = 13, evening = 17, night = 21, midnight = 00 } |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
47 | |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
48 | local quantity; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
49 | local quantities = { |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
50 | ["a"] = 1; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
51 | ["an"] = 1; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
52 | |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
53 | ["a couple of"] = 2; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
54 | |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
55 | ["a few"] = 3; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
56 | ["several"] = 3; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
57 | }; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
58 | |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
59 | -- Create 'quantity' to match any of the quantities we know |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
60 | do |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
61 | local quantity_list = {}; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
62 | for k in pairs(quantities) do |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
63 | quantity_list[#quantity_list+1] = k; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
64 | end |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
65 | table.sort(quantity_list, function (a,b) return #a>#b; end); |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
66 | quantity = number + lpeg.one_of(quantity_list); |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
67 | end |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
68 | |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
69 | seconds_in_a = { second = 1 } |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
70 | seconds_in_a.minute = seconds_in_a.second * 60; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
71 | seconds_in_a.hour = seconds_in_a.minute * 60; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
72 | seconds_in_a.day = seconds_in_a.hour * 24; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
73 | seconds_in_a.week = seconds_in_a.day * 7; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
74 | seconds_in_a.month = seconds_in_a.week * 4; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
75 | seconds_in_a.year = seconds_in_a.day * 365; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
76 | |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
77 | local function get_time_part(time, part) |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
78 | return os.date("*t", time)[part]; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
79 | end |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
80 | |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
81 | local function adjust_time(time, part, value) |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
82 | local split_time = os.date("*t", time); |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
83 | |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
84 | split_time[part] = value; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
85 | |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
86 | return os.time(split_time); |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
87 | end |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
88 | |
1
29a492373a7c
Implement find_next_day_by_name
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
89 | local function find_next_day_by_name(time, day_name) |
29a492373a7c
Implement find_next_day_by_name
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
90 | day_name = day_name:lower():gsub("^.", string.upper); -- Normalize |
29a492373a7c
Implement find_next_day_by_name
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
91 | |
29a492373a7c
Implement find_next_day_by_name
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
92 | for i=1,8 do |
29a492373a7c
Implement find_next_day_by_name
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
93 | time = time + seconds_in_a.day; |
29a492373a7c
Implement find_next_day_by_name
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
94 | if os.date("%A", time) == day_name then |
29a492373a7c
Implement find_next_day_by_name
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
95 | return time; |
29a492373a7c
Implement find_next_day_by_name
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
96 | end |
29a492373a7c
Implement find_next_day_by_name
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
97 | end |
6
a8bbbfdd12db
Implement find_next_month_by_name
Matthew Wild <mwild1@gmail.com>
parents:
5
diff
changeset
|
98 | return; |
a8bbbfdd12db
Implement find_next_month_by_name
Matthew Wild <mwild1@gmail.com>
parents:
5
diff
changeset
|
99 | end |
a8bbbfdd12db
Implement find_next_month_by_name
Matthew Wild <mwild1@gmail.com>
parents:
5
diff
changeset
|
100 | |
a8bbbfdd12db
Implement find_next_month_by_name
Matthew Wild <mwild1@gmail.com>
parents:
5
diff
changeset
|
101 | local function find_next_month_by_name(time, month_name) |
a8bbbfdd12db
Implement find_next_month_by_name
Matthew Wild <mwild1@gmail.com>
parents:
5
diff
changeset
|
102 | month_name = month_name:lower():gsub("^.", string.upper); -- Normalize |
a8bbbfdd12db
Implement find_next_month_by_name
Matthew Wild <mwild1@gmail.com>
parents:
5
diff
changeset
|
103 | |
a8bbbfdd12db
Implement find_next_month_by_name
Matthew Wild <mwild1@gmail.com>
parents:
5
diff
changeset
|
104 | local split_time = os.date("*t", time); |
a8bbbfdd12db
Implement find_next_month_by_name
Matthew Wild <mwild1@gmail.com>
parents:
5
diff
changeset
|
105 | for i=1,13 do |
a8bbbfdd12db
Implement find_next_month_by_name
Matthew Wild <mwild1@gmail.com>
parents:
5
diff
changeset
|
106 | split_time.month = split_time.month + 1; |
a8bbbfdd12db
Implement find_next_month_by_name
Matthew Wild <mwild1@gmail.com>
parents:
5
diff
changeset
|
107 | if split_time.month == 13 then split_time.month = 1; end |
a8bbbfdd12db
Implement find_next_month_by_name
Matthew Wild <mwild1@gmail.com>
parents:
5
diff
changeset
|
108 | |
a8bbbfdd12db
Implement find_next_month_by_name
Matthew Wild <mwild1@gmail.com>
parents:
5
diff
changeset
|
109 | time = os.time(split_time); |
a8bbbfdd12db
Implement find_next_month_by_name
Matthew Wild <mwild1@gmail.com>
parents:
5
diff
changeset
|
110 | if os.date("%B", time) == month_name then |
a8bbbfdd12db
Implement find_next_month_by_name
Matthew Wild <mwild1@gmail.com>
parents:
5
diff
changeset
|
111 | return time; |
a8bbbfdd12db
Implement find_next_month_by_name
Matthew Wild <mwild1@gmail.com>
parents:
5
diff
changeset
|
112 | end |
a8bbbfdd12db
Implement find_next_month_by_name
Matthew Wild <mwild1@gmail.com>
parents:
5
diff
changeset
|
113 | end |
1
29a492373a7c
Implement find_next_day_by_name
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
114 | |
29a492373a7c
Implement find_next_day_by_name
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
115 | return; |
29a492373a7c
Implement find_next_day_by_name
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
116 | end |
29a492373a7c
Implement find_next_day_by_name
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
117 | |
25
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
118 | local function advance_months(time, n) |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
119 | local split_time = os.date("*t", time); |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
120 | split_time.month = ((split_time.month-1)+n)%12+1; |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
121 | split_time.year = split_time.year + math.floor(n/12); |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
122 | return os.time(split_time); |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
123 | end |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
124 | |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
125 | local function advance_years(time, n) |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
126 | local split_time = os.date("*t", time); |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
127 | split_time.year = split_time.year + n; |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
128 | return os.time(split_time); |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
129 | end |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
130 | |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
131 | function when(str, relative_to) |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
132 | local time = relative_to or os.time(); |
13 | 133 | local P, Pi = lpeg.P, lpeg.Pi; |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
134 | |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
135 | local patterns = |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
136 | { |
26
309073a2bb53
Support for 'today' and 'the day after'
Matthew Wild <mwild1@gmail.com>
parents:
25
diff
changeset
|
137 | { Pi"today" }; |
13 | 138 | { Pi"tomorrow" / |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
139 | function () |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
140 | time = time + seconds_in_a.day; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
141 | end }; |
26
309073a2bb53
Support for 'today' and 'the day after'
Matthew Wild <mwild1@gmail.com>
parents:
25
diff
changeset
|
142 | { (lpeg.one_of{"a ", "the "}+true) * Pi"day after" / |
309073a2bb53
Support for 'today' and 'the day after'
Matthew Wild <mwild1@gmail.com>
parents:
25
diff
changeset
|
143 | function () |
309073a2bb53
Support for 'today' and 'the day after'
Matthew Wild <mwild1@gmail.com>
parents:
25
diff
changeset
|
144 | time = time + seconds_in_a.day; |
309073a2bb53
Support for 'today' and 'the day after'
Matthew Wild <mwild1@gmail.com>
parents:
25
diff
changeset
|
145 | end }; |
13 | 146 | { Pi"next week" / |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
147 | function () |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
148 | time = time + seconds_in_a.week; |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
149 | end }; |
25
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
150 | { Pi"next month" / |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
151 | function () |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
152 | time = advance_months(time, 1); |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
153 | end }; |
13 | 154 | { Pi"next year" / |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
155 | function () |
25
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
156 | time = advance_years(time, 1); |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
157 | end }; |
5
3eee607e57e8
Add support for specifying a year in the input
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
158 | { year / |
3eee607e57e8
Add support for specifying a year in the input
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
159 | function (year) |
3eee607e57e8
Add support for specifying a year in the input
Matthew Wild <mwild1@gmail.com>
parents:
1
diff
changeset
|
160 | time = adjust_time(time, "year", tonumber(year)); |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
161 | end }; |
17
3a7672943895
Correct (I think) notation to make optional phrases optional
Matthew Wild <mwild1@gmail.com>
parents:
16
diff
changeset
|
162 | { (Pi"in " + true) * month_name / |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
163 | function (month_name) |
1
29a492373a7c
Implement find_next_day_by_name
Matthew Wild <mwild1@gmail.com>
parents:
0
diff
changeset
|
164 | time = find_next_month_by_name(time, month_name:match("%S+$")); |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
165 | end }; |
17
3a7672943895
Correct (I think) notation to make optional phrases optional
Matthew Wild <mwild1@gmail.com>
parents:
16
diff
changeset
|
166 | { (Pi"on " + true) * day_name / |
7 | 167 | function (day_name) |
168 | time = find_next_day_by_name(time, day_name:match("%S+$")); | |
169 | end }; | |
17
3a7672943895
Correct (I think) notation to make optional phrases optional
Matthew Wild <mwild1@gmail.com>
parents:
16
diff
changeset
|
170 | { (Pi"in " + true) * ( quantity * P" " * unit_of_time ) * (P"s"^-1) / |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
171 | function (number_and_unit) |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
172 | local number, unit = number_and_unit:gsub("^in ", ""):match("^(.+)%s+(.-)s?$"); |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
173 | |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
174 | number = quantities[number] or tonumber(number); |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
175 | |
25
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
176 | if unit == "month" then |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
177 | time = advance_months(time, number); |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
178 | elseif unit == "year" then |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
179 | time = advance_years(time, number); |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
180 | else |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
181 | time = time + seconds_in_a[unit] * number; |
caf8bbcbaf07
Support for accurate 'next month' and 'next year'
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
182 | end |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
183 | end }; |
21
983f96ebef08
Make prefix phrases to the times of day optional again, to satisfy the tests
Matthew Wild <mwild1@gmail.com>
parents:
17
diff
changeset
|
184 | { (lpeg.one_of{"this ", "in the ", "at "} + true)* time_of_day / |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
185 | function (time_of_day) |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
186 | time_of_day = time_of_day:match("%S+$"); |
15
9c9e64488e54
Allow to specify 'in the morning' to refer to tomorrow
Matthew Wild <mwild1@gmail.com>
parents:
14
diff
changeset
|
187 | |
9c9e64488e54
Allow to specify 'in the morning' to refer to tomorrow
Matthew Wild <mwild1@gmail.com>
parents:
14
diff
changeset
|
188 | if time_of_day == "morning" and get_time_part(time, "hour") > time_of_days.morning then |
9c9e64488e54
Allow to specify 'in the morning' to refer to tomorrow
Matthew Wild <mwild1@gmail.com>
parents:
14
diff
changeset
|
189 | time = time + seconds_in_a.day; -- Morning has passed, so next morning |
9c9e64488e54
Allow to specify 'in the morning' to refer to tomorrow
Matthew Wild <mwild1@gmail.com>
parents:
14
diff
changeset
|
190 | end |
9c9e64488e54
Allow to specify 'in the morning' to refer to tomorrow
Matthew Wild <mwild1@gmail.com>
parents:
14
diff
changeset
|
191 | |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
192 | time = adjust_time(time, "hour", time_of_days[time_of_day]); |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
193 | if time_of_day == "noon" or time_of_day == "midnight" then |
16 | 194 | time = adjust_time(time, "min", 00); |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
195 | else |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
196 | time = adjust_time(time, "min", 30); |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
197 | end |
16 | 198 | end }; |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
199 | } |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
200 | |
9
dc0c8914ac04
Return the position of the start and end of the matched text
Matthew Wild <mwild1@gmail.com>
parents:
7
diff
changeset
|
201 | local ret, min_pos, max_pos; |
11
a40db377a1b5
Optimisation by saving a function per loop iteration
Matthew Wild <mwild1@gmail.com>
parents:
9
diff
changeset
|
202 | local function check_min_pos(start) start = start - 1; if not min_pos or start < min_pos then min_pos = start; end end; |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
203 | for _, pattern in pairs(patterns) do |
12
a127265f3257
Match only at word boundaries
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
204 | ret = lpeg.match(lpeg.P{ lpeg.Cp()*pattern[1] + 1 * (1-wordsep)^0 * wordsep * lpeg.V(1) }/check_min_pos, str); |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
205 | if ret then |
9
dc0c8914ac04
Return the position of the start and end of the matched text
Matthew Wild <mwild1@gmail.com>
parents:
7
diff
changeset
|
206 | if not max_pos or ret > max_pos then max_pos = ret; end |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
207 | --print("Matches ".._.." until "..ret); |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
208 | end |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
209 | end |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
210 | |
9
dc0c8914ac04
Return the position of the start and end of the matched text
Matthew Wild <mwild1@gmail.com>
parents:
7
diff
changeset
|
211 | return time, min_pos, max_pos; |
0
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
212 | end |
44416491923e
Initial commit of ndp, the natural date processing library
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
213 |