mhc 1.0.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 +7 -0
- data/.gitignore +27 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/COPYRIGHT +28 -0
- data/Gemfile +8 -0
- data/README.org +209 -0
- data/Rakefile +13 -0
- data/bin/mhc +312 -0
- data/emacs/Cask +25 -0
- data/emacs/Makefile +58 -0
- data/emacs/mhc-calendar.el +1723 -0
- data/emacs/mhc-calfw.el +135 -0
- data/emacs/mhc-compat.el +90 -0
- data/emacs/mhc-date.el +642 -0
- data/emacs/mhc-day.el +149 -0
- data/emacs/mhc-db.el +158 -0
- data/emacs/mhc-draft.el +211 -0
- data/emacs/mhc-e21.el +167 -0
- data/emacs/mhc-face.el +236 -0
- data/emacs/mhc-file.el +224 -0
- data/emacs/mhc-guess.el +648 -0
- data/emacs/mhc-header.el +176 -0
- data/emacs/mhc-logic.el +563 -0
- data/emacs/mhc-message.el +130 -0
- data/emacs/mhc-minibuf.el +466 -0
- data/emacs/mhc-misc.el +248 -0
- data/emacs/mhc-mua.el +260 -0
- data/emacs/mhc-parse.el +286 -0
- data/emacs/mhc-process.el +35 -0
- data/emacs/mhc-ps.el +1174 -0
- data/emacs/mhc-record.el +201 -0
- data/emacs/mhc-schedule.el +202 -0
- data/emacs/mhc-summary.el +763 -0
- data/emacs/mhc-sync.el +158 -0
- data/emacs/mhc-vars.el +149 -0
- data/emacs/mhc.el +1114 -0
- data/icons/Anniversary.xbm +6 -0
- data/icons/Anniversary.xpm +27 -0
- data/icons/Birthday.xbm +6 -0
- data/icons/Birthday.xpm +25 -0
- data/icons/Business.xbm +6 -0
- data/icons/Business.xpm +24 -0
- data/icons/CheckBox.xbm +6 -0
- data/icons/CheckBox.xpm +24 -0
- data/icons/CheckedBox.xbm +6 -0
- data/icons/CheckedBox.xpm +25 -0
- data/icons/Conflict.xbm +6 -0
- data/icons/Conflict.xpm +22 -0
- data/icons/Date.xbm +6 -0
- data/icons/Date.xpm +29 -0
- data/icons/Holiday.xbm +6 -0
- data/icons/Holiday.xpm +25 -0
- data/icons/Link.xbm +6 -0
- data/icons/Link.xpm +25 -0
- data/icons/Other.xbm +6 -0
- data/icons/Other.xpm +28 -0
- data/icons/Party.xbm +6 -0
- data/icons/Party.xpm +23 -0
- data/icons/Private.xbm +6 -0
- data/icons/Private.xpm +26 -0
- data/icons/Recurrence.xbm +6 -0
- data/icons/Recurrence.xpm +98 -0
- data/icons/Vacation.xbm +6 -0
- data/icons/Vacation.xpm +26 -0
- data/lib/mhc.rb +45 -0
- data/lib/mhc/builder.rb +64 -0
- data/lib/mhc/caldav.rb +304 -0
- data/lib/mhc/calendar.rb +106 -0
- data/lib/mhc/command.rb +13 -0
- data/lib/mhc/command/cache.rb +14 -0
- data/lib/mhc/command/completions.rb +108 -0
- data/lib/mhc/command/init.rb +133 -0
- data/lib/mhc/command/scan.rb +33 -0
- data/lib/mhc/command/sync.rb +22 -0
- data/lib/mhc/config.rb +229 -0
- data/lib/mhc/converter.rb +330 -0
- data/lib/mhc/datastore.rb +164 -0
- data/lib/mhc/date_enumerator.rb +274 -0
- data/lib/mhc/date_frame.rb +124 -0
- data/lib/mhc/date_helper.rb +49 -0
- data/lib/mhc/etag.rb +68 -0
- data/lib/mhc/event.rb +396 -0
- data/lib/mhc/formatter.rb +312 -0
- data/lib/mhc/logger.rb +94 -0
- data/lib/mhc/modifier.rb +149 -0
- data/lib/mhc/occurrence.rb +94 -0
- data/lib/mhc/occurrence_enumerator.rb +113 -0
- data/lib/mhc/property_value.rb +33 -0
- data/lib/mhc/property_value/date.rb +190 -0
- data/lib/mhc/property_value/integer.rb +15 -0
- data/lib/mhc/property_value/list.rb +41 -0
- data/lib/mhc/property_value/period.rb +49 -0
- data/lib/mhc/property_value/range.rb +100 -0
- data/lib/mhc/property_value/recurrence_condition.rb +272 -0
- data/lib/mhc/property_value/text.rb +11 -0
- data/lib/mhc/property_value/time.rb +45 -0
- data/lib/mhc/query.rb +210 -0
- data/lib/mhc/sync.rb +46 -0
- data/lib/mhc/sync/driver.rb +108 -0
- data/lib/mhc/sync/status.rb +70 -0
- data/lib/mhc/sync/status_manager.rb +142 -0
- data/lib/mhc/sync/strategy.rb +233 -0
- data/lib/mhc/sync/syncinfo.rb +98 -0
- data/lib/mhc/templates/config.yml.erb +142 -0
- data/lib/mhc/version.rb +4 -0
- data/lib/mhc/webdav.rb +319 -0
- data/mhc.gemspec +24 -0
- data/samples/DOT.mhc-config.yml +116 -0
- data/samples/japanese-holidays.mhcc +153 -0
- data/samples/mhc-completions.zsh +11 -0
- data/spec/mhc_spec.rb +682 -0
- data/spec/spec_helper.rb +9 -0
- data/xpm/close.xpm +18 -0
- data/xpm/delete.xpm +19 -0
- data/xpm/exit.xpm +18 -0
- data/xpm/month.xpm +18 -0
- data/xpm/next.xpm +18 -0
- data/xpm/next2.xpm +18 -0
- data/xpm/next_year.xpm +18 -0
- data/xpm/open.xpm +19 -0
- data/xpm/prev.xpm +18 -0
- data/xpm/prev2.xpm +18 -0
- data/xpm/prev_year.xpm +18 -0
- data/xpm/save.xpm +19 -0
- data/xpm/today.xpm +18 -0
- metadata +214 -0
data/emacs/mhc-guess.el
ADDED
@@ -0,0 +1,648 @@
|
|
1
|
+
;;; mhc-guess.el -- Guess the important date from a Japanese mail article.
|
2
|
+
|
3
|
+
;; Author: Yoshinari Nomura <nom@quickhack.net>
|
4
|
+
;;
|
5
|
+
;; Created: 1999/04/13
|
6
|
+
;; Revised: $Date: 2007/12/05 04:59:35 $
|
7
|
+
;;
|
8
|
+
|
9
|
+
;;;
|
10
|
+
;;; Commentary:
|
11
|
+
;;;
|
12
|
+
|
13
|
+
;;
|
14
|
+
;; バッファから mhc-guess-{time,date}: 日付、時間を集めて、
|
15
|
+
;; 予定の日付けを表わしていると思われる可能性の高い順に並べて
|
16
|
+
;; 返す。
|
17
|
+
;;
|
18
|
+
;; 以下のような GUESS-CANDIDATE のリストを返す
|
19
|
+
;; ([mhc-{date,time} mhc-{date,time}-end point-begin point-end score]..)
|
20
|
+
;;
|
21
|
+
;; mhc-{date,time}: 予定の開始 {日, 時間}
|
22
|
+
;; mhc-{date,time}-end 予定の終了 {日, 時間} or nil
|
23
|
+
;;
|
24
|
+
;; 日付推測の手順
|
25
|
+
;;
|
26
|
+
;; 1. 日付/時刻を表すキーワード見付けて、発見個所リストを作る。
|
27
|
+
;;
|
28
|
+
;; (mhc-guess/gather-candidate mhc-guess-date-regexp-list now)
|
29
|
+
;; (mhc-guess/gather-candidate mhc-guess-time-regexp-list now)
|
30
|
+
;;
|
31
|
+
;; の 2つの関数で、
|
32
|
+
;;
|
33
|
+
;; ([found-date found-date-end found-point-begin found-point-end nil] ...)
|
34
|
+
;; ([found-time found-time-end found-point-begin found-point-end nil] ...)
|
35
|
+
;;
|
36
|
+
;; のような candidate-list を得る。
|
37
|
+
;;
|
38
|
+
;; 2. みつかった日付時刻に点数をつける。
|
39
|
+
;;
|
40
|
+
;; (mhc-guess/score candidate-list mhc-guess-keyword-score-alist)
|
41
|
+
;;
|
42
|
+
;; ([found-date found-date-end found-point-begin found-point-end score] ...)
|
43
|
+
;;
|
44
|
+
;; キーワードが引用行中にある
|
45
|
+
;; 同一行に特定の文字列がある
|
46
|
+
;; ある範囲の前方/後方に特定の文字列がある
|
47
|
+
;;
|
48
|
+
;; のような条件と加点/減点を表す mhc-guess-keyword-score-alist に基
|
49
|
+
;; づいて採点をする。
|
50
|
+
;;
|
51
|
+
;; 3. 得点順 (得点が同じ場合は,日付や時間を表わす文字列が長い順)
|
52
|
+
;; に sort して返す
|
53
|
+
|
54
|
+
;;;
|
55
|
+
;;; Code:
|
56
|
+
;;;
|
57
|
+
|
58
|
+
(require 'mhc-date)
|
59
|
+
(provide 'mhc-guess)
|
60
|
+
|
61
|
+
;;; Customize variables:
|
62
|
+
|
63
|
+
(defcustom mhc-guess-ignore-english-date nil
|
64
|
+
"*Ignore English dates."
|
65
|
+
:group 'mhc
|
66
|
+
:type '(choice (const :tag "Ignore" t)
|
67
|
+
(const :tag "Don't Ignore" nil)))
|
68
|
+
|
69
|
+
(defcustom mhc-guess-english-date-format '(usa)
|
70
|
+
"*English date formats.
|
71
|
+
You can specify following symbols as a list.
|
72
|
+
usa: Suppose the USA style date formats. (e.g. Feb 25, 2004)
|
73
|
+
british: Suppose British style date formats. (e.g. 25 Feb, 2004)"
|
74
|
+
:group 'mhc
|
75
|
+
:type '(repeat (choice (const :tag "USA" usa)
|
76
|
+
(const :tag "British" british))))
|
77
|
+
|
78
|
+
;;
|
79
|
+
;; regexp for get date strings.
|
80
|
+
;;
|
81
|
+
|
82
|
+
(defvar mhc-guess-date-regexp-list
|
83
|
+
`(
|
84
|
+
(,(concat "\\([0-90-9][0-90-9][0-90-9][0-90-9]\\)[-−//]"
|
85
|
+
"\\([0-90-9][0-90-9]\\)[-−//]"
|
86
|
+
"\\([0-90-9][0-90-9]\\)")
|
87
|
+
mhc-guess/make-date-from-yyyymmdd 1 2 3)
|
88
|
+
|
89
|
+
(,(concat "\\([0-90-9]+年\\)?"
|
90
|
+
"\\([来今0-90-9]+\\)[\n ]*月[\n ]*の?[\n ]*"
|
91
|
+
"\\([0-90-9]+\\)日?"
|
92
|
+
"\\([()()月火水木金土日曜\n ]*"
|
93
|
+
"\\([〜−,,、-]\\|から\\|より\\)[\n ]*"
|
94
|
+
"\\([0-90-9]+年\\)?"
|
95
|
+
"\\(\\([来今0-90-9]+\\)[\n ]*月\\)?[\n ]*の?[\n ]*"
|
96
|
+
"\\([0-90-9]+\\)日?\\(間\\)?"
|
97
|
+
"\\)?")
|
98
|
+
mhc-guess/make-date-from-mmdd 2 3 8 9 10)
|
99
|
+
|
100
|
+
(,(concat "\\([0-90-9]+[ ]*[//][ ]*\\)?"
|
101
|
+
"\\([0-90-9]+\\)[ ]*[//][ ]*\\([0-90-9]+\\)"
|
102
|
+
"\\([()()月火水木金土日曜\n ]*"
|
103
|
+
"\\([〜−,,、-]\\|から\\|より\\)[\n ]*"
|
104
|
+
"\\([0-90-9]+[ ]*[//][ ]*\\)?"
|
105
|
+
"\\(\\([0-90-9]+\\)[ ]*[//][ ]*\\)"
|
106
|
+
"\\([0-90-9]+\\)日?\\(間\\)?"
|
107
|
+
"\\)?")
|
108
|
+
mhc-guess/make-date-from-mmdd 2 3 8 9 10)
|
109
|
+
|
110
|
+
;; USA style date format
|
111
|
+
(,(concat "\\(Jan\\(uary\\)?\\|Feb\\(ruary\\)?\\|Mar\\(ch\\)?\\|"
|
112
|
+
"Apr\\(il\\)?\\|May\\|June?\\|July?\\|Aug\\(ust\\)?\\|"
|
113
|
+
"Sep\\(tember\\)?\\|Oct\\(ober\\)?\\|"
|
114
|
+
"Nov\\(ember\\)?\\|Dec\\(ember\\)?\\)"
|
115
|
+
"\.?,? +"
|
116
|
+
"\\([0-9][0-9]?\\)\\(st\\|nd\\rd\\|th\\)?,?[ \n]+" ;; day
|
117
|
+
"\\(\\('\\|[1-9][0-9]\\)?[0-9][0-9]\\)?") ;; year
|
118
|
+
mhc-guess/make-date-from-usa-style-date 1 11 13)
|
119
|
+
|
120
|
+
;; British style date format
|
121
|
+
(,(concat "\\([0-9][0-9]?\\)\\(st\\|nd\\rd\\|th\\)?,? " ;; day
|
122
|
+
"\\(Jan\\(uary\\)?\\|Feb\\(ruary\\)?\\|Mar\\(ch\\)?\\|"
|
123
|
+
"Apr\\(il\\)?\\|May\\|June?\\|July?\\|Aug\\(ust\\)?\\|"
|
124
|
+
"Sep\\(tember\\)?\\|Oct\\(ober\\)?\\|"
|
125
|
+
"Nov\\(ember\\)?\\|Dec\\(ember\\)?\\)"
|
126
|
+
"\.?,?[ \n]+"
|
127
|
+
"\\(\\('\\|[1-9][0-9]\\)?[0-9][0-9]\\)?") ;; year
|
128
|
+
mhc-guess/make-date-from-british-style-date 1 3 13)
|
129
|
+
|
130
|
+
throw
|
131
|
+
|
132
|
+
(,(concat "\\(今度\\|[今来次]週\\|再来週\\)[\n ]*の?[\n ]*"
|
133
|
+
"\\([月火水木金土日]\\)曜")
|
134
|
+
mhc-guess/make-date-from-relative-week 1 2)
|
135
|
+
|
136
|
+
(,(concat "\\([Tt]his\\|[Nn]ext\\)[\n ]+"
|
137
|
+
"\\(Monday\\|Tuesday\\|Wednesday\\|Thursday\\|Friday\\|"
|
138
|
+
"Saturday\\|Sunday\\)")
|
139
|
+
mhc-guess/make-date-from-english-relative-week 2 1 nil)
|
140
|
+
|
141
|
+
(,(concat "\\(Monday\\|Tuesday\\|Wednesday\\|Thursday\\|Friday\\|"
|
142
|
+
"Saturday\\|Sunday\\)[\n ]+"
|
143
|
+
"\\([Tt]his\\|[Nn]ext\\)[ \n]+\\([Ww]eek\\)")
|
144
|
+
mhc-guess/make-date-from-english-relative-week 1 2 3)
|
145
|
+
|
146
|
+
throw
|
147
|
+
|
148
|
+
("\\([0-90-9]+\\)[\n ]*日"
|
149
|
+
mhc-guess/make-date-from-mmdd nil 1)
|
150
|
+
|
151
|
+
("\\([0-90-9]+\\)[ ]*[((][月火水木金土日]"
|
152
|
+
mhc-guess/make-date-from-mmdd nil 1)
|
153
|
+
|
154
|
+
("[^\((]\\([月火水木金土日]\\)\n?曜"
|
155
|
+
mhc-guess/make-date-from-relative-week nil 1)
|
156
|
+
|
157
|
+
(,(concat "\\(Monday\\|Tuesday\\|Wednesday\\|Thursday\\|Friday\\|"
|
158
|
+
"Saturday\\|Sunday\\)")
|
159
|
+
mhc-guess/make-date-from-english-relative-week 1 nil nil)
|
160
|
+
|
161
|
+
("\\(本日\\|今日\\|あす\\|あした\\|あさって\\|明日\\|明後日\\)"
|
162
|
+
mhc-guess/make-date-from-relative-day 1)
|
163
|
+
|
164
|
+
(,(concat "\\([Tt]oday\\|[Tt]omorrow\\|"
|
165
|
+
"[Tt]he[ \n]+[Dd]ay[ \n]+[Aa]fter[ \n]+[Tt]omorrow\\)")
|
166
|
+
mhc-guess/make-date-from-english-relative-day 1)
|
167
|
+
))
|
168
|
+
|
169
|
+
(defvar mhc-guess-time-regexp-list
|
170
|
+
`(
|
171
|
+
(,(concat "\\([0-90-9]+\\) *[時] *\\([0-90-9]+\\|半\\)?分?"
|
172
|
+
"\\([\n ]*\\([〜−-]\\|から\\|より\\)[\n 午前後]*"
|
173
|
+
"\\([0-90-9]+\\) *[時]\\(間\\)? *\\([0-90-9]+\\|半\\)?\\)?")
|
174
|
+
mhc-guess/make-time-from-hhmm 1 2 5 7 6)
|
175
|
+
(,(concat "\\([0-90-9]+\\)[::]\\([0-90-9]+\\)"
|
176
|
+
"\\([\n ]*\\([〜−-]\\|から\\|より\\)[\n 午前後]*"
|
177
|
+
"\\([0-90-9]+\\) *[::時]\\(間\\)? *\\([0-90-9]+\\|半\\)?\\)?")
|
178
|
+
mhc-guess/make-time-from-hhmm 1 2 5 7 6)
|
179
|
+
))
|
180
|
+
|
181
|
+
(defvar mhc-guess-location-list '()
|
182
|
+
"*List of the regexps of the location, like this
|
183
|
+
'(\"第?[0-90-9〇-九]+応接室?\"
|
184
|
+
\"第?[0-90-9〇-九]+会議室[0-90-9〇-九]?\"))")
|
185
|
+
|
186
|
+
(defvar mhc-guess-location-regexp-list
|
187
|
+
`(
|
188
|
+
(,(concat "場[ ]*所[ ]*[::]*[\n ]*\\([^\n ]+\\)")
|
189
|
+
mhc-guess/make-location-from-string 1)
|
190
|
+
(,(concat "於[ ]*\\([^\n ]+\\)")
|
191
|
+
mhc-guess/make-location-from-string 1)
|
192
|
+
(,(concat "[@@][ ]*\\([^\n .]+\\)[ \n]")
|
193
|
+
mhc-guess/make-location-from-string 1)))
|
194
|
+
|
195
|
+
;; keyword to score-alist:
|
196
|
+
;; each element consists of (regexp relative-boundary sameline? score)
|
197
|
+
(defvar mhc-guess-keyword-score-alist
|
198
|
+
'(
|
199
|
+
;; positive factor
|
200
|
+
("^[\t ]+" -200 t +5)
|
201
|
+
("次回" -200 nil +10)
|
202
|
+
("\\(期間\\|月日\\|日程\\|時間帯\\|日時\\|開始時間\\)" -150 nil +5)
|
203
|
+
("\\(期間\\|月日\\|日程\\|時間帯\\|日時\\|開始時間\\)[::]" -150 t +5)
|
204
|
+
("\\(から\\|〜\\|変更\\|延期\\|順延\\|開始\\)" +80 nil +4)
|
205
|
+
;; negative factor
|
206
|
+
("\\(休み\\|除く\\|中止\\|までに\\)" +80 t -10)
|
207
|
+
("出欠" -80 nil -5)
|
208
|
+
("^\\(On\\|At\\|Date:\\) " -200 t -20)
|
209
|
+
("\\(Jan\\|Feb\\|Mar\\|Apr\\|May\\|Jun\\)" -200 t -20)
|
210
|
+
("\\(Jul\\|Aug\\|Sep\\|Oct\\|Nov\\|Dec\\)" -200 t -20)
|
211
|
+
("^\\([ a-zA-Z]*>\\)+ *" -200 t -15)
|
212
|
+
))
|
213
|
+
|
214
|
+
(defvar mhc-guess/location-regexp-list nil)
|
215
|
+
|
216
|
+
;;
|
217
|
+
;; manipulate guess-candidate structure.
|
218
|
+
;;
|
219
|
+
|
220
|
+
(defmacro mhc-guess-get-date (obj) `(aref ,obj 0))
|
221
|
+
(defmacro mhc-guess-get-time (obj) `(aref ,obj 0))
|
222
|
+
(defmacro mhc-guess-get-date-or-time (obj) `(aref ,obj 0))
|
223
|
+
|
224
|
+
(defmacro mhc-guess-get-date-end (obj) `(aref ,obj 1))
|
225
|
+
(defmacro mhc-guess-get-time-end (obj) `(aref ,obj 1))
|
226
|
+
(defmacro mhc-guess-get-date-or-time-end (obj) `(aref ,obj 1))
|
227
|
+
|
228
|
+
(defmacro mhc-guess-get-begin (obj) `(aref ,obj 2))
|
229
|
+
(defmacro mhc-guess-get-end (obj) `(aref ,obj 3))
|
230
|
+
(defmacro mhc-guess-get-score (obj) `(aref ,obj 4))
|
231
|
+
(defmacro mhc-guess-get-debug (obj) `(aref ,obj 5))
|
232
|
+
|
233
|
+
(defmacro mhc-guess-set-date (obj val) `(aset ,obj 0 ,val))
|
234
|
+
(defmacro mhc-guess-set-time (obj val) `(aset ,obj 0 ,val))
|
235
|
+
|
236
|
+
(defmacro mhc-guess-set-date-end (obj val) `(aset ,obj 1 ,val))
|
237
|
+
(defmacro mhc-guess-set-time-end (obj val) `(aset ,obj 1 ,val))
|
238
|
+
|
239
|
+
(defmacro mhc-guess-set-begin (obj val) `(aset ,obj 2 ,val))
|
240
|
+
(defmacro mhc-guess-set-end (obj val) `(aset ,obj 3 ,val))
|
241
|
+
(defmacro mhc-guess-set-score (obj val) `(aset ,obj 4 ,val))
|
242
|
+
(defmacro mhc-guess-set-debug (obj val) `(aset ,obj 5 ,val))
|
243
|
+
|
244
|
+
(defun mhc-guess/new (&optional date-or-time date-or-time-end begin end score debug)
|
245
|
+
(vector date-or-time date-or-time-end begin end score debug))
|
246
|
+
|
247
|
+
;;
|
248
|
+
;; pulic entry
|
249
|
+
;;
|
250
|
+
|
251
|
+
(defun mhc-guess-date (&optional hint1)
|
252
|
+
(let ((now (or (mhc-date-new-from-string3 (mhc-header-get-value "Date"))
|
253
|
+
(mhc-date-now))))
|
254
|
+
(mhc-guess/guess mhc-guess-date-regexp-list hint1 now)))
|
255
|
+
|
256
|
+
(defun mhc-guess-time (&optional hint1)
|
257
|
+
(mhc-guess/guess mhc-guess-time-regexp-list hint1))
|
258
|
+
|
259
|
+
(defun mhc-guess-location-setup ()
|
260
|
+
(if mhc-guess-location-list
|
261
|
+
(let ((list mhc-guess-location-list)
|
262
|
+
regex)
|
263
|
+
(while list
|
264
|
+
(setq regex (concat regex "\\(" (car list) "\\)"))
|
265
|
+
(setq list (cdr list))
|
266
|
+
(when list (setq regex (concat regex "\\|"))))
|
267
|
+
(setq mhc-guess/location-regexp-list
|
268
|
+
(cons `(,regex mhc-guess/make-location-from-string 0)
|
269
|
+
mhc-guess-location-regexp-list)))
|
270
|
+
(setq mhc-guess/location-regexp-list mhc-guess-location-regexp-list)))
|
271
|
+
|
272
|
+
(defun mhc-guess-location (&optional hint1)
|
273
|
+
(mhc-guess/guess mhc-guess/location-regexp-list hint1))
|
274
|
+
|
275
|
+
(defun mhc-guess/guess (control-regexp-lst &optional hint1 now)
|
276
|
+
(let ((score-list
|
277
|
+
(mhc-guess/score (mhc-guess/gather-candidate control-regexp-lst now)
|
278
|
+
mhc-guess-keyword-score-alist
|
279
|
+
hint1
|
280
|
+
now)))
|
281
|
+
(sort score-list
|
282
|
+
(function (lambda (a b)
|
283
|
+
(if (= (mhc-guess-get-score a) (mhc-guess-get-score b))
|
284
|
+
(< (- (mhc-guess-get-end b) (mhc-guess-get-begin b))
|
285
|
+
(- (mhc-guess-get-end a) (mhc-guess-get-begin a)))
|
286
|
+
(< (mhc-guess-get-score b)
|
287
|
+
(mhc-guess-get-score a))))))))
|
288
|
+
;;
|
289
|
+
;; gather date/time.
|
290
|
+
;;
|
291
|
+
|
292
|
+
(defun mhc-guess/gather-candidate (control-regexp-lst &optional now)
|
293
|
+
(let ((ret nil) cand-lst)
|
294
|
+
(while control-regexp-lst
|
295
|
+
(cond
|
296
|
+
((listp (car control-regexp-lst))
|
297
|
+
(if (setq cand-lst
|
298
|
+
(mhc-guess/gather-candidate2
|
299
|
+
(car (car control-regexp-lst)) ;; regexp
|
300
|
+
(car (cdr (car control-regexp-lst))) ;; convfunc
|
301
|
+
(cdr (cdr (car control-regexp-lst))) ;; posision list
|
302
|
+
now ;; current date
|
303
|
+
))
|
304
|
+
(setq ret (nconc ret cand-lst))))
|
305
|
+
((and (string= "throw" (symbol-name (car control-regexp-lst))) ret)
|
306
|
+
(setq control-regexp-lst nil)))
|
307
|
+
(setq control-regexp-lst (cdr control-regexp-lst)))
|
308
|
+
ret))
|
309
|
+
|
310
|
+
(defun mhc-guess/gather-candidate2 (regexp convfunc pos-list &optional now)
|
311
|
+
(let* (lst duration param-list p)
|
312
|
+
(save-excursion
|
313
|
+
;; skip Header
|
314
|
+
(goto-char (point-min))
|
315
|
+
(re-search-forward "^-*$" nil t)
|
316
|
+
;; search candities.
|
317
|
+
(while (re-search-forward regexp nil t)
|
318
|
+
(setq p pos-list
|
319
|
+
param-list nil)
|
320
|
+
(while p
|
321
|
+
(setq param-list
|
322
|
+
(cons
|
323
|
+
(if (and (car p) (match-beginning (car p)))
|
324
|
+
(buffer-substring (match-beginning (car p))
|
325
|
+
(match-end (car p)))
|
326
|
+
nil)
|
327
|
+
param-list))
|
328
|
+
(setq p (cdr p)))
|
329
|
+
(setq duration (apply 'funcall convfunc now (nreverse param-list)))
|
330
|
+
(if (car duration)
|
331
|
+
(setq lst
|
332
|
+
(cons
|
333
|
+
(mhc-guess/new (car duration)
|
334
|
+
(cdr duration)
|
335
|
+
(match-beginning 0)
|
336
|
+
(match-end 0)
|
337
|
+
nil
|
338
|
+
(format "%s with %s" convfunc regexp))
|
339
|
+
lst)))))
|
340
|
+
(nreverse lst)))
|
341
|
+
|
342
|
+
;;
|
343
|
+
;; make date from string.
|
344
|
+
;;
|
345
|
+
|
346
|
+
|
347
|
+
(defun mhc-guess/make-date-from-yyyymmdd (now yy-str mm-str dd-str)
|
348
|
+
(let (date)
|
349
|
+
(if (setq date (mhc-date-new
|
350
|
+
(mhc-guess/string-to-int yy-str)
|
351
|
+
(mhc-guess/string-to-int mm-str)
|
352
|
+
(mhc-guess/string-to-int dd-str)
|
353
|
+
t)) ; noerror is t.
|
354
|
+
(cons date nil))))
|
355
|
+
|
356
|
+
(defun mhc-guess/make-date-from-mmdd
|
357
|
+
(now mm-str dd-str &optional mm-str2 dd-str2 relative)
|
358
|
+
(let* ((start nil) (end nil))
|
359
|
+
(setq start (mhc-guess/make-date-from-mmdd2 now mm-str dd-str))
|
360
|
+
(if start
|
361
|
+
(setq end (mhc-guess/make-date-from-mmdd2 start mm-str2 dd-str2)))
|
362
|
+
(cond
|
363
|
+
((null start)
|
364
|
+
nil)
|
365
|
+
((null end)
|
366
|
+
(cons start nil))
|
367
|
+
(relative
|
368
|
+
(cons start (mhc-date+ start end)))
|
369
|
+
(t
|
370
|
+
(cons start end)))))
|
371
|
+
|
372
|
+
(defun mhc-guess/make-date-from-mmdd2 (now mm-str dd-str)
|
373
|
+
(let ((data (match-data))
|
374
|
+
(mm (if mm-str (mhc-guess/string-to-int mm-str) 0))
|
375
|
+
(dd (if dd-str (mhc-guess/string-to-int dd-str) 0))
|
376
|
+
(year-offset 0)
|
377
|
+
date)
|
378
|
+
(cond
|
379
|
+
((string= mm-str "来")
|
380
|
+
(setq mm (mhc-date-mm (mhc-date-mm++ now))))
|
381
|
+
((string= mm-str "今")
|
382
|
+
(setq mm (mhc-date-mm now)))
|
383
|
+
((= mm 0)
|
384
|
+
(setq mm (mhc-date-mm now))))
|
385
|
+
(if (not
|
386
|
+
(setq date
|
387
|
+
(mhc-date-new (mhc-date-yy now) mm dd t))) ;; noerror is t
|
388
|
+
()
|
389
|
+
;; if date is past, assume the next year.
|
390
|
+
(if (mhc-date< date now)
|
391
|
+
(setq year-offset (1+ year-offset)))
|
392
|
+
;; if date is far future, assume the last year.
|
393
|
+
(if (< 300 (+ (mhc-date- date now) (* year-offset 365)))
|
394
|
+
(setq year-offset (1- year-offset)))
|
395
|
+
(setq date (mhc-date-yy+ date year-offset)))
|
396
|
+
(store-match-data data)
|
397
|
+
date))
|
398
|
+
|
399
|
+
(defun mhc-guess/make-date-from-usa-style-date (now month-str dd-str yy-str)
|
400
|
+
(if (and (null mhc-guess-ignore-english-date)
|
401
|
+
(memq 'usa mhc-guess-english-date-format))
|
402
|
+
(mhc-guess/make-date-from-english-date now month-str dd-str yy-str)))
|
403
|
+
|
404
|
+
(defun mhc-guess/make-date-from-british-style-date (now dd-str month-str yy-str)
|
405
|
+
(if (and (null mhc-guess-ignore-english-date)
|
406
|
+
(memq 'british mhc-guess-english-date-format))
|
407
|
+
(mhc-guess/make-date-from-english-date now month-str dd-str yy-str)))
|
408
|
+
|
409
|
+
(defun mhc-guess/make-date-from-english-date (now month-str dd-str yy-str)
|
410
|
+
(let* ((month-alist
|
411
|
+
'(("Jan" . "1") ("Feb" . "2") ("Mar" . "3") ("Apr" . "4")
|
412
|
+
("May" . "5") ("Jun" . "6") ("Jul" . "7") ("Aug" . "8")
|
413
|
+
("Sep" . "9") ("Oct" . "10") ("Nov" . "11") ("Dec" . "12")))
|
414
|
+
(mm-str (cdr (assoc (capitalize (substring month-str 0 3))
|
415
|
+
month-alist)))
|
416
|
+
(yy-length (length yy-str)))
|
417
|
+
(cond ((= yy-length 4) ; "yyyy"
|
418
|
+
(mhc-guess/make-date-from-yyyymmdd now yy-str mm-str dd-str))
|
419
|
+
((or (= yy-length 3) (= yy-length 2)) ; "'yy" or "yy"
|
420
|
+
(mhc-guess/make-date-from-yyyymmdd
|
421
|
+
now
|
422
|
+
(concat (substring (format-time-string "%Y") 0 2)
|
423
|
+
(substring yy-str -2))
|
424
|
+
mm-str dd-str))
|
425
|
+
(t
|
426
|
+
(mhc-guess/make-date-from-mmdd now mm-str dd-str)))))
|
427
|
+
|
428
|
+
(defun mhc-guess/make-date-from-relative-day (now rel-word)
|
429
|
+
(cond
|
430
|
+
((null rel-word)
|
431
|
+
nil)
|
432
|
+
((or (string= rel-word "今日") (string= rel-word "本日"))
|
433
|
+
(cons now nil))
|
434
|
+
((or (string= rel-word "あす")
|
435
|
+
(string= rel-word "あした")
|
436
|
+
(string= rel-word "明日"))
|
437
|
+
(cons (mhc-date++ now) nil))
|
438
|
+
((or (string= rel-word "あさって")
|
439
|
+
(string= rel-word "明後日"))
|
440
|
+
(cons (mhc-date+ now 2) nil))))
|
441
|
+
|
442
|
+
(defun mhc-guess/make-date-from-english-relative-day (now rel-word)
|
443
|
+
(unless mhc-guess-ignore-english-date
|
444
|
+
(let ((rel (downcase rel-word)))
|
445
|
+
(cond
|
446
|
+
((null rel)
|
447
|
+
nil)
|
448
|
+
((string= rel "today")
|
449
|
+
(cons now nil))
|
450
|
+
((string= rel "tomorrow")
|
451
|
+
(cons (mhc-date++ now) nil))
|
452
|
+
(t ;; the day after tommorow.
|
453
|
+
(cons (mhc-date+ now 2) nil))))))
|
454
|
+
|
455
|
+
(defun mhc-guess/make-date-from-relative-week (now rel-word week)
|
456
|
+
(let ((data (match-data))
|
457
|
+
(ww (string-match week "日月火水木金土"))
|
458
|
+
(date (or now (mhc-date-now)))
|
459
|
+
off)
|
460
|
+
(setq off (- ww (mhc-date-ww date)))
|
461
|
+
(if (string= week "日") (setq off (+ 7 off)))
|
462
|
+
(setq off
|
463
|
+
(cond
|
464
|
+
((or (null rel-word)
|
465
|
+
(string= rel-word "今度")
|
466
|
+
(string= rel-word "次"))
|
467
|
+
(if (<= off 0) (+ 7 off) off))
|
468
|
+
((string= rel-word "今週") off)
|
469
|
+
((string= rel-word "来週")
|
470
|
+
(+ off 7))
|
471
|
+
((string= rel-word "再来週")
|
472
|
+
(+ off 14))))
|
473
|
+
(store-match-data data)
|
474
|
+
(cons (mhc-date+ date off) nil)
|
475
|
+
))
|
476
|
+
|
477
|
+
(defun mhc-guess/make-date-from-english-relative-week (now dow rel-word week)
|
478
|
+
(unless mhc-guess-ignore-english-date
|
479
|
+
(let ((dow-alist '(("Monday" . "月") ("Tuesday" . "火")
|
480
|
+
("Wednesday" . "水") ("Thursday" . "木")
|
481
|
+
("Friday" . "金") ("Saturday" . "土")
|
482
|
+
("Sunday" . "日")))
|
483
|
+
(rel (when (stringp rel-word)
|
484
|
+
(downcase rel-word))))
|
485
|
+
(mhc-guess/make-date-from-relative-week
|
486
|
+
now
|
487
|
+
(if (null rel)
|
488
|
+
nil
|
489
|
+
(cond ((and (string= rel "this") (null week))
|
490
|
+
"今度")
|
491
|
+
((and (string= rel "this") week)
|
492
|
+
"今週")
|
493
|
+
((and (string= rel "next") (null week))
|
494
|
+
"今度")
|
495
|
+
((and (string= rel "next") week)
|
496
|
+
"来週")
|
497
|
+
(t
|
498
|
+
nil)))
|
499
|
+
(cdr (assoc-string dow dow-alist t))))))
|
500
|
+
|
501
|
+
;;
|
502
|
+
;; make time from string.
|
503
|
+
;;
|
504
|
+
|
505
|
+
(defun mhc-guess/make-time-from-hhmm
|
506
|
+
(now hh-str mm-str hh-str2 mm-str2 &optional relative)
|
507
|
+
(let ((start (mhc-guess/make-time-from-hhmm2 hh-str mm-str))
|
508
|
+
(end (mhc-guess/make-time-from-hhmm2 hh-str2 mm-str2 relative)))
|
509
|
+
(cond
|
510
|
+
((null start)
|
511
|
+
nil)
|
512
|
+
((null end)
|
513
|
+
(cons start nil))
|
514
|
+
(relative
|
515
|
+
(cons start (mhc-time+ start end)))
|
516
|
+
(t
|
517
|
+
(cons start end)))))
|
518
|
+
|
519
|
+
(defun mhc-guess/make-time-from-hhmm2 (hh-str mm-str &optional relative)
|
520
|
+
(let (xHH xMM)
|
521
|
+
(if (null hh-str)
|
522
|
+
nil ;; retun value
|
523
|
+
|
524
|
+
(setq xHH (mhc-guess/string-to-int hh-str))
|
525
|
+
(if (and (not relative) (< xHH 8)) ;; 8 depends on my life style.
|
526
|
+
(setq xHH (+ xHH 12)))
|
527
|
+
(setq xMM
|
528
|
+
(cond
|
529
|
+
((not mm-str) 0)
|
530
|
+
((string= mm-str "半") 30)
|
531
|
+
(t (mhc-guess/string-to-int mm-str))))
|
532
|
+
(mhc-time-new xHH xMM t))))
|
533
|
+
|
534
|
+
;;
|
535
|
+
;; make location from string
|
536
|
+
;;
|
537
|
+
|
538
|
+
(defun mhc-guess/make-location-from-string (now str)
|
539
|
+
(cons str nil))
|
540
|
+
|
541
|
+
;;
|
542
|
+
;; scoring
|
543
|
+
;;
|
544
|
+
|
545
|
+
(defun mhc-guess/score (candidate-lst score-alist &optional hint1 now)
|
546
|
+
(let ((clist candidate-lst)
|
547
|
+
total-score candidate regexp boundary sameline score slist)
|
548
|
+
(while clist
|
549
|
+
(setq candidate (car clist)
|
550
|
+
slist score-alist
|
551
|
+
total-score 0)
|
552
|
+
|
553
|
+
;; set score using score-alist
|
554
|
+
(while slist
|
555
|
+
(setq regexp (nth 0 (car slist))
|
556
|
+
boundary (nth 1 (car slist))
|
557
|
+
sameline (nth 2 (car slist))
|
558
|
+
score (nth 3 (car slist)))
|
559
|
+
(if (mhc-guess/search-in-boundary
|
560
|
+
regexp
|
561
|
+
(mhc-guess-get-begin candidate)
|
562
|
+
boundary
|
563
|
+
sameline)
|
564
|
+
(setq total-score (+ total-score score)))
|
565
|
+
(setq slist (cdr slist)))
|
566
|
+
|
567
|
+
;; hint1 is a position hint to encourage the near one.
|
568
|
+
(if (and hint1
|
569
|
+
(< hint1 (mhc-guess-get-begin candidate))
|
570
|
+
(< (- (mhc-guess-get-begin candidate) hint1) 100))
|
571
|
+
(setq total-score (+ total-score 10)))
|
572
|
+
|
573
|
+
;; now is a date hint to discourage a past date.
|
574
|
+
(if (and now (mhc-date<= (mhc-guess-get-date candidate) now))
|
575
|
+
(setq total-score (- total-score 5)))
|
576
|
+
|
577
|
+
(mhc-guess-set-score candidate total-score)
|
578
|
+
(setq clist (cdr clist)))
|
579
|
+
candidate-lst))
|
580
|
+
|
581
|
+
(defun mhc-guess/search-in-boundary (regexp ptr rel-boundary sameline)
|
582
|
+
(let ((pmin (+ ptr rel-boundary)) (pmax (+ ptr rel-boundary)))
|
583
|
+
(save-excursion
|
584
|
+
(goto-char ptr)
|
585
|
+
(if sameline
|
586
|
+
(setq pmax (min pmax (save-excursion (end-of-line) (point)))
|
587
|
+
pmin (max pmin (save-excursion (beginning-of-line) (point)))))
|
588
|
+
(if (< 0 rel-boundary)
|
589
|
+
(and (< (point) pmax) (search-forward-regexp regexp pmax t))
|
590
|
+
(and (< pmin (point)) (search-backward-regexp regexp pmin t))))))
|
591
|
+
|
592
|
+
;;
|
593
|
+
;; string-to-int with code conversion.
|
594
|
+
;;
|
595
|
+
|
596
|
+
(defconst mhc-guess/zenkaku-hankaku-alist
|
597
|
+
'(("0" . "0") ("1" . "1") ("2" . "2") ("3" . "3") ("4" . "4")
|
598
|
+
("5" . "5") ("6" . "6") ("7" . "7") ("8" . "8") ("9" . "9")
|
599
|
+
("/" . "/") (":" . ":")))
|
600
|
+
|
601
|
+
(defun mhc-guess/string-to-int (str)
|
602
|
+
(let ((chr "") (ret "") (data (match-data))
|
603
|
+
(z2h-alist
|
604
|
+
'(("0" . "0") ("1" . "1") ("2" . "2") ("3" . "3") ("4" . "4")
|
605
|
+
("5" . "5") ("6" . "6") ("7" . "7") ("8" . "8") ("9" . "9")
|
606
|
+
("/" . "/") (":" . ":"))))
|
607
|
+
(while (string-match "^." str)
|
608
|
+
(setq chr (substring str (match-beginning 0) (match-end 0)))
|
609
|
+
(setq ret (concat ret (or (cdr (assoc chr z2h-alist)) chr)))
|
610
|
+
(setq str (substring str (match-end 0))))
|
611
|
+
(store-match-data data)
|
612
|
+
(string-to-number ret)))
|
613
|
+
|
614
|
+
|
615
|
+
;;; Copyright Notice:
|
616
|
+
|
617
|
+
;; Copyright (C) 1999, 2000 Yoshinari Nomura. All rights reserved.
|
618
|
+
;; Copyright (C) 2000 MHC developing team. All rights reserved.
|
619
|
+
|
620
|
+
;; Redistribution and use in source and binary forms, with or without
|
621
|
+
;; modification, are permitted provided that the following conditions
|
622
|
+
;; are met:
|
623
|
+
;;
|
624
|
+
;; 1. Redistributions of source code must retain the above copyright
|
625
|
+
;; notice, this list of conditions and the following disclaimer.
|
626
|
+
;; 2. Redistributions in binary form must reproduce the above copyright
|
627
|
+
;; notice, this list of conditions and the following disclaimer in the
|
628
|
+
;; documentation and/or other materials provided with the distribution.
|
629
|
+
;; 3. Neither the name of the team nor the names of its contributors
|
630
|
+
;; may be used to endorse or promote products derived from this software
|
631
|
+
;; without specific prior written permission.
|
632
|
+
;;
|
633
|
+
;; THIS SOFTWARE IS PROVIDED BY THE TEAM AND CONTRIBUTORS ``AS IS''
|
634
|
+
;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
635
|
+
;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
636
|
+
;; FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
637
|
+
;; THE TEAM OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
638
|
+
;; INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
639
|
+
;; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
640
|
+
;; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
641
|
+
;; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
642
|
+
;; STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
643
|
+
;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
644
|
+
;; OF THE POSSIBILITY OF SUCH DAMAGE.
|
645
|
+
|
646
|
+
;;; mhc-guess.el ends here
|
647
|
+
|
648
|
+
|