comparison lisp/calendar/diary-lib.el @ 92859:15bd5abe194e

Whitespace only.
author Glenn Morris <rgm@gnu.org>
date Thu, 13 Mar 2008 06:29:03 +0000
parents de680a2b3b3b
children 532b44d84fec
comparison
equal deleted inserted replaced
92858:7096add7a945 92859:15bd5abe194e
52 (defcustom diary-face 'diary 52 (defcustom diary-face 'diary
53 "Face name to use for diary entries." 53 "Face name to use for diary entries."
54 :type 'face 54 :type 'face
55 :group 'diary) 55 :group 'diary)
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 ;; Face markup of calendar and diary displays: Any entry line that 59 ;; Face markup of calendar and diary displays: Any entry line that
60 ;; ends with [foo:value] where foo is a face attribute (except :box 60 ;; ends with [foo:value] where foo is a face attribute (except :box
61 ;; :stipple) or with [face:blah] tags, will have these values applied 61 ;; :stipple) or with [face:blah] tags, will have these values applied
62 ;; to the calendar and fancy diary displays. These attributes "stack" 62 ;; to the calendar and fancy diary displays. These attributes "stack"
88 specifies which face attribute (e.g. `:foreground') to modify, or 88 specifies which face attribute (e.g. `:foreground') to modify, or
89 that this is a face (`:face') to apply. TYPE is the type of 89 that this is a face (`:face') to apply. TYPE is the type of
90 attribute being applied. Available TYPES (see `diary-attrtype-convert') 90 attribute being applied. Available TYPES (see `diary-attrtype-convert')
91 are: `string', `symbol', `int', `tnil',`stringtnil.'" 91 are: `string', `symbol', `int', `tnil',`stringtnil.'"
92 :type '(repeat (list (string :tag "Regular expression") 92 :type '(repeat (list (string :tag "Regular expression")
93 (integer :tag "Sub-expression") 93 (integer :tag "Sub-expression")
94 (symbol :tag "Attribute (e.g. :foreground)") 94 (symbol :tag "Attribute (e.g. :foreground)")
95 (choice (const string :tag "A string") 95 (choice (const string :tag "A string")
96 (const symbol :tag "A symbol") 96 (const symbol :tag "A symbol")
97 (const int :tag "An integer") 97 (const int :tag "An integer")
98 (const tnil :tag "`t' or `nil'") 98 (const tnil :tag "`t' or `nil'")
99 (const stringtnil 99 (const stringtnil
100 :tag "A string, `t', or `nil'")))) 100 :tag "A string, `t', or `nil'"))))
101 :group 'diary) 101 :group 'diary)
102 102
103 (defcustom diary-glob-file-regexp-prefix "^\\#" 103 (defcustom diary-glob-file-regexp-prefix "^\\#"
104 "Regular expression prepended to `diary-face-attrs' for file-wide specifiers." 104 "Regular expression prepended to `diary-face-attrs' for file-wide specifiers."
105 :type 'regexp 105 :type 'regexp
175 `list-hebrew-diary-entries', `list-islamic-diary-entries' and 175 `list-hebrew-diary-entries', `list-islamic-diary-entries' and
176 `diary-bahai-list-entries'. The documentation for these functions 176 `diary-bahai-list-entries'. The documentation for these functions
177 describes the style of such diary entries." 177 describes the style of such diary entries."
178 :type 'hook 178 :type 'hook
179 :options '(list-hebrew-diary-entries 179 :options '(list-hebrew-diary-entries
180 list-islamic-diary-entries 180 list-islamic-diary-entries
181 diary-bahai-list-entries) 181 diary-bahai-list-entries)
182 :group 'diary) 182 :group 'diary)
183 183
184 (defcustom nongregorian-diary-marking-hook nil 184 (defcustom nongregorian-diary-marking-hook nil
185 "List of functions called for marking diary file and included files. 185 "List of functions called for marking diary file and included files.
186 As the files are processed for diary entries, these functions are used 186 As the files are processed for diary entries, these functions are used
188 `mark-hebrew-diary-entries', `mark-islamic-diary-entries' and 188 `mark-hebrew-diary-entries', `mark-islamic-diary-entries' and
189 `bahai-mark-diary-entries'. The documentation for these functions 189 `bahai-mark-diary-entries'. The documentation for these functions
190 describes the style of such diary entries." 190 describes the style of such diary entries."
191 :type 'hook 191 :type 'hook
192 :options '(mark-hebrew-diary-entries 192 :options '(mark-hebrew-diary-entries
193 mark-islamic-diary-entries 193 mark-islamic-diary-entries
194 diary-bahai-mark-entries) 194 diary-bahai-mark-entries)
195 :group 'diary) 195 :group 'diary)
196 196
197 (defcustom print-diary-entries-hook 'lpr-buffer 197 (defcustom print-diary-entries-hook 'lpr-buffer
198 "List of functions called after a temporary diary buffer is prepared. 198 "List of functions called after a temporary diary buffer is prepared.
199 The buffer shows only the diary entries currently visible in the diary 199 The buffer shows only the diary entries currently visible in the diary
276 276
277 If the template is actually a function, it is called with the message 277 If the template is actually a function, it is called with the message
278 body text as argument, and may use `match-string' etc. to make a 278 body text as argument, and may use `match-string' etc. to make a
279 template following the rules above." 279 template following the rules above."
280 :type '(alist :key-type (regexp :tag "Regexp matching time/place") 280 :type '(alist :key-type (regexp :tag "Regexp matching time/place")
281 :value-type (choice 281 :value-type (choice
282 (string :tag "Template for entry") 282 (string :tag "Template for entry")
283 (function :tag 283 (function :tag
284 "Unary function providing template"))) 284 "Unary function providing template")))
285 :version "22.1" 285 :version "22.1"
286 :group 'diary) 286 :group 'diary)
287 287
288 ;;; More user options below and in calendar.el. 288 ;;; More user options below and in calendar.el.
289 289
343 343
344 (defun diary-attrtype-convert (attrvalue type) 344 (defun diary-attrtype-convert (attrvalue type)
345 "Convert string ATTRVALUE to TYPE appropriate for a face description. 345 "Convert string ATTRVALUE to TYPE appropriate for a face description.
346 Valid TYPEs are: string, symbol, int, stringtnil, tnil." 346 Valid TYPEs are: string, symbol, int, stringtnil, tnil."
347 (cond ((eq type 'string) attrvalue) 347 (cond ((eq type 'string) attrvalue)
348 ((eq type 'symbol) (read attrvalue)) ; FIXME intern-soft? 348 ((eq type 'symbol) (read attrvalue)) ; FIXME intern-soft?
349 ((eq type 'int) (string-to-number attrvalue)) 349 ((eq type 'int) (string-to-number attrvalue))
350 ((eq type 'stringtnil) 350 ((eq type 'stringtnil)
351 (cond ((string-equal "t" attrvalue) t) 351 (cond ((string-equal "t" attrvalue) t)
352 ((string-equal "nil" attrvalue) nil) 352 ((string-equal "nil" attrvalue) nil)
353 (t attrvalue))) 353 (t attrvalue)))
354 ((eq type 'tnil) (string-equal "t" attrvalue)))) 354 ((eq type 'tnil) (string-equal "t" attrvalue))))
355 355
356 (defun diary-pull-attrs (entry fileglobattrs) 356 (defun diary-pull-attrs (entry fileglobattrs)
357 "Search for matches for regexps from `diary-face-attrs'. 357 "Search for matches for regexps from `diary-face-attrs'.
358 If ENTRY is nil, searches from the start of the current buffer, and 358 If ENTRY is nil, searches from the start of the current buffer, and
359 prepends all regexps with `diary-glob-file-regexp-prefix'. 359 prepends all regexps with `diary-glob-file-regexp-prefix'.
361 Returns a list of ENTRY followed by (ATTRIBUTE VALUE) pairs. 361 Returns a list of ENTRY followed by (ATTRIBUTE VALUE) pairs.
362 When ENTRY is non-nil, FILEGLOBATTRS forms the start of the (ATTRIBUTE VALUE) 362 When ENTRY is non-nil, FILEGLOBATTRS forms the start of the (ATTRIBUTE VALUE)
363 pairs." 363 pairs."
364 (let (regexp regnum attrname attrname attrvalue type ret-attr) 364 (let (regexp regnum attrname attrname attrvalue type ret-attr)
365 (if (null entry) 365 (if (null entry)
366 (save-excursion 366 (save-excursion
367 (dolist (attr diary-face-attrs) 367 (dolist (attr diary-face-attrs)
368 ;; FIXME inefficient searching. 368 ;; FIXME inefficient searching.
369 (goto-char (point-min)) 369 (goto-char (point-min))
370 (setq regexp (concat diary-glob-file-regexp-prefix (car attr)) 370 (setq regexp (concat diary-glob-file-regexp-prefix (car attr))
371 regnum (cadr attr) 371 regnum (cadr attr)
372 attrname (nth 2 attr) 372 attrname (nth 2 attr)
373 type (nth 3 attr) 373 type (nth 3 attr)
374 attrvalue (if (re-search-forward regexp nil t) 374 attrvalue (if (re-search-forward regexp nil t)
375 (match-string-no-properties regnum))) 375 (match-string-no-properties regnum)))
376 (and attrvalue 376 (and attrvalue
377 (setq attrvalue (diary-attrtype-convert attrvalue type)) 377 (setq attrvalue (diary-attrtype-convert attrvalue type))
378 (setq ret-attr (append ret-attr 378 (setq ret-attr (append ret-attr
379 (list attrname attrvalue)))))) 379 (list attrname attrvalue))))))
380 (setq ret-attr fileglobattrs) 380 (setq ret-attr fileglobattrs)
381 (dolist (attr diary-face-attrs) 381 (dolist (attr diary-face-attrs)
382 (setq regexp (car attr) 382 (setq regexp (car attr)
383 regnum (cadr attr) 383 regnum (cadr attr)
384 attrname (nth 2 attr) 384 attrname (nth 2 attr)
385 type (nth 3 attr) 385 type (nth 3 attr)
386 attrvalue nil) 386 attrvalue nil)
387 ;; FIXME multiple matches? 387 ;; FIXME multiple matches?
388 (if (string-match regexp entry) 388 (if (string-match regexp entry)
389 (setq attrvalue (match-string-no-properties regnum entry) 389 (setq attrvalue (match-string-no-properties regnum entry)
390 entry (replace-match "" t t entry))) 390 entry (replace-match "" t t entry)))
391 (and attrvalue 391 (and attrvalue
392 (setq attrvalue (diary-attrtype-convert attrvalue type)) 392 (setq attrvalue (diary-attrtype-convert attrvalue type))
393 (setq ret-attr (append ret-attr (list attrname attrvalue)))))) 393 (setq ret-attr (append ret-attr (list attrname attrvalue))))))
394 (list entry ret-attr))) 394 (list entry ret-attr)))
395 395
396 ;;;###cal-autoload 396 ;;;###cal-autoload
397 (defun diary-set-maybe-redraw (symbol value) 397 (defun diary-set-maybe-redraw (symbol value)
398 "Set SYMBOL's value to VALUE, and redraw the diary if necessary. 398 "Set SYMBOL's value to VALUE, and redraw the diary if necessary.
469 469
470 This variable does not affect the diary display with the `d' command 470 This variable does not affect the diary display with the `d' command
471 from the calendar; in that case, the prefix argument controls the 471 from the calendar; in that case, the prefix argument controls the
472 number of days of diary entries displayed." 472 number of days of diary entries displayed."
473 :type '(choice (integer :tag "Entries") 473 :type '(choice (integer :tag "Entries")
474 (vector :value [0 0 0 0 0 0 0] 474 (vector :value [0 0 0 0 0 0 0]
475 (integer :tag "Sunday") 475 (integer :tag "Sunday")
476 (integer :tag "Monday") 476 (integer :tag "Monday")
477 (integer :tag "Tuesday") 477 (integer :tag "Tuesday")
478 (integer :tag "Wednesday") 478 (integer :tag "Wednesday")
479 (integer :tag "Thursday") 479 (integer :tag "Thursday")
480 (integer :tag "Friday") 480 (integer :tag "Friday")
481 (integer :tag "Saturday"))) 481 (integer :tag "Saturday")))
482 :initialize 'custom-initialize-default 482 :initialize 'custom-initialize-default
483 :set 'diary-set-maybe-redraw 483 :set 'diary-set-maybe-redraw
484 :group 'diary) 484 :group 'diary)
485 485
486 486
488 "Function applied to entry string before putting it into the entries list. 488 "Function applied to entry string before putting it into the entries list.
489 Can be used by programs integrating a diary list into other buffers (e.g. 489 Can be used by programs integrating a diary list into other buffers (e.g.
490 org.el and planner.el) to modify the string or add properties to it. 490 org.el and planner.el) to modify the string or add properties to it.
491 The function takes a string argument and must return a string.") 491 The function takes a string argument and must return a string.")
492 492
493 (defvar diary-entries-list) ; bound in diary-list-entries 493 (defvar diary-entries-list) ; bound in diary-list-entries
494 494
495 (defun add-to-diary-list (date string specifier &optional marker 495 (defun add-to-diary-list (date string specifier &optional marker
496 globcolor literal) 496 globcolor literal)
497 "Add an entry to `diary-entries-list'. 497 "Add an entry to `diary-entries-list'.
498 Do nothing if DATE or STRING is nil. DATE is the (MONTH DAY 498 Do nothing if DATE or STRING is nil. DATE is the (MONTH DAY
511 (let ((prefix (funcall diary-file-name-prefix-function 511 (let ((prefix (funcall diary-file-name-prefix-function
512 (buffer-file-name)))) 512 (buffer-file-name))))
513 (or (string-equal prefix "") 513 (or (string-equal prefix "")
514 (setq string (format "[%s] %s" prefix string))))) 514 (setq string (format "[%s] %s" prefix string)))))
515 (and diary-modify-entry-list-string-function 515 (and diary-modify-entry-list-string-function
516 (setq string (funcall diary-modify-entry-list-string-function 516 (setq string (funcall diary-modify-entry-list-string-function
517 string))) 517 string)))
518 (setq diary-entries-list 518 (setq diary-entries-list
519 (append diary-entries-list 519 (append diary-entries-list
520 (list (list date string specifier 520 (list (list date string specifier
521 (list marker (buffer-file-name) literal) 521 (list marker (buffer-file-name) literal)
522 globcolor)))))) 522 globcolor))))))
565 (unless number 565 (unless number
566 (setq number (if (vectorp number-of-diary-entries) 566 (setq number (if (vectorp number-of-diary-entries)
567 (aref number-of-diary-entries (calendar-day-of-week date)) 567 (aref number-of-diary-entries (calendar-day-of-week date))
568 number-of-diary-entries))) 568 number-of-diary-entries)))
569 (when (> number 0) 569 (when (> number 0)
570 (let ((original-date date) ; save for possible use in the hooks 570 (let ((original-date date) ; save for possible use in the hooks
571 diary-entries-list 571 diary-entries-list
572 file-glob-attrs 572 file-glob-attrs
573 (date-string (calendar-date-string date)) 573 (date-string (calendar-date-string date))
574 (d-file (substitute-in-file-name diary-file))) 574 (d-file (substitute-in-file-name diary-file)))
575 (message "Preparing diary...") 575 (message "Preparing diary...")
609 (day (extract-calendar-day date)) 609 (day (extract-calendar-day date))
610 (year (extract-calendar-year date)) 610 (year (extract-calendar-year date))
611 (entry-found (list-sexp-diary-entries date))) 611 (entry-found (list-sexp-diary-entries date)))
612 (dolist (date-form diary-date-forms) 612 (dolist (date-form diary-date-forms)
613 (let* ((backup (when (eq (car date-form) 'backup) 613 (let* ((backup (when (eq (car date-form) 'backup)
614 (setq date-form (cdr date-form)) 614 (setq date-form (cdr date-form))
615 t)) 615 t))
616 (dayname 616 (dayname
617 (format "%s\\|%s\\.?" 617 (format "%s\\|%s\\.?"
618 (calendar-day-name date) 618 (calendar-day-name date)
619 (calendar-day-name date 'abbrev))) 619 (calendar-day-name date 'abbrev)))
620 (monthname 620 (monthname
621 (format "\\*\\|%s\\|%s\\.?" 621 (format "\\*\\|%s\\|%s\\.?"
622 (calendar-month-name month) 622 (calendar-month-name month)
623 (calendar-month-name month 'abbrev))) 623 (calendar-month-name month 'abbrev)))
624 (month (concat "\\*\\|0*" (int-to-string month))) 624 (month (concat "\\*\\|0*" (int-to-string month)))
625 (day (concat "\\*\\|0*" (int-to-string day))) 625 (day (concat "\\*\\|0*" (int-to-string day)))
626 (year 626 (year
627 (concat 627 (concat
628 "\\*\\|0*" (int-to-string year) 628 "\\*\\|0*" (int-to-string year)
629 (if abbreviated-calendar-year 629 (if abbreviated-calendar-year
630 (concat "\\|" (format "%02d" (% year 100))) 630 (concat "\\|" (format "%02d" (% year 100)))
631 ""))) 631 "")))
632 (regexp 632 (regexp
633 (concat 633 (concat
634 "^" mark "?\\(" 634 "^" mark "?\\("
635 ;; This must be let* so that date-form 635 ;; This must be let* so that date-form
636 ;; can use day etc. 636 ;; can use day etc.
637 (mapconcat 'eval date-form "\\)\\(?:") 637 (mapconcat 'eval date-form "\\)\\(?:")
638 "\\)")) 638 "\\)"))
639 (case-fold-search t)) 639 (case-fold-search t))
640 (goto-char (point-min)) 640 (goto-char (point-min))
641 (while (re-search-forward regexp nil t) 641 (while (re-search-forward regexp nil t)
642 (if backup (re-search-backward "\\<" nil t)) 642 (if backup (re-search-backward "\\<" nil t))
643 (if (and (bolp) (not (looking-at "[ \t]"))) 643 (if (and (bolp) (not (looking-at "[ \t]")))
644 ;; Diary entry that consists only of date. 644 ;; Diary entry that consists only of date.
645 (backward-char 1) 645 (backward-char 1)
646 ;; Found a nonempty diary entry--make it 646 ;; Found a nonempty diary entry--make it
647 ;; visible and add it to the list. 647 ;; visible and add it to the list.
648 (setq entry-found t) 648 (setq entry-found t)
649 (if (looking-at "[ \t]*\n[ \t]") (forward-line 1)) 649 (if (looking-at "[ \t]*\n[ \t]") (forward-line 1))
650 (let ((entry-start (point)) 650 (let ((entry-start (point))
651 date-start temp) 651 date-start temp)
652 (setq date-start 652 (setq date-start
653 (line-end-position 653 (line-end-position
654 (if (and (bolp) (> number 1)) -1 0))) 654 (if (and (bolp) (> number 1)) -1 0)))
655 (forward-line 1) 655 (forward-line 1)
656 (while (looking-at "[ \t]") 656 (while (looking-at "[ \t]")
657 (forward-line 1)) 657 (forward-line 1))
658 (unless (and (eobp) (not (bolp))) 658 (unless (and (eobp) (not (bolp)))
659 (backward-char 1)) 659 (backward-char 1))
660 (unless list-only 660 (unless list-only
661 (remove-overlays date-start (point) 661 (remove-overlays date-start (point)
662 'invisible 'diary)) 662 'invisible 'diary))
663 (setq temp (diary-pull-attrs 663 (setq temp (diary-pull-attrs
664 (buffer-substring entry-start (point)) 664 (buffer-substring entry-start (point))
665 file-glob-attrs)) 665 file-glob-attrs))
666 (add-to-diary-list 666 (add-to-diary-list
667 date 667 date
668 (car temp) 668 (car temp)
669 (buffer-substring 669 (buffer-substring
670 (1+ date-start) (1- entry-start)) 670 (1+ date-start) (1- entry-start))
679 (goto-char (point-min)) 679 (goto-char (point-min))
680 (run-hooks 'nongregorian-diary-listing-hook 680 (run-hooks 'nongregorian-diary-listing-hook
681 'list-diary-entries-hook) 681 'list-diary-entries-hook)
682 (unless list-only 682 (unless list-only
683 (if diary-display-hook 683 (if diary-display-hook
684 (run-hooks 'diary-display-hook) 684 (run-hooks 'diary-display-hook)
685 (simple-diary-display))) 685 (simple-diary-display)))
686 (run-hooks 'diary-hook) 686 (run-hooks 'diary-hook)
687 diary-entries-list)))))) 687 diary-entries-list))))))
688 688
689 (defun diary-unhide-everything () 689 (defun diary-unhide-everything ()
690 "Show all invisible text in the diary." 690 "Show all invisible text in the diary."
691 (kill-local-variable 'diary-selective-display) 691 (kill-local-variable 'diary-selective-display)
692 (remove-overlays (point-min) (point-max) 'invisible 'diary) 692 (remove-overlays (point-min) (point-max) 'invisible 'diary)
693 (kill-local-variable 'mode-line-format)) 693 (kill-local-variable 'mode-line-format))
694 694
695 (defvar original-date) ; bound in diary-list-entries 695 (defvar original-date) ; bound in diary-list-entries
696 (defvar number) 696 (defvar number)
697 697
698 (defun include-other-diary-files () 698 (defun include-other-diary-files ()
699 "Include the diary entries from other diary files with those of `diary-file'. 699 "Include the diary entries from other diary files with those of `diary-file'.
700 This function is suitable for use in `list-diary-entries-hook'; 700 This function is suitable for use in `list-diary-entries-hook';
710 "^" 710 "^"
711 (regexp-quote diary-include-string) 711 (regexp-quote diary-include-string)
712 " \"\\([^\"]*\\)\"") 712 " \"\\([^\"]*\\)\"")
713 nil t) 713 nil t)
714 (let ((diary-file (substitute-in-file-name 714 (let ((diary-file (substitute-in-file-name
715 (match-string-no-properties 1))) 715 (match-string-no-properties 1)))
716 (diary-list-include-blanks nil) 716 (diary-list-include-blanks nil)
717 (list-diary-entries-hook 'include-other-diary-files) 717 (list-diary-entries-hook 'include-other-diary-files)
718 (diary-display-hook 'ignore) 718 (diary-display-hook 'ignore)
719 (diary-hook nil)) 719 (diary-hook nil))
720 (if (file-exists-p diary-file) 720 (if (file-exists-p diary-file)
721 (if (file-readable-p diary-file) 721 (if (file-readable-p diary-file)
722 (unwind-protect 722 (unwind-protect
723 (setq diary-entries-list 723 (setq diary-entries-list
724 (append diary-entries-list 724 (append diary-entries-list
729 (message "Can't read included diary file %s" diary-file) 729 (message "Can't read included diary file %s" diary-file)
730 (sleep-for 2)) 730 (sleep-for 2))
731 (beep) 731 (beep)
732 (message "Can't find included diary file %s" diary-file) 732 (message "Can't find included diary file %s" diary-file)
733 (sleep-for 2)))) 733 (sleep-for 2))))
734 (goto-char (point-min))) 734 (goto-char (point-min)))
735 735
736 ;; Bound in diary-list-entries. 736 ;; Bound in diary-list-entries.
737 (defvar date-string) 737 (defvar date-string)
738 (defvar diary-saved-point) 738 (defvar diary-saved-point)
739 739
773 (set-window-point window diary-saved-point) 773 (set-window-point window diary-saved-point)
774 (set-window-start window (point-min)))) 774 (set-window-start window (point-min))))
775 (message "Preparing diary...done")))) 775 (message "Preparing diary...done"))))
776 776
777 (defface diary-button '((((type pc) (class color)) 777 (defface diary-button '((((type pc) (class color))
778 (:foreground "lightblue"))) 778 (:foreground "lightblue")))
779 "Default face used for buttons." 779 "Default face used for buttons."
780 :version "22.1" 780 :version "22.1"
781 :group 'diary) 781 :group 'diary)
782 ;; Backward-compatibility alias. FIXME make obsolete. 782 ;; Backward-compatibility alias. FIXME make obsolete.
783 (put 'diary-button-face 'face-alias 'diary-button) 783 (put 'diary-button-face 'face-alias 'diary-button)
843 (let ((entry-list diary-entries-list) 843 (let ((entry-list diary-entries-list)
844 (holiday-list) 844 (holiday-list)
845 (holiday-list-last-month 1) 845 (holiday-list-last-month 1)
846 (holiday-list-last-year 1) 846 (holiday-list-last-year 1)
847 (date (list 0 0 0))) 847 (date (list 0 0 0)))
848 (dolist (entry entry-list) 848 (dolist (entry entry-list)
849 (if (not (calendar-date-equal date (car entry))) 849 (if (not (calendar-date-equal date (car entry)))
850 (progn 850 (progn
851 (setq date (car entry)) 851 (setq date (car entry))
852 (and holidays-in-diary-buffer 852 (and holidays-in-diary-buffer
853 (calendar-date-compare 853 (calendar-date-compare
858 holiday-list-last-year)) 858 holiday-list-last-year))
859 (list date)) 859 (list date))
860 ;; We need to get the holidays for the next 3 months. 860 ;; We need to get the holidays for the next 3 months.
861 (setq holiday-list-last-month 861 (setq holiday-list-last-month
862 (extract-calendar-month date) 862 (extract-calendar-month date)
863 holiday-list-last-year 863 holiday-list-last-year
864 (extract-calendar-year date)) 864 (extract-calendar-year date))
865 (progn 865 (progn
866 (increment-calendar-month 866 (increment-calendar-month
867 holiday-list-last-month holiday-list-last-year 1) 867 holiday-list-last-month holiday-list-last-year 1)
868 t) 868 t)
871 (displayed-year holiday-list-last-year)) 871 (displayed-year holiday-list-last-year))
872 (calendar-holiday-list))) 872 (calendar-holiday-list)))
873 (increment-calendar-month 873 (increment-calendar-month
874 holiday-list-last-month holiday-list-last-year 1)) 874 holiday-list-last-month holiday-list-last-year 1))
875 (let (date-holiday-list) 875 (let (date-holiday-list)
876 ;; Make a list of all holidays for date. 876 ;; Make a list of all holidays for date.
877 (dolist (h holiday-list) 877 (dolist (h holiday-list)
878 (if (calendar-date-equal date (car h)) 878 (if (calendar-date-equal date (car h))
879 (setq date-holiday-list (append date-holiday-list 879 (setq date-holiday-list (append date-holiday-list
880 (cdr h))))) 880 (cdr h)))))
881 (insert (if (bobp) "" ?\n) (calendar-date-string date)) 881 (insert (if (bobp) "" ?\n) (calendar-date-string date))
882 (if date-holiday-list (insert ": ")) 882 (if date-holiday-list (insert ": "))
883 (let ((l (current-column)) 883 (let ((l (current-column))
884 (longest 0)) 884 (longest 0))
885 (insert (mapconcat (lambda (x) 885 (insert (mapconcat (lambda (x)
886 (if (< longest (length x)) 886 (if (< longest (length x))
887 (setq longest (length x))) 887 (setq longest (length x)))
888 x) 888 x)
889 date-holiday-list 889 date-holiday-list
890 (concat "\n" (make-string l ? )))) 890 (concat "\n" (make-string l ? ))))
891 (insert ?\n (make-string (+ l longest) ?=) ?\n))))) 891 (insert ?\n (make-string (+ l longest) ?=) ?\n)))))
892 (let ((this-entry (cadr entry)) 892 (let ((this-entry (cadr entry))
893 this-loc) 893 this-loc)
894 (unless (zerop (length this-entry)) 894 (unless (zerop (length this-entry))
895 (if (setq this-loc (nth 3 entry)) 895 (if (setq this-loc (nth 3 entry))
896 (insert-button (concat this-entry "\n") 896 (insert-button (concat this-entry "\n")
897 ;; (MARKER FILENAME SPECIFIER LITERAL) 897 ;; (MARKER FILENAME SPECIFIER LITERAL)
898 'locator (list (car this-loc) 898 'locator (list (car this-loc)
899 (cadr this-loc) 899 (cadr this-loc)
900 (nth 2 entry) 900 (nth 2 entry)
901 (or (nth 2 this-loc) 901 (or (nth 2 this-loc)
902 (nth 1 entry))) 902 (nth 1 entry)))
903 :type 'diary-entry) 903 :type 'diary-entry)
904 (insert this-entry ?\n)) 904 (insert this-entry ?\n))
905 (save-excursion 905 (save-excursion
906 (let* ((marks (nth 4 entry)) 906 (let* ((marks (nth 4 entry))
907 (faceinfo marks) 907 (faceinfo marks)
908 temp-face) 908 temp-face)
909 (when marks 909 (when marks
910 (setq temp-face (make-symbol 910 (setq temp-face (make-symbol
911 (apply 911 (apply
912 'concat "temp-face-" 912 'concat "temp-face-"
913 (mapcar (lambda (sym) 913 (mapcar (lambda (sym)
914 (if (stringp sym) 914 (if (stringp sym)
915 sym 915 sym
916 (symbol-name sym))) 916 (symbol-name sym)))
917 marks)))) 917 marks))))
918 (make-face temp-face) 918 (make-face temp-face)
919 ;; Remove :face info from the marks, 919 ;; Remove :face info from the marks,
920 ;; copy the face info into temp-face 920 ;; copy the face info into temp-face
921 (while (setq faceinfo (memq :face faceinfo)) 921 (while (setq faceinfo (memq :face faceinfo))
922 (copy-face (read (nth 1 faceinfo)) temp-face) 922 (copy-face (read (nth 1 faceinfo)) temp-face)
923 (setcar faceinfo nil) 923 (setcar faceinfo nil)
924 (setcar (cdr faceinfo) nil)) 924 (setcar (cdr faceinfo) nil))
925 (setq marks (delq nil marks)) 925 (setq marks (delq nil marks))
926 ;; Apply the font aspects. 926 ;; Apply the font aspects.
927 (apply 'set-face-attribute temp-face nil marks) 927 (apply 'set-face-attribute temp-face nil marks)
928 (search-backward this-entry) 928 (search-backward this-entry)
929 (overlay-put 929 (overlay-put
930 (make-overlay (match-beginning 0) (match-end 0)) 930 (make-overlay (match-beginning 0) (match-end 0))
931 'face temp-face)))))))) 931 'face temp-face))))))))
932 (set-buffer-modified-p nil) 932 (set-buffer-modified-p nil)
933 (goto-char (point-min)) 933 (goto-char (point-min))
934 (setq buffer-read-only t) 934 (setq buffer-read-only t)
935 (display-buffer fancy-diary-buffer) 935 (display-buffer fancy-diary-buffer)
936 (fancy-diary-display-mode) 936 (fancy-diary-display-mode)
1164 (- y 100) 1164 (- y 100)
1165 (if (> (- current-y y) 50) 1165 (if (> (- current-y y) 50)
1166 (+ y 100) 1166 (+ y 100)
1167 y))) 1167 y)))
1168 (string-to-number y-str))))) 1168 (string-to-number y-str)))))
1169 (setq marks (nth 1 1169 (setq marks (nth 1
1170 (diary-pull-attrs 1170 (diary-pull-attrs
1171 (buffer-substring-no-properties 1171 (buffer-substring-no-properties
1172 (point) (line-end-position)) 1172 (point) (line-end-position))
1173 file-glob-attrs))) 1173 file-glob-attrs)))
1174 (if dd-name 1174 (if dd-name
1175 (mark-calendar-days-named 1175 (mark-calendar-days-named
1176 (cdr (assoc-string 1176 (cdr (assoc-string
1177 dd-name 1177 dd-name
1178 (calendar-make-alist 1178 (calendar-make-alist
1190 (mark-sexp-diary-entries) 1190 (mark-sexp-diary-entries)
1191 (run-hooks 'nongregorian-diary-marking-hook 1191 (run-hooks 'nongregorian-diary-marking-hook
1192 'mark-diary-entries-hook)) 1192 'mark-diary-entries-hook))
1193 (message "Marking diary entries...done"))))) 1193 (message "Marking diary entries...done")))))
1194 1194
1195 (defvar displayed-year) ; bound in generate-calendar 1195 (defvar displayed-year) ; bound in generate-calendar
1196 (defvar displayed-month) 1196 (defvar displayed-month)
1197 1197
1198 (defun mark-sexp-diary-entries () 1198 (defun mark-sexp-diary-entries ()
1199 "Mark days in the calendar window that have sexp diary entries. 1199 "Mark days in the calendar window that have sexp diary entries.
1200 Each entry in the diary file (or included files) visible in the calendar window 1200 Each entry in the diary file (or included files) visible in the calendar window
1224 sexp entry entry-start marks) 1224 sexp entry entry-start marks)
1225 (forward-sexp) 1225 (forward-sexp)
1226 (setq sexp (buffer-substring-no-properties sexp-start (point))) 1226 (setq sexp (buffer-substring-no-properties sexp-start (point)))
1227 (forward-char 1) 1227 (forward-char 1)
1228 (if (and (bolp) (not (looking-at "[ \t]"))) 1228 (if (and (bolp) (not (looking-at "[ \t]")))
1229 ;; Diary entry consists only of the sexp. 1229 ;; Diary entry consists only of the sexp.
1230 (progn 1230 (progn
1231 (backward-char 1) 1231 (backward-char 1)
1232 (setq entry "")) 1232 (setq entry ""))
1233 (setq entry-start (point)) 1233 (setq entry-start (point))
1234 ;; Find end of entry. 1234 ;; Find end of entry.
1236 (while (looking-at "[ \t]") 1236 (while (looking-at "[ \t]")
1237 (forward-line 1)) 1237 (forward-line 1))
1238 (if (bolp) (backward-char 1)) 1238 (if (bolp) (backward-char 1))
1239 (setq entry (buffer-substring-no-properties entry-start (point)))) 1239 (setq entry (buffer-substring-no-properties entry-start (point))))
1240 (calendar-for-loop date from first-date to last-date do 1240 (calendar-for-loop date from first-date to last-date do
1241 (if (setq mark (diary-sexp-entry sexp entry 1241 (if (setq mark (diary-sexp-entry sexp entry
1242 (calendar-gregorian-from-absolute date))) 1242 (calendar-gregorian-from-absolute date)))
1243 (progn 1243 (progn
1244 (setq marks (diary-pull-attrs entry file-glob-attrs) 1244 (setq marks (diary-pull-attrs entry file-glob-attrs)
1245 marks (nth 1 (diary-pull-attrs entry file-glob-attrs))) 1245 marks (nth 1 (diary-pull-attrs entry file-glob-attrs)))
1246 (mark-visible-calendar-date 1246 (mark-visible-calendar-date
1247 (calendar-gregorian-from-absolute date) 1247 (calendar-gregorian-from-absolute date)
1248 (if (< 0 (length marks)) 1248 (if (< 0 (length marks))
1249 marks 1249 marks
1250 (if (consp mark) 1250 (if (consp mark)
1251 (car mark))))))))))) 1251 (car mark)))))))))))
1252 1252
1253 (defun mark-included-diary-files () 1253 (defun mark-included-diary-files ()
1254 "Mark the diary entries from other diary files with those of the diary file. 1254 "Mark the diary entries from other diary files with those of the diary file.
1255 This function is suitable for use as the `mark-diary-entries-hook'; it enables 1255 This function is suitable for use as the `mark-diary-entries-hook'; it enables
1256 you to use shared diary files together with your own. The files included are 1256 you to use shared diary files together with your own. The files included are
1297 (day)) 1297 (day))
1298 (increment-calendar-month succ-month succ-year 1) 1298 (increment-calendar-month succ-month succ-year 1)
1299 (increment-calendar-month prev-month prev-year -1) 1299 (increment-calendar-month prev-month prev-year -1)
1300 (setq day (calendar-absolute-from-gregorian 1300 (setq day (calendar-absolute-from-gregorian
1301 (calendar-nth-named-day 1 dayname prev-month prev-year)) 1301 (calendar-nth-named-day 1 dayname prev-month prev-year))
1302 last-day (calendar-absolute-from-gregorian 1302 last-day (calendar-absolute-from-gregorian
1303 (calendar-nth-named-day -1 dayname succ-month succ-year))) 1303 (calendar-nth-named-day -1 dayname succ-month succ-year)))
1304 (while (<= day last-day) 1304 (while (<= day last-day)
1305 (mark-visible-calendar-date (calendar-gregorian-from-absolute day) 1305 (mark-visible-calendar-date (calendar-gregorian-from-absolute day)
1306 color) 1306 color)
1307 (setq day (+ day 7)))))) 1307 (setq day (+ day 7))))))
1308 1308
1309 (defun mark-calendar-date-pattern (month day year &optional color) 1309 (defun mark-calendar-date-pattern (month day year &optional color)
1310 "Mark all dates in the calendar window that conform to MONTH/DAY/YEAR. 1310 "Mark all dates in the calendar window that conform to MONTH/DAY/YEAR.
1311 A value of 0 in any position is a wildcard. 1311 A value of 0 in any position is a wildcard.
1326 (or (zerop p-year) (= year p-year))) 1326 (or (zerop p-year) (= year p-year)))
1327 (and (zerop p-month) 1327 (and (zerop p-month)
1328 (or (zerop p-year) (= year p-year)))) 1328 (or (zerop p-year) (= year p-year))))
1329 (if (zerop p-day) 1329 (if (zerop p-day)
1330 (calendar-for-loop 1330 (calendar-for-loop
1331 i from 1 to (calendar-last-day-of-month month year) do 1331 i from 1 to (calendar-last-day-of-month month year) do
1332 (mark-visible-calendar-date (list month i year) color)) 1332 (mark-visible-calendar-date (list month i year) color))
1333 (mark-visible-calendar-date (list month p-day year) color)))) 1333 (mark-visible-calendar-date (list month p-day year) color))))
1334 1334
1335 (defun sort-diary-entries () 1335 (defun sort-diary-entries ()
1336 "Sort the list of diary entries by time of day." 1336 "Sort the list of diary entries by time of day."
1337 (setq diary-entries-list (sort diary-entries-list 'diary-entry-compare))) 1337 (setq diary-entries-list (sort diary-entries-list 'diary-entry-compare)))
1353 Returns `diary-unknown-time' (default value -9999) if no time is recognized. 1353 Returns `diary-unknown-time' (default value -9999) if no time is recognized.
1354 The recognized forms are XXXX, X:XX, or XX:XX (military time), and XXam, 1354 The recognized forms are XXXX, X:XX, or XX:XX (military time), and XXam,
1355 XXAM, XXpm, XXPM, XX:XXam, XX:XXAM XX:XXpm, or XX:XXPM. A period (.) can 1355 XXAM, XXpm, XXPM, XX:XXam, XX:XXAM XX:XXpm, or XX:XXPM. A period (.) can
1356 be used instead of a colon (:) to separate the hour and minute parts." 1356 be used instead of a colon (:) to separate the hour and minute parts."
1357 (let ((case-fold-search nil)) 1357 (let ((case-fold-search nil))
1358 (cond ((string-match ; military time 1358 (cond ((string-match ; military time
1359 "\\`[ \t\n]*\\([0-9]?[0-9]\\)[:.]?\\([0-9][0-9]\\)\\(\\>\\|[^ap]\\)" 1359 "\\`[ \t\n]*\\([0-9]?[0-9]\\)[:.]?\\([0-9][0-9]\\)\\(\\>\\|[^ap]\\)"
1360 s) 1360 s)
1361 (+ (* 100 (string-to-number (match-string 1 s))) 1361 (+ (* 100 (string-to-number (match-string 1 s)))
1362 (string-to-number (match-string 2 s)))) 1362 (string-to-number (match-string 2 s))))
1363 ((string-match ; hour only (XXam or XXpm) 1363 ((string-match ; hour only (XXam or XXpm)
1364 "\\`[ \t\n]*\\([0-9]?[0-9]\\)\\([ap]\\)m\\>" s) 1364 "\\`[ \t\n]*\\([0-9]?[0-9]\\)\\([ap]\\)m\\>" s)
1365 (+ (* 100 (% (string-to-number (match-string 1 s)) 12)) 1365 (+ (* 100 (% (string-to-number (match-string 1 s)) 12))
1366 (if (equal ?a (downcase (aref s (match-beginning 2)))) 1366 (if (equal ?a (downcase (aref s (match-beginning 2))))
1367 0 1200))) 1367 0 1200)))
1368 ((string-match ; hour and minute (XX:XXam or XX:XXpm) 1368 ((string-match ; hour and minute (XX:XXam or XX:XXpm)
1369 "\\`[ \t\n]*\\([0-9]?[0-9]\\)[:.]\\([0-9][0-9]\\)\\([ap]\\)m\\>" s) 1369 "\\`[ \t\n]*\\([0-9]?[0-9]\\)[:.]\\([0-9][0-9]\\)\\([ap]\\)m\\>" s)
1370 (+ (* 100 (% (string-to-number (match-string 1 s)) 12)) 1370 (+ (* 100 (% (string-to-number (match-string 1 s)) 12))
1371 (string-to-number (match-string 2 s)) 1371 (string-to-number (match-string 2 s))
1372 (if (equal ?a (downcase (aref s (match-beginning 3)))) 1372 (if (equal ?a (downcase (aref s (match-beginning 3))))
1373 0 1200))) 1373 0 1200)))
1374 (t diary-unknown-time)))) ; unrecognizable 1374 (t diary-unknown-time)))) ; unrecognizable
1375 1375
1376 (defun list-sexp-diary-entries (date) 1376 (defun list-sexp-diary-entries (date)
1377 "Add sexp entries for DATE from the diary file to `diary-entries-list'. 1377 "Add sexp entries for DATE from the diary file to `diary-entries-list'.
1378 Also, make them visible in the diary file. Returns t if any entries were 1378 Also, make them visible in the diary file. Returns t if any entries were
1379 found. 1379 found.
1555 (setq specifier 1555 (setq specifier
1556 (buffer-substring-no-properties (1+ line-start) (point)) 1556 (buffer-substring-no-properties (1+ line-start) (point))
1557 entry-start (1+ line-start)) 1557 entry-start (1+ line-start))
1558 (forward-char 1) 1558 (forward-char 1)
1559 (if (and (bolp) (not (looking-at "[ \t]"))) 1559 (if (and (bolp) (not (looking-at "[ \t]")))
1560 ;; Diary entry consists only of the sexp. 1560 ;; Diary entry consists only of the sexp.
1561 (progn 1561 (progn
1562 (backward-char 1) 1562 (backward-char 1)
1563 (setq entry "")) 1563 (setq entry ""))
1564 (setq entry-start (point)) 1564 (setq entry-start (point))
1565 (forward-line 1) 1565 (forward-line 1)
1602 (message "Bad sexp at line %d in %s: %s" 1602 (message "Bad sexp at line %d in %s: %s"
1603 (count-lines (point-min) (point)) 1603 (count-lines (point-min) (point))
1604 diary-file sexp) 1604 diary-file sexp)
1605 (sleep-for 2)))))) 1605 (sleep-for 2))))))
1606 (cond ((stringp result) result) 1606 (cond ((stringp result) result)
1607 ((and (consp result) 1607 ((and (consp result)
1608 (stringp (cdr result))) result) 1608 (stringp (cdr result))) result)
1609 (result entry) 1609 (result entry)
1610 (t nil)))) 1610 (t nil))))
1611 1611
1612 (defvar date) 1612 (defvar date)
1613 (defvar entry) 1613 (defvar entry)
1614 1614
1674 backward from the end of the month. 1674 backward from the end of the month.
1675 1675
1676 An optional parameter DAY means the Nth DAYNAME on or after/before MONTH DAY. 1676 An optional parameter DAY means the Nth DAYNAME on or after/before MONTH DAY.
1677 Optional MARK specifies a face or single-character string to use when 1677 Optional MARK specifies a face or single-character string to use when
1678 highlighting the day in the calendar." 1678 highlighting the day in the calendar."
1679 ;; This is messy because the diary entry may apply, but the date on which it 1679 ;; This is messy because the diary entry may apply, but the date on which it
1680 ;; is based can be in a different month/year. For example, asking for the 1680 ;; is based can be in a different month/year. For example, asking for the
1681 ;; first Monday after December 30. For large values of |n| the problem is 1681 ;; first Monday after December 30. For large values of |n| the problem is
1682 ;; more grotesque. 1682 ;; more grotesque.
1683 (and (= dayname (calendar-day-of-week date)) 1683 (and (= dayname (calendar-day-of-week date))
1684 (let* ((m (extract-calendar-month date)) 1684 (let* ((m (extract-calendar-month date))
1685 (d (extract-calendar-day date)) 1685 (d (extract-calendar-day date))
1686 (y (extract-calendar-year date)) 1686 (y (extract-calendar-year date))
1687 ;; Last (n>0) or first (n<0) possible base date for entry. 1687 ;; Last (n>0) or first (n<0) possible base date for entry.
1688 (limit 1688 (limit
1689 (calendar-nth-named-absday (- n) dayname m y d)) 1689 (calendar-nth-named-absday (- n) dayname m y d))
1690 (last-abs (if (> n 0) limit (+ limit 6))) 1690 (last-abs (if (> n 0) limit (+ limit 6)))
1691 (first-abs (if (> n 0) (- limit 6) limit)) 1691 (first-abs (if (> n 0) (- limit 6) limit))
1692 (last (calendar-gregorian-from-absolute last-abs)) 1692 (last (calendar-gregorian-from-absolute last-abs))
1697 (y1 (extract-calendar-year first)) 1697 (y1 (extract-calendar-year first))
1698 ;; m2, d2 is last possible base date. 1698 ;; m2, d2 is last possible base date.
1699 (m2 (extract-calendar-month last)) 1699 (m2 (extract-calendar-month last))
1700 (d2 (extract-calendar-day last)) 1700 (d2 (extract-calendar-day last))
1701 (y2 (extract-calendar-year last))) 1701 (y2 (extract-calendar-year last)))
1702 (if (or (and (= m1 m2) ; only possible base dates in one month 1702 (if (or (and (= m1 m2) ; only possible base dates in one month
1703 (or (eq month t) 1703 (or (eq month t)
1704 (if (listp month) 1704 (if (listp month)
1705 (memq m1 month) 1705 (memq m1 month)
1706 (= m1 month))) 1706 (= m1 month)))
1707 (let ((d (or day (if (> n 0) 1707 (let ((d (or day (if (> n 0)
1708 1 1708 1
1709 (calendar-last-day-of-month m1 y1))))) 1709 (calendar-last-day-of-month m1 y1)))))
1710 (and (<= d1 d) (<= d d2)))) 1710 (and (<= d1 d) (<= d d2))))
1711 ;; Only possible base dates straddle two months. 1711 ;; Only possible base dates straddle two months.
1712 (and (or (< y1 y2) 1712 (and (or (< y1 y2)
1713 (and (= y1 y2) (< m1 m2))) 1713 (and (= y1 y2) (< m1 m2)))
1714 (or 1714 (or
1715 ;; m1, d1 works as a base date. 1715 ;; m1, d1 works as a base date.
1716 (and 1716 (and
1717 (or (eq month t) 1717 (or (eq month t)
1718 (if (listp month) 1718 (if (listp month)
1719 (memq m1 month) 1719 (memq m1 month)
1720 (= m1 month))) 1720 (= m1 month)))
1721 (<= d1 (or day (if (> n 0) 1721 (<= d1 (or day (if (> n 0)
1722 1 1722 1
1723 (calendar-last-day-of-month m1 y1))))) 1723 (calendar-last-day-of-month m1 y1)))))
1724 ;; m2, d2 works as a base date. 1724 ;; m2, d2 works as a base date.
1725 (and (or (eq month t) 1725 (and (or (eq month t)
1726 (if (listp month) 1726 (if (listp month)
1727 (memq m2 month) 1727 (memq m2 month)
1728 (= m2 month))) 1728 (= m2 month)))
1729 (<= (or day (if (> n 0) 1729 (<= (or day (if (> n 0)
1730 1 1730 1
1731 (calendar-last-day-of-month m2 y2))) 1731 (calendar-last-day-of-month m2 y2)))
1732 d2))))) 1732 d2)))))
1733 (cons mark entry))))) 1733 (cons mark entry)))))
1734 1734
1735 ;; To be called from diary-sexp-entry, where DATE, ENTRY are bound. 1735 ;; To be called from diary-sexp-entry, where DATE, ENTRY are bound.
1736 (defun diary-anniversary (month day &optional year mark) 1736 (defun diary-anniversary (month day &optional year mark)
1737 "Anniversary diary entry. 1737 "Anniversary diary entry.
1738 Entry applies if date is the anniversary of MONTH, DAY, YEAR if 1738 Entry applies if date is the anniversary of MONTH, DAY, YEAR if
1816 ((and diary-entry 1816 ((and diary-entry
1817 (or (not marking-diary-entries) marking-diary-entry)) 1817 (or (not marking-diary-entries) marking-diary-entry))
1818 diary-entry) 1818 diary-entry)
1819 ;; Diary entry may apply to `days' before date. 1819 ;; Diary entry may apply to `days' before date.
1820 ((and (integerp days) 1820 ((and (integerp days)
1821 (not diary-entry) ; diary entry does not apply to date 1821 (not diary-entry) ; diary entry does not apply to date
1822 (or (not marking-diary-entries) marking)) 1822 (or (not marking-diary-entries) marking))
1823 (let ((date (calendar-gregorian-from-absolute 1823 (let ((date (calendar-gregorian-from-absolute
1824 (+ (calendar-absolute-from-gregorian date) days)))) 1824 (+ (calendar-absolute-from-gregorian date) days))))
1825 (when (setq diary-entry (eval sexp)) ; re-evaluate with adjusted date 1825 (when (setq diary-entry (eval sexp)) ; re-evaluate with adjusted date
1826 ;; Discard any mark portion from diary-anniversary, etc. 1826 ;; Discard any mark portion from diary-anniversary, etc.
1924 (interactive "P") 1924 (interactive "P")
1925 (let ((calendar-date-display-form 1925 (let ((calendar-date-display-form
1926 (if european-calendar-style 1926 (if european-calendar-style
1927 '(day " " month " " year) 1927 '(day " " month " " year)
1928 '(month " " day " " year))) 1928 '(month " " day " " year)))
1929 (cursor (calendar-cursor-to-date t)) 1929 (cursor (calendar-cursor-to-date t))
1930 (mark (or (car calendar-mark-ring) 1930 (mark (or (car calendar-mark-ring)
1931 (error "No mark set in this buffer"))) 1931 (error "No mark set in this buffer")))
1932 start end) 1932 start end)
1933 (if (< (calendar-absolute-from-gregorian mark) 1933 (if (< (calendar-absolute-from-gregorian mark)
1934 (calendar-absolute-from-gregorian cursor)) 1934 (calendar-absolute-from-gregorian cursor))
1935 (setq start mark 1935 (setq start mark
1936 end cursor) 1936 end cursor)
1937 (setq start cursor 1937 (setq start cursor
1938 end mark)) 1938 end mark))
1939 (make-diary-entry 1939 (make-diary-entry
1940 (format "%s(diary-block %s %s)" 1940 (format "%s(diary-block %s %s)"
1941 sexp-diary-entry-symbol 1941 sexp-diary-entry-symbol
1942 (calendar-date-string start nil t) 1942 (calendar-date-string start nil t)
1943 (calendar-date-string end nil t)) 1943 (calendar-date-string end nil t))
1944 arg))) 1944 arg)))
1945 1945
1946 ;;;###cal-autoload 1946 ;;;###cal-autoload
1947 (defun insert-cyclic-diary-entry (arg) 1947 (defun insert-cyclic-diary-entry (arg)
1948 "Insert a cyclic diary entry starting at the date given by point. 1948 "Insert a cyclic diary entry starting at the date given by point.
2063 (if (re-search-forward 2063 (if (re-search-forward
2064 (concat "^" (regexp-quote diary-nonmarking-symbol) 2064 (concat "^" (regexp-quote diary-nonmarking-symbol)
2065 "?\\(" (regexp-quote sexp-diary-entry-symbol) "\\)") 2065 "?\\(" (regexp-quote sexp-diary-entry-symbol) "\\)")
2066 limit t) 2066 limit t)
2067 (condition-case nil 2067 (condition-case nil
2068 (save-restriction 2068 (save-restriction
2069 (narrow-to-region (point-min) limit) 2069 (narrow-to-region (point-min) limit)
2070 (let ((start (point))) 2070 (let ((start (point)))
2071 (forward-sexp 1) 2071 (forward-sexp 1)
2072 (store-match-data (list start (point))) 2072 (store-match-data (list start (point)))
2073 t)) 2073 t))
2074 (error t)))) 2074 (error t))))
2075 2075
2076 (defun diary-font-lock-date-forms (month-array &optional symbol abbrev-array) 2076 (defun diary-font-lock-date-forms (month-array &optional symbol abbrev-array)
2077 "Create font-lock patterns for `diary-date-forms' using MONTH-ARRAY. 2077 "Create font-lock patterns for `diary-date-forms' using MONTH-ARRAY.
2078 If given, optional SYMBOL must be a prefix to entries. 2078 If given, optional SYMBOL must be a prefix to entries.
2079 If optional ABBREV-ARRAY is present, the abbreviations constructed 2079 If optional ABBREV-ARRAY is present, the abbreviations constructed
2086 (diary-name-pattern month-array abbrev-array))) 2086 (diary-name-pattern month-array abbrev-array)))
2087 (month "\\([0-9]+\\|\\*\\)") 2087 (month "\\([0-9]+\\|\\*\\)")
2088 (day "\\([0-9]+\\|\\*\\)") 2088 (day "\\([0-9]+\\|\\*\\)")
2089 (year "-?\\([0-9]+\\|\\*\\)")) 2089 (year "-?\\([0-9]+\\|\\*\\)"))
2090 (mapcar (lambda (x) 2090 (mapcar (lambda (x)
2091 (cons 2091 (cons
2092 (concat "^" (regexp-quote diary-nonmarking-symbol) "?" 2092 (concat "^" (regexp-quote diary-nonmarking-symbol) "?"
2093 (if symbol (regexp-quote symbol) "") "\\(" 2093 (if symbol (regexp-quote symbol) "") "\\("
2094 (mapconcat 'eval 2094 (mapconcat 'eval
2095 ;; If backup, omit first item (backup) 2095 ;; If backup, omit first item (backup)
2096 ;; and last item (not part of date). 2096 ;; and last item (not part of date).
2097 (if (equal (car x) 'backup) 2097 (if (equal (car x) 'backup)
2098 (nreverse (cdr (reverse (cdr x)))) 2098 (nreverse (cdr (reverse (cdr x))))
2099 x) 2099 x)
2100 "") 2100 "")
2101 ;; With backup, last item is not part of date. 2101 ;; With backup, last item is not part of date.
2102 (if (equal (car x) 'backup) 2102 (if (equal (car x) 'backup)
2103 (concat "\\)" (eval (car (reverse x)))) 2103 (concat "\\)" (eval (car (reverse x))))
2104 "\\)")) 2104 "\\)"))
2105 '(1 diary-face))) 2105 '(1 diary-face)))
2106 diary-date-forms))) 2106 diary-date-forms)))
2107 2107
2108 (defvar calendar-hebrew-month-name-array-leap-year) 2108 (defvar calendar-hebrew-month-name-array-leap-year)
2109 (defvar calendar-islamic-month-name-array) 2109 (defvar calendar-islamic-month-name-array)
2110 (defvar calendar-bahai-month-name-array) 2110 (defvar calendar-bahai-month-name-array)
2128 nongregorian-diary-listing-hook)) 2128 nongregorian-diary-listing-hook))
2129 (require 'cal-islam) 2129 (require 'cal-islam)
2130 (diary-font-lock-date-forms 2130 (diary-font-lock-date-forms
2131 calendar-islamic-month-name-array islamic-diary-entry-symbol)) 2131 calendar-islamic-month-name-array islamic-diary-entry-symbol))
2132 (when (or (memq 'diary-bahai-mark-entries 2132 (when (or (memq 'diary-bahai-mark-entries
2133 nongregorian-diary-marking-hook) 2133 nongregorian-diary-marking-hook)
2134 (memq 'diary-bahai-list-entries 2134 (memq 'diary-bahai-list-entries
2135 nongregorian-diary-marking-hook)) 2135 nongregorian-diary-marking-hook))
2136 (require 'cal-bahai) 2136 (require 'cal-bahai)
2137 (diary-font-lock-date-forms 2137 (diary-font-lock-date-forms
2138 calendar-bahai-month-name-array bahai-diary-entry-symbol)) 2138 calendar-bahai-month-name-array bahai-diary-entry-symbol))
2139 (list 2139 (list
2140 (cons 2140 (cons
2141 (format "^%s.*$" (regexp-quote diary-include-string)) 2141 (format "^%s.*$" (regexp-quote diary-include-string))
2142 'font-lock-keyword-face) 2142 'font-lock-keyword-face)
2143 (cons 2143 (cons
2144 (format "^%s?\\(%s\\)" (regexp-quote diary-nonmarking-symbol) 2144 (format "^%s?\\(%s\\)" (regexp-quote diary-nonmarking-symbol)
2145 (regexp-quote sexp-diary-entry-symbol)) 2145 (regexp-quote sexp-diary-entry-symbol))
2146 '(1 font-lock-reference-face)) 2146 '(1 font-lock-reference-face))
2147 (cons 2147 (cons
2148 (format "^%s" (regexp-quote diary-nonmarking-symbol)) 2148 (format "^%s" (regexp-quote diary-nonmarking-symbol))
2149 'font-lock-reference-face) 2149 'font-lock-reference-face)
2150 (cons 2150 (cons
2151 (format "^%s?%s" (regexp-quote diary-nonmarking-symbol) 2151 (format "^%s?%s" (regexp-quote diary-nonmarking-symbol)
2152 (regexp-opt (mapcar 'regexp-quote 2152 (regexp-opt (mapcar 'regexp-quote
2153 (list hebrew-diary-entry-symbol 2153 (list hebrew-diary-entry-symbol
2154 islamic-diary-entry-symbol 2154 islamic-diary-entry-symbol
2155 bahai-diary-entry-symbol)) 2155 bahai-diary-entry-symbol))
2156 t)) 2156 t))
2157 '(1 font-lock-reference-face)) 2157 '(1 font-lock-reference-face))
2158 '(diary-font-lock-sexps . font-lock-keyword-face) 2158 '(diary-font-lock-sexps . font-lock-keyword-face)
2159 `(,(format "\\(^\\|\\s-\\)%s\\(-%s\\)?" diary-time-regexp 2159 `(,(format "\\(^\\|\\s-\\)%s\\(-%s\\)?" diary-time-regexp
2160 diary-time-regexp) 2160 diary-time-regexp)
2161 . 'diary-time)))) 2161 . 'diary-time))))
2162 2162
2163 (defvar diary-font-lock-keywords (diary-font-lock-keywords) 2163 (defvar diary-font-lock-keywords (diary-font-lock-keywords)
2164 "Forms to highlight in `diary-mode'.") 2164 "Forms to highlight in `diary-mode'.")
2165 2165
2182 Arg TEST-ONLY non-nil means return non-nil if and only if the 2182 Arg TEST-ONLY non-nil means return non-nil if and only if the
2183 message contains an appointment, don't make a diary entry." 2183 message contains an appointment, don't make a diary entry."
2184 (catch 'finished 2184 (catch 'finished
2185 (let (format-string) 2185 (let (format-string)
2186 (dotimes (i (length diary-outlook-formats)) 2186 (dotimes (i (length diary-outlook-formats))
2187 (when (eq 0 (string-match (car (nth i diary-outlook-formats)) 2187 (when (eq 0 (string-match (car (nth i diary-outlook-formats))
2188 body)) 2188 body))
2189 (unless test-only 2189 (unless test-only
2190 (setq format-string (cdr (nth i diary-outlook-formats))) 2190 (setq format-string (cdr (nth i diary-outlook-formats)))
2191 (save-excursion 2191 (save-excursion
2192 (save-window-excursion 2192 (save-window-excursion
2193 ;; Fixme: References to optional fields in the format 2193 ;; Fixme: References to optional fields in the format
2194 ;; are treated literally, not replaced by the empty 2194 ;; are treated literally, not replaced by the empty
2195 ;; string. I think this is an Emacs bug. 2195 ;; string. I think this is an Emacs bug.
2196 (make-diary-entry 2196 (make-diary-entry
2197 (format (replace-match (if (functionp format-string) 2197 (format (replace-match (if (functionp format-string)
2198 (funcall format-string body) 2198 (funcall format-string body)
2199 format-string) 2199 format-string)
2200 t nil (match-string 0 body)) 2200 t nil (match-string 0 body))
2201 subject)) 2201 subject))
2202 (save-buffer)))) 2202 (save-buffer))))
2203 (throw 'finished t)))) 2203 (throw 'finished t))))
2204 nil)) 2204 nil))
2205 2205
2206 (defun diary-from-outlook (&optional noconfirm) 2206 (defun diary-from-outlook (&optional noconfirm)
2207 "Maybe snarf diary entry from current Outlook-generated message. 2207 "Maybe snarf diary entry from current Outlook-generated message.
2208 Currently knows about Gnus and Rmail modes. Unless the optional 2208 Currently knows about Gnus and Rmail modes. Unless the optional
2209 argument NOCONFIRM is non-nil (which is the case when this 2209 argument NOCONFIRM is non-nil (which is the case when this
2210 function is called interactively), then if an entry is found the 2210 function is called interactively), then if an entry is found the
2211 user is asked to confirm its addition." 2211 user is asked to confirm its addition."
2212 (interactive "p") 2212 (interactive "p")
2213 (let ((func (cond 2213 (let ((func (cond
2214 ((eq major-mode 'rmail-mode) 2214 ((eq major-mode 'rmail-mode)
2215 #'diary-from-outlook-rmail) 2215 #'diary-from-outlook-rmail)
2216 ((memq major-mode '(gnus-summary-mode gnus-article-mode)) 2216 ((memq major-mode '(gnus-summary-mode gnus-article-mode))
2217 #'diary-from-outlook-gnus) 2217 #'diary-from-outlook-gnus)
2218 (t (error "Don't know how to snarf in `%s'" major-mode))))) 2218 (t (error "Don't know how to snarf in `%s'" major-mode)))))
2219 (funcall func noconfirm))) 2219 (funcall func noconfirm)))
2220 2220
2221 2221
2222 (defvar gnus-article-mime-handles) 2222 (defvar gnus-article-mime-handles)
2223 (defvar gnus-article-buffer) 2223 (defvar gnus-article-buffer)
2234 Add this function to `gnus-article-prepare-hook' to notice appointments 2234 Add this function to `gnus-article-prepare-hook' to notice appointments
2235 automatically." 2235 automatically."
2236 (interactive "p") 2236 (interactive "p")
2237 (with-current-buffer gnus-article-buffer 2237 (with-current-buffer gnus-article-buffer
2238 (let ((subject (gnus-fetch-field "subject")) 2238 (let ((subject (gnus-fetch-field "subject"))
2239 (body (if gnus-article-mime-handles 2239 (body (if gnus-article-mime-handles
2240 ;; We're multipart. Don't get confused by part 2240 ;; We're multipart. Don't get confused by part
2241 ;; buttons &c. Assume info is in first part. 2241 ;; buttons &c. Assume info is in first part.
2242 (mm-get-part (nth 1 gnus-article-mime-handles)) 2242 (mm-get-part (nth 1 gnus-article-mime-handles))
2243 (save-restriction 2243 (save-restriction
2244 (gnus-narrow-to-body) 2244 (gnus-narrow-to-body)
2245 (buffer-string))))) 2245 (buffer-string)))))
2246 (when (diary-from-outlook-internal t) 2246 (when (diary-from-outlook-internal t)
2247 (when (or noconfirm (y-or-n-p "Snarf diary entry? ")) 2247 (when (or noconfirm (y-or-n-p "Snarf diary entry? "))
2248 (diary-from-outlook-internal) 2248 (diary-from-outlook-internal)
2249 (message "Diary entry added")))))) 2249 (message "Diary entry added"))))))
2250 2250
2251 (custom-add-option 'gnus-article-prepare-hook 'diary-from-outlook-gnus) 2251 (custom-add-option 'gnus-article-prepare-hook 'diary-from-outlook-gnus)
2252 2252
2253 2253
2254 (defvar rmail-buffer) 2254 (defvar rmail-buffer)
2259 this function is called interactively), then if an entry is found the 2259 this function is called interactively), then if an entry is found the
2260 user is asked to confirm its addition." 2260 user is asked to confirm its addition."
2261 (interactive "p") 2261 (interactive "p")
2262 (with-current-buffer rmail-buffer 2262 (with-current-buffer rmail-buffer
2263 (let ((subject (mail-fetch-field "subject")) 2263 (let ((subject (mail-fetch-field "subject"))
2264 (body (buffer-substring (save-excursion 2264 (body (buffer-substring (save-excursion
2265 (rfc822-goto-eoh) 2265 (rfc822-goto-eoh)
2266 (point)) 2266 (point))
2267 (point-max)))) 2267 (point-max))))
2268 (when (diary-from-outlook-internal t) 2268 (when (diary-from-outlook-internal t)
2269 (when (or noconfirm (y-or-n-p "Snarf diary entry? ")) 2269 (when (or noconfirm (y-or-n-p "Snarf diary entry? "))
2270 (diary-from-outlook-internal) 2270 (diary-from-outlook-internal)
2271 (message "Diary entry added")))))) 2271 (message "Diary entry added"))))))
2272 2272
2273 2273
2274 (provide 'diary-lib) 2274 (provide 'diary-lib)
2275 2275
2276 ;; arch-tag: 22dd506e-2e33-410d-9ae1-095a0c1b2010 2276 ;; arch-tag: 22dd506e-2e33-410d-9ae1-095a0c1b2010