Update copyright notices for 2013.
[bpt/emacs.git] / lisp / calendar / diary-lib.el
index f21247e..f4aa26a 100644 (file)
@@ -1,7 +1,7 @@
 ;;; diary-lib.el --- diary functions
 
-;; Copyright (C) 1989-1990, 1992-1995, 2001-2011
-;;   Free Software Foundation, Inc.
+;; Copyright (C) 1989-1990, 1992-1995, 2001-2013 Free Software
+;; Foundation, Inc.
 
 ;; Author: Edward M. Reingold <reingold@cs.uiuc.edu>
 ;; Maintainer: Glenn Morris <rgm@gnu.org>
@@ -147,7 +147,7 @@ See the documentation for the function `diary-list-sexp-entries'."
 Nil means there are no comments.  The diary does not display
 parts of entries that are inside comments.  You can use comments
 for whatever you like, e.g. for meta-data that packages such as
-`appt.el' can use.  Comments may not span mutliple lines, and there
+`appt.el' can use.  Comments may not span multiple lines, and there
 can be only one comment on any line.
 See also `diary-comment-end'."
   :version "24.1"
@@ -200,19 +200,21 @@ holidays), or hard copy output."
   'diary-list-entries-hook "23.1")
 
 (defcustom diary-list-entries-hook nil
-  "List of functions called after diary file is culled for relevant entries.
-You might wish to add `diary-include-other-diary-files', in which case
-you will probably also want to add `diary-mark-included-diary-files' to
-`diary-mark-entries-hook'.  For example, you could use
+  "Hook run after diary file is culled for relevant entries.
+
+If you add `diary-include-other-diary-files' to this hook, you
+will probably also want to add `diary-mark-included-diary-files'
+to `diary-mark-entries-hook'.  For example, to cause the fancy
+diary buffer to be displayed with diary entries from various
+included files, each day's entries sorted into lexicographic
+order, add the following to your init file:
 
      (setq diary-display-function 'diary-fancy-display)
      (add-hook 'diary-list-entries-hook 'diary-include-other-diary-files)
      (add-hook 'diary-list-entries-hook 'diary-sort-entries t)
 
-in your `.emacs' file to cause the fancy diary buffer to be displayed with
-diary entries from various included files, each day's entries sorted into
-lexicographic order.  Note how the sort function is placed last,
-so that it can sort the entries included from other files.
+Note how the sort function is placed last, so that it can sort
+the entries included from other files.
 
 This hook runs after `diary-nongregorian-listing-hook'.  These two hooks
 differ only if you are using included diary files.  In that case,
@@ -337,7 +339,7 @@ expressions that can involve the keywords `days' (a number), `date'
 
 (defcustom diary-abbreviated-year-flag t
   "Interpret a two-digit year DD in a diary entry as either 19DD or 20DD.
-This applies to the Gregorian, Hebrew, Islamic, and Baha'i calendars.
+This applies to the Gregorian, Hebrew, Islamic, and Bahá'í calendars.
 When the current century is added to a two-digit year, if the result
 is more than 50 years in the future, the previous century is assumed.
 If the result is more than 50 years in the past, the next century is assumed.
@@ -442,8 +444,7 @@ The format of the header is specified by `diary-header-line-format'."
 (defcustom diary-header-line-format
   '(:eval (calendar-string-spread
            (list (if diary-selective-display
-                     "Some text is hidden - press \"s\" in calendar \
-before edit/copy"
+                     "Some text is hidden - press \"C-c C-s\" before edit/copy"
                    "Diary"))
            ?\s (window-width)))
   "Format of the header line displayed by `diary-simple-display'.
@@ -532,7 +533,7 @@ If so, return the expanded file name, otherwise signal an error."
   "Generate the diary window for ARG days starting with the current date.
 If no argument is provided, the number of days of diary entries is governed
 by the variable `diary-number-of-entries'.  A value of ARG less than 1
-does nothing.  This function is suitable for execution in a `.emacs' file."
+does nothing.  This function is suitable for execution in an init file."
   (interactive "P")
   (diary-check-diary-file)
   (diary-list-entries (calendar-current-date)
@@ -776,7 +777,8 @@ of the appropriate type."
   (goto-char (point-min)))
 
 (defvar diary-included-files nil
-  "List of any diary files included in the last call to `diary-list-entries'.")
+  "List of any diary files included in the last call to `diary-list-entries'.
+Or to `diary-mark-entries'.")
 
 (defun diary-list-entries (date number &optional list-only)
   "Create and display a buffer containing the relevant lines in `diary-file'.
@@ -832,7 +834,7 @@ LIST-ONLY is non-nil, in which case it just returns the list."
     (let* ((original-date date)    ; save for possible use in the hooks
            (date-string (calendar-date-string date))
            (diary-buffer (find-buffer-visiting diary-file))
-           ;; Dynamically bound in diary-include-other-diary-files.
+           ;; Dynamically bound in diary-include-files.
            (d-incp (and (boundp 'diary-including) diary-including))
            diary-entries-list file-glob-attrs temp-buff)
       (unless d-incp
@@ -921,19 +923,20 @@ LIST-ONLY is non-nil, in which case it just returns the list."
 (defvar original-date)                  ; bound in diary-list-entries
 ;(defvar number)                         ; already declared above
 
-(defun diary-include-other-diary-files ()
-  "Add diary entries from included diary files to `diary-entries-list'.
+(defun diary-include-files (&optional mark)
+  "Process diary entries from included diary files.
+By default, lists included entries, but if optional argument MARK is non-nil
+marks entries instead.
 For example, this enables you to share common diary files.
-To use, add this function to `diary-list-entries-hook'.
 Specify include files using lines matching `diary-include-string', e.g.
     #include \"filename\"
-This is recursive; that is, included files may include other files.
-See also `diary-mark-included-diary-files'."
+This is recursive; that is, included files may include other files."
   (goto-char (point-min))
   (while (re-search-forward
           (format "^%s \"\\([^\"]*\\)\"" (regexp-quote diary-include-string))
           nil t)
     (let ((diary-file (match-string-no-properties 1))
+          (diary-mark-entries-hook 'diary-mark-included-diary-files)
           (diary-list-entries-hook 'diary-include-other-diary-files)
           (diary-including t)
           diary-hook diary-list-include-blanks efile)
@@ -943,18 +946,27 @@ See also `diary-mark-included-diary-files'."
                           diary-included-files)
                   (error "Recursive diary include for %s" diary-file)
                 (setq diary-included-files
-                      (append diary-included-files (list efile))
-                      diary-entries-list
-                      (append diary-entries-list
-                              (diary-list-entries original-date number t))))
-            (beep)
-            (message "Can't read included diary file %s" diary-file)
-            (sleep-for 2))
-        (beep)
-        (message "Can't find included diary file %s" diary-file)
-        (sleep-for 2))))
+                      (append diary-included-files (list efile)))
+                (if mark
+                    (diary-mark-entries)
+                  (setq diary-entries-list
+                        (append diary-entries-list
+                                (diary-list-entries original-date number t)))))
+            (display-warning
+             :error
+             (format "Can't read included diary file %s\n" diary-file)))
+        (display-warning
+         :error
+         (format "Can't find included diary file %s\n" diary-file)))))
   (goto-char (point-min)))
 
+(defun diary-include-other-diary-files ()
+  "Add diary entries from included diary files to `diary-entries-list'.
+To use, add this function to `diary-list-entries-hook'.
+For details, see `diary-include-files'.
+See also `diary-mark-included-diary-files'."
+  (diary-include-files))
+
 (define-obsolete-function-alias 'include-other-diary-files
   'diary-include-other-diary-files "23.1")
 
@@ -1219,8 +1231,8 @@ Mail is sent to the address specified by `diary-mail-addr'.
 
 Here is an example of a script to call `diary-mail-entries',
 suitable for regular scheduling using cron (or at).  Note that
-since `emacs -script' does not load your `.emacs' file, you
-should ensure that all relevant variables are set.
+since `emacs -script' does not load your init file, you should
+ensure that all relevant variables are set.
 
 #!/usr/bin/emacs -script
 ;; diary-rem.el - run the Emacs diary-reminder
@@ -1405,22 +1417,37 @@ marks.  This is intended to deal with deleted diary entries."
     (setq calendar-mark-diary-entries-flag nil)
     (calendar-redraw))
   (let ((diary-marking-entries-flag t)
-        file-glob-attrs)
-    (with-current-buffer (find-file-noselect (diary-check-diary-file) t)
-      (save-excursion
-        (when (eq major-mode (default-value 'major-mode)) (diary-mode))
-        (setq calendar-mark-diary-entries-flag t)
-        (message "Marking diary entries...")
-        (setq file-glob-attrs (nth 1 (diary-pull-attrs nil '())))
-        (with-syntax-table diary-syntax-table
-          (diary-mark-entries-1 'calendar-mark-date-pattern)
-          (diary-mark-sexp-entries)
-          ;; Although it looks like mark-entries-hook runs every time,
-          ;; diary-mark-included-diary-files binds it to nil
-          ;; (essentially) when it runs in included files.
-          (run-hooks 'diary-nongregorian-marking-hook
-                     'diary-mark-entries-hook))
-        (message "Marking diary entries...done")))))
+        (diary-buffer (find-buffer-visiting diary-file))
+        ;; Dynamically bound in diary-include-files.
+        (d-incp (and (boundp 'diary-including) diary-including))
+        file-glob-attrs temp-buff)
+    (unless d-incp
+      (setq diary-included-files nil)
+      (message "Marking diary entries..."))
+    (unwind-protect
+        (with-current-buffer (or diary-buffer
+                                 (if d-incp
+                                     (setq temp-buff (generate-new-buffer
+                                                        " *diary-temp*"))
+                                   (find-file-noselect
+                                    (diary-check-diary-file) t)))
+          (if temp-buff
+              ;; If including, caller has already verified it is readable.
+              (insert-file-contents diary-file)
+            (if (eq major-mode (default-value 'major-mode)) (diary-mode)))
+          (setq calendar-mark-diary-entries-flag t)
+          (setq file-glob-attrs (nth 1 (diary-pull-attrs nil '())))
+          (with-syntax-table diary-syntax-table
+            (save-excursion
+              (diary-mark-entries-1 'calendar-mark-date-pattern)
+              (diary-mark-sexp-entries)
+              ;; Although it looks like mark-entries-hook runs every time,
+              ;; diary-mark-included-diary-files binds it to nil
+              ;; (essentially) when it runs in included files.
+              (run-hooks 'diary-nongregorian-marking-hook
+                         'diary-mark-entries-hook))))
+      (and temp-buff (buffer-name temp-buff) (kill-buffer temp-buff)))
+    (or d-incp (message "Marking diary entries...done"))))
 
 ;;;###cal-autoload
 (define-obsolete-function-alias 'mark-diary-entries 'diary-mark-entries "23.1")
@@ -1430,14 +1457,17 @@ marks.  This is intended to deal with deleted diary entries."
   (let ((result (if calendar-debug-sexp
                     (let ((debug-on-error t))
                       (eval (car (read-from-string sexp))))
-                  (condition-case nil
-                      (eval (car (read-from-string sexp)))
-                    (error
-                     (beep)
-                     (message "Bad sexp at line %d in %s: %s"
-                              (count-lines (point-min) (point))
-                              diary-file sexp)
-                     (sleep-for 2))))))
+                  (let (err)
+                    (condition-case err
+                        (eval (car (read-from-string sexp)))
+                      (error
+                       (display-warning
+                        :error
+                        (format "Bad diary sexp at line %d in %s:\n%s\n\
+Error: %s\n"
+                                (count-lines (point-min) (point))
+                                diary-file sexp err))
+                       nil))))))
     (cond ((stringp result) result)
           ((and (consp result)
                 (stringp (cdr result))) result)
@@ -1504,32 +1534,10 @@ is marked.  See the documentation for the function `diary-list-sexp-entries'."
 
 (defun diary-mark-included-diary-files ()
   "Mark diary entries from included diary files.
-For example, this enables you to share common diary files.
 To use, add this function to `diary-mark-entries-hook'.
-Specify include files using lines matching `diary-include-string', e.g.
-    #include \"filename\"
-This is recursive; that is, included files may include other files.
+For details, see `diary-include-files'.
 See also `diary-include-other-diary-files'."
-  (goto-char (point-min))
-  (while (re-search-forward
-          (format "^%s \"\\([^\"]*\\)\"" (regexp-quote diary-include-string))
-          nil t)
-    (let* ((diary-file (match-string-no-properties 1))
-           (diary-mark-entries-hook 'diary-mark-included-diary-files)
-           (dbuff (find-buffer-visiting diary-file)))
-      (if (file-exists-p diary-file)
-          (if (file-readable-p diary-file)
-              (progn
-                (diary-mark-entries)
-                (unless dbuff
-                  (kill-buffer (find-buffer-visiting diary-file))))
-            (beep)
-            (message "Can't read included diary file %s" diary-file)
-            (sleep-for 2))
-        (beep)
-        (message "Can't find included diary file %s" diary-file)
-        (sleep-for 2))))
-  (goto-char (point-min)))
+  (diary-include-files t))
 
 (define-obsolete-function-alias 'mark-included-diary-files
   'diary-mark-included-diary-files "23.1")
@@ -2391,10 +2399,10 @@ return a font-lock pattern matching array of MONTHS and marking SYMBOL."
     (cons
      (format "^%s?\\(%s\\)" (regexp-quote diary-nonmarking-symbol)
              (regexp-quote diary-sexp-entry-symbol))
-     '(1 font-lock-reference-face))
+     '(1 font-lock-constant-face))
     (cons
      (format "^%s" (regexp-quote diary-nonmarking-symbol))
-     'font-lock-reference-face)
+     'font-lock-constant-face)
     (cons
      (format "^%s?%s" (regexp-quote diary-nonmarking-symbol)
              (regexp-opt (mapcar 'regexp-quote
@@ -2402,7 +2410,7 @@ return a font-lock pattern matching array of MONTHS and marking SYMBOL."
                                        diary-islamic-entry-symbol
                                        diary-bahai-entry-symbol))
                          t))
-     '(1 font-lock-reference-face))
+     '(1 font-lock-constant-face))
     '(diary-font-lock-sexps . font-lock-keyword-face)
     ;; Don't need to worry about space around "-" because the first
     ;; match takes care of that.  It does mean the "-" itself may or
@@ -2473,7 +2481,7 @@ This depends on the calendar date style."
 (defvar diary-fancy-font-lock-keywords
   `((diary-fancy-date-matcher . diary-face)
     ("^.*\\([aA]nniversary\\|[bB]irthday\\).*$" . 'diary-anniversary)
-    ("^.*Yahrzeit.*$" . font-lock-reference-face)
+    ("^.*Yahrzeit.*$" . font-lock-constant-face)
     ("^\\(Erev \\)?Rosh Hodesh.*" . font-lock-function-name-face)
     ("^Day.*omer.*$" . font-lock-builtin-face)
     ("^Parashat.*$" . font-lock-comment-face)
@@ -2620,4 +2628,8 @@ user is asked to confirm its addition."
 
 (provide 'diary-lib)
 
+;; Local Variables:
+;; coding: utf-8
+;; End:
+
 ;;; diary-lib.el ends here