comparison lisp/calendar/diary-lib.el @ 90228:fa0da9b57058

Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-82 Merge from emacs--cvs-trunk--0 Patches applied: * emacs--cvs-trunk--0 (patch 542-553) - Update from CVS - Merge from gnus--rel--5.10 * gnus--rel--5.10 (patch 116-121) - Merge from emacs--cvs-trunk--0 - Update from CVS
author Miles Bader <miles@gnu.org>
date Mon, 19 Sep 2005 10:20:33 +0000
parents 2d92f5c9d6ae 23bf1a7921e0
children ee12d75eb214
comparison
equal deleted inserted replaced
90227:10fe5fadaf89 90228:fa0da9b57058
56 by the variable `number-of-diary-entries'. A value of ARG less than 1 56 by the variable `number-of-diary-entries'. A value of ARG less than 1
57 does nothing. This function is suitable for execution in a `.emacs' file." 57 does nothing. This function is suitable for execution in a `.emacs' file."
58 (interactive "P") 58 (interactive "P")
59 (diary-check-diary-file) 59 (diary-check-diary-file)
60 (let ((date (calendar-current-date))) 60 (let ((date (calendar-current-date)))
61 (list-diary-entries 61 (diary-list-entries date (if arg (prefix-numeric-value arg)))))
62 date 62
63 (cond (arg (prefix-numeric-value arg)) 63 (define-obsolete-function-alias 'view-diary-entries 'diary-view-entries)
64 ((vectorp number-of-diary-entries) 64 (defun diary-view-entries (&optional arg)
65 (aref number-of-diary-entries (calendar-day-of-week date)))
66 (t number-of-diary-entries)))))
67
68 (defun view-diary-entries (arg)
69 "Prepare and display a buffer with diary entries. 65 "Prepare and display a buffer with diary entries.
70 Searches the file named in `diary-file' for entries that 66 Searches the file named in `diary-file' for entries that
71 match ARG days starting with the date indicated by the cursor position 67 match ARG days starting with the date indicated by the cursor position
72 in the displayed three-month calendar." 68 in the displayed three-month calendar."
73 (interactive "p") 69 (interactive "p")
74 (diary-check-diary-file) 70 (diary-check-diary-file)
75 (list-diary-entries (calendar-cursor-to-date t) arg)) 71 (diary-list-entries (calendar-cursor-to-date t) arg))
76 72
77 (defun view-other-diary-entries (arg d-file) 73 (defun view-other-diary-entries (arg d-file)
78 "Prepare and display buffer of diary entries from an alternative diary file. 74 "Prepare and display buffer of diary entries from an alternative diary file.
79 Searches for entries that match ARG days, starting with the date indicated 75 Searches for entries that match ARG days, starting with the date indicated
80 by the cursor position in the displayed three-month calendar. 76 by the cursor position in the displayed three-month calendar.
180 176
181 (autoload 'diary-sabbath-candles "solar" 177 (autoload 'diary-sabbath-candles "solar"
182 "Local time of candle lighting diary entry--applies if date is a Friday. 178 "Local time of candle lighting diary entry--applies if date is a Friday.
183 No diary entry if there is no sunset on that date.") 179 No diary entry if there is no sunset on that date.")
184 180
185 (defvar diary-syntax-table (copy-syntax-table (standard-syntax-table)) 181 (defvar diary-syntax-table
182 (let ((st (copy-syntax-table (standard-syntax-table))))
183 (modify-syntax-entry ?* "w" st)
184 (modify-syntax-entry ?: "w" st)
185 st)
186 "The syntax table used when parsing dates in the diary file. 186 "The syntax table used when parsing dates in the diary file.
187 It is the standard syntax table used in Fundamental mode, but with the 187 It is the standard syntax table used in Fundamental mode, but with the
188 syntax of `*' and `:' changed to be word constituents.") 188 syntax of `*' and `:' changed to be word constituents.")
189
190 (modify-syntax-entry ?* "w" diary-syntax-table)
191 (modify-syntax-entry ?: "w" diary-syntax-table)
192 189
193 (defvar diary-entries-list) 190 (defvar diary-entries-list)
194 (defvar displayed-year) 191 (defvar displayed-year)
195 (defvar displayed-month) 192 (defvar displayed-month)
196 (defvar entry) 193 (defvar entry)
241 attrname (nth 2 attr) 238 attrname (nth 2 attr)
242 type (nth 3 attr) 239 type (nth 3 attr)
243 regexp (concat diary-glob-file-regexp-prefix regexp)) 240 regexp (concat diary-glob-file-regexp-prefix regexp))
244 (setq attrvalue nil) 241 (setq attrvalue nil)
245 (if (re-search-forward regexp (point-max) t) 242 (if (re-search-forward regexp (point-max) t)
246 (setq attrvalue (buffer-substring-no-properties 243 (setq attrvalue (match-string-no-properties regnum)))
247 (match-beginning regnum)
248 (match-end regnum))))
249 (if (and attrvalue 244 (if (and attrvalue
250 (setq attrvalue (diary-attrtype-convert attrvalue type))) 245 (setq attrvalue (diary-attrtype-convert attrvalue type)))
251 (setq ret-attr (append ret-attr (list attrname attrvalue)))) 246 (setq ret-attr (append ret-attr (list attrname attrvalue))))
252 (setq attr-list (cdr attr-list))) 247 (setq attr-list (cdr attr-list)))
253 (setq fileglobattrs ret-attr)) 248 (setq fileglobattrs ret-attr))
262 attrname (nth 2 attr) 257 attrname (nth 2 attr)
263 type (nth 3 attr)) 258 type (nth 3 attr))
264 (setq attrvalue nil) 259 (setq attrvalue nil)
265 (if (string-match regexp entry) 260 (if (string-match regexp entry)
266 (progn 261 (progn
267 (setq attrvalue (substring-no-properties entry 262 (setq attrvalue (match-string-no-properties regnum entry))
268 (match-beginning regnum)
269 (match-end regnum)))
270 (setq entry (replace-match "" t t entry)))) 263 (setq entry (replace-match "" t t entry))))
271 (if (and attrvalue 264 (if (and attrvalue
272 (setq attrvalue (diary-attrtype-convert attrvalue type))) 265 (setq attrvalue (diary-attrtype-convert attrvalue type)))
273 (setq ret-attr (append ret-attr (list attrname attrvalue)))) 266 (setq ret-attr (append ret-attr (list attrname attrvalue))))
274 (setq attr-list (cdr attr-list))))) 267 (setq attr-list (cdr attr-list)))))
297 :type 'sexp 290 :type 'sexp
298 :version "22.1") 291 :version "22.1")
299 292
300 (defvar diary-saved-point) ; internal 293 (defvar diary-saved-point) ; internal
301 294
302 (defun list-diary-entries (date number) 295
303 "Create and display a buffer containing the relevant lines in diary-file. 296 (defcustom number-of-diary-entries 1
297 "Specifies how many days of diary entries are to be displayed initially.
298 This variable affects the diary display when the command \\[diary] is used,
299 or if the value of the variable `view-diary-entries-initially' is t. For
300 example, if the default value 1 is used, then only the current day's diary
301 entries will be displayed. If the value 2 is used, then both the current
302 day's and the next day's entries will be displayed.
303
304 The value can also be a vector such as [0 2 2 2 2 4 1]; this value
305 says to display no diary entries on Sunday, the display the entries
306 for the current date and the day after on Monday through Thursday,
307 display Friday through Monday's entries on Friday, and display only
308 Saturday's entries on Saturday.
309
310 This variable does not affect the diary display with the `d' command
311 from the calendar; in that case, the prefix argument controls the
312 number of days of diary entries displayed."
313 :type '(choice (integer :tag "Entries")
314 (vector :value [0 0 0 0 0 0 0]
315 (integer :tag "Sunday")
316 (integer :tag "Monday")
317 (integer :tag "Tuesday")
318 (integer :tag "Wednesday")
319 (integer :tag "Thursday")
320 (integer :tag "Friday")
321 (integer :tag "Saturday")))
322 :group 'diary)
323
324 (define-obsolete-function-alias 'list-diary-entries 'diary-list-entries)
325 (defun diary-list-entries (date number)
326 "Create and display a buffer containing the relevant lines in `diary-file'.
304 The arguments are DATE and NUMBER; the entries selected are those 327 The arguments are DATE and NUMBER; the entries selected are those
305 for NUMBER days starting with date DATE. The other entries are hidden 328 for NUMBER days starting with date DATE. The other entries are hidden
306 using selective display. If NUMBER is less than 1, this function does nothing. 329 using selective display. If NUMBER is less than 1, this function does nothing.
307 330
308 Returns a list of all relevant diary entries found, if any, in order by date. 331 Returns a list of all relevant diary entries found, if any, in order by date.
330 fancy-diary-display, if desired. If you want no diary display, use 353 fancy-diary-display, if desired. If you want no diary display, use
331 add-hook to set this to ignore. 354 add-hook to set this to ignore.
332 355
333 `diary-hook' is run last. This can be used for an appointment 356 `diary-hook' is run last. This can be used for an appointment
334 notification function." 357 notification function."
335 358 (unless number
359 (setq number (if (vectorp number-of-diary-entries)
360 (aref number-of-diary-entries (calendar-day-of-week date))
361 number-of-diary-entries)))
336 (when (> number 0) 362 (when (> number 0)
337 (let ((original-date date);; save for possible use in the hooks 363 (let ((original-date date);; save for possible use in the hooks
338 old-diary-syntax-table
339 diary-entries-list 364 diary-entries-list
340 file-glob-attrs 365 file-glob-attrs
341 (date-string (calendar-date-string date)) 366 (date-string (calendar-date-string date))
342 (d-file (substitute-in-file-name diary-file))) 367 (d-file (substitute-in-file-name diary-file)))
343 (message "Preparing diary...") 368 (message "Preparing diary...")
354 (setq file-glob-attrs (nth 1 (diary-pull-attrs nil ""))) 379 (setq file-glob-attrs (nth 1 (diary-pull-attrs nil "")))
355 (setq selective-display t) 380 (setq selective-display t)
356 (setq selective-display-ellipses nil) 381 (setq selective-display-ellipses nil)
357 (if diary-header-line-flag 382 (if diary-header-line-flag
358 (setq header-line-format diary-header-line-format)) 383 (setq header-line-format diary-header-line-format))
359 (setq old-diary-syntax-table (syntax-table)) 384 (with-syntax-table diary-syntax-table
360 (set-syntax-table diary-syntax-table) 385 (let ((buffer-read-only nil)
361 (unwind-protect 386 (diary-modified (buffer-modified-p))
362 (let ((buffer-read-only nil) 387 (mark (regexp-quote diary-nonmarking-symbol)))
363 (diary-modified (buffer-modified-p)) 388 ;; First and last characters must be ^M or \n for
364 (mark (regexp-quote diary-nonmarking-symbol))) 389 ;; selective display to work properly
365 ;; First and last characters must be ^M or \n for 390 (goto-char (1- (point-max)))
366 ;; selective display to work properly 391 (if (not (looking-at "\^M\\|\n"))
367 (goto-char (1- (point-max))) 392 (progn
368 (if (not (looking-at "\^M\\|\n")) 393 (goto-char (point-max))
369 (progn 394 (insert "\^M")))
370 (goto-char (point-max)) 395 (goto-char (point-min))
371 (insert "\^M"))) 396 (if (not (looking-at "\^M\\|\n"))
372 (goto-char (point-min)) 397 (insert "\^M"))
373 (if (not (looking-at "\^M\\|\n")) 398 (subst-char-in-region (point-min) (point-max) ?\n ?\^M t)
374 (insert "\^M")) 399 (calendar-for-loop
375 (subst-char-in-region (point-min) (point-max) ?\n ?\^M t) 400 i from 1 to number do
376 (calendar-for-loop 401 (let ((month (extract-calendar-month date))
377 i from 1 to number do 402 (day (extract-calendar-day date))
378 (let ((d diary-date-forms) 403 (year (extract-calendar-year date))
379 (month (extract-calendar-month date)) 404 (entry-found (list-sexp-diary-entries date)))
380 (day (extract-calendar-day date)) 405 (dolist (date-form diary-date-forms)
381 (year (extract-calendar-year date)) 406 (let*
382 (entry-found (list-sexp-diary-entries date))) 407 ((backup (when (eq (car date-form) 'backup)
383 (while d 408 (setq date-form (cdr date-form))
384 (let* 409 t))
385 ((date-form (if (equal (car (car d)) 'backup) 410 (dayname
386 (cdr (car d)) 411 (format "%s\\|%s\\.?"
387 (car d))) 412 (calendar-day-name date)
388 (backup (equal (car (car d)) 'backup)) 413 (calendar-day-name date 'abbrev)))
389 (dayname 414 (monthname
390 (format "%s\\|%s\\.?" 415 (format "\\*\\|%s\\|%s\\.?"
391 (calendar-day-name date) 416 (calendar-month-name month)
392 (calendar-day-name date 'abbrev))) 417 (calendar-month-name month 'abbrev)))
393 (monthname 418 (month (concat "\\*\\|0*" (int-to-string month)))
394 (format "\\*\\|%s\\|%s\\.?" 419 (day (concat "\\*\\|0*" (int-to-string day)))
395 (calendar-month-name month) 420 (year
396 (calendar-month-name month 'abbrev))) 421 (concat
397 (month (concat "\\*\\|0*" (int-to-string month))) 422 "\\*\\|0*" (int-to-string year)
398 (day (concat "\\*\\|0*" (int-to-string day))) 423 (if abbreviated-calendar-year
399 (year 424 (concat "\\|" (format "%02d" (% year 100)))
400 (concat 425 "")))
401 "\\*\\|0*" (int-to-string year) 426 (regexp
402 (if abbreviated-calendar-year 427 (concat
403 (concat "\\|" (format "%02d" (% year 100))) 428 "\\(\\`\\|\^M\\|\n\\)" mark "?\\("
404 ""))) 429 (mapconcat 'eval date-form "\\)\\(")
405 (regexp 430 "\\)"))
406 (concat 431 (case-fold-search t))
407 "\\(\\`\\|\^M\\|\n\\)" mark "?\\(" 432 (goto-char (point-min))
408 (mapconcat 'eval date-form "\\)\\(") 433 (while (re-search-forward regexp nil t)
409 "\\)")) 434 (if backup (re-search-backward "\\<" nil t))
410 (case-fold-search t)) 435 (if (and (or (char-equal (preceding-char) ?\^M)
411 (goto-char (point-min)) 436 (char-equal (preceding-char) ?\n))
412 (while (re-search-forward regexp nil t) 437 (not (looking-at " \\|\^I")))
413 (if backup (re-search-backward "\\<" nil t)) 438 ;; Diary entry that consists only of date.
414 (if (and (or (char-equal (preceding-char) ?\^M) 439 (backward-char 1)
415 (char-equal (preceding-char) ?\n)) 440 ;; Found a nonempty diary entry--make it
416 (not (looking-at " \\|\^I"))) 441 ;; visible and add it to the list.
417 ;; Diary entry that consists only of date. 442 (setq entry-found t)
418 (backward-char 1) 443 (let ((entry-start (point))
419 ;; Found a nonempty diary entry--make it 444 date-start temp)
420 ;; visible and add it to the list. 445 (re-search-backward "\^M\\|\n\\|\\`")
421 (setq entry-found t) 446 (setq date-start (point))
422 (let ((entry-start (point)) 447 (re-search-forward "\^M\\|\n" nil t 2)
423 date-start temp) 448 (while (looking-at " \\|\^I")
424 (re-search-backward "\^M\\|\n\\|\\`") 449 (re-search-forward "\^M\\|\n" nil t))
425 (setq date-start (point)) 450 (backward-char 1)
426 (re-search-forward "\^M\\|\n" nil t 2) 451 (subst-char-in-region date-start
427 (while (looking-at " \\|\^I") 452 (point) ?\^M ?\n t)
428 (re-search-forward "\^M\\|\n" nil t)) 453 (setq entry (buffer-substring entry-start (point))
429 (backward-char 1) 454 temp (diary-pull-attrs entry file-glob-attrs)
430 (subst-char-in-region date-start 455 entry (nth 0 temp))
431 (point) ?\^M ?\n t) 456 (add-to-diary-list
432 (setq entry (buffer-substring entry-start (point)) 457 date
433 temp (diary-pull-attrs entry file-glob-attrs) 458 entry
434 entry (nth 0 temp)) 459 (buffer-substring
435 (add-to-diary-list 460 (1+ date-start) (1- entry-start))
436 date 461 (copy-marker entry-start) (nth 1 temp)))))))
437 entry 462 (or entry-found
438 (buffer-substring 463 (not diary-list-include-blanks)
439 (1+ date-start) (1- entry-start)) 464 (setq diary-entries-list
440 (copy-marker entry-start) (nth 1 temp)))))) 465 (append diary-entries-list
441 (setq d (cdr d))) 466 (list (list date "" "" "" "")))))
442 (or entry-found 467 (setq date
443 (not diary-list-include-blanks) 468 (calendar-gregorian-from-absolute
444 (setq diary-entries-list 469 (1+ (calendar-absolute-from-gregorian date))))
445 (append diary-entries-list 470 (setq entry-found nil)))
446 (list (list date "" "" "" ""))))) 471 (set-buffer-modified-p diary-modified)))
447 (setq date
448 (calendar-gregorian-from-absolute
449 (1+ (calendar-absolute-from-gregorian date))))
450 (setq entry-found nil)))
451 (set-buffer-modified-p diary-modified))
452 (set-syntax-table old-diary-syntax-table))
453 (goto-char (point-min)) 472 (goto-char (point-min))
454 (run-hooks 'nongregorian-diary-listing-hook 473 (run-hooks 'nongregorian-diary-listing-hook
455 'list-diary-entries-hook) 474 'list-diary-entries-hook)
456 (if diary-display-hook 475 (if diary-display-hook
457 (run-hooks 'diary-display-hook) 476 (run-hooks 'diary-display-hook)
458 (simple-diary-display)) 477 (simple-diary-display))
459 (run-hooks 'diary-hook) 478 (run-hooks 'diary-hook)
460 diary-entries-list)))))) 479 diary-entries-list))))))
480
481 (defun diary-unhide-everything ()
482 (setq selective-display nil)
483 (let ((inhibit-read-only t)
484 (modified (buffer-modified-p)))
485 (subst-char-in-region (point-min) (point-max) ?\^M ?\n t)
486 (set-buffer-modified-p modified))
487 (kill-local-variable 'mode-line-format))
461 488
462 (defun include-other-diary-files () 489 (defun include-other-diary-files ()
463 "Include the diary entries from other diary files with those of diary-file. 490 "Include the diary entries from other diary files with those of diary-file.
464 This function is suitable for use in `list-diary-entries-hook'; 491 This function is suitable for use in `list-diary-entries-hook';
465 it enables you to use shared diary files together with your own. 492 it enables you to use shared diary files together with your own.
469 are obeyed. You can change the `#include' to some other string by 496 are obeyed. You can change the `#include' to some other string by
470 changing the variable `diary-include-string'." 497 changing the variable `diary-include-string'."
471 (goto-char (point-min)) 498 (goto-char (point-min))
472 (while (re-search-forward 499 (while (re-search-forward
473 (concat 500 (concat
474 "\\(\\`\\|\^M\\|\n\\)" 501 "\\(?:\\`\\|\^M\\|\n\\)"
475 (regexp-quote diary-include-string) 502 (regexp-quote diary-include-string)
476 " \"\\([^\"]*\\)\"") 503 " \"\\([^\"]*\\)\"")
477 nil t) 504 nil t)
478 (let* ((diary-file (substitute-in-file-name 505 (let* ((diary-file (substitute-in-file-name
479 (buffer-substring-no-properties 506 (match-string-no-properties 1)))
480 (match-beginning 2) (match-end 2))))
481 (diary-list-include-blanks nil) 507 (diary-list-include-blanks nil)
482 (list-diary-entries-hook 'include-other-diary-files) 508 (list-diary-entries-hook 'include-other-diary-files)
483 (diary-display-hook 'ignore) 509 (diary-display-hook 'ignore)
484 (diary-hook nil) 510 (diary-hook nil))
485 (d-buffer (find-buffer-visiting diary-file))
486 (diary-modified (if d-buffer
487 (save-excursion
488 (set-buffer d-buffer)
489 (buffer-modified-p)))))
490 (if (file-exists-p diary-file) 511 (if (file-exists-p diary-file)
491 (if (file-readable-p diary-file) 512 (if (file-readable-p diary-file)
492 (unwind-protect 513 (unwind-protect
493 (setq diary-entries-list 514 (setq diary-entries-list
494 (append diary-entries-list 515 (append diary-entries-list
495 (list-diary-entries original-date number))) 516 (list-diary-entries original-date number)))
496 (save-excursion 517 (with-current-buffer (find-buffer-visiting diary-file)
497 (set-buffer (find-buffer-visiting diary-file)) 518 (diary-unhide-everything)))
498 (let ((inhibit-read-only t))
499 (subst-char-in-region (point-min) (point-max) ?\^M ?\n t))
500 (setq selective-display nil)
501 (set-buffer-modified-p diary-modified)))
502 (beep) 519 (beep)
503 (message "Can't read included diary file %s" diary-file) 520 (message "Can't read included diary file %s" diary-file)
504 (sleep-for 2)) 521 (sleep-for 2))
505 (beep) 522 (beep)
506 (message "Can't find included diary file %s" diary-file) 523 (message "Can't find included diary file %s" diary-file)
562 (goto-char (marker-position marker))))) 579 (goto-char (marker-position marker)))))
563 580
564 (defun fancy-diary-display () 581 (defun fancy-diary-display ()
565 "Prepare a diary buffer with relevant entries in a fancy, noneditable form. 582 "Prepare a diary buffer with relevant entries in a fancy, noneditable form.
566 This function is provided for optional use as the `diary-display-hook'." 583 This function is provided for optional use as the `diary-display-hook'."
567 (save-excursion;; Turn off selective-display in the diary file's buffer. 584 (with-current-buffer ;; Turn off selective-display in the diary file's buffer.
568 (set-buffer (find-buffer-visiting (substitute-in-file-name diary-file))) 585 (find-buffer-visiting (substitute-in-file-name diary-file))
569 (let ((diary-modified (buffer-modified-p))) 586 (diary-unhide-everything))
570 (subst-char-in-region (point-min) (point-max) ?\^M ?\n t)
571 (setq selective-display nil)
572 (kill-local-variable 'mode-line-format)
573 (set-buffer-modified-p diary-modified)))
574 (if (or (not diary-entries-list) 587 (if (or (not diary-entries-list)
575 (and (not (cdr diary-entries-list)) 588 (and (not (cdr diary-entries-list))
576 (string-equal (car (cdr (car diary-entries-list))) ""))) 589 (string-equal (car (cdr (car diary-entries-list))) "")))
577 (let* ((holiday-list (if holidays-in-diary-buffer 590 (let* ((holiday-list (if holidays-in-diary-buffer
578 (check-calendar-holidays original-date))) 591 (check-calendar-holidays original-date)))
738 (make-string (length heading) ?=) "\n") 751 (make-string (length heading) ?=) "\n")
739 (run-hooks 'print-diary-entries-hook) 752 (run-hooks 'print-diary-entries-hook)
740 (kill-buffer temp-buffer))) 753 (kill-buffer temp-buffer)))
741 (error "You don't have a diary buffer!"))))) 754 (error "You don't have a diary buffer!")))))
742 755
743 (defun show-all-diary-entries () 756 (define-obsolete-function-alias 'show-all-diary-entries 'diary-show-all-entries)
757 (defun diary-show-all-entries ()
744 "Show all of the diary entries in the diary file. 758 "Show all of the diary entries in the diary file.
745 This function gets rid of the selective display of the diary file so that 759 This function gets rid of the selective display of the diary file so that
746 all entries, not just some, are visible. If there is no diary buffer, one 760 all entries, not just some, are visible. If there is no diary buffer, one
747 is created." 761 is created."
748 (interactive) 762 (interactive)
749 (let ((d-file (diary-check-diary-file)) 763 (let ((d-file (diary-check-diary-file))
750 (pop-up-frames (window-dedicated-p (selected-window)))) 764 (pop-up-frames (window-dedicated-p (selected-window))))
751 (save-excursion 765 (with-current-buffer (or (find-buffer-visiting d-file)
752 (set-buffer (or (find-buffer-visiting d-file) 766 (find-file-noselect d-file t))
753 (find-file-noselect d-file t))) 767 (diary-unhide-everything)
754 (let ((buffer-read-only nil) 768 (display-buffer (current-buffer)))))
755 (diary-modified (buffer-modified-p)))
756 (subst-char-in-region (point-min) (point-max) ?\^M ?\n t)
757 (setq selective-display nil
758 mode-line-format default-mode-line-format)
759 (display-buffer (current-buffer))
760 (set-buffer-modified-p diary-modified)))))
761 769
762 (defcustom diary-mail-addr 770 (defcustom diary-mail-addr
763 (if (boundp 'user-mail-address) user-mail-address "") 771 (if (boundp 'user-mail-address) user-mail-address "")
764 "*Email address that `diary-mail-entries' will send email to." 772 "*Email address that `diary-mail-entries' will send email to."
765 :group 'diary 773 :group 'diary
805 (compose-mail diary-mail-addr 813 (compose-mail diary-mail-addr
806 (concat "Diary entries generated " 814 (concat "Diary entries generated "
807 (calendar-date-string (calendar-current-date)))) 815 (calendar-date-string (calendar-current-date))))
808 (insert 816 (insert
809 (if (get-buffer fancy-diary-buffer) 817 (if (get-buffer fancy-diary-buffer)
810 (save-excursion 818 (with-current-buffer fancy-diary-buffer (buffer-string))
811 (set-buffer fancy-diary-buffer)
812 (buffer-substring (point-min) (point-max)))
813 "No entries found")) 819 "No entries found"))
814 (call-interactively (get mail-user-agent 'sendfunc)))) 820 (call-interactively (get mail-user-agent 'sendfunc))))
815 821
816 (defun diary-name-pattern (string-array &optional abbrev-array paren) 822 (defun diary-name-pattern (string-array &optional abbrev-array paren)
817 "Return a regexp matching the strings in the array STRING-ARRAY. 823 "Return a regexp matching the strings in the array STRING-ARRAY.
842 Each entry in the diary file visible in the calendar window is 848 Each entry in the diary file visible in the calendar window is
843 marked. After the entries are marked, the hooks 849 marked. After the entries are marked, the hooks
844 `nongregorian-diary-marking-hook' and `mark-diary-entries-hook' 850 `nongregorian-diary-marking-hook' and `mark-diary-entries-hook'
845 are run. If the optional argument REDRAW is non-nil (which is 851 are run. If the optional argument REDRAW is non-nil (which is
846 the case interactively, for example) then any existing diary 852 the case interactively, for example) then any existing diary
847 marks are first removed. This is intended to deal with deleted 853 marks are first removed. This is intended to deal with deleted
848 diary entries." 854 diary entries."
849 (interactive "p") 855 (interactive "p")
850 ;; To remove any deleted diary entries. Do not redraw when: 856 ;; To remove any deleted diary entries. Do not redraw when:
851 ;; i) processing #include diary files (else only get the marks from 857 ;; i) processing #include diary files (else only get the marks from
852 ;; the last #include file processed). 858 ;; the last #include file processed).
857 (setq mark-diary-entries-in-calendar nil) 863 (setq mark-diary-entries-in-calendar nil)
858 (redraw-calendar)) 864 (redraw-calendar))
859 (let ((marking-diary-entries t) 865 (let ((marking-diary-entries t)
860 file-glob-attrs marks) 866 file-glob-attrs marks)
861 (save-excursion 867 (save-excursion
862 (set-buffer (find-file-noselect (diary-check-diary-file) t)) 868 (with-current-buffer (find-file-noselect (diary-check-diary-file) t)
863 (setq mark-diary-entries-in-calendar t) 869 (setq mark-diary-entries-in-calendar t)
864 (message "Marking diary entries...") 870 (message "Marking diary entries...")
865 (setq file-glob-attrs (nth 1 (diary-pull-attrs nil '()))) 871 (setq file-glob-attrs (nth 1 (diary-pull-attrs nil '())))
866 (let ((d diary-date-forms) 872 (with-syntax-table diary-syntax-table
867 (old-diary-syntax-table (syntax-table)) 873 (dolist (date-form diary-date-forms)
868 temp) 874 (if (eq (car date-form) 'backup)
869 (set-syntax-table diary-syntax-table) 875 (setq date-form (cdr date-form))) ;; ignore 'backup directive
870 (while d 876 (let* ((dayname
871 (let* ((date-form (if (equal (car (car d)) 'backup) 877 (diary-name-pattern calendar-day-name-array
872 (cdr (car d)) 878 calendar-day-abbrev-array))
873 (car d)));; ignore 'backup directive 879 (monthname
874 (dayname 880 (format "%s\\|\\*"
875 (diary-name-pattern calendar-day-name-array 881 (diary-name-pattern calendar-month-name-array
876 calendar-day-abbrev-array)) 882 calendar-month-abbrev-array)))
877 (monthname 883 (month "[0-9]+\\|\\*")
878 (format "%s\\|\\*" 884 (day "[0-9]+\\|\\*")
879 (diary-name-pattern calendar-month-name-array 885 (year "[0-9]+\\|\\*")
880 calendar-month-abbrev-array))) 886 (l (length date-form))
881 (month "[0-9]+\\|\\*") 887 (d-name-pos (- l (length (memq 'dayname date-form))))
882 (day "[0-9]+\\|\\*") 888 (d-name-pos (if (/= l d-name-pos) (+ 2 d-name-pos)))
883 (year "[0-9]+\\|\\*") 889 (m-name-pos (- l (length (memq 'monthname date-form))))
884 (l (length date-form)) 890 (m-name-pos (if (/= l m-name-pos) (+ 2 m-name-pos)))
885 (d-name-pos (- l (length (memq 'dayname date-form)))) 891 (d-pos (- l (length (memq 'day date-form))))
886 (d-name-pos (if (/= l d-name-pos) (+ 2 d-name-pos))) 892 (d-pos (if (/= l d-pos) (+ 2 d-pos)))
887 (m-name-pos (- l (length (memq 'monthname date-form)))) 893 (m-pos (- l (length (memq 'month date-form))))
888 (m-name-pos (if (/= l m-name-pos) (+ 2 m-name-pos))) 894 (m-pos (if (/= l m-pos) (+ 2 m-pos)))
889 (d-pos (- l (length (memq 'day date-form)))) 895 (y-pos (- l (length (memq 'year date-form))))
890 (d-pos (if (/= l d-pos) (+ 2 d-pos))) 896 (y-pos (if (/= l y-pos) (+ 2 y-pos)))
891 (m-pos (- l (length (memq 'month date-form)))) 897 (regexp
892 (m-pos (if (/= l m-pos) (+ 2 m-pos))) 898 (concat
893 (y-pos (- l (length (memq 'year date-form)))) 899 "\\(\\`\\|\^M\\|\n\\)\\("
894 (y-pos (if (/= l y-pos) (+ 2 y-pos))) 900 (mapconcat 'eval date-form "\\)\\(")
895 (regexp 901 "\\)"))
896 (concat 902 (case-fold-search t))
897 "\\(\\`\\|\^M\\|\n\\)\\(" 903 (goto-char (point-min))
898 (mapconcat 'eval date-form "\\)\\(") 904 (while (re-search-forward regexp nil t)
899 "\\)")) 905 (let* ((dd-name
900 (case-fold-search t)) 906 (if d-name-pos
901 (goto-char (point-min)) 907 (match-string-no-properties d-name-pos)))
902 (while (re-search-forward regexp nil t) 908 (mm-name
903 (let* ((dd-name 909 (if m-name-pos
904 (if d-name-pos 910 (match-string-no-properties m-name-pos)))
905 (buffer-substring-no-properties 911 (mm (string-to-number
906 (match-beginning d-name-pos) 912 (if m-pos
907 (match-end d-name-pos)))) 913 (match-string-no-properties m-pos)
908 (mm-name 914 "")))
909 (if m-name-pos 915 (dd (string-to-number
910 (buffer-substring-no-properties 916 (if d-pos
911 (match-beginning m-name-pos) 917 (match-string-no-properties d-pos)
912 (match-end m-name-pos)))) 918 "")))
913 (mm (string-to-number 919 (y-str (if y-pos
914 (if m-pos 920 (match-string-no-properties y-pos)))
915 (buffer-substring-no-properties 921 (yy (if (not y-str)
916 (match-beginning m-pos) 922 0
917 (match-end m-pos)) 923 (if (and (= (length y-str) 2)
918 ""))) 924 abbreviated-calendar-year)
919 (dd (string-to-number 925 (let* ((current-y
920 (if d-pos 926 (extract-calendar-year
921 (buffer-substring-no-properties 927 (calendar-current-date)))
922 (match-beginning d-pos) 928 (y (+ (string-to-number y-str)
923 (match-end d-pos)) 929 (* 100
924 ""))) 930 (/ current-y 100)))))
925 (y-str (if y-pos 931 (if (> (- y current-y) 50)
926 (buffer-substring-no-properties 932 (- y 100)
927 (match-beginning y-pos) 933 (if (> (- current-y y) 50)
928 (match-end y-pos)))) 934 (+ y 100)
929 (yy (if (not y-str) 935 y)))
930 0 936 (string-to-number y-str)))))
931 (if (and (= (length y-str) 2) 937 (let ((tmp (diary-pull-attrs (buffer-substring-no-properties
932 abbreviated-calendar-year) 938 (point) (line-end-position))
933 (let* ((current-y 939 file-glob-attrs)))
934 (extract-calendar-year 940 (setq entry (nth 0 tmp)
935 (calendar-current-date))) 941 marks (nth 1 tmp)))
936 (y (+ (string-to-number y-str) 942 (if dd-name
937 (* 100 943 (mark-calendar-days-named
938 (/ current-y 100))))) 944 (cdr (assoc-string
939 (if (> (- y current-y) 50) 945 dd-name
940 (- y 100) 946 (calendar-make-alist
941 (if (> (- current-y y) 50) 947 calendar-day-name-array
942 (+ y 100) 948 0 nil calendar-day-abbrev-array) t)) marks)
943 y))) 949 (if mm-name
944 (string-to-number y-str)))) 950 (setq mm
945 (save-excursion 951 (if (string-equal mm-name "*") 0
946 (setq entry (buffer-substring-no-properties 952 (cdr (assoc-string
947 (point) (line-end-position)) 953 mm-name
948 temp (diary-pull-attrs entry file-glob-attrs) 954 (calendar-make-alist
949 entry (nth 0 temp) 955 calendar-month-name-array
950 marks (nth 1 temp)))) 956 1 nil calendar-month-abbrev-array) t)))))
951 (if dd-name 957 (mark-calendar-date-pattern mm dd yy marks))))))
952 (mark-calendar-days-named 958 (mark-sexp-diary-entries)
953 (cdr (assoc-string 959 (run-hooks 'nongregorian-diary-marking-hook
954 dd-name 960 'mark-diary-entries-hook))
955 (calendar-make-alist
956 calendar-day-name-array
957 0 nil calendar-day-abbrev-array) t)) marks)
958 (if mm-name
959 (setq mm
960 (if (string-equal mm-name "*") 0
961 (cdr (assoc-string
962 mm-name
963 (calendar-make-alist
964 calendar-month-name-array
965 1 nil calendar-month-abbrev-array) t)))))
966 (mark-calendar-date-pattern mm dd yy marks))))
967 (setq d (cdr d))))
968 (mark-sexp-diary-entries)
969 (run-hooks 'nongregorian-diary-marking-hook
970 'mark-diary-entries-hook)
971 (set-syntax-table old-diary-syntax-table)
972 (message "Marking diary entries...done"))))) 961 (message "Marking diary entries...done")))))
973 962
974 (defun mark-sexp-diary-entries () 963 (defun mark-sexp-diary-entries ()
975 "Mark days in the calendar window that have sexp diary entries. 964 "Mark days in the calendar window that have sexp diary entries.
976 Each entry in the diary file (or included files) visible in the calendar window 965 Each entry in the diary file (or included files) visible in the calendar window
980 sexp-mark "(\\)\\|\\(" 969 sexp-mark "(\\)\\|\\("
981 (regexp-quote diary-nonmarking-symbol) 970 (regexp-quote diary-nonmarking-symbol)
982 sexp-mark "(diary-remind\\)")) 971 sexp-mark "(diary-remind\\)"))
983 (file-glob-attrs (nth 1 (diary-pull-attrs nil '()))) 972 (file-glob-attrs (nth 1 (diary-pull-attrs nil '())))
984 m y first-date last-date mark file-glob-attrs) 973 m y first-date last-date mark file-glob-attrs)
985 (save-excursion 974 (with-current-buffer calendar-buffer
986 (set-buffer calendar-buffer)
987 (setq m displayed-month) 975 (setq m displayed-month)
988 (setq y displayed-year)) 976 (setq y displayed-year))
989 (increment-calendar-month m y -1) 977 (increment-calendar-month m y -1)
990 (setq first-date 978 (setq first-date
991 (calendar-absolute-from-gregorian (list m 1 y))) 979 (calendar-absolute-from-gregorian (list m 1 y)))
1046 are obeyed. You can change the `#include' to some other string by 1034 are obeyed. You can change the `#include' to some other string by
1047 changing the variable `diary-include-string'." 1035 changing the variable `diary-include-string'."
1048 (goto-char (point-min)) 1036 (goto-char (point-min))
1049 (while (re-search-forward 1037 (while (re-search-forward
1050 (concat 1038 (concat
1051 "\\(\\`\\|\^M\\|\n\\)" 1039 "\\(?:\\`\\|\^M\\|\n\\)"
1052 (regexp-quote diary-include-string) 1040 (regexp-quote diary-include-string)
1053 " \"\\([^\"]*\\)\"") 1041 " \"\\([^\"]*\\)\"")
1054 nil t) 1042 nil t)
1055 (let* ((diary-file (substitute-in-file-name 1043 (let* ((diary-file (substitute-in-file-name
1056 (match-string-no-properties 2))) 1044 (match-string-no-properties 1)))
1057 (mark-diary-entries-hook 'mark-included-diary-files) 1045 (mark-diary-entries-hook 'mark-included-diary-files)
1058 (dbuff (find-buffer-visiting diary-file))) 1046 (dbuff (find-buffer-visiting diary-file)))
1059 (if (file-exists-p diary-file) 1047 (if (file-exists-p diary-file)
1060 (if (file-readable-p diary-file) 1048 (if (file-readable-p diary-file)
1061 (progn 1049 (progn
1071 (goto-char (point-min))) 1059 (goto-char (point-min)))
1072 1060
1073 (defun mark-calendar-days-named (dayname &optional color) 1061 (defun mark-calendar-days-named (dayname &optional color)
1074 "Mark all dates in the calendar window that are day DAYNAME of the week. 1062 "Mark all dates in the calendar window that are day DAYNAME of the week.
1075 0 means all Sundays, 1 means all Mondays, and so on." 1063 0 means all Sundays, 1 means all Mondays, and so on."
1076 (save-excursion 1064 (with-current-buffer calendar-buffer
1077 (set-buffer calendar-buffer)
1078 (let ((prev-month displayed-month) 1065 (let ((prev-month displayed-month)
1079 (prev-year displayed-year) 1066 (prev-year displayed-year)
1080 (succ-month displayed-month) 1067 (succ-month displayed-month)
1081 (succ-year displayed-year) 1068 (succ-year displayed-year)
1082 (last-day) 1069 (last-day)
1092 (setq day (+ day 7)))))) 1079 (setq day (+ day 7))))))
1093 1080
1094 (defun mark-calendar-date-pattern (month day year &optional color) 1081 (defun mark-calendar-date-pattern (month day year &optional color)
1095 "Mark all dates in the calendar window that conform to MONTH/DAY/YEAR. 1082 "Mark all dates in the calendar window that conform to MONTH/DAY/YEAR.
1096 A value of 0 in any position is a wildcard." 1083 A value of 0 in any position is a wildcard."
1097 (save-excursion 1084 (with-current-buffer calendar-buffer
1098 (set-buffer calendar-buffer)
1099 (let ((m displayed-month) 1085 (let ((m displayed-month)
1100 (y displayed-year)) 1086 (y displayed-year))
1101 (increment-calendar-month m y -1) 1087 (increment-calendar-month m y -1)
1102 (calendar-for-loop i from 0 to 2 do 1088 (calendar-for-loop i from 0 to 2 do
1103 (mark-calendar-month m y month day year color) 1089 (mark-calendar-month m y month day year color)
1150 be used instead of a colon (:) to separate the hour and minute parts." 1136 be used instead of a colon (:) to separate the hour and minute parts."
1151 (let ((case-fold-search nil)) 1137 (let ((case-fold-search nil))
1152 (cond ((string-match ; Military time 1138 (cond ((string-match ; Military time
1153 "\\`[ \t\n\\^M]*\\([0-9]?[0-9]\\)[:.]?\\([0-9][0-9]\\)\\(\\>\\|[^ap]\\)" 1139 "\\`[ \t\n\\^M]*\\([0-9]?[0-9]\\)[:.]?\\([0-9][0-9]\\)\\(\\>\\|[^ap]\\)"
1154 s) 1140 s)
1155 (+ (* 100 (string-to-number 1141 (+ (* 100 (string-to-number (match-string 1 s)))
1156 (substring s (match-beginning 1) (match-end 1)))) 1142 (string-to-number (match-string 2 s))))
1157 (string-to-number (substring s (match-beginning 2) (match-end 2)))))
1158 ((string-match ; Hour only XXam or XXpm 1143 ((string-match ; Hour only XXam or XXpm
1159 "\\`[ \t\n\\^M]*\\([0-9]?[0-9]\\)\\([ap]\\)m\\>" s) 1144 "\\`[ \t\n\\^M]*\\([0-9]?[0-9]\\)\\([ap]\\)m\\>" s)
1160 (+ (* 100 (% (string-to-number 1145 (+ (* 100 (% (string-to-number (match-string 1 s)) 12))
1161 (substring s (match-beginning 1) (match-end 1)))
1162 12))
1163 (if (equal ?a (downcase (aref s (match-beginning 2)))) 1146 (if (equal ?a (downcase (aref s (match-beginning 2))))
1164 0 1200))) 1147 0 1200)))
1165 ((string-match ; Hour and minute XX:XXam or XX:XXpm 1148 ((string-match ; Hour and minute XX:XXam or XX:XXpm
1166 "\\`[ \t\n\\^M]*\\([0-9]?[0-9]\\)[:.]\\([0-9][0-9]\\)\\([ap]\\)m\\>" s) 1149 "\\`[ \t\n\\^M]*\\([0-9]?[0-9]\\)[:.]\\([0-9][0-9]\\)\\([ap]\\)m\\>" s)
1167 (+ (* 100 (% (string-to-number 1150 (+ (* 100 (% (string-to-number (match-string 1 s)) 12))
1168 (substring s (match-beginning 1) (match-end 1))) 1151 (string-to-number (match-string 2 s))
1169 12))
1170 (string-to-number (substring s (match-beginning 2) (match-end 2)))
1171 (if (equal ?a (downcase (aref s (match-beginning 3)))) 1152 (if (equal ?a (downcase (aref s (match-beginning 3))))
1172 0 1200))) 1153 0 1200)))
1173 (t diary-unknown-time)))) ; Unrecognizable 1154 (t diary-unknown-time)))) ; Unrecognizable
1174 1155
1175 ;; Unrecognizable 1156 ;; Unrecognizable
1402 (condition-case nil 1383 (condition-case nil
1403 (eval (car (read-from-string sexp))) 1384 (eval (car (read-from-string sexp)))
1404 (error 1385 (error
1405 (beep) 1386 (beep)
1406 (message "Bad sexp at line %d in %s: %s" 1387 (message "Bad sexp at line %d in %s: %s"
1407 (save-excursion 1388 (count-lines (point-min) (point))
1408 (save-restriction
1409 (narrow-to-region 1 (point))
1410 (goto-char (point-min))
1411 (let ((lines 1))
1412 (while (re-search-forward "\n\\|\^M" nil t)
1413 (setq lines (1+ lines)))
1414 lines)))
1415 diary-file sexp) 1389 diary-file sexp)
1416 (sleep-for 2)))))) 1390 (sleep-for 2))))))
1417 (cond ((stringp result) result) 1391 (cond ((stringp result) result)
1418 ((and (consp result) 1392 ((and (consp result)
1419 (stringp (cdr result))) result) 1393 (stringp (cdr result))) result)
1686 `diary-file'. Adds `diary-redraw-calendar' to 1660 `diary-file'. Adds `diary-redraw-calendar' to
1687 `write-contents-functions' for FILE, so that the calendar will be 1661 `write-contents-functions' for FILE, so that the calendar will be
1688 redrawn with the new entry marked, if necessary." 1662 redrawn with the new entry marked, if necessary."
1689 (let ((pop-up-frames (window-dedicated-p (selected-window)))) 1663 (let ((pop-up-frames (window-dedicated-p (selected-window))))
1690 (find-file-other-window (substitute-in-file-name (or file diary-file)))) 1664 (find-file-other-window (substitute-in-file-name (or file diary-file))))
1691 (add-hook 'write-contents-functions 'diary-redraw-calendar nil t) 1665 (add-hook 'after-save-hook 'diary-redraw-calendar nil t)
1692 (when selective-display
1693 (subst-char-in-region (point-min) (point-max) ?\^M ?\n t)
1694 (setq selective-display nil)
1695 (kill-local-variable 'mode-line-format))
1696 (widen) 1666 (widen)
1667 (diary-unhide-everything)
1697 (goto-char (point-max)) 1668 (goto-char (point-max))
1698 (when (let ((case-fold-search t)) 1669 (when (let ((case-fold-search t))
1699 (search-backward "Local Variables:" 1670 (search-backward "Local Variables:"
1700 (max (- (point-max) 3000) (point-min)) 1671 (max (- (point-max) 3000) (point-min))
1701 t)) 1672 t))
1702 (beginning-of-line) 1673 (beginning-of-line)
1703 (insert "\n") 1674 (insert "\n")
1704 (previous-line 1)) 1675 (forward-line -1))
1705 (insert 1676 (insert
1706 (if (bolp) "" "\n") 1677 (if (bolp) "" "\n")
1707 (if nonmarking diary-nonmarking-symbol "") 1678 (if nonmarking diary-nonmarking-symbol "")
1708 string " ")) 1679 string " "))
1709 1680
1796 (calendar-read "Repeat every how many days: " 1767 (calendar-read "Repeat every how many days: "
1797 (lambda (x) (> x 0))) 1768 (lambda (x) (> x 0)))
1798 (calendar-date-string (calendar-cursor-to-date t) nil t)) 1769 (calendar-date-string (calendar-cursor-to-date t) nil t))
1799 arg))) 1770 arg)))
1800 1771
1772 (defvar diary-mode-map
1773 (let ((map (make-sparse-keymap)))
1774 (define-key map "\C-c\C-s" 'diary-show-all-entries)
1775 (define-key map "\C-c\C-q" 'quit-window)
1776 map)
1777 "Keymap for `diary-mode'.")
1778
1801 ;;;###autoload 1779 ;;;###autoload
1802 (define-derived-mode diary-mode fundamental-mode 1780 (define-derived-mode diary-mode fundamental-mode "Diary"
1803 "Diary"
1804 "Major mode for editing the diary file." 1781 "Major mode for editing the diary file."
1805 (set (make-local-variable 'font-lock-defaults) 1782 (set (make-local-variable 'font-lock-defaults)
1806 '(diary-font-lock-keywords t))) 1783 '(diary-font-lock-keywords t))
1784 (add-to-invisibility-spec '(diary . nil))
1785 (add-hook 'after-save-hook 'diary-redraw-calendar nil t)
1786 (if diary-header-line-flag
1787 (setq header-line-format diary-header-line-format)))
1807 1788
1808 (define-derived-mode fancy-diary-display-mode fundamental-mode 1789 (define-derived-mode fancy-diary-display-mode fundamental-mode
1809 "Diary" 1790 "Diary"
1810 "Major mode used while displaying diary entries using Fancy Display." 1791 "Major mode used while displaying diary entries using Fancy Display."
1811 (set (make-local-variable 'font-lock-defaults) 1792 (set (make-local-variable 'font-lock-defaults)
1812 '(fancy-diary-font-lock-keywords t)) 1793 '(fancy-diary-font-lock-keywords t))
1813 (define-key (current-local-map) "q" 'quit-window)) 1794 (local-set-key "q" 'quit-window))
1814 1795
1815 1796
1816 (defvar fancy-diary-font-lock-keywords 1797 (defvar fancy-diary-font-lock-keywords
1817 (list 1798 (list
1818 (cons 1799 (cons
1834 '("^[ \t]*[0-9]?[0-9]\\([:.]?[0-9][0-9]\\)?\\(am\\|pm\\|AM\\|PM\\)?\\(-[0-9]?[0-9]\\([:.]?[0-9][0-9]\\)?\\(am\\|pm\\|AM\\|PM\\)?\\)?" 1815 '("^[ \t]*[0-9]?[0-9]\\([:.]?[0-9][0-9]\\)?\\(am\\|pm\\|AM\\|PM\\)?\\(-[0-9]?[0-9]\\([:.]?[0-9][0-9]\\)?\\(am\\|pm\\|AM\\|PM\\)?\\)?"
1835 . font-lock-variable-name-face)) 1816 . font-lock-variable-name-face))
1836 "Keywords to highlight in fancy diary display") 1817 "Keywords to highlight in fancy diary display")
1837 1818
1838 1819
1839 (defun font-lock-diary-sexps (limit) 1820 (defun diary-font-lock-sexps (limit)
1840 "Recognize sexp diary entry for font-locking." 1821 "Recognize sexp diary entry for font-locking."
1841 (if (re-search-forward 1822 (if (re-search-forward
1842 (concat "^" (regexp-quote diary-nonmarking-symbol) 1823 (concat "^" (regexp-quote diary-nonmarking-symbol)
1843 "?\\(" (regexp-quote sexp-diary-entry-symbol) "\\)") 1824 "?\\(" (regexp-quote sexp-diary-entry-symbol) "\\)")
1844 limit t) 1825 limit t)
1849 (forward-sexp 1) 1830 (forward-sexp 1)
1850 (store-match-data (list start (point))) 1831 (store-match-data (list start (point)))
1851 t)) 1832 t))
1852 (error t)))) 1833 (error t))))
1853 1834
1854 (defun font-lock-diary-date-forms (month-array &optional symbol abbrev-array) 1835 (defun diary-font-lock-date-forms (month-array &optional symbol abbrev-array)
1855 "Create font-lock patterns for `diary-date-forms' using MONTH-ARRAY. 1836 "Create font-lock patterns for `diary-date-forms' using MONTH-ARRAY.
1856 If given, optional SYMBOL must be a prefix to entries. 1837 If given, optional SYMBOL must be a prefix to entries.
1857 If optional ABBREV-ARRAY is present, the abbreviations constructed 1838 If optional ABBREV-ARRAY is present, the abbreviations constructed
1858 from this array by the function `calendar-abbrev-construct' are 1839 from this array by the function `calendar-abbrev-construct' are
1859 matched (with or without a final `.'), in addition to the full month 1840 matched (with or without a final `.'), in addition to the full month
1863 (monthname (format "\\(%s\\|\\*\\)" 1844 (monthname (format "\\(%s\\|\\*\\)"
1864 (diary-name-pattern month-array abbrev-array))) 1845 (diary-name-pattern month-array abbrev-array)))
1865 (month "\\([0-9]+\\|\\*\\)") 1846 (month "\\([0-9]+\\|\\*\\)")
1866 (day "\\([0-9]+\\|\\*\\)") 1847 (day "\\([0-9]+\\|\\*\\)")
1867 (year "-?\\([0-9]+\\|\\*\\)")) 1848 (year "-?\\([0-9]+\\|\\*\\)"))
1868 (mapcar '(lambda (x) 1849 (mapcar (lambda (x)
1869 (cons 1850 (cons
1870 (concat "^" (regexp-quote diary-nonmarking-symbol) "?" 1851 (concat "^" (regexp-quote diary-nonmarking-symbol) "?"
1871 (if symbol (regexp-quote symbol) "") "\\(" 1852 (if symbol (regexp-quote symbol) "") "\\("
1872 (mapconcat 'eval 1853 (mapconcat 'eval
1873 ;; If backup, omit first item (backup) 1854 ;; If backup, omit first item (backup)
1874 ;; and last item (not part of date) 1855 ;; and last item (not part of date)
1875 (if (equal (car x) 'backup) 1856 (if (equal (car x) 'backup)
1876 (reverse (cdr (reverse (cdr x)))) 1857 (nreverse (cdr (reverse (cdr x))))
1877 x) 1858 x)
1878 "") 1859 "")
1879 ;; With backup, last item is not part of date 1860 ;; With backup, last item is not part of date
1880 (if (equal (car x) 'backup) 1861 (if (equal (car x) 'backup)
1881 (concat "\\)" (eval (car (reverse x)))) 1862 (concat "\\)" (eval (car (reverse x))))
1886 (eval-when-compile (require 'cal-hebrew) 1867 (eval-when-compile (require 'cal-hebrew)
1887 (require 'cal-islam)) 1868 (require 'cal-islam))
1888 1869
1889 (defvar diary-font-lock-keywords 1870 (defvar diary-font-lock-keywords
1890 (append 1871 (append
1891 (font-lock-diary-date-forms calendar-month-name-array 1872 (diary-font-lock-date-forms calendar-month-name-array
1892 nil calendar-month-abbrev-array) 1873 nil calendar-month-abbrev-array)
1893 (when (or (memq 'mark-hebrew-diary-entries 1874 (when (or (memq 'mark-hebrew-diary-entries
1894 nongregorian-diary-marking-hook) 1875 nongregorian-diary-marking-hook)
1895 (memq 'list-hebrew-diary-entries 1876 (memq 'list-hebrew-diary-entries
1896 nongregorian-diary-listing-hook)) 1877 nongregorian-diary-listing-hook))
1897 (require 'cal-hebrew) 1878 (require 'cal-hebrew)
1898 (font-lock-diary-date-forms 1879 (diary-font-lock-date-forms
1899 calendar-hebrew-month-name-array-leap-year 1880 calendar-hebrew-month-name-array-leap-year
1900 hebrew-diary-entry-symbol)) 1881 hebrew-diary-entry-symbol))
1901 (when (or (memq 'mark-islamic-diary-entries 1882 (when (or (memq 'mark-islamic-diary-entries
1902 nongregorian-diary-marking-hook) 1883 nongregorian-diary-marking-hook)
1903 (memq 'list-islamic-diary-entries 1884 (memq 'list-islamic-diary-entries
1904 nongregorian-diary-listing-hook)) 1885 nongregorian-diary-listing-hook))
1905 (require 'cal-islam) 1886 (require 'cal-islam)
1906 (font-lock-diary-date-forms 1887 (diary-font-lock-date-forms
1907 calendar-islamic-month-name-array 1888 calendar-islamic-month-name-array
1908 islamic-diary-entry-symbol)) 1889 islamic-diary-entry-symbol))
1909 (list 1890 (list
1910 (cons 1891 (cons
1911 (concat "^" (regexp-quote diary-include-string) ".*$") 1892 (concat "^" (regexp-quote diary-include-string) ".*$")
1923 '(1 font-lock-reference-face)) 1904 '(1 font-lock-reference-face))
1924 (cons 1905 (cons
1925 (concat "^" (regexp-quote diary-nonmarking-symbol) 1906 (concat "^" (regexp-quote diary-nonmarking-symbol)
1926 "?\\(" (regexp-quote islamic-diary-entry-symbol) "\\)") 1907 "?\\(" (regexp-quote islamic-diary-entry-symbol) "\\)")
1927 '(1 font-lock-reference-face)) 1908 '(1 font-lock-reference-face))
1928 '(font-lock-diary-sexps . font-lock-keyword-face) 1909 '(diary-font-lock-sexps . font-lock-keyword-face)
1929 '("[0-9]?[0-9]\\([:.]?[0-9][0-9]\\)?\\(am\\|pm\\|AM\\|PM\\)\\(-[0-9]?[0-9]\\([:.]?[0-9][0-9]\\)?\\(am\\|pm\\|AM\\|PM\\)\\)?" 1910 '("[0-9]?[0-9]\\([:.]?[0-9][0-9]\\)?\\(am\\|pm\\|AM\\|PM\\)\\(-[0-9]?[0-9]\\([:.]?[0-9][0-9]\\)?\\(am\\|pm\\|AM\\|PM\\)\\)?"
1930 . font-lock-function-name-face))) 1911 . font-lock-function-name-face)))
1931 "Forms to highlight in diary-mode") 1912 "Forms to highlight in `diary-mode'.")
1932 1913
1933 1914
1934 ;; Following code from Dave Love <fx@gnu.org>. 1915 ;; Following code from Dave Love <fx@gnu.org>.
1935 ;; Import Outlook-format appointments from mail messages in Gnus or 1916 ;; Import Outlook-format appointments from mail messages in Gnus or
1936 ;; Rmail using command `diary-from-outlook'. This, or the specialized 1917 ;; Rmail using command `diary-from-outlook'. This, or the specialized
2085 (message "Diary entry added")))))) 2066 (message "Diary entry added"))))))
2086 2067
2087 2068
2088 (provide 'diary-lib) 2069 (provide 'diary-lib)
2089 2070
2090 ;;; arch-tag: 22dd506e-2e33-410d-9ae1-095a0c1b2010 2071 ;; arch-tag: 22dd506e-2e33-410d-9ae1-095a0c1b2010
2091 ;;; diary-lib.el ends here 2072 ;;; diary-lib.el ends here