mhc 1.0.0 → 1.0.1

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.
@@ -35,7 +35,7 @@
35
35
  "MHC-Msg"
36
36
  "Major mode for viewing schdule files of MHC."
37
37
  (save-excursion
38
- (mhc-decode-header)
38
+ (mhc-header-decode-ewords)
39
39
  (goto-char (point-max))
40
40
  (unless (re-search-backward
41
41
  (regexp-quote mhc-message-end-of-messge-marker)
@@ -212,6 +212,10 @@
212
212
  (sit-for 0)
213
213
  pass))))
214
214
 
215
+ (eval-and-compile
216
+ (autoload 'rfc2047-decode-string "rfc2047"))
217
+ (defalias 'mhc-misc-decode-eword-string 'rfc2047-decode-string)
218
+
215
219
  (provide 'mhc-misc)
216
220
 
217
221
  ;;; Copyright Notice:
@@ -17,6 +17,7 @@
17
17
  (require 'mhc-logic)
18
18
  (require 'mhc-record)
19
19
  (require 'mhc-header)
20
+ (require 'mhc-misc)
20
21
 
21
22
  (defvar mhc-parse/strict nil)
22
23
 
@@ -65,13 +66,13 @@
65
66
  (defun mhc-parse/subject (record schedule)
66
67
  (mhc-schedule/set-subject
67
68
  schedule
68
- (mhc-eword-decode-string (mhc-parse/continuous-lines)))
69
+ (mhc-misc-decode-eword-string (mhc-parse/continuous-lines)))
69
70
  schedule)
70
71
 
71
72
  (defun mhc-parse/location (record schedule)
72
73
  (mhc-schedule/set-location
73
74
  schedule
74
- (mhc-eword-decode-string (mhc-parse/continuous-lines)))
75
+ (mhc-misc-decode-eword-string (mhc-parse/continuous-lines)))
75
76
  schedule)
76
77
 
77
78
  (defconst mhc-parse/time-regexp "\\([012][0-9]\\):\\([0-5][0-9]\\)")
@@ -121,7 +122,7 @@
121
122
  (lambda (str)
122
123
  (and (stringp str) (downcase str)))
123
124
  (mhc-misc-split
124
- (mhc-eword-decode-string category)
125
+ (mhc-misc-decode-eword-string category)
125
126
  "[ \t]+")))
126
127
  (mhc-schedule-categories schedule))))
127
128
  (mhc-logic/set-todo (mhc-schedule-condition schedule)
@@ -132,7 +133,7 @@
132
133
  (defun mhc-parse/recurrence-tag (record schedule)
133
134
  (mhc-schedule/set-recurrence-tag
134
135
  schedule
135
- (mhc-eword-decode-string (mhc-parse/continuous-lines)))
136
+ (mhc-misc-decode-eword-string (mhc-parse/continuous-lines)))
136
137
  schedule)
137
138
 
138
139
  (defun mhc-parse/sequence (record schedule)
@@ -24,47 +24,10 @@
24
24
  ;; Return the file name of the article on the current line in
25
25
  ;; this summary buffer.
26
26
  ;;
27
- ;; (mhc-foo-summary-display-article)
28
- ;; Display the article on the current line in this buffer.
29
- ;;
30
- ;; (mhc-foo-get-import-buffer GET-ORIGINAL)
31
- ;; Return buffer visiting import article. If GET-ORIGINAL,
32
- ;; return it without MIME decode.
33
- ;;
34
- ;; (mhc-foo-generate-summary-buffer DATE)
35
- ;; Generate summary buffer of mailer, and change current
36
- ;; buffer to it. This function will be called at the top of
37
- ;; mhc-scan-month.
38
- ;;
39
- ;; (mhc-foo-insert-summary-contents INSERTER)
40
- ;; Insert schedule with INSERTER.
41
- ;;
42
- ;; (mhc-foo-summary-mode-setup DATE)
43
- ;; Setup buffer as summary of mailer. This function will be
44
- ;; called at the end of mhc-scan-month.
45
- ;;
46
- ;; (mhc-foo-highlight-message FOR-DRAFT)
47
- ;; Hilight message in the current buffer.
48
- ;; If FOR-DRAFT is non-nil, Hilight message as draft message."
49
- ;;
50
- ;; (mhc-foo-eword-decode-string STRING)
51
- ;; Decode encoded STRING.
52
- ;;
53
- ;; (mhc-foo-decode-header)
54
- ;; Decode encoded header.
55
- ;;
56
27
  ;; Define these methods appropriately, and put definitions as follows:
57
28
  ;;
58
29
  ;; (provide 'mhc-foo)
59
30
  ;; (put 'mhc-foo 'summary-filename 'mhc-foo-summary-filename)
60
- ;; (put 'mhc-foo 'summary-display-article 'mhc-foo-summary-display-article)
61
- ;; (put 'mhc-foo 'get-import-buffer 'mhc-foo-get-import-buffer)
62
- ;; (put 'mhc-foo 'generate-summary-buffer 'mhc-foo-generate-summary-buffer)
63
- ;; (put 'mhc-foo 'insert-summary-contents 'mhc-foo-insert-summary-contents)
64
- ;; (put 'mhc-foo 'summary-mode-setup 'mhc-foo-summary-mode-setup)
65
- ;; (put 'mhc-foo 'highlight-message 'mhc-foo-highlight-message)
66
- ;; (put 'mhc-foo 'eword-decode-string 'mhc-foo-eword-decode-string)
67
- ;; (put 'mhc-foo 'decode-header 'mhc-foo-decode-header)
68
31
 
69
32
  ;;; Code:
70
33
 
@@ -285,67 +248,101 @@ PROP-VALUE is the property value correspond to PROP-TYPE.
285
248
 
286
249
  ;;; MUA Backend Functions:
287
250
 
288
- ;; (defun mhc-summary-mailer-type ()
289
- ;; "Return mailer backend symbol using currently."
290
- ;; (or (cdr (assq major-mode mhc-summary-major-mode-alist))
291
- ;; (intern (concat "mhc-" (symbol-name mhc-mailer-package)))))
292
-
293
- (defun mhc-summary-mailer-type () 'mhc-mua)
294
-
295
251
  (defun mhc-summary/true (&rest args)
296
252
  "This is the dummy backend function, which always returns t."
297
253
  t)
298
254
 
299
- (defsubst mhc-summary-get-function (operation &optional mailer)
300
- "Return appropriate function to do OPERATION for MAILER."
301
- (or (get (require (or mailer (mhc-summary-mailer-type))) operation)
302
- 'mhc-summary/true))
303
-
304
- (defsubst mhc-get-function (operation)
305
- "Return appropriate function to do OPERATION."
306
- (or (get (require (intern (concat "mhc-" (symbol-name mhc-mailer-package))))
307
- operation)
308
- 'mhc-summary/true))
309
-
310
255
  (defsubst mhc-highlight-message (&optional for-draft)
311
256
  "Hilight message in the current buffer.
312
257
  If optional argument FOR-DRAFT is non-nil, Hilight message as draft message."
313
- (funcall (mhc-get-function 'highlight-message) for-draft))
314
-
315
- (defsubst mhc-eword-decode-string (string)
316
- "Decode encoded STRING."
317
- (funcall (mhc-get-function 'eword-decode-string) string))
318
-
319
- (defsubst mhc-decode-header ()
320
- "Decode encoded header."
321
- (funcall (mhc-get-function 'decode-header)))
322
-
323
- (defsubst mhc-summary-filename (&optional mailer)
324
- "Return file name of article on current line."
325
- (funcall (mhc-summary-get-function 'summary-filename mailer)))
326
-
327
- (defsubst mhc-summary-display-article (&optional mailer)
328
- "Display article on current line."
329
- (funcall (mhc-summary-get-function 'summary-display-article mailer)))
330
-
331
- (defsubst mhc-summary-get-import-buffer (&optional get-original mailer)
332
- "Return buffer to import article."
333
- (funcall (mhc-summary-get-function 'get-import-buffer mailer) get-original))
334
-
335
- (defsubst mhc-summary-generate-buffer (date &optional mailer)
336
- "Generate buffer with summary mode of MAILER."
337
- (funcall (mhc-summary-get-function 'generate-summary-buffer mailer) date))
338
-
339
- (defsubst mhc-summary-insert-contents (mhc-tmp-schedule
258
+ (set (make-local-variable 'font-lock-defaults)
259
+ '(mhc-message-font-lock-keywords t)))
260
+
261
+ (defun mhc-summary-filename ()
262
+ (let ((schedule) (filename))
263
+ (if (and (setq schedule (get-text-property (point) 'mhc-schedule))
264
+ (setq filename (mhc-record-name
265
+ (mhc-schedule-record schedule)))
266
+ (file-exists-p filename)
267
+ (not (file-directory-p filename)))
268
+ filename
269
+ nil)))
270
+
271
+ (defun mhc-summary-display-article ()
272
+ "Display the current article pointed in summary."
273
+ (let ((file (mhc-summary-filename)))
274
+ (if (not (and (stringp file) (file-exists-p file)))
275
+ (message "File does not exist.")
276
+ (mhc-window-push)
277
+ ;; (view-file-other-window file)
278
+ (pop-to-buffer (get-buffer-create "*MHC message*"))
279
+ ;; eword decode
280
+ (let ((buffer-read-only nil))
281
+ (goto-char (point-min))
282
+ (erase-buffer)
283
+ (insert-file-contents file)
284
+ (mhc-header-narrowing
285
+ (mhc-header-delete-header
286
+ "^\\(Content-.*\\|Mime-Version\\|User-Agent\\):" 'regexp))
287
+ (mhc-header-delete-empty-header
288
+ "^X-SC-.*:" 'regexp)
289
+ (mhc-message-mode)
290
+ (mhc-message-set-file-name file))
291
+ ;; (setq view-exit-action 'mhc-calendar-view-exit-action)
292
+ (set-visited-file-name nil)
293
+ ;; (rename-buffer (file-name-nondirectory file) 'unique)
294
+ ;; (run-hooks 'mhc-calendar-view-file-hook)
295
+ (set-buffer-modified-p nil)
296
+ (setq buffer-read-only t)
297
+ )))
298
+
299
+
300
+ (defun mhc-summary-get-import-buffer (&optional get-original)
301
+ "Return a buffer visiting import article.
302
+ If GET-ORIGINAL is non-nil, return a cons of buffer: car keeps a raw
303
+ message and cdr keeps a visible message."
304
+ (let ((buffer
305
+ (or
306
+ (save-window-excursion
307
+ (let ((mode (progn (other-window 1) major-mode)))
308
+ (if (or
309
+ (eq mode 'mew-message-mode)
310
+ (eq mode 'mhc-message-mode))
311
+ (current-buffer))))
312
+ (current-buffer))))
313
+ ;; XXX get-original is not effective now. gone soon.
314
+ (if get-original
315
+ (cons buffer buffer)
316
+ buffer)))
317
+
318
+
319
+ (defun mhc-summary-generate-buffer (name-or-date)
320
+ "Generate a summary buffer for DATE-OR-DATE, and change current buffer to it."
321
+ (switch-to-buffer
322
+ (set-buffer
323
+ (mhc-get-buffer-create
324
+ (if (stringp name-or-date)
325
+ name-or-date
326
+ (mhc-date-format name-or-date "%04d-%02d" yy mm)))))
327
+ (setq inhibit-read-only t
328
+ buffer-read-only nil
329
+ indent-tabs-mode nil)
330
+ (widen)
331
+ (delete-region (point-min) (point-max)))
332
+
333
+ (defun mhc-summary-insert-contents (mhc-tmp-schedule
340
334
  mhc-tmp-private
341
335
  inserter
342
336
  &optional mailer)
343
- (if (eq 'direct mailer)
344
- (let ((mhc-use-icon nil))
345
- (mhc-summary-line-insert)
346
- (insert "\n"))
347
- (funcall (mhc-summary-get-function 'insert-summary-contents mailer)
348
- inserter)))
337
+ (let ((beg (point)))
338
+ (if (eq 'direct mailer)
339
+ (let ((mhc-use-icon nil))
340
+ (mhc-summary-line-insert)
341
+ (insert "\n"))
342
+ (funcall inserter)
343
+ (put-text-property beg (point) 'mhc-schedule mhc-tmp-schedule)
344
+ (insert "\n")
345
+ )))
349
346
 
350
347
  (defsubst mhc-summary-search-date (date)
351
348
  "Search day in the current buffer."
@@ -357,13 +354,9 @@ If optional argument FOR-DRAFT is non-nil, Hilight message as draft message."
357
354
  (not (eq (mhc-day-date dayinfo) date))))
358
355
  (goto-char (next-single-property-change (point) 'mhc-dayinfo)))))
359
356
 
360
- (defsubst mhc-summary-mode-setup (date &optional mailer)
361
- "Setup buffer as summary mode of MAILER."
362
- (funcall (mhc-summary-get-function 'summary-mode-setup mailer) date))
363
-
364
357
  (defun mhc-summary-record (&optional mailer)
365
358
  "Return record on current line."
366
- (let ((filename (mhc-summary-filename mailer)))
359
+ (let ((filename (mhc-summary-filename)))
367
360
  (if filename
368
361
  (mhc-parse-file filename))))
369
362
 
@@ -634,6 +627,8 @@ If BANNER is set, it is printed on the horizontal line."
634
627
  (define-key mhc-summary-mode-map "t" 'mhc-calendar-toggle-insert-rectangle)
635
628
  (define-key mhc-summary-mode-map "E" 'mhc-edit)
636
629
  (define-key mhc-summary-mode-map "M" 'mhc-modify)
630
+ (define-key mhc-summary-mode-map "C" 'mhc-reuse-copy)
631
+ (define-key mhc-summary-mode-map "Y" 'mhc-reuse-create)
637
632
 
638
633
  (define-key mhc-summary-mode-map "n" 'mhc-summary-display-next)
639
634
  (define-key mhc-summary-mode-map "p" 'mhc-summary-display-previous)
@@ -25,13 +25,6 @@
25
25
  "Various sorts of MH Calender."
26
26
  :group 'mail)
27
27
 
28
- (defcustom mhc-mailer-package 'mua
29
- "*Variable to set your favorite mailer."
30
- :group 'mhc
31
- :type '(radio (const :tag "Mew" mew)
32
- (const :tag "Wanderlust" wl)
33
- (const :tag "Gnus" gnus)))
34
-
35
28
  (defcustom mhc-start-day-of-week 0
36
29
  "*Day of the week as the start of the week."
37
30
  :group 'mhc
@@ -9,22 +9,16 @@
9
9
  ;;; Commentary:
10
10
  ;;;
11
11
 
12
- ;; Mhc is the personal schedule management package cooperating
13
- ;; with Mew, Wanderlust or Gnus.
12
+ ;; Mhc is the personal schedule management package.
13
+ ;; Please visit http://www.quickhack.net/mhc for details.
14
14
  ;;
15
15
  ;; Minimum setup:
16
16
  ;;
17
- ;; for Mew user:
18
- ;; (autoload 'mhc-mew-setup "mhc-mew")
19
- ;; (add-hook 'mew-init-hook 'mhc-mew-setup)
17
+ ;; (setq load-path
18
+ ;; (cons "~/src/mhc/emacs" load-path))
19
+ ;; (autoload 'mhc "mhc")
20
20
  ;;
21
- ;; for Wanderlust user:
22
- ;; (autoload 'mhc-wl-setup "mhc-wl")
23
- ;; (add-hook 'wl-init-hook 'mhc-wl-setup)
24
- ;;
25
- ;; for Gnus user:
26
- ;; (autoload 'mhc-gnus-setup "mhc-gnus")
27
- ;; (add-hook 'gnus-startup-hook 'mhc-gnus-setup)
21
+ ;; and M-x mhc
28
22
 
29
23
  ;;; Code:
30
24
 
@@ -382,7 +376,7 @@ If HIDE-PRIVATE, priavate schedules are suppressed."
382
376
  (not current-prefix-arg)
383
377
  current-prefix-arg)))
384
378
  (mhc-scan-month date
385
- (mhc-summary-mailer-type)
379
+ 'mhc-mua
386
380
  mhc-default-category-predicate-sexp
387
381
  hide-private))
388
382
 
@@ -417,6 +411,7 @@ If HIDE-PRIVATE, private schedules are suppressed."
417
411
  (if (not (pos-visible-in-window-p (point)))
418
412
  (recenter)))))
419
413
 
414
+ ;;;###autoload
420
415
  (defun mhc-goto-this-month (&optional hide-private)
421
416
  "*Show schedules of this month.
422
417
  If HIDE-PRIVATE, private schedules are suppressed."
@@ -425,6 +420,7 @@ If HIDE-PRIVATE, private schedules are suppressed."
425
420
  (if mhc-default-hide-private-schedules
426
421
  (not current-prefix-arg)
427
422
  current-prefix-arg)))
423
+ (mhc-setup)
428
424
  (mhc-goto-month (mhc-date-now) hide-private))
429
425
 
430
426
  (defun mhc-goto-next-month (&optional arg)
@@ -484,7 +480,7 @@ If HIDE-PRIVATE, private schedules are suppressed."
484
480
  (let ((line (+ (count-lines (point-min) (point))
485
481
  (if (= (current-column) 0) 1 0))))
486
482
  (mhc-scan-month (or (mhc-current-date-month) (mhc-date-now))
487
- (mhc-summary-mailer-type)
483
+ 'mhc-mua
488
484
  mhc-default-category-predicate-sexp
489
485
  hide-private)
490
486
  (goto-char (point-min))
@@ -550,7 +546,7 @@ listed in ``mhc-category-as-private''."
550
546
  ;; need three months for mini-calendar
551
547
  (dayinfo-list (mhc-db-scan (mhc-date-mm-- from) (mhc-date-mm++ to))))
552
548
  (unless (eq 'direct mailer)
553
- (mhc-summary-generate-buffer date mailer)
549
+ (mhc-summary-generate-buffer date)
554
550
  (setq mhc-summary-buffer-current-date-month
555
551
  (mhc-date-mm-first date)))
556
552
  (when mhc-use-wide-scope
@@ -567,7 +563,7 @@ listed in ``mhc-category-as-private''."
567
563
  (- (mhc-misc-get-width) mhc-calendar-width)
568
564
  mhc-vertical-calendar-length
569
565
  dayinfo-list))
570
- (mhc-summary-mode-setup date mailer)
566
+ (mhc-summary-mode)
571
567
  (mhc-mode 1)
572
568
  (setq mhc-summary-buffer-current-date-month
573
569
  (mhc-date-mm-first date))
@@ -861,6 +857,34 @@ the default action of this command is changed to the latter."
861
857
  (and (mhc-calendar-p) (mhc-calendar-rescan)))
862
858
  (run-hooks 'mhc-delete-file-hook))))
863
859
 
860
+ (defun mhc-reuse-create ()
861
+ "Create new draft buffer using stored template."
862
+ (interactive)
863
+ (let ((date-list (mapconcat
864
+ (lambda (day)
865
+ (mhc-date-format day "%04d%02d%02d" yy mm dd))
866
+ (mhc-input-day "Date: " (mhc-current-date))
867
+ " ")))
868
+ (mhc-window-push)
869
+ (mhc-draft-new (mhc-draft-template)
870
+ `(("x-sc-record-id" . ,(mhc-record-create-id))
871
+ ("x-sc-sequence" . 0)
872
+ ("x-sc-day" . ,date-list)))))
873
+
874
+ (defun mhc-reuse-copy ()
875
+ "Copy current schedule to template."
876
+ (interactive)
877
+ (let ((file (mhc-summary-filename))
878
+ (record (mhc-summary-record)))
879
+ (if (and (stringp file) (file-exists-p file))
880
+ (with-temp-buffer
881
+ (insert-file-contents file)
882
+ (mhc-header-decode-ewords)
883
+ (mhc-draft-store-template
884
+ (buffer-substring-no-properties (point-min) (point-max)))
885
+ (message "%s is copied." (mhc-record-subject-as-string record)))
886
+ (message "No file here."))))
887
+
864
888
  (defun mhc-modify ()
865
889
  "Modify the current schedule."
866
890
  (interactive)
@@ -1049,6 +1073,15 @@ the default action of this command is changed to the latter."
1049
1073
  (setq mhc-setup-p t)
1050
1074
  (run-hooks 'mhc-setup-hook)))
1051
1075
 
1076
+ ;;;###autoload
1077
+ (defun mhc ()
1078
+ "Show schedules of this month."
1079
+ (interactive)
1080
+ (mhc-setup)
1081
+ (mhc-goto-this-month))
1082
+
1083
+ (defalias 'mhc-mua-setup 'mhc-setup)
1084
+
1052
1085
  (defun mhc-reset ()
1053
1086
  "Reset MHC."
1054
1087
  (interactive)
data/lib/mhc.rb CHANGED
@@ -2,6 +2,65 @@ require 'tzinfo'
2
2
  require 'ri_cal'
3
3
  require "kconv"
4
4
 
5
+ ## Monkey patch to the original RiCal https://github.com/rubyredrick/ri_cal
6
+ ## delived from:
7
+ ## git clone https://github.com/yoshinari-nomura/ri_cal.git
8
+ ## git diff 369a4ee..dc740e7
9
+ ##
10
+ module RiCal
11
+ class Component #:nodoc:
12
+
13
+ def method_missing(selector, *args, &b) #:nodoc:
14
+ xprop_candidate = selector.to_s
15
+ if (match = /^(x_[^=]+)(=?)$/.match(xprop_candidate))
16
+ x_property_key = match[1].gsub('_','-').upcase
17
+ if match[2] == "="
18
+ args.each do |val|
19
+ add_x_property(x_property_key, val)
20
+ end
21
+ else
22
+ x_properties[x_property_key].map {|property| property.ruby_value}
23
+ end
24
+ else
25
+ super
26
+ end
27
+ end # def method_missing
28
+
29
+ def export_x_properties_to(export_stream) #:nodoc:
30
+ x_properties.each do |name, props|
31
+ props.each do | prop |
32
+ export_stream.puts("#{name}#{prop.to_s}")
33
+ end
34
+ end
35
+ end # def export_x_properties_to
36
+
37
+ end # class Component
38
+
39
+ class PropertyValue
40
+ class OccurrenceList < Array
41
+
42
+ def visible_params # :nodoc:
43
+ result = params.dup
44
+
45
+ case @elements.first
46
+ when Date
47
+ result = {"VALUE" => "DATE"}.merge(params)
48
+ when DateTime
49
+ result = {"VALUE" => "DATE-TIME"}.merge(params)
50
+ end
51
+
52
+ if has_local_timezone?
53
+ result['TZID'] = tzid
54
+ else
55
+ result.delete('TZID')
56
+ end
57
+ result
58
+ end
59
+ end
60
+ end # class PropertyValue
61
+
62
+ end # module RiCal
63
+
5
64
  module Mhc # :nodoc:
6
65
  def self.default_tzid=(tzid)
7
66
  @tzid = tzid