org-mode/lisp/org-datetree.el

142 lines
4.7 KiB
EmacsLisp

;;; org-datetree.el --- Create Date entries in a tree
;; Copyright (C) 2009 Free Software Foundation, Inc.
;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: http://orgmode.org
;; Version: 6.32trans
;;
;; This file is part of GNU Emacs.
;;
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Commentary:
;; This file contains code to create entries in a tree where the top-level
;; nodes represent years, the level 2 nodes represent the months, and the
;; level 1 entries days.
;;; Code:
(require 'org)
(defvar org-datetree-base-level 1
"The level at which years should be placed in the date tree.
This is normally one, but if the buffer has an entry with a DATE_TREE
property, the date tree will become a subtree under that entry, so the
base level will be properly adjusted.")
(defun org-datetree-find-date-create (date)
"Find or create an entry for DATE."
(let ((year (nth 2 date))
(month (car date))
(day (nth 1 date)))
(org-set-local 'org-datetree-base-level 1)
(widen)
(goto-char (point-min))
(when (re-search-forward "^[ \t]*:DATE_TREE:[ \t]+\\S-" nil t)
(org-back-to-heading t)
(org-set-local 'org-datetree-base-level
(org-get-valid-level (funcall outline-level) 1))
(org-narrow-to-subtree))
(goto-char (point-min))
(org-datetree-find-year-create year)
(org-datetree-find-month-create year month)
(org-datetree-find-day-create year month day)
(goto-char (prog1 (point) (widen)))))
(defun org-datetree-find-year-create (year)
(let ((re "^\\*+[ \t]+\\([12][0-9][0-9][0-9]\\)[ \t\n]")
match)
(goto-char (point-min))
(while (and (setq match (re-search-forward re nil t))
(goto-char (match-beginning 1))
(< (string-to-number (match-string 1)) year)))
(cond
((not match)
(goto-char (point-max))
(or (bolp) (newline))
(org-datetree-insert-line year))
((= (string-to-number (match-string 1)) year)
(goto-char (point-at-bol)))
(t
(beginning-of-line 1)
(org-datetree-insert-line year)))))
(defun org-datetree-find-month-create (year month)
(org-narrow-to-subtree)
(let ((re (format "^\\*+[ \t]+%d-\\([01][0-9]\\)[ \t\n]" year))
match)
(goto-char (point-min))
(while (and (setq match (re-search-forward re nil t))
(goto-char (match-beginning 1))
(< (string-to-number (match-string 1)) month)))
(cond
((not match)
(goto-char (point-max))
(or (bolp) (newline))
(org-datetree-insert-line year month))
((= (string-to-number (match-string 1)) month)
(goto-char (point-at-bol)))
(t
(beginning-of-line 1)
(org-datetree-insert-line year month)))))
(defun org-datetree-find-day-create (year month day)
(org-narrow-to-subtree)
(let ((re (format "^\\*+[ \t]+%d-%02d-\\([01][0-9]\\)[ \t\n]" year month))
match)
(goto-char (point-min))
(while (and (setq match (re-search-forward re nil t))
(goto-char (match-beginning 1))
(< (string-to-number (match-string 1)) day)))
(cond
((not match)
(goto-char (point-max))
(or (bolp) (newline))
(org-datetree-insert-line year month day))
((= (string-to-number (match-string 1)) day)
(goto-char (point-at-bol)))
(t
(beginning-of-line 1)
(org-datetree-insert-line year month day)))))
(defun org-datetree-insert-line (year &optional month day)
(let ((pos (point)))
(skip-chars-backward " \t\n")
(delete-region (point) pos)
(insert "\n" (make-string org-datetree-base-level ?*) " \n")
(backward-char 1)
(if month (org-do-demote))
(if day (org-do-demote))
(insert (format "%d" year))
(when month
(insert (format "-%02d" month))
(if day
(insert (format "-%02d %s"
day (format-time-string
"%A" (encode-time 0 0 0 day month year))))
(insert (format " %s"
(format-time-string
"%B" (encode-time 0 0 0 1 month year))))))
(beginning-of-line 1)))
(provide 'org-datetree)
;; arch-tag: 1daea962-fd08-448b-9f98-6e8b511b3601
;;; org-datetree.el ends here