aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Morris2008-03-17 02:33:49 +0000
committerGlenn Morris2008-03-17 02:33:49 +0000
commit1435831ffaba3d79686dc557da3ca055a62b420d (patch)
treebb75b2da24ec227238f53548a8d05d9f643d5eef
parentbf0cce5ad9125e890ce775924e6ad85f20938ed4 (diff)
downloademacs-1435831ffaba3d79686dc557da3ca055a62b420d.tar.gz
emacs-1435831ffaba3d79686dc557da3ca055a62b420d.zip
Re-order some definitions before their use.
(nongregorian-diary-listing-hook, nongregorian-diary-marking-hook) (diary-list-entries): Doc fixes. (simple-diary-display, fancy-diary-display): Use calendar-in-read-only-buffer to replace previous code and disable undo. (make-fancy-diary-display): Remove function.
-rw-r--r--lisp/calendar/diary-lib.el444
1 files changed, 215 insertions, 229 deletions
diff --git a/lisp/calendar/diary-lib.el b/lisp/calendar/diary-lib.el
index deb0be41359..f8321d43d3f 100644
--- a/lisp/calendar/diary-lib.el
+++ b/lisp/calendar/diary-lib.el
@@ -56,6 +56,24 @@ are holidays."
56(make-obsolete-variable 'diary-face "customize the face `diary' instead." 56(make-obsolete-variable 'diary-face "customize the face `diary' instead."
57 "23.1") 57 "23.1")
58 58
59(defface diary-anniversary '((t :inherit font-lock-keyword-face))
60 "Face used for anniversaries in the fancy diary display."
61 :version "22.1"
62 :group 'diary)
63
64(defface diary-time '((t :inherit font-lock-variable-name-face))
65 "Face used for times of day in the diary."
66 :version "22.1"
67 :group 'diary)
68
69(defface diary-button '((((type pc) (class color))
70 (:foreground "lightblue")))
71 "Default face used for buttons."
72 :version "22.1"
73 :group 'diary)
74;; Backward-compatibility alias. FIXME make obsolete.
75(put 'diary-button-face 'face-alias 'diary-button)
76
59;; Face markup of calendar and diary displays: Any entry line that 77;; Face markup of calendar and diary displays: Any entry line that
60;; ends with [foo:value] where foo is a face attribute (except :box 78;; ends with [foo:value] where foo is a face attribute (except :box
61;; :stipple) or with [face:blah] tags, will have these values applied 79;; :stipple) or with [face:blah] tags, will have these values applied
@@ -121,6 +139,7 @@ See the documentation for the function `list-sexp-diary-entries'."
121 :type 'string 139 :type 'string
122 :group 'diary) 140 :group 'diary)
123 141
142;; FIXME
124(defcustom list-diary-entries-hook nil 143(defcustom list-diary-entries-hook nil
125 "List of functions called after diary file is culled for relevant entries. 144 "List of functions called after diary file is culled for relevant entries.
126It is to be used for diary entries that are not found in the diary file. 145It is to be used for diary entries that are not found in the diary file.
@@ -151,6 +170,7 @@ lexicographic order."
151 :options '(include-other-diary-files sort-diary-entries) 170 :options '(include-other-diary-files sort-diary-entries)
152 :group 'diary) 171 :group 'diary)
153 172
173;; FIXME
154(defcustom mark-diary-entries-hook nil 174(defcustom mark-diary-entries-hook nil
155 "List of functions called after marking diary entries in the calendar. 175 "List of functions called after marking diary entries in the calendar.
156 176
@@ -171,7 +191,7 @@ function `include-other-diary-files' as part of `list-diary-entries-hook'."
171(defcustom nongregorian-diary-listing-hook nil 191(defcustom nongregorian-diary-listing-hook nil
172 "List of functions called for listing diary file and included files. 192 "List of functions called for listing diary file and included files.
173As the files are processed for diary entries, these functions are used 193As the files are processed for diary entries, these functions are used
174to cull relevant entries. You can use either or both of 194to cull relevant entries. You can use any or all of
175`list-hebrew-diary-entries', `list-islamic-diary-entries' and 195`list-hebrew-diary-entries', `list-islamic-diary-entries' and
176`diary-bahai-list-entries'. The documentation for these functions 196`diary-bahai-list-entries'. The documentation for these functions
177describes the style of such diary entries." 197describes the style of such diary entries."
@@ -184,7 +204,7 @@ describes the style of such diary entries."
184(defcustom nongregorian-diary-marking-hook nil 204(defcustom nongregorian-diary-marking-hook nil
185 "List of functions called for marking diary file and included files. 205 "List of functions called for marking diary file and included files.
186As the files are processed for diary entries, these functions are used 206As the files are processed for diary entries, these functions are used
187to cull relevant entries. You can use either or both of 207to cull relevant entries. You can use any or all of
188`mark-hebrew-diary-entries', `mark-islamic-diary-entries' and 208`mark-hebrew-diary-entries', `mark-islamic-diary-entries' and
189`bahai-mark-diary-entries'. The documentation for these functions 209`bahai-mark-diary-entries'. The documentation for these functions
190describes the style of such diary entries." 210describes the style of such diary entries."
@@ -393,12 +413,30 @@ pairs."
393 (setq ret-attr (append ret-attr (list attrname attrvalue)))))) 413 (setq ret-attr (append ret-attr (list attrname attrvalue))))))
394 (list entry ret-attr))) 414 (list entry ret-attr)))
395 415
416;; The first version of this also checked for diary-selective-display
417;; in the non-fancy case. This was an attempt to distinguish between
418;; displaying the diary and just visiting the diary file. However,
419;; when using fancy diary, calling diary when there are no entries to
420;; display does not create the fancy buffer, nor does it set
421;; diary-selective-display in the diary buffer. This means some
422;; customizations will not take effect, eg:
423;; http://lists.gnu.org/archive/html/emacs-pretest-bug/2007-03/msg00466.html
424;; So the check for diary-selective-display was dropped. This means the
425;; diary will be displayed if one customizes a diary variable while
426;; just visiting the diary-file. This is i) unlikely, and ii) no great loss.
427;;;###cal-autoload
428(defun diary-live-p ()
429 "Return non-nil if the diary is being displayed."
430 (or (get-buffer fancy-diary-buffer)
431 (and diary-file
432 (find-buffer-visiting (substitute-in-file-name diary-file)))))
433
396;;;###cal-autoload 434;;;###cal-autoload
397(defun diary-set-maybe-redraw (symbol value) 435(defun diary-set-maybe-redraw (symbol value)
398 "Set SYMBOL's value to VALUE, and redraw the diary if necessary. 436 "Set SYMBOL's value to VALUE, and redraw the diary if necessary.
399Redraws the diary if it is being displayed (note this is not the same as 437Redraws the diary if it is being displayed (note this is not the same as
400just visiting the `diary-file'), and SYMBOL's value is to be changed." 438just visiting the `diary-file'), and SYMBOL's value is to be changed."
401 (let ((oldvalue (eval symbol))) 439 (let ((oldvalue (eval symbol))) ; FIXME symbol-value?
402 (custom-set-default symbol value) 440 (custom-set-default symbol value)
403 (and (not (equal value oldvalue)) 441 (and (not (equal value oldvalue))
404 (diary-live-p) 442 (diary-live-p)
@@ -429,31 +467,13 @@ before edit/copy"
429 ?\s (frame-width))) 467 ?\s (frame-width)))
430 "Format of the header line displayed by `simple-diary-display'. 468 "Format of the header line displayed by `simple-diary-display'.
431Only used if `diary-header-line-flag' is non-nil." 469Only used if `diary-header-line-flag' is non-nil."
432 :group 'diary 470 :group 'diary
433 :type 'sexp 471 :type 'sexp
434 :initialize 'custom-initialize-default 472 :initialize 'custom-initialize-default
435 ;; FIXME overkill. 473 ;; FIXME overkill.
436 :set 'diary-set-maybe-redraw 474 :set 'diary-set-maybe-redraw
437 :version "22.1") 475 :version "22.1")
438 476
439;; The first version of this also checked for diary-selective-display
440;; in the non-fancy case. This was an attempt to distinguish between
441;; displaying the diary and just visiting the diary file. However,
442;; when using fancy diary, calling diary when there are no entries to
443;; display does not create the fancy buffer, nor does it set
444;; diary-selective-display in the diary buffer. This means some
445;; customizations will not take effect, eg:
446;; http://lists.gnu.org/archive/html/emacs-pretest-bug/2007-03/msg00466.html
447;; So the check for diary-selective-display was dropped. This means the
448;; diary will be displayed if one customizes a diary variable while
449;; just visiting the diary-file. This is i) unlikely, and ii) no great loss.
450;;;###cal-autoload
451(defun diary-live-p ()
452 "Return non-nil if the diary is being displayed."
453 (or (get-buffer fancy-diary-buffer)
454 (and diary-file
455 (find-buffer-visiting (substitute-in-file-name diary-file)))))
456
457(defcustom number-of-diary-entries 1 477(defcustom number-of-diary-entries 1
458 "Specifies how many days of diary entries are to be displayed initially. 478 "Specifies how many days of diary entries are to be displayed initially.
459This variable affects the diary display when the command \\[diary] is used, 479This variable affects the diary display when the command \\[diary] is used,
@@ -613,6 +633,7 @@ of the appropriate type."
613 (1+ (calendar-absolute-from-gregorian gdate)))))) 633 (1+ (calendar-absolute-from-gregorian gdate))))))
614 (goto-char (point-min))) 634 (goto-char (point-min)))
615 635
636;; FIXME non-greg and list hooks run same number of times?
616(define-obsolete-function-alias 'list-diary-entries 'diary-list-entries) 637(define-obsolete-function-alias 'list-diary-entries 'diary-list-entries)
617(defun diary-list-entries (date number &optional list-only) 638(defun diary-list-entries (date number &optional list-only)
618 "Create and display a buffer containing the relevant lines in `diary-file'. 639 "Create and display a buffer containing the relevant lines in `diary-file'.
@@ -632,8 +653,8 @@ After the list is prepared, the hooks `nongregorian-diary-listing-hook',
632These hooks have the following distinct roles: 653These hooks have the following distinct roles:
633 654
634 `nongregorian-diary-listing-hook' can cull dates from the diary 655 `nongregorian-diary-listing-hook' can cull dates from the diary
635 and each included file. Usually used for Hebrew or Islamic 656 and each included file, for example to process Islamic diary
636 diary entries in files. Applied to *each* file. 657 entries. Applied to *each* file.
637 658
638 `list-diary-entries-hook' adds or manipulates diary entries from 659 `list-diary-entries-hook' adds or manipulates diary entries from
639 external sources. Used, for example, to include diary entries 660 external sources. Used, for example, to include diary entries
@@ -687,7 +708,8 @@ If LIST-ONLY is non-nil don't modify or display the buffer, only return a list."
687 ;; d-s-p is passed to the diary display function. 708 ;; d-s-p is passed to the diary display function.
688 (let ((diary-saved-point (point))) 709 (let ((diary-saved-point (point)))
689 (save-excursion 710 (save-excursion
690 (setq file-glob-attrs (nth 1 (diary-pull-attrs nil ""))) 711 ;; FIXME move after goto?
712 (setq file-glob-attrs (cadr (diary-pull-attrs nil "")))
691 (with-syntax-table diary-syntax-table 713 (with-syntax-table diary-syntax-table
692 (goto-char (point-min)) 714 (goto-char (point-min))
693 (unless list-only 715 (unless list-only
@@ -764,6 +786,7 @@ changing the variable `diary-include-string'."
764(defvar date-string) 786(defvar date-string)
765(defvar diary-saved-point) 787(defvar diary-saved-point)
766 788
789;; FIXME common code with fancy-diary-display.
767(defun simple-diary-display () 790(defun simple-diary-display ()
768 "Display the diary buffer if there are any relevant entries or holidays." 791 "Display the diary buffer if there are any relevant entries or holidays."
769 (let* ((holiday-list (if holidays-in-diary-buffer 792 (let* ((holiday-list (if holidays-in-diary-buffer
@@ -783,15 +806,9 @@ changing the variable `diary-include-string'."
783 (string-equal (cadr (car diary-entries-list)) ""))) 806 (string-equal (cadr (car diary-entries-list)) "")))
784 (if (< (length msg) (frame-width)) 807 (if (< (length msg) (frame-width))
785 (message "%s" msg) 808 (message "%s" msg)
786 (set-buffer (get-buffer-create holiday-buffer)) 809 (calendar-in-read-only-buffer holiday-buffer
787 (setq buffer-read-only nil) 810 (calendar-set-mode-line date-string)
788 (calendar-set-mode-line date-string) 811 (insert (mapconcat 'identity holiday-list "\n")))
789 (erase-buffer)
790 (insert (mapconcat 'identity holiday-list "\n"))
791 (goto-char (point-min))
792 (set-buffer-modified-p nil)
793 (setq buffer-read-only t)
794 (display-buffer holiday-buffer)
795 (message "No diary entries for %s" date-string)) 812 (message "No diary entries for %s" date-string))
796 (with-current-buffer 813 (with-current-buffer
797 (find-buffer-visiting (substitute-in-file-name diary-file)) 814 (find-buffer-visiting (substitute-in-file-name diary-file))
@@ -801,14 +818,6 @@ changing the variable `diary-include-string'."
801 (set-window-start window (point-min)))) 818 (set-window-start window (point-min))))
802 (message "Preparing diary...done")))) 819 (message "Preparing diary...done"))))
803 820
804(defface diary-button '((((type pc) (class color))
805 (:foreground "lightblue")))
806 "Default face used for buttons."
807 :version "22.1"
808 :group 'diary)
809;; Backward-compatibility alias. FIXME make obsolete.
810(put 'diary-button-face 'face-alias 'diary-button)
811
812(define-button-type 'diary-entry 821(define-button-type 'diary-entry
813 'action #'diary-goto-entry 822 'action #'diary-goto-entry
814 'face 'diary-button) 823 'face 'diary-button)
@@ -854,19 +863,12 @@ This function is provided for optional use as the `diary-display-hook'."
854 (mapconcat 'identity holiday-list "; ")))) 863 (mapconcat 'identity holiday-list "; "))))
855 (if (<= (length msg) (frame-width)) 864 (if (<= (length msg) (frame-width))
856 (message "%s" msg) 865 (message "%s" msg)
857 (set-buffer (get-buffer-create holiday-buffer)) 866 (calendar-in-read-only-buffer holiday-buffer
858 (setq buffer-read-only nil) 867 (insert (mapconcat 'identity holiday-list "\n")))
859 (erase-buffer)
860 (insert (mapconcat 'identity holiday-list "\n"))
861 (goto-char (point-min))
862 (set-buffer-modified-p nil)
863 (setq buffer-read-only t)
864 (display-buffer holiday-buffer)
865 (message "No diary entries for %s" date-string))) 868 (message "No diary entries for %s" date-string)))
866 ;; Prepare the fancy diary buffer. 869 ;; Prepare the fancy diary buffer.
867 (with-current-buffer 870 (calendar-in-read-only-buffer fancy-diary-buffer
868 (make-fancy-diary-buffer) 871 (calendar-set-mode-line "Diary Entries")
869 (setq buffer-read-only nil)
870 (let ((entry-list diary-entries-list) 872 (let ((entry-list diary-entries-list)
871 (holiday-list) 873 (holiday-list)
872 (holiday-list-last-month 1) 874 (holiday-list-last-month 1)
@@ -955,24 +957,11 @@ This function is provided for optional use as the `diary-display-hook'."
955 (overlay-put 957 (overlay-put
956 (make-overlay (match-beginning 0) (match-end 0)) 958 (make-overlay (match-beginning 0) (match-end 0))
957 'face temp-face)))))))) 959 'face temp-face))))))))
958 (set-buffer-modified-p nil)
959 (goto-char (point-min))
960 (setq buffer-read-only t)
961 (display-buffer fancy-diary-buffer)
962 (fancy-diary-display-mode) 960 (fancy-diary-display-mode)
963 (calendar-set-mode-line date-string) 961 (calendar-set-mode-line date-string)
964 (message "Preparing diary...done")))) 962 (message "Preparing diary...done"))))
965 963
966(defun make-fancy-diary-buffer () 964;; FIXME modernize?
967 "Create and return the initial fancy diary buffer."
968 (with-current-buffer (get-buffer-create fancy-diary-buffer)
969 (setq buffer-read-only nil)
970 (calendar-set-mode-line "Diary Entries")
971 (erase-buffer)
972 (set-buffer-modified-p nil)
973 (setq buffer-read-only t)
974 (get-buffer fancy-diary-buffer)))
975
976(defun print-diary-entries () 965(defun print-diary-entries ()
977 "Print a hard copy of the diary display. 966 "Print a hard copy of the diary display.
978 967
@@ -991,8 +980,9 @@ the actual printing."
991 (let ((diary-buffer 980 (let ((diary-buffer
992 (find-buffer-visiting (substitute-in-file-name diary-file)))) 981 (find-buffer-visiting (substitute-in-file-name diary-file))))
993 (if diary-buffer 982 (if diary-buffer
983 ;; Name affects printing?
994 (let ((temp-buffer (get-buffer-create " *Printable Diary Entries*")) 984 (let ((temp-buffer (get-buffer-create " *Printable Diary Entries*"))
995 (heading)) 985 heading)
996 (with-current-buffer diary-buffer 986 (with-current-buffer diary-buffer
997 (setq heading 987 (setq heading
998 (if (not (stringp mode-line-format)) 988 (if (not (stringp mode-line-format))
@@ -1341,18 +1331,6 @@ Optional argument COLOR is passed to `mark-visible-calendar-date' as MARK."
1341 color) 1331 color)
1342 (setq day (+ day 7)))))) 1332 (setq day (+ day 7))))))
1343 1333
1344(defun mark-calendar-date-pattern (month day year &optional color)
1345 "Mark all dates in the calendar window that conform to MONTH/DAY/YEAR.
1346A value of 0 in any position is a wildcard. Optional argument COLOR is
1347passed to `mark-visible-calendar-date' as MARK."
1348 (with-current-buffer calendar-buffer
1349 (let ((m displayed-month)
1350 (y displayed-year))
1351 (increment-calendar-month m y -1)
1352 (dotimes (idummy 3)
1353 (mark-calendar-month m y month day year color)
1354 (increment-calendar-month m y 1)))))
1355
1356(defun mark-calendar-month (month year p-month p-day p-year &optional color) 1334(defun mark-calendar-month (month year p-month p-day p-year &optional color)
1357 "Mark dates in the MONTH/YEAR that conform to pattern P-MONTH/P-DAY/P-YEAR. 1335 "Mark dates in the MONTH/YEAR that conform to pattern P-MONTH/P-DAY/P-YEAR.
1358A value of 0 in any position of the pattern is a wildcard. 1336A value of 0 in any position of the pattern is a wildcard.
@@ -1366,6 +1344,19 @@ Optional argument COLOR is passed to `mark-visible-calendar-date' as MARK."
1366 (mark-visible-calendar-date (list month (1+ i) year) color)) 1344 (mark-visible-calendar-date (list month (1+ i) year) color))
1367 (mark-visible-calendar-date (list month p-day year) color)))) 1345 (mark-visible-calendar-date (list month p-day year) color))))
1368 1346
1347(defun mark-calendar-date-pattern (month day year &optional color)
1348 "Mark all dates in the calendar window that conform to MONTH/DAY/YEAR.
1349A value of 0 in any position is a wildcard. Optional argument COLOR is
1350passed to `mark-visible-calendar-date' as MARK."
1351 (with-current-buffer calendar-buffer
1352 (let ((m displayed-month)
1353 (y displayed-year))
1354 (increment-calendar-month m y -1)
1355 (dotimes (idummy 3)
1356 (mark-calendar-month m y month day year color)
1357 (increment-calendar-month m y 1)))))
1358
1359
1369;; Bahai, Hebrew, Islamic. 1360;; Bahai, Hebrew, Islamic.
1370(defun calendar-mark-complex (month day year fromabs &optional color) 1361(defun calendar-mark-complex (month day year fromabs &optional color)
1371 "Mark dates in the calendar conforming to MONTH DAY YEAR of some system. 1362 "Mark dates in the calendar conforming to MONTH DAY YEAR of some system.
@@ -1428,19 +1419,6 @@ COLOR is passed to `mark-visible-calendar-date' as MARK."
1428 (calendar-mark-complex month day year 1419 (calendar-mark-complex month day year
1429 'calendar-bahai-from-absolute color)))) 1420 'calendar-bahai-from-absolute color))))
1430 1421
1431(defun sort-diary-entries ()
1432 "Sort the list of diary entries by time of day."
1433 (setq diary-entries-list (sort diary-entries-list 'diary-entry-compare)))
1434
1435(defun diary-entry-compare (e1 e2)
1436 "Return t if E1 is earlier than E2."
1437 (or (calendar-date-compare e1 e2)
1438 (and (calendar-date-equal (car e1) (car e2))
1439 (let* ((ts1 (cadr e1)) (t1 (diary-entry-time ts1))
1440 (ts2 (cadr e2)) (t2 (diary-entry-time ts2)))
1441 (or (< t1 t2)
1442 (and (= t1 t2)
1443 (string-lessp ts1 ts2)))))))
1444 1422
1445(defun diary-entry-time (s) 1423(defun diary-entry-time (s)
1446 "Return time at the beginning of the string S as a military-style integer. 1424 "Return time at the beginning of the string S as a military-style integer.
@@ -1469,6 +1447,40 @@ be used instead of a colon (:) to separate the hour and minute parts."
1469 0 1200))) 1447 0 1200)))
1470 (t diary-unknown-time)))) ; unrecognizable 1448 (t diary-unknown-time)))) ; unrecognizable
1471 1449
1450(defun diary-entry-compare (e1 e2)
1451 "Return t if E1 is earlier than E2."
1452 (or (calendar-date-compare e1 e2)
1453 (and (calendar-date-equal (car e1) (car e2))
1454 (let* ((ts1 (cadr e1)) (t1 (diary-entry-time ts1))
1455 (ts2 (cadr e2)) (t2 (diary-entry-time ts2)))
1456 (or (< t1 t2)
1457 (and (= t1 t2)
1458 (string-lessp ts1 ts2)))))))
1459
1460(defun sort-diary-entries ()
1461 "Sort the list of diary entries by time of day."
1462 (setq diary-entries-list (sort diary-entries-list 'diary-entry-compare)))
1463
1464
1465(defun diary-sexp-entry (sexp entry date)
1466 "Process a SEXP diary ENTRY for DATE."
1467 (let ((result (if calendar-debug-sexp
1468 (let ((stack-trace-on-error t))
1469 (eval (car (read-from-string sexp))))
1470 (condition-case nil
1471 (eval (car (read-from-string sexp)))
1472 (error
1473 (beep)
1474 (message "Bad sexp at line %d in %s: %s"
1475 (count-lines (point-min) (point))
1476 diary-file sexp)
1477 (sleep-for 2))))))
1478 (cond ((stringp result) result)
1479 ((and (consp result)
1480 (stringp (cdr result))) result)
1481 (result entry)
1482 (t nil))))
1483
1472(defun list-sexp-diary-entries (date) 1484(defun list-sexp-diary-entries (date)
1473 "Add sexp entries for DATE from the diary file to `diary-entries-list'. 1485 "Add sexp entries for DATE from the diary file to `diary-entries-list'.
1474Also, make them visible in the diary file. Returns t if any entries were 1486Also, make them visible in the diary file. Returns t if any entries were
@@ -1680,25 +1692,6 @@ best if they are nonmarking."
1680 (setq entry-found (or entry-found diary-entry))))) 1692 (setq entry-found (or entry-found diary-entry)))))
1681 entry-found)) 1693 entry-found))
1682 1694
1683(defun diary-sexp-entry (sexp entry date)
1684 "Process a SEXP diary ENTRY for DATE."
1685 (let ((result (if calendar-debug-sexp
1686 (let ((stack-trace-on-error t))
1687 (eval (car (read-from-string sexp))))
1688 (condition-case nil
1689 (eval (car (read-from-string sexp)))
1690 (error
1691 (beep)
1692 (message "Bad sexp at line %d in %s: %s"
1693 (count-lines (point-min) (point))
1694 diary-file sexp)
1695 (sleep-for 2))))))
1696 (cond ((stringp result) result)
1697 ((and (consp result)
1698 (stringp (cdr result))) result)
1699 (result entry)
1700 (t nil))))
1701
1702(defvar date) 1695(defvar date)
1703(defvar entry) 1696(defvar entry)
1704 1697
@@ -1820,6 +1813,13 @@ highlighting the day in the calendar."
1820 d2))))) 1813 d2)))))
1821 (cons mark entry))))) 1814 (cons mark entry)))))
1822 1815
1816(defun diary-ordinal-suffix (n)
1817 "Ordinal suffix for N. (That is, `st', `nd', `rd', or `th', as appropriate.)"
1818 (if (or (memq (% n 100) '(11 12 13))
1819 (< 3 (% n 10)))
1820 "th"
1821 (aref ["th" "st" "nd" "rd"] (% n 10))))
1822
1823;; To be called from diary-sexp-entry, where DATE, ENTRY are bound. 1823;; To be called from diary-sexp-entry, where DATE, ENTRY are bound.
1824(defun diary-anniversary (month day &optional year mark) 1824(defun diary-anniversary (month day &optional year mark)
1825 "Anniversary diary entry. 1825 "Anniversary diary entry.
@@ -1871,13 +1871,6 @@ use when highlighting the day in the calendar."
1871 (if (and (>= diff 0) (zerop (% diff n))) 1871 (if (and (>= diff 0) (zerop (% diff n)))
1872 (cons mark (format entry cycle (diary-ordinal-suffix cycle)))))) 1872 (cons mark (format entry cycle (diary-ordinal-suffix cycle))))))
1873 1873
1874(defun diary-ordinal-suffix (n)
1875 "Ordinal suffix for N. (That is, `st', `nd', `rd', or `th', as appropriate.)"
1876 (if (or (memq (% n 100) '(11 12 13))
1877 (< 3 (% n 10)))
1878 "th"
1879 (aref ["th" "st" "nd" "rd"] (% n 10))))
1880
1881(defun diary-day-of-year () 1874(defun diary-day-of-year ()
1882 "Day of year and number of days remaining in the year of date diary entry." 1875 "Day of year and number of days remaining in the year of date diary entry."
1883 (calendar-day-of-year-string date)) 1876 (calendar-day-of-year-string date))
@@ -1938,6 +1931,7 @@ If omitted, NONMARKING defaults to nil and FILE defaults to
1938 (widen) 1931 (widen)
1939 (diary-unhide-everything) 1932 (diary-unhide-everything)
1940 (goto-char (point-max)) 1933 (goto-char (point-max))
1934 ;; FIXME cf hack-local-variables.
1941 (when (let ((case-fold-search t)) 1935 (when (let ((case-fold-search t))
1942 (search-backward "Local Variables:" 1936 (search-backward "Local Variables:"
1943 (max (- (point-max) 3000) (point-min)) 1937 (max (- (point-max) 3000) (point-min))
@@ -1945,6 +1939,7 @@ If omitted, NONMARKING defaults to nil and FILE defaults to
1945 (beginning-of-line) 1939 (beginning-of-line)
1946 (insert "\n") 1940 (insert "\n")
1947 (forward-line -1)) 1941 (forward-line -1))
1942
1948 (insert 1943 (insert
1949 (if (bolp) "" "\n") 1944 (if (bolp) "" "\n")
1950 (if nonmarking diary-nonmarking-symbol "") 1945 (if nonmarking diary-nonmarking-symbol "")
@@ -2048,6 +2043,8 @@ Prefix argument ARG makes the entry nonmarking."
2048 (calendar-date-string (calendar-cursor-to-date t) nil t)) 2043 (calendar-date-string (calendar-cursor-to-date t) nil t))
2049 arg))) 2044 arg)))
2050 2045
2046;;; Diary mode.
2047
2051(defvar diary-mode-map 2048(defvar diary-mode-map
2052 (let ((map (make-sparse-keymap))) 2049 (let ((map (make-sparse-keymap)))
2053 (define-key map "\C-c\C-s" 'diary-show-all-entries) 2050 (define-key map "\C-c\C-s" 'diary-show-all-entries)
@@ -2055,98 +2052,6 @@ Prefix argument ARG makes the entry nonmarking."
2055 map) 2052 map)
2056 "Keymap for `diary-mode'.") 2053 "Keymap for `diary-mode'.")
2057 2054
2058;;;###autoload
2059(define-derived-mode diary-mode fundamental-mode "Diary"
2060 "Major mode for editing the diary file."
2061 (set (make-local-variable 'font-lock-defaults)
2062 '(diary-font-lock-keywords t))
2063 (add-to-invisibility-spec '(diary . nil))
2064 (add-hook 'after-save-hook 'diary-redraw-calendar nil t)
2065 (if diary-header-line-flag
2066 (setq header-line-format diary-header-line-format)))
2067
2068
2069(defvar diary-fancy-date-pattern
2070 (concat
2071 (let ((dayname (diary-name-pattern calendar-day-name-array nil t))
2072 (monthname (diary-name-pattern calendar-month-name-array nil t))
2073 (day "[0-9]+")
2074 (month "[0-9]+")
2075 (year "-?[0-9]+"))
2076 (mapconcat 'eval calendar-date-display-form ""))
2077 ;; Optional ": holiday name" after the date.
2078 "\\(: .*\\)?")
2079 "Regular expression matching a date header in Fancy Diary.")
2080
2081(defconst diary-time-regexp
2082 ;; Accepted formats: 10:00 10.00 10h00 10h 10am 10:00am 10.00am
2083 ;; Use of "." as a separator annoyingly matches numbers, eg "123.45".
2084 ;; Hence often prefix this with "\\(^\\|\\s-\\)."
2085 (concat "[0-9]?[0-9]\\([AaPp][mM]\\|\\("
2086 "[Hh]\\([0-9][0-9]\\)?\\|[:.][0-9][0-9]"
2087 "\\)\\([AaPp][Mm]\\)?\\)")
2088 "Regular expression matching a time of day.")
2089
2090(defface diary-anniversary '((t :inherit font-lock-keyword-face))
2091 "Face used for anniversaries in the diary."
2092 :version "22.1"
2093 :group 'diary)
2094
2095(defface diary-time '((t :inherit font-lock-variable-name-face))
2096 "Face used for times of day in the diary."
2097 :version "22.1"
2098 :group 'diary)
2099
2100(defvar fancy-diary-font-lock-keywords
2101 (list
2102 (list
2103 ;; Any number of " other holiday name" lines, followed by "==" line.
2104 (concat diary-fancy-date-pattern "\\(\n +.*\\)*\n=+$")
2105 '(0 (progn (put-text-property (match-beginning 0) (match-end 0)
2106 'font-lock-multiline t)
2107 diary-face)))
2108 '("^.*\\([aA]nniversary\\|[bB]irthday\\).*$" . 'diary-anniversary)
2109 '("^.*Yahrzeit.*$" . font-lock-reference-face)
2110 '("^\\(Erev \\)?Rosh Hodesh.*" . font-lock-function-name-face)
2111 '("^Day.*omer.*$" . font-lock-builtin-face)
2112 '("^Parashat.*$" . font-lock-comment-face)
2113 `(,(format "\\(^\\|\\s-\\)%s\\(-%s\\)?" diary-time-regexp
2114 diary-time-regexp) . 'diary-time))
2115 "Keywords to highlight in fancy diary display.")
2116
2117;; If region looks like it might start or end in the middle of a
2118;; multiline pattern, extend the region to encompass the whole pattern.
2119(defun diary-fancy-font-lock-fontify-region-function (beg end &optional verbose)
2120 "Function to use for `font-lock-fontify-region-function' in Fancy Diary.
2121Needed to handle multiline keyword in `fancy-diary-font-lock-keywords'.
2122Fontify the region between BEG and END, quietly unless VERBOSE is non-nil."
2123 (goto-char beg)
2124 (forward-line 0)
2125 (if (looking-at "=+$") (forward-line -1))
2126 (while (and (looking-at " +[^ ]")
2127 (zerop (forward-line -1))))
2128 ;; This check not essential.
2129 (if (looking-at diary-fancy-date-pattern)
2130 (setq beg (line-beginning-position)))
2131 (goto-char end)
2132 (forward-line 0)
2133 (while (and (looking-at " +[^ ]")
2134 (zerop (forward-line 1))))
2135 (if (looking-at "=+$")
2136 (setq end (line-beginning-position 2)))
2137 (font-lock-default-fontify-region beg end verbose))
2138
2139(define-derived-mode fancy-diary-display-mode fundamental-mode
2140 "Diary"
2141 "Major mode used while displaying diary entries using Fancy Display."
2142 (set (make-local-variable 'font-lock-defaults)
2143 '(fancy-diary-font-lock-keywords
2144 t nil nil nil
2145 (font-lock-fontify-region-function
2146 . diary-fancy-font-lock-fontify-region-function)))
2147 (local-set-key "q" 'quit-window))
2148
2149
2150(defun diary-font-lock-sexps (limit) 2055(defun diary-font-lock-sexps (limit)
2151 "Recognize sexp diary entry up to LIMIT for font-locking." 2056 "Recognize sexp diary entry up to LIMIT for font-locking."
2152 (if (re-search-forward 2057 (if (re-search-forward
@@ -2204,6 +2109,15 @@ and return a font-lock pattern matching array of MONTHS and marking SYMBOL."
2204 (require ',feature) 2109 (require ',feature)
2205 (diary-font-lock-date-forms ,months ,symbol))) 2110 (diary-font-lock-date-forms ,months ,symbol)))
2206 2111
2112(defconst diary-time-regexp
2113 ;; Accepted formats: 10:00 10.00 10h00 10h 10am 10:00am 10.00am
2114 ;; Use of "." as a separator annoyingly matches numbers, eg "123.45".
2115 ;; Hence often prefix this with "\\(^\\|\\s-\\)."
2116 (concat "[0-9]?[0-9]\\([AaPp][mM]\\|\\("
2117 "[Hh]\\([0-9][0-9]\\)?\\|[:.][0-9][0-9]"
2118 "\\)\\([AaPp][Mm]\\)?\\)")
2119 "Regular expression matching a time of day.")
2120
2207(defvar calendar-hebrew-month-name-array-leap-year) 2121(defvar calendar-hebrew-month-name-array-leap-year)
2208(defvar calendar-islamic-month-name-array) 2122(defvar calendar-islamic-month-name-array)
2209(defvar calendar-bahai-month-name-array) 2123(defvar calendar-bahai-month-name-array)
@@ -2256,6 +2170,81 @@ and return a font-lock pattern matching array of MONTHS and marking SYMBOL."
2256(defvar diary-font-lock-keywords (diary-font-lock-keywords) 2170(defvar diary-font-lock-keywords (diary-font-lock-keywords)
2257 "Forms to highlight in `diary-mode'.") 2171 "Forms to highlight in `diary-mode'.")
2258 2172
2173;;;###autoload
2174(define-derived-mode diary-mode fundamental-mode "Diary"
2175 "Major mode for editing the diary file."
2176 (set (make-local-variable 'font-lock-defaults)
2177 '(diary-font-lock-keywords t))
2178 (add-to-invisibility-spec '(diary . nil))
2179 (add-hook 'after-save-hook 'diary-redraw-calendar nil t)
2180 (if diary-header-line-flag
2181 (setq header-line-format diary-header-line-format)))
2182
2183
2184;;; Fancy Diary Mode.
2185
2186(defvar diary-fancy-date-pattern
2187 (concat
2188 (let ((dayname (diary-name-pattern calendar-day-name-array nil t))
2189 (monthname (diary-name-pattern calendar-month-name-array nil t))
2190 (day "[0-9]+")
2191 (month "[0-9]+")
2192 (year "-?[0-9]+"))
2193 (mapconcat 'eval calendar-date-display-form ""))
2194 ;; Optional ": holiday name" after the date.
2195 "\\(: .*\\)?")
2196 "Regular expression matching a date header in Fancy Diary.")
2197
2198(defvar fancy-diary-font-lock-keywords
2199 (list
2200 (list
2201 ;; Any number of " other holiday name" lines, followed by "==" line.
2202 (concat diary-fancy-date-pattern "\\(\n +.*\\)*\n=+$")
2203 '(0 (progn (put-text-property (match-beginning 0) (match-end 0)
2204 'font-lock-multiline t)
2205 diary-face)))
2206 '("^.*\\([aA]nniversary\\|[bB]irthday\\).*$" . 'diary-anniversary)
2207 '("^.*Yahrzeit.*$" . font-lock-reference-face)
2208 '("^\\(Erev \\)?Rosh Hodesh.*" . font-lock-function-name-face)
2209 '("^Day.*omer.*$" . font-lock-builtin-face)
2210 '("^Parashat.*$" . font-lock-comment-face)
2211 `(,(format "\\(^\\|\\s-\\)%s\\(-%s\\)?" diary-time-regexp
2212 diary-time-regexp) . 'diary-time))
2213 "Keywords to highlight in fancy diary display.")
2214
2215;; If region looks like it might start or end in the middle of a
2216;; multiline pattern, extend the region to encompass the whole pattern.
2217(defun diary-fancy-font-lock-fontify-region-function (beg end &optional verbose)
2218 "Function to use for `font-lock-fontify-region-function' in Fancy Diary.
2219Needed to handle multiline keyword in `fancy-diary-font-lock-keywords'.
2220Fontify the region between BEG and END, quietly unless VERBOSE is non-nil."
2221 (goto-char beg)
2222 (forward-line 0)
2223 (if (looking-at "=+$") (forward-line -1))
2224 (while (and (looking-at " +[^ ]")
2225 (zerop (forward-line -1))))
2226 ;; This check not essential.
2227 (if (looking-at diary-fancy-date-pattern)
2228 (setq beg (line-beginning-position)))
2229 (goto-char end)
2230 (forward-line 0)
2231 (while (and (looking-at " +[^ ]")
2232 (zerop (forward-line 1))))
2233 (if (looking-at "=+$")
2234 (setq end (line-beginning-position 2)))
2235 (font-lock-default-fontify-region beg end verbose))
2236
2237(define-derived-mode fancy-diary-display-mode fundamental-mode
2238 "Diary"
2239 "Major mode used while displaying diary entries using Fancy Display."
2240 (set (make-local-variable 'font-lock-defaults)
2241 '(fancy-diary-font-lock-keywords
2242 t nil nil nil
2243 (font-lock-fontify-region-function
2244 . diary-fancy-font-lock-fontify-region-function)))
2245 (local-set-key "q" 'quit-window))
2246
2247
2259;; Following code from Dave Love <fx@gnu.org>. 2248;; Following code from Dave Love <fx@gnu.org>.
2260;; Import Outlook-format appointments from mail messages in Gnus or 2249;; Import Outlook-format appointments from mail messages in Gnus or
2261;; Rmail using command `diary-from-outlook'. This, or the specialized 2250;; Rmail using command `diary-from-outlook'. This, or the specialized
@@ -2295,22 +2284,6 @@ message contains an appointment, don't make a diary entry."
2295 (throw 'finished t)))) 2284 (throw 'finished t))))
2296 nil)) 2285 nil))
2297 2286
2298(defun diary-from-outlook (&optional noconfirm)
2299 "Maybe snarf diary entry from current Outlook-generated message.
2300Currently knows about Gnus and Rmail modes. Unless the optional
2301argument NOCONFIRM is non-nil (which is the case when this
2302function is called interactively), then if an entry is found the
2303user is asked to confirm its addition."
2304 (interactive "p")
2305 (let ((func (cond
2306 ((eq major-mode 'rmail-mode)
2307 #'diary-from-outlook-rmail)
2308 ((memq major-mode '(gnus-summary-mode gnus-article-mode))
2309 #'diary-from-outlook-gnus)
2310 (t (error "Don't know how to snarf in `%s'" major-mode)))))
2311 (funcall func noconfirm)))
2312
2313
2314(defvar gnus-article-mime-handles) 2287(defvar gnus-article-mime-handles)
2315(defvar gnus-article-buffer) 2288(defvar gnus-article-buffer)
2316 2289
@@ -2342,7 +2315,6 @@ automatically."
2342 2315
2343(custom-add-option 'gnus-article-prepare-hook 'diary-from-outlook-gnus) 2316(custom-add-option 'gnus-article-prepare-hook 'diary-from-outlook-gnus)
2344 2317
2345
2346(defvar rmail-buffer) 2318(defvar rmail-buffer)
2347 2319
2348(defun diary-from-outlook-rmail (&optional noconfirm) 2320(defun diary-from-outlook-rmail (&optional noconfirm)
@@ -2362,6 +2334,20 @@ user is asked to confirm its addition."
2362 (diary-from-outlook-internal) 2334 (diary-from-outlook-internal)
2363 (message "Diary entry added")))))) 2335 (message "Diary entry added"))))))
2364 2336
2337(defun diary-from-outlook (&optional noconfirm)
2338 "Maybe snarf diary entry from current Outlook-generated message.
2339Currently knows about Gnus and Rmail modes. Unless the optional
2340argument NOCONFIRM is non-nil (which is the case when this
2341function is called interactively), then if an entry is found the
2342user is asked to confirm its addition."
2343 (interactive "p")
2344 (let ((func (cond
2345 ((eq major-mode 'rmail-mode)
2346 #'diary-from-outlook-rmail)
2347 ((memq major-mode '(gnus-summary-mode gnus-article-mode))
2348 #'diary-from-outlook-gnus)
2349 (t (error "Don't know how to snarf in `%s'" major-mode)))))
2350 (funcall func noconfirm)))
2365 2351
2366(provide 'diary-lib) 2352(provide 'diary-lib)
2367 2353