comparison lisp/calendar/diary-lib.el @ 92994:deb2f6126df1

(diary-remind-message, mark-sexp-diary-entries, list-sexp-diary-entries) (diary-font-lock-sexps): Use format rather than concat. (diary): Remove un-needed let. (view-other-diary-entries): Rename argument. (diary-list-entries-2): New function. (diary-list-entries-1, diary-list-entries): Use diary-list-entries-2. (print-diary-entries): Use unless. (diary-mark-entries-1): Change argument order, make all but markfunc optional. Handle the standard (Gregorian) case. Use match-string-no-properties. Handle marks. (mark-diary-entries): Use diary-mark-entries-1. (calendar-mark-complex, calendar-mark-1): New functions. (diary-font-lock-keywords-1): New macro. (diary-font-lock-keywords): Use diary-font-lock-keywords-1.
author Glenn Morris <rgm@gnu.org>
date Sun, 16 Mar 2008 01:26:48 +0000
parents 122f4beea537
children 9c718a4c0412
comparison
equal deleted inserted replaced
92993:61c2483cb400 92994:deb2f6126df1
226 :version "20.3") 226 :version "20.3")
227 227
228 (defcustom diary-remind-message 228 (defcustom diary-remind-message
229 '("Reminder: Only " 229 '("Reminder: Only "
230 (if (zerop (% days 7)) 230 (if (zerop (% days 7))
231 (concat (int-to-string (/ days 7)) (if (= 7 days) " week" " weeks")) 231 (format "%d week%s" (/ days 7) (if (= 7 days) "" "s"))
232 (concat (int-to-string days) (if (= 1 days) " day" " days"))) 232 (format "%d day%s" days (if (= 1 days) "" "s")))
233 " until " 233 " until "
234 diary-entry) 234 diary-entry)
235 "Pseudo-pattern giving form of reminder messages in the fancy diary display. 235 "Pseudo-pattern giving form of reminder messages in the fancy diary display.
236 236
237 Used by the function `diary-remind', a pseudo-pattern is a list of 237 Used by the function `diary-remind', a pseudo-pattern is a list of
304 If no argument is provided, the number of days of diary entries is governed 304 If no argument is provided, the number of days of diary entries is governed
305 by the variable `number-of-diary-entries'. A value of ARG less than 1 305 by the variable `number-of-diary-entries'. A value of ARG less than 1
306 does nothing. This function is suitable for execution in a `.emacs' file." 306 does nothing. This function is suitable for execution in a `.emacs' file."
307 (interactive "P") 307 (interactive "P")
308 (diary-check-diary-file) 308 (diary-check-diary-file)
309 (let ((date (calendar-current-date))) 309 (diary-list-entries (calendar-current-date)
310 (diary-list-entries date (if arg (prefix-numeric-value arg))))) 310 (if arg (prefix-numeric-value arg))))
311 311
312 (define-obsolete-function-alias 'view-diary-entries 'diary-view-entries) 312 (define-obsolete-function-alias 'view-diary-entries 'diary-view-entries)
313 ;;;###cal-autoload 313 ;;;###cal-autoload
314 (defun diary-view-entries (&optional arg) 314 (defun diary-view-entries (&optional arg)
315 "Prepare and display a buffer with diary entries. 315 "Prepare and display a buffer with diary entries.
319 (interactive "p") 319 (interactive "p")
320 (diary-check-diary-file) 320 (diary-check-diary-file)
321 (diary-list-entries (calendar-cursor-to-date t) arg)) 321 (diary-list-entries (calendar-cursor-to-date t) arg))
322 322
323 ;;;###cal-autoload 323 ;;;###cal-autoload
324 (defun view-other-diary-entries (arg d-file) 324 (defun view-other-diary-entries (arg dfile)
325 "Prepare and display buffer of diary entries from an alternative diary file. 325 "Prepare and display buffer of diary entries from an alternative diary file.
326 Searches for entries that match ARG days, starting with the date indicated 326 Searches for entries that match ARG days, starting with the date indicated
327 by the cursor position in the displayed three-month calendar. 327 by the cursor position in the displayed three-month calendar.
328 D-FILE specifies the file to use as the diary file." 328 DFILE specifies the file to use as the diary file."
329 (interactive 329 (interactive
330 (list (prefix-numeric-value current-prefix-arg) 330 (list (prefix-numeric-value current-prefix-arg)
331 (read-file-name "Enter diary file name: " default-directory nil t))) 331 (read-file-name "Enter diary file name: " default-directory nil t)))
332 (let ((diary-file d-file)) 332 (let ((diary-file dfile))
333 (diary-view-entries arg))) 333 (diary-view-entries arg)))
334 334
335 (defvar diary-syntax-table 335 (defvar diary-syntax-table
336 (let ((st (copy-syntax-table (standard-syntax-table)))) 336 (let ((st (copy-syntax-table (standard-syntax-table))))
337 (modify-syntax-entry ?* "w" st) 337 (modify-syntax-entry ?* "w" st)
520 (append diary-entries-list 520 (append diary-entries-list
521 (list (list date string specifier 521 (list (list date string specifier
522 (list marker (buffer-file-name) literal) 522 (list marker (buffer-file-name) literal)
523 globcolor)))))) 523 globcolor))))))
524 524
525 (defvar number) 525 (defvar number) ; not clear this should use number
526 (defvar original-date) 526
527 527 (defun diary-list-entries-2 (date mark globattr list-only
528 ;; FIXME use for list-diary-entries. 528 &optional months symbol)
529 "Internal subroutine of `diary-list-entries'.
530 Find diary entries applying to DATE, by searching from point-min for
531 each element of `diary-date-forms'. MARK indicates an entry is non-marking.
532 GLOBATTR is the list of global file attributes. If LIST-ONLY is
533 non-nil, don't change the buffer, only return a list of entries.
534 Optional array MONTHS replaces `calendar-month-name-array', and
535 means months cannot be abbreviated. Optional string SYMBOL marks diary
536 entries of the desired type. Returns non-nil if any entries were found."
537 (let* ((month (extract-calendar-month date))
538 (day (extract-calendar-day date))
539 (year (extract-calendar-year date))
540 (dayname (format "%s\\|%s\\.?" (calendar-day-name date)
541 (calendar-day-name date 'abbrev)))
542 (calendar-month-name-array (or months calendar-month-name-array))
543 (monthname (format "\\*\\|%s%s" (calendar-month-name month)
544 (if months ""
545 (format "\\|%s\\.?"
546 (calendar-month-name month 'abbrev)))))
547 (month (format "\\*\\|0*%d" month))
548 (day (format "\\*\\|0*%d" day))
549 (year (format "\\*\\|0*%d%s" year
550 (if abbreviated-calendar-year
551 ;; FIXME was %d in non-greg case.
552 (format "\\|%02d" (% year 100))
553 "")))
554 (case-fold-search t)
555 entry-found)
556 (dolist (date-form diary-date-forms)
557 (let ((backup (when (eq (car date-form) 'backup)
558 (setq date-form (cdr date-form))
559 t))
560 ;; date-form uses day etc as set above.
561 (regexp (format "^%s?%s\\(%s\\)" (regexp-quote mark)
562 (if symbol (regexp-quote symbol) "")
563 (mapconcat 'eval date-form "\\)\\(?:")))
564 entry-start date-start temp)
565 (goto-char (point-min))
566 (while (re-search-forward regexp nil t)
567 (if backup (re-search-backward "\\<" nil t))
568 (if (and (bolp) (not (looking-at "[ \t]")))
569 ;; Diary entry that consists only of date.
570 (backward-char 1)
571 ;; Found a nonempty diary entry--make it
572 ;; visible and add it to the list.
573 ;; Actual entry starts on the next-line?
574 (if (looking-at "[ \t]*\n[ \t]") (forward-line 1))
575 (setq entry-found t
576 entry-start (point)
577 ;; If bolp, must have done (forward-line 1).
578 ;; FIXME Why number > 1?
579 date-start (line-end-position (if (and (bolp) (> number 1))
580 -1 0)))
581 (forward-line 1)
582 (while (looking-at "[ \t]") ; continued entry
583 (forward-line 1))
584 (unless (and (eobp) (not (bolp)))
585 (backward-char 1))
586 (unless list-only
587 (remove-overlays date-start (point) 'invisible 'diary))
588 (setq temp (diary-pull-attrs
589 (buffer-substring-no-properties
590 entry-start (point)) globattr))
591 (add-to-diary-list
592 date (car temp)
593 (buffer-substring-no-properties (1+ date-start) (1- entry-start))
594 (copy-marker entry-start) (cadr temp))))))
595 entry-found))
596
597 (defvar original-date) ; from diary-list-entries
598 (defvar file-glob-attrs)
599 (defvar list-only)
600
529 (defun diary-list-entries-1 (months symbol absfunc) 601 (defun diary-list-entries-1 (months symbol absfunc)
530 "List diary entries of a certain type. 602 "List diary entries of a certain type.
531 MONTHS is an array of month names. SYMBOL marks diary entries of the type 603 MONTHS is an array of month names. SYMBOL marks diary entries of the type
532 in question. ABSFUNC is a function that converts absolute dates to dates 604 in question. ABSFUNC is a function that converts absolute dates to dates
533 of the appropriate type." 605 of the appropriate type."
534 (if (< 0 number) 606 (let ((gdate original-date))
535 (let ((gdate original-date) 607 (dotimes (idummy number)
536 (mark (regexp-quote diary-nonmarking-symbol))) 608 (diary-list-entries-2
537 (dotimes (idummy number) 609 (funcall absfunc (calendar-absolute-from-gregorian gdate))
538 (let* ((tdate (funcall absfunc 610 diary-nonmarking-symbol file-glob-attrs list-only months symbol)
539 (calendar-absolute-from-gregorian gdate))) 611 (setq gdate
540 (month (extract-calendar-month tdate)) 612 (calendar-gregorian-from-absolute
541 (day (extract-calendar-day tdate)) 613 (1+ (calendar-absolute-from-gregorian gdate))))))
542 (year (extract-calendar-year tdate)) 614 (goto-char (point-min)))
543 backup)
544 (dolist (date-form diary-date-forms)
545 (if (setq backup (eq (car date-form) 'backup))
546 (setq date-form (cdr date-form)))
547 (let* ((dayname
548 (format "%s\\|%s\\.?"
549 (calendar-day-name gdate)
550 (calendar-day-name gdate 'abbrev)))
551 (calendar-month-name-array months)
552 (monthname
553 (format "\\*\\|%s" (calendar-month-name month)))
554 (month (format "\\*\\|0*%s" (int-to-string month)))
555 (day (format "\\*\\|0*%s" (int-to-string day)))
556 (year
557 (format "\\*\\|0*%s%s" (int-to-string year)
558 (if abbreviated-calendar-year
559 (format "\\|%s"
560 (int-to-string (% year 100)))
561 "")))
562 (regexp
563 (format "^%s?%s\\(%s\\)" mark (regexp-quote symbol)
564 (mapconcat 'eval date-form "\\)\\(")))
565 (case-fold-search t))
566 (goto-char (point-min))
567 (while (re-search-forward regexp nil t)
568 (if backup (re-search-backward "\\<" nil t))
569 (if (and (bolp) (not (looking-at "[ \t]")))
570 ;; Diary entry that consists only of date.
571 (backward-char 1)
572 ;; Found a nonempty diary entry--make it visible and
573 ;; add it to the list.
574 ;; Actual entry starts on the next-line?
575 (if (looking-at "[ \t]*\n[ \t]") (forward-line 1))
576 (let ((entry-start (point))
577 ;; If bolp, must have done (forward-line 1).
578 (date-start (line-end-position (if (bolp) -1 0))))
579 (forward-line 1)
580 (while (looking-at "[ \t]") ; continued entry
581 (forward-line 1))
582 (unless (and (eobp) (not (bolp)))
583 (backward-char 1))
584 (remove-overlays date-start (point) 'invisible 'diary)
585 (add-to-diary-list
586 gdate
587 (buffer-substring-no-properties entry-start (point))
588 (buffer-substring-no-properties
589 (1+ date-start) (1- entry-start))
590 (copy-marker entry-start))))))))
591 (setq gdate
592 (calendar-gregorian-from-absolute
593 (1+ (calendar-absolute-from-gregorian gdate))))))
594 (goto-char (point-min))))
595 615
596 (define-obsolete-function-alias 'list-diary-entries 'diary-list-entries) 616 (define-obsolete-function-alias 'list-diary-entries 'diary-list-entries)
597 (defun diary-list-entries (date number &optional list-only) 617 (defun diary-list-entries (date number &optional list-only)
598 "Create and display a buffer containing the relevant lines in `diary-file'. 618 "Create and display a buffer containing the relevant lines in `diary-file'.
599 The arguments are DATE and NUMBER; the entries selected are those 619 The arguments are DATE and NUMBER; the entries selected are those
667 ;; d-s-p is passed to the diary display function. 687 ;; d-s-p is passed to the diary display function.
668 (let ((diary-saved-point (point))) 688 (let ((diary-saved-point (point)))
669 (save-excursion 689 (save-excursion
670 (setq file-glob-attrs (nth 1 (diary-pull-attrs nil ""))) 690 (setq file-glob-attrs (nth 1 (diary-pull-attrs nil "")))
671 (with-syntax-table diary-syntax-table 691 (with-syntax-table diary-syntax-table
672 (let ((mark (regexp-quote diary-nonmarking-symbol))) 692 (goto-char (point-min))
673 (goto-char (point-min)) 693 (unless list-only
674 (unless list-only 694 (let ((ol (make-overlay (point-min) (point-max) nil t nil)))
675 (let ((ol (make-overlay (point-min) (point-max) nil t nil))) 695 (set (make-local-variable 'diary-selective-display) t)
676 (set (make-local-variable 'diary-selective-display) t) 696 (overlay-put ol 'invisible 'diary)
677 (overlay-put ol 'invisible 'diary) 697 (overlay-put ol 'evaporate t)))
678 (overlay-put ol 'evaporate t))) 698 (dotimes (idummy number)
679 (dotimes (idummy number) 699 (let ((sexp-found (list-sexp-diary-entries date))
680 (let ((month (extract-calendar-month date)) 700 (entry-found (diary-list-entries-2
681 (day (extract-calendar-day date)) 701 date diary-nonmarking-symbol
682 (year (extract-calendar-year date)) 702 file-glob-attrs list-only)))
683 (entry-found (list-sexp-diary-entries date))) 703 (if diary-list-include-blanks
684 (dolist (date-form diary-date-forms) 704 (or sexp-found entry-found
685 (let* ((backup (when (eq (car date-form) 'backup) 705 (add-to-diary-list date "" "" "" "")))
686 (setq date-form (cdr date-form)) 706 (setq date
687 t)) 707 (calendar-gregorian-from-absolute
688 (dayname 708 (1+ (calendar-absolute-from-gregorian date)))))))
689 (format "%s\\|%s\\.?"
690 (calendar-day-name date)
691 (calendar-day-name date 'abbrev)))
692 (monthname
693 (format "\\*\\|%s\\|%s\\.?"
694 (calendar-month-name month)
695 (calendar-month-name month 'abbrev)))
696 (month (concat "\\*\\|0*" (int-to-string month)))
697 (day (concat "\\*\\|0*" (int-to-string day)))
698 (year
699 (concat
700 "\\*\\|0*" (int-to-string year)
701 (if abbreviated-calendar-year
702 (concat "\\|" (format "%02d" (% year 100)))
703 "")))
704 (regexp
705 (concat
706 "^" mark "?\\("
707 ;; This must be let* so that date-form
708 ;; can use day etc.
709 (mapconcat 'eval date-form "\\)\\(?:")
710 "\\)"))
711 (case-fold-search t))
712 (goto-char (point-min))
713 (while (re-search-forward regexp nil t)
714 (if backup (re-search-backward "\\<" nil t))
715 (if (and (bolp) (not (looking-at "[ \t]")))
716 ;; Diary entry that consists only of date.
717 (backward-char 1)
718 ;; Found a nonempty diary entry--make it
719 ;; visible and add it to the list.
720 (setq entry-found t)
721 (if (looking-at "[ \t]*\n[ \t]") (forward-line 1))
722 (let ((entry-start (point))
723 (temp)
724 (date-start
725 (line-end-position
726 ;; FIXME Why number > 1?
727 (if (and (bolp) (> number 1)) -1 0))))
728 (forward-line 1)
729 (while (looking-at "[ \t]")
730 (forward-line 1))
731 (unless (and (eobp) (not (bolp)))
732 (backward-char 1))
733 (unless list-only
734 (remove-overlays date-start (point)
735 'invisible 'diary))
736 (setq temp (diary-pull-attrs
737 (buffer-substring entry-start (point))
738 file-glob-attrs))
739 (add-to-diary-list
740 date
741 (car temp)
742 (buffer-substring
743 (1+ date-start) (1- entry-start))
744 (copy-marker entry-start) (nth 1 temp)))))))
745 (or entry-found
746 (not diary-list-include-blanks)
747 (add-to-diary-list date "" "" "" ""))
748 (setq date
749 (calendar-gregorian-from-absolute
750 (1+ (calendar-absolute-from-gregorian date))))
751 (setq entry-found nil)))))
752 (goto-char (point-min)) 709 (goto-char (point-min))
753 (run-hooks 'nongregorian-diary-listing-hook 710 (run-hooks 'nongregorian-diary-listing-hook
754 'list-diary-entries-hook) 711 'list-diary-entries-hook)
755 (unless list-only 712 (unless list-only
756 (if diary-display-hook 713 (if diary-display-hook
1046 end) 1003 end)
1047 (while 1004 (while
1048 (progn 1005 (progn
1049 (setq end (next-single-char-property-change 1006 (setq end (next-single-char-property-change
1050 start 'invisible)) 1007 start 'invisible))
1051 (if (get-char-property start 'invisible) 1008 (unless (get-char-property start 'invisible)
1052 nil
1053 (with-current-buffer temp-buffer 1009 (with-current-buffer temp-buffer
1054 (insert-buffer-substring diary-buffer 1010 (insert-buffer-substring diary-buffer
1055 start (or end (point-max))))) 1011 start (or end (point-max)))))
1056 (setq start end) 1012 (setq start end)
1057 (and end (< end (point-max)))))) 1013 (and end (< end (point-max))))))
1140 "True during the marking of diary entries, nil otherwise.") 1096 "True during the marking of diary entries, nil otherwise.")
1141 1097
1142 (defvar marking-diary-entry nil 1098 (defvar marking-diary-entry nil
1143 "True during the marking of diary entries, if current entry is marking.") 1099 "True during the marking of diary entries, if current entry is marking.")
1144 1100
1145 ;; FIXME use for mark-diary-entries. 1101 ;; file-glob-attrs bound in mark-diary-entries.
1146 (defun diary-mark-entries-1 (months symbol absfunc markfunc) 1102 (defun diary-mark-entries-1 (markfunc &optional months symbol absfunc)
1147 "Mark diary entries of a certain type. 1103 "Mark diary entries of a certain type.
1148 MONTHS is an array of month names. SYMBOL marks diary entries of the type 1104 MARKFUNC is a function that marks entries of the appropriate type
1149 in question. ABSFUNC is a function that converts absolute dates to dates 1105 matching a given date pattern. MONTHS is an array of month names.
1150 of the appropriate type. MARKFUNC is a function that marks entries 1106 SYMBOL marks diary entries of the type in question. ABSFUNC is a
1151 of the appropriate type matching a given date pattern." 1107 function that converts absolute dates to dates of the appropriate type. "
1152 (let ((dayname (diary-name-pattern calendar-day-name-array 1108 (let ((dayname (diary-name-pattern calendar-day-name-array
1153 calendar-day-abbrev-array)) 1109 calendar-day-abbrev-array))
1154 (monthname (format "%s\\|\\*" (diary-name-pattern months))) 1110 (monthname (format "%s\\|\\*"
1111 (if months
1112 (diary-name-pattern months)
1113 (diary-name-pattern calendar-month-name-array
1114 calendar-month-abbrev-array))))
1155 (month "[0-9]+\\|\\*") 1115 (month "[0-9]+\\|\\*")
1156 (day "[0-9]+\\|\\*") 1116 (day "[0-9]+\\|\\*")
1157 (year "[0-9]+\\|\\*") 1117 (year "[0-9]+\\|\\*")
1158 (case-fold-search t)) 1118 (case-fold-search t)
1119 ;; FIXME is this the right reason for 1 versus 2?
1120 ;; Should docs of symbols say must be single character?
1121 (inc (if symbol 2 1))
1122 marks)
1159 (dolist (date-form diary-date-forms) 1123 (dolist (date-form diary-date-forms)
1160 (if (eq (car date-form) 'backup) ; ignore 'backup directive 1124 (if (eq (car date-form) 'backup) ; ignore 'backup directive
1161 (setq date-form (cdr date-form))) 1125 (setq date-form (cdr date-form)))
1162 (let* ((l (length date-form)) 1126 (let* ((l (length date-form))
1163 (d-name-pos (- l (length (memq 'dayname date-form)))) 1127 (d-name-pos (- l (length (memq 'dayname date-form))))
1164 (d-name-pos (if (/= l d-name-pos) (+ 2 d-name-pos))) 1128 (d-name-pos (if (/= l d-name-pos) (+ inc d-name-pos)))
1165 (m-name-pos (- l (length (memq 'monthname date-form)))) 1129 (m-name-pos (- l (length (memq 'monthname date-form))))
1166 (m-name-pos (if (/= l m-name-pos) (+ 2 m-name-pos))) 1130 (m-name-pos (if (/= l m-name-pos) (+ inc m-name-pos)))
1167 (d-pos (- l (length (memq 'day date-form)))) 1131 (d-pos (- l (length (memq 'day date-form))))
1168 (d-pos (if (/= l d-pos) (+ 2 d-pos))) 1132 (d-pos (if (/= l d-pos) (+ inc d-pos)))
1169 (m-pos (- l (length (memq 'month date-form)))) 1133 (m-pos (- l (length (memq 'month date-form))))
1170 (m-pos (if (/= l m-pos) (+ 2 m-pos))) 1134 (m-pos (if (/= l m-pos) (+ inc m-pos)))
1171 (y-pos (- l (length (memq 'year date-form)))) 1135 (y-pos (- l (length (memq 'year date-form))))
1172 (y-pos (if (/= l y-pos) (+ 2 y-pos))) 1136 (y-pos (if (/= l y-pos) (+ inc y-pos)))
1173 (regexp (format "^%s\\(%s\\)" (regexp-quote symbol) 1137 (regexp (format "^%s\\(%s\\)"
1138 (if symbol (regexp-quote symbol) "")
1174 (mapconcat 'eval date-form "\\)\\(")))) 1139 (mapconcat 'eval date-form "\\)\\("))))
1175 (goto-char (point-min)) 1140 (goto-char (point-min))
1176 (while (re-search-forward regexp nil t) 1141 (while (re-search-forward regexp nil t)
1177 (let* ((dd-name 1142 (let* ((dd-name
1178 (if d-name-pos 1143 (if d-name-pos
1179 (buffer-substring 1144 (match-string-no-properties d-name-pos)))
1180 (match-beginning d-name-pos)
1181 (match-end d-name-pos))))
1182 (mm-name 1145 (mm-name
1183 (if m-name-pos 1146 (if m-name-pos
1184 (buffer-substring 1147 (match-string-no-properties m-name-pos)))
1185 (match-beginning m-name-pos)
1186 (match-end m-name-pos))))
1187 (mm (string-to-number 1148 (mm (string-to-number
1188 (if m-pos 1149 (if m-pos
1189 (buffer-substring 1150 (match-string-no-properties m-pos)
1190 (match-beginning m-pos)
1191 (match-end m-pos))
1192 ""))) 1151 "")))
1193 (dd (string-to-number 1152 (dd (string-to-number
1194 (if d-pos 1153 (if d-pos
1195 (buffer-substring 1154 (match-string-no-properties d-pos)
1196 (match-beginning d-pos)
1197 (match-end d-pos))
1198 ""))) 1155 "")))
1199 (y-str (if y-pos 1156 (y-str (if y-pos
1200 (buffer-substring 1157 (match-string-no-properties y-pos)))
1201 (match-beginning y-pos)
1202 (match-end y-pos))))
1203 (yy (if (not y-str) 1158 (yy (if (not y-str)
1204 0 1159 0
1205 (if (and (= (length y-str) 2) 1160 (if (and (= (length y-str) 2)
1206 abbreviated-calendar-year) 1161 abbreviated-calendar-year)
1207 (let* ((current-y 1162 (let* ((current-y
1208 (extract-calendar-year 1163 (extract-calendar-year
1209 (funcall absfunc 1164 (if absfunc
1210 (calendar-absolute-from-gregorian 1165 (funcall
1211 (calendar-current-date))))) 1166 absfunc
1167 (calendar-absolute-from-gregorian
1168 (calendar-current-date)))
1169 (calendar-current-date))))
1212 (y (+ (string-to-number y-str) 1170 (y (+ (string-to-number y-str)
1213 (* 100 (/ current-y 100))))) 1171 (* 100 (/ current-y 100)))))
1214 (if (> (- y current-y) 50) 1172 (if (> (- y current-y) 50)
1215 (- y 100) 1173 (- y 100)
1216 (if (> (- current-y y) 50) 1174 (if (> (- current-y y) 50)
1217 (+ y 100) 1175 (+ y 100)
1218 y))) 1176 y)))
1219 (string-to-number y-str))))) 1177 (string-to-number y-str)))))
1178 (setq marks (cadr (diary-pull-attrs
1179 (buffer-substring-no-properties
1180 (point) (line-end-position))
1181 file-glob-attrs)))
1220 (if dd-name 1182 (if dd-name
1221 (mark-calendar-days-named 1183 (mark-calendar-days-named
1222 (cdr (assoc-string dd-name 1184 (cdr (assoc-string dd-name
1223 (calendar-make-alist 1185 (calendar-make-alist
1224 calendar-day-name-array 1186 calendar-day-name-array
1225 0 nil calendar-day-abbrev-array) t))) 1187 0 nil calendar-day-abbrev-array) t)) marks)
1226 (if mm-name 1188 (if mm-name
1227 (setq mm 1189 (setq mm
1228 (if (string-equal mm-name "*") 0 1190 (if (string-equal mm-name "*") 0
1229 (cdr (assoc-string 1191 (cdr (assoc-string
1230 mm-name 1192 mm-name
1231 (calendar-make-alist months) t))))) 1193 (if months (calendar-make-alist months)
1232 (funcall markfunc mm dd yy)))))))) 1194 (calendar-make-alist
1195 calendar-month-name-array
1196 1 nil calendar-month-abbrev-array)) t)))))
1197 (funcall markfunc mm dd yy marks))))))))
1233 1198
1234 ;;;###cal-autoload 1199 ;;;###cal-autoload
1235 (defun mark-diary-entries (&optional redraw) 1200 (defun mark-diary-entries (&optional redraw)
1236 "Mark days in the calendar window that have diary entries. 1201 "Mark days in the calendar window that have diary entries.
1237 Each entry in the diary file visible in the calendar window is 1202 Each entry in the diary file visible in the calendar window is
1250 ;; Use of REDRAW handles both of these cases. 1215 ;; Use of REDRAW handles both of these cases.
1251 (when (and redraw mark-diary-entries-in-calendar) 1216 (when (and redraw mark-diary-entries-in-calendar)
1252 (setq mark-diary-entries-in-calendar nil) 1217 (setq mark-diary-entries-in-calendar nil)
1253 (redraw-calendar)) 1218 (redraw-calendar))
1254 (let ((marking-diary-entries t) 1219 (let ((marking-diary-entries t)
1255 (dayname 1220 file-glob-attrs)
1256 (diary-name-pattern calendar-day-name-array
1257 calendar-day-abbrev-array))
1258 (monthname
1259 (format "%s\\|\\*"
1260 (diary-name-pattern calendar-month-name-array
1261 calendar-month-abbrev-array)))
1262 (month "[0-9]+\\|\\*")
1263 (day "[0-9]+\\|\\*")
1264 (year "[0-9]+\\|\\*")
1265 file-glob-attrs marks)
1266 (with-current-buffer (find-file-noselect (diary-check-diary-file) t) 1221 (with-current-buffer (find-file-noselect (diary-check-diary-file) t)
1267 (save-excursion 1222 (save-excursion
1268 (when (eq major-mode default-major-mode) (diary-mode)) 1223 (when (eq major-mode default-major-mode) (diary-mode))
1269 (setq mark-diary-entries-in-calendar t) 1224 (setq mark-diary-entries-in-calendar t)
1270 (message "Marking diary entries...") 1225 (message "Marking diary entries...")
1271 (setq file-glob-attrs (nth 1 (diary-pull-attrs nil '()))) 1226 (setq file-glob-attrs (nth 1 (diary-pull-attrs nil '())))
1272 (with-syntax-table diary-syntax-table 1227 (with-syntax-table diary-syntax-table
1273 (dolist (date-form diary-date-forms) 1228 (diary-mark-entries-1 'mark-calendar-date-pattern)
1274 (if (eq (car date-form) 'backup)
1275 (setq date-form (cdr date-form))) ; ignore 'backup directive
1276 (let* ((l (length date-form))
1277 (d-name-pos (- l (length (memq 'dayname date-form))))
1278 (d-name-pos (if (/= l d-name-pos) (1+ d-name-pos)))
1279 (m-name-pos (- l (length (memq 'monthname date-form))))
1280 (m-name-pos (if (/= l m-name-pos) (1+ m-name-pos)))
1281 (d-pos (- l (length (memq 'day date-form))))
1282 (d-pos (if (/= l d-pos) (1+ d-pos)))
1283 (m-pos (- l (length (memq 'month date-form))))
1284 (m-pos (if (/= l m-pos) (1+ m-pos)))
1285 (y-pos (- l (length (memq 'year date-form))))
1286 (y-pos (if (/= l y-pos) (1+ y-pos)))
1287 (regexp
1288 (concat
1289 "^\\("
1290 (mapconcat 'eval date-form "\\)\\(")
1291 "\\)"))
1292 (case-fold-search t))
1293 (goto-char (point-min))
1294 (while (re-search-forward regexp nil t)
1295 (let* ((dd-name
1296 (if d-name-pos
1297 (match-string-no-properties d-name-pos)))
1298 (mm-name
1299 (if m-name-pos
1300 (match-string-no-properties m-name-pos)))
1301 (mm (string-to-number
1302 (if m-pos
1303 (match-string-no-properties m-pos)
1304 "")))
1305 (dd (string-to-number
1306 (if d-pos
1307 (match-string-no-properties d-pos)
1308 "")))
1309 (y-str (if y-pos
1310 (match-string-no-properties y-pos)))
1311 (yy (if (not y-str)
1312 0
1313 (if (and (= (length y-str) 2)
1314 abbreviated-calendar-year)
1315 (let* ((current-y
1316 (extract-calendar-year
1317 (calendar-current-date)))
1318 (y (+ (string-to-number y-str)
1319 (* 100
1320 (/ current-y 100)))))
1321 (if (> (- y current-y) 50)
1322 (- y 100)
1323 (if (> (- current-y y) 50)
1324 (+ y 100)
1325 y)))
1326 (string-to-number y-str)))))
1327 (setq marks (nth 1
1328 (diary-pull-attrs
1329 (buffer-substring-no-properties
1330 (point) (line-end-position))
1331 file-glob-attrs)))
1332 (if dd-name
1333 (mark-calendar-days-named
1334 (cdr (assoc-string
1335 dd-name
1336 (calendar-make-alist
1337 calendar-day-name-array
1338 0 nil calendar-day-abbrev-array) t)) marks)
1339 (if mm-name
1340 (setq mm
1341 (if (string-equal mm-name "*") 0
1342 (cdr (assoc-string
1343 mm-name
1344 (calendar-make-alist
1345 calendar-month-name-array
1346 1 nil calendar-month-abbrev-array) t)))))
1347 (mark-calendar-date-pattern mm dd yy marks))))))
1348 (mark-sexp-diary-entries) 1229 (mark-sexp-diary-entries)
1349 (run-hooks 'nongregorian-diary-marking-hook 1230 (run-hooks 'nongregorian-diary-marking-hook
1350 'mark-diary-entries-hook)) 1231 'mark-diary-entries-hook))
1351 (message "Marking diary entries...done"))))) 1232 (message "Marking diary entries...done")))))
1352 1233
1356 (defun mark-sexp-diary-entries () 1237 (defun mark-sexp-diary-entries ()
1357 "Mark days in the calendar window that have sexp diary entries. 1238 "Mark days in the calendar window that have sexp diary entries.
1358 Each entry in the diary file (or included files) visible in the calendar window 1239 Each entry in the diary file (or included files) visible in the calendar window
1359 is marked. See the documentation for the function `list-sexp-diary-entries'." 1240 is marked. See the documentation for the function `list-sexp-diary-entries'."
1360 (let* ((sexp-mark (regexp-quote sexp-diary-entry-symbol)) 1241 (let* ((sexp-mark (regexp-quote sexp-diary-entry-symbol))
1361 (s-entry (concat "^\\(" 1242 (s-entry (format "^\\(%s(\\)\\|\\(%s%s(diary-remind\\)" sexp-mark
1362 sexp-mark "(\\)\\|\\("
1363 (regexp-quote diary-nonmarking-symbol) 1243 (regexp-quote diary-nonmarking-symbol)
1364 sexp-mark "(diary-remind\\)")) 1244 sexp-mark))
1365 (file-glob-attrs (nth 1 (diary-pull-attrs nil '()))) 1245 (file-glob-attrs (nth 1 (diary-pull-attrs nil '())))
1366 m y first-date last-date mark file-glob-attrs) 1246 m y first-date last-date mark file-glob-attrs)
1367 (with-current-buffer calendar-buffer 1247 (with-current-buffer calendar-buffer
1368 (setq m displayed-month) 1248 (setq m displayed-month
1369 (setq y displayed-year)) 1249 y displayed-year))
1370 (increment-calendar-month m y -1) 1250 (increment-calendar-month m y -1)
1371 (setq first-date 1251 (setq first-date
1372 (calendar-absolute-from-gregorian (list m 1 y))) 1252 (calendar-absolute-from-gregorian (list m 1 y)))
1373 (increment-calendar-month m y 2) 1253 (increment-calendar-month m y 2)
1374 (setq last-date 1254 (setq last-date
1394 (while (looking-at "[ \t]") 1274 (while (looking-at "[ \t]")
1395 (forward-line 1)) 1275 (forward-line 1))
1396 (if (bolp) (backward-char 1)) 1276 (if (bolp) (backward-char 1))
1397 (setq entry (buffer-substring-no-properties entry-start (point)))) 1277 (setq entry (buffer-substring-no-properties entry-start (point))))
1398 (calendar-for-loop date from first-date to last-date do 1278 (calendar-for-loop date from first-date to last-date do
1399 (when (setq mark 1279 (when (setq mark (diary-sexp-entry
1400 (diary-sexp-entry 1280 sexp entry
1401 sexp entry 1281 (calendar-gregorian-from-absolute date)))
1402 (calendar-gregorian-from-absolute 1282 ;; FIXME does this make sense?
1403 date))) 1283 (setq marks (diary-pull-attrs entry file-glob-attrs)
1404 ;; FIXME does this make sense? 1284 marks (nth 1 (diary-pull-attrs entry file-glob-attrs)))
1405 (setq marks (diary-pull-attrs 1285 (mark-visible-calendar-date
1406 entry file-glob-attrs) 1286 (calendar-gregorian-from-absolute date)
1407 marks (nth 1 (diary-pull-attrs 1287 (if (< 0 (length marks))
1408 entry file-glob-attrs))) 1288 marks
1409 (mark-visible-calendar-date 1289 (if (consp mark) (car mark))))))))))
1410 (calendar-gregorian-from-absolute date)
1411 (if (< 0 (length marks))
1412 marks
1413 (if (consp mark)
1414 (car mark))))))))))
1415 1290
1416 (defun mark-included-diary-files () 1291 (defun mark-included-diary-files ()
1417 "Mark the diary entries from other diary files with those of the diary file. 1292 "Mark the diary entries from other diary files with those of the diary file.
1418 This function is suitable for use as the `mark-diary-entries-hook'; it enables 1293 This function is suitable for use as the `mark-diary-entries-hook'; it enables
1419 you to use shared diary files together with your own. The files included are 1294 you to use shared diary files together with your own. The files included are
1466 color) 1341 color)
1467 (setq day (+ day 7)))))) 1342 (setq day (+ day 7))))))
1468 1343
1469 (defun mark-calendar-date-pattern (month day year &optional color) 1344 (defun mark-calendar-date-pattern (month day year &optional color)
1470 "Mark all dates in the calendar window that conform to MONTH/DAY/YEAR. 1345 "Mark all dates in the calendar window that conform to MONTH/DAY/YEAR.
1471 A value of 0 in any position is a wildcard. 1346 A value of 0 in any position is a wildcard. Optional argument COLOR is
1472 Optional argument COLOR is passed to `mark-visible-calendar-date' as MARK." 1347 passed to `mark-visible-calendar-date' as MARK."
1473 (with-current-buffer calendar-buffer 1348 (with-current-buffer calendar-buffer
1474 (let ((m displayed-month) 1349 (let ((m displayed-month)
1475 (y displayed-year)) 1350 (y displayed-year))
1476 (increment-calendar-month m y -1) 1351 (increment-calendar-month m y -1)
1477 (dotimes (idummy 3) 1352 (dotimes (idummy 3)
1488 (or (zerop p-year) (= year p-year)))) 1363 (or (zerop p-year) (= year p-year))))
1489 (if (zerop p-day) 1364 (if (zerop p-day)
1490 (dotimes (i (calendar-last-day-of-month month year)) 1365 (dotimes (i (calendar-last-day-of-month month year))
1491 (mark-visible-calendar-date (list month (1+ i) year) color)) 1366 (mark-visible-calendar-date (list month (1+ i) year) color))
1492 (mark-visible-calendar-date (list month p-day year) color)))) 1367 (mark-visible-calendar-date (list month p-day year) color))))
1368
1369 ;; Bahai, Hebrew, Islamic.
1370 (defun calendar-mark-complex (month day year fromabs &optional color)
1371 "Mark dates in the calendar conforming to MONTH DAY YEAR of some system.
1372 The function FROMABS converts absolute dates to the appropriate date system.
1373 Optional argument COLOR is passed to `mark-visible-calendar-date' as MARK."
1374 ;; Not one of the simple cases--check all visible dates for match.
1375 ;; Actually, the following code takes care of ALL of the cases, but
1376 ;; it's much too slow to be used for the simple (common) cases.
1377 (let ((m displayed-month)
1378 (y displayed-year)
1379 first-date last-date)
1380 (increment-calendar-month m y -1)
1381 (setq first-date (calendar-absolute-from-gregorian (list m 1 y)))
1382 (increment-calendar-month m y 2)
1383 (setq last-date (calendar-absolute-from-gregorian
1384 (list m (calendar-last-day-of-month m y) y)))
1385 (calendar-for-loop date from first-date to last-date do
1386 (let* ((i-date (funcall fromabs date))
1387 (i-month (extract-calendar-month i-date))
1388 (i-day (extract-calendar-day i-date))
1389 (i-year (extract-calendar-year i-date)))
1390 (and (or (zerop month)
1391 (= month i-month))
1392 (or (zerop day)
1393 (= day i-day))
1394 (or (zerop year)
1395 (= year i-year))
1396 (mark-visible-calendar-date
1397 (calendar-gregorian-from-absolute date) color))))))
1398
1399 ;; Bahai, Islamic.
1400 (defun calendar-mark-1 (month day year fromabs toabs &optional color)
1401 "Mark dates in the calendar conforming to MONTH DAY YEAR of some system.
1402 The function FROMABS converts absolute dates to the appropriate date system.
1403 The function TOABDS carries out the inverse operation. Optional argument
1404 COLOR is passed to `mark-visible-calendar-date' as MARK."
1405 (save-excursion
1406 (set-buffer calendar-buffer)
1407 (if (and (not (zerop month)) (not (zerop day)))
1408 (if (not (zerop year))
1409 ;; Fully specified date.
1410 (let ((date (calendar-gregorian-from-absolute
1411 (funcall toabs (list month day year)))))
1412 (if (calendar-date-is-visible-p date)
1413 (mark-visible-calendar-date date color)))
1414 ;; Month and day in any year--this taken from the holiday stuff.
1415 (let* ((i-date (funcall fromabs
1416 (calendar-absolute-from-gregorian
1417 (list displayed-month 15 displayed-year))))
1418 (m (extract-calendar-month i-date))
1419 (y (extract-calendar-year i-date))
1420 date)
1421 (unless (< m 1) ; calendar doesn't apply
1422 (increment-calendar-month m y (- 10 month))
1423 (if (> m 7) ; date might be visible
1424 (let ((date (calendar-gregorian-from-absolute
1425 (funcall toabs (list month day y)))))
1426 (if (calendar-date-is-visible-p date)
1427 (mark-visible-calendar-date date color)))))))
1428 (calendar-mark-complex month day year
1429 'calendar-bahai-from-absolute color))))
1493 1430
1494 (defun sort-diary-entries () 1431 (defun sort-diary-entries ()
1495 "Sort the list of diary entries by time of day." 1432 "Sort the list of diary entries by time of day."
1496 (setq diary-entries-list (sort diary-entries-list 'diary-entry-compare))) 1433 (setq diary-entries-list (sort diary-entries-list 'diary-entry-compare)))
1497 1434
1692 from Passover to Shavuot. Note that since there is no text, 1629 from Passover to Shavuot. Note that since there is no text,
1693 it makes sense only if the fancy diary display is used. 1630 it makes sense only if the fancy diary display is used.
1694 1631
1695 Marking these entries is *extremely* time consuming, so these entries are 1632 Marking these entries is *extremely* time consuming, so these entries are
1696 best if they are nonmarking." 1633 best if they are nonmarking."
1697 (let ((s-entry (concat "^" 1634 (let ((s-entry (format "^%s?%s(" (regexp-quote diary-nonmarking-symbol)
1698 (regexp-quote diary-nonmarking-symbol) 1635 (regexp-quote sexp-diary-entry-symbol)))
1699 "?"
1700 (regexp-quote sexp-diary-entry-symbol)
1701 "("))
1702 entry-found file-glob-attrs marks) 1636 entry-found file-glob-attrs marks)
1703 (goto-char (point-min)) 1637 (goto-char (point-min))
1704 (save-excursion 1638 (save-excursion
1705 (setq file-glob-attrs (nth 1 (diary-pull-attrs nil '())))) 1639 (setq file-glob-attrs (nth 1 (diary-pull-attrs nil '()))))
1706 (while (re-search-forward s-entry nil t) 1640 (while (re-search-forward s-entry nil t)
2214 2148
2215 2149
2216 (defun diary-font-lock-sexps (limit) 2150 (defun diary-font-lock-sexps (limit)
2217 "Recognize sexp diary entry up to LIMIT for font-locking." 2151 "Recognize sexp diary entry up to LIMIT for font-locking."
2218 (if (re-search-forward 2152 (if (re-search-forward
2219 (concat "^" (regexp-quote diary-nonmarking-symbol) 2153 (format "^%s?\\(%s\\)" (regexp-quote diary-nonmarking-symbol)
2220 "?\\(" (regexp-quote sexp-diary-entry-symbol) "\\)") 2154 (regexp-quote sexp-diary-entry-symbol))
2221 limit t) 2155 limit t)
2222 (condition-case nil 2156 (condition-case nil
2223 (save-restriction 2157 (save-restriction
2224 (narrow-to-region (point-min) limit) 2158 (narrow-to-region (point-min) limit)
2225 (let ((start (point))) 2159 (let ((start (point)))
2258 (concat "\\)" (eval (car (reverse x)))) 2192 (concat "\\)" (eval (car (reverse x))))
2259 "\\)")) 2193 "\\)"))
2260 '(1 diary-face))) 2194 '(1 diary-face)))
2261 diary-date-forms))) 2195 diary-date-forms)))
2262 2196
2197 (defmacro diary-font-lock-keywords-1 (markfunc listfunc feature months symbol)
2198 "Subroutine of the function `diary-font-lock-keywords'.
2199 If MARKFUNC is a member of `nongregorian-diary-marking-hook', or
2200 LISTFUNC of `nongregorian-diary-listing-hook', then require FEATURE
2201 and return a font-lock pattern matching array of MONTHS and marking SYMBOL."
2202 `(when (or (memq ',markfunc nongregorian-diary-marking-hook)
2203 (memq ',listfunc nongregorian-diary-listing-hook))
2204 (require ',feature)
2205 (diary-font-lock-date-forms ,months ,symbol)))
2206
2263 (defvar calendar-hebrew-month-name-array-leap-year) 2207 (defvar calendar-hebrew-month-name-array-leap-year)
2264 (defvar calendar-islamic-month-name-array) 2208 (defvar calendar-islamic-month-name-array)
2265 (defvar calendar-bahai-month-name-array) 2209 (defvar calendar-bahai-month-name-array)
2266 2210
2267 ;;;###cal-autoload 2211 ;;;###cal-autoload
2268 (defun diary-font-lock-keywords () 2212 (defun diary-font-lock-keywords ()
2269 "Return a value for the variable `diary-font-lock-keywords'." 2213 "Return a value for the variable `diary-font-lock-keywords'."
2270 (append 2214 (append
2271 (diary-font-lock-date-forms calendar-month-name-array 2215 (diary-font-lock-date-forms calendar-month-name-array
2272 nil calendar-month-abbrev-array) 2216 nil calendar-month-abbrev-array)
2273 (when (or (memq 'mark-hebrew-diary-entries 2217 (diary-font-lock-keywords-1 mark-hebrew-diary-entries
2274 nongregorian-diary-marking-hook) 2218 list-hebrew-diary-entries
2275 (memq 'list-hebrew-diary-entries 2219 cal-hebrew
2276 nongregorian-diary-listing-hook)) 2220 calendar-hebrew-month-name-array-leap-year
2277 (require 'cal-hebrew) 2221 hebrew-diary-entry-symbol)
2278 (diary-font-lock-date-forms 2222 (diary-font-lock-keywords-1 mark-islamic-diary-entries
2279 calendar-hebrew-month-name-array-leap-year hebrew-diary-entry-symbol)) 2223 list-islamic-diary-entries
2280 (when (or (memq 'mark-islamic-diary-entries 2224 cal-islam
2281 nongregorian-diary-marking-hook) 2225 calendar-islamic-month-name-array
2282 (memq 'list-islamic-diary-entries 2226 islamic-diary-entry-symbol)
2283 nongregorian-diary-listing-hook)) 2227 (diary-font-lock-keywords-1 diary-bahai-mark-entries
2284 (require 'cal-islam) 2228 diary-bahai-list-entries
2285 (diary-font-lock-date-forms 2229 cal-bahai
2286 calendar-islamic-month-name-array islamic-diary-entry-symbol)) 2230 calendar-bahai-month-name-array
2287 (when (or (memq 'diary-bahai-mark-entries 2231 bahai-diary-entry-symbol)
2288 nongregorian-diary-marking-hook)
2289 (memq 'diary-bahai-list-entries
2290 nongregorian-diary-marking-hook))
2291 (require 'cal-bahai)
2292 (diary-font-lock-date-forms
2293 calendar-bahai-month-name-array bahai-diary-entry-symbol))
2294 (list 2232 (list
2295 (cons 2233 (cons
2296 (format "^%s.*$" (regexp-quote diary-include-string)) 2234 (format "^%s.*$" (regexp-quote diary-include-string))
2297 'font-lock-keyword-face) 2235 'font-lock-keyword-face)
2298 (cons 2236 (cons