* [PATCH 1/3] org-datetree.el: Code cleanup. [not found] <cover.1441180730.git.ruediger@c-plusplus.net> @ 2015-09-02 8:06 ` Rüdiger Sonderfeld 2015-09-02 19:48 ` Nicolas Goaziou 2015-09-02 8:06 ` [PATCH 2/3] org-datetree.el: Add support for ISO week trees Rüdiger Sonderfeld 2015-09-02 8:06 ` [PATCH " Rüdiger Sonderfeld 2 siblings, 1 reply; 20+ messages in thread From: Rüdiger Sonderfeld @ 2015-09-02 8:06 UTC (permalink / raw) To: emacs-orgmode * lisp/org-datetree.el (org-datetree--find-create): New function. (org-datetree-find-year-create, org-datetree-find-month-create, org-datetree-find-day-create): Removed functions (org-datetree-find-date-create): Use `org-datetree--find-create' instead of removed functions. Use calendar extract functions. (org-datetree-insert-line): Do more formatting in `format-time-string' since we call it anyway * testing/lisp/test-org-datetree.el (test-org-datetree/find-date-create): Test if new entries are put at the right place. --- lisp/org-datetree.el | 77 +++++++++------------------------------ testing/lisp/test-org-datetree.el | 9 +++++ 2 files changed, 27 insertions(+), 59 deletions(-) diff --git a/lisp/org-datetree.el b/lisp/org-datetree.el index a97a9d0..3620bbd 100644 --- a/lisp/org-datetree.el +++ b/lisp/org-datetree.el @@ -64,67 +64,30 @@ (defun org-datetree-find-date-create (date &optional keep-restriction) (org-get-valid-level (org-current-level) 1)) (org-narrow-to-subtree))) (goto-char (point-min)) - (let ((year (nth 2 date)) - (month (car date)) - (day (nth 1 date))) - (org-datetree-find-year-create year) - (org-datetree-find-month-create year month) - (org-datetree-find-day-create year month day)))) - -(defun org-datetree-find-year-create (year) - "Find the YEAR datetree or create it." - (let ((re "^\\*+[ \t]+\\([12][0-9]\\{3\\}\\)\\(\\s-*?\\([ \t]:[[:alnum:]:_@#%]+:\\)?\\s-*$\\)") + (let ((year (calendar-extract-year date)) + (month (calendar-extract-month date)) + (day (calendar-extract-day date))) + (org-datetree--find-create "^\\*+[ \t]+\\([12][0-9]\\{3\\}\\)\\(\\s-*?\\([ \t]:[[:alnum:]:_@#%%]+:\\)?\\s-*$\\)" + year) + (org-datetree--find-create "^\\*+[ \t]+%d-\\([01][0-9]\\) \\w+$" + year month) + (org-datetree--find-create "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" + year month day)))) + +(defun org-datetree--find-create (regex year &optional month day) + "Find the datetree matched by REGEX for YEAR, MONTH, or DAY." + (let ((re (format regex year month day)) 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))) + (< (string-to-number (match-string 1)) (or day month 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) - "Find the datetree for YEAR and MONTH or create it." - (org-narrow-to-subtree) - (let ((re (format "^\\*+[ \t]+%d-\\([01][0-9]\\) \\w+$" 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) - "Find the datetree for YEAR, MONTH and DAY or create it." - (org-narrow-to-subtree) - (let ((re (format "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" 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)) + (unless (bolp) (newline)) (org-datetree-insert-line year month day)) - ((= (string-to-number (match-string 1)) day) + ((= (string-to-number (match-string 1)) (or day month year)) (goto-char (point-at-bol))) (t (beginning-of-line 1) @@ -139,13 +102,9 @@ (defun org-datetree-insert-line (year &optional month day) (insert (format "%d" year)) (when month (insert - (format "-%02d" month) (if day - (format "-%02d %s" - day - (format-time-string "%A" (encode-time 0 0 0 day month year))) - (format " %s" - (format-time-string "%B" (encode-time 0 0 0 1 month year)))))) + (format-time-string "-%m-%d %A" (encode-time 0 0 0 day month year)) + (format-time-string "-%m %B" (encode-time 0 0 0 1 month year))))) (when (and day org-datetree-add-timestamp) (save-excursion (insert "\n") diff --git a/testing/lisp/test-org-datetree.el b/testing/lisp/test-org-datetree.el index d500130..0135ab9 100644 --- a/testing/lisp/test-org-datetree.el +++ b/testing/lisp/test-org-datetree.el @@ -55,6 +55,15 @@ (ert-deftest test-org-datetree/find-date-create () (let ((org-datetree-add-timestamp nil)) (org-datetree-find-date-create '(3 29 2012))) (org-trim (buffer-string))))) + ;; Sort new entry in right place + (should + (string-match + "\\`\\* 2012\n\\*\\* 2012-02 .*\n\\*\\*\\* 2012-02-01 .*\n\n\\*\\* 2012-03 .*\n\\*\\*\\* 2012-03-29 .*\\'" + (org-test-with-temp-text "* 2012\n** 2012-03 month\n*** 2012-03-29 day" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-date-create '(3 29 2012)) + (org-datetree-find-date-create '(2 1 2012))) + (org-trim (buffer-string))))) ;; When `org-datetree-add-timestamp' is non-nil, insert a timestamp ;; in entry. When set to `inactive', insert an inactive one. (should -- 2.5.1 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 1/3] org-datetree.el: Code cleanup. 2015-09-02 8:06 ` [PATCH 1/3] org-datetree.el: Code cleanup Rüdiger Sonderfeld @ 2015-09-02 19:48 ` Nicolas Goaziou 0 siblings, 0 replies; 20+ messages in thread From: Nicolas Goaziou @ 2015-09-02 19:48 UTC (permalink / raw) To: Rüdiger Sonderfeld; +Cc: emacs-orgmode Hello, Rüdiger Sonderfeld <ruediger@c-plusplus.net> writes: > * lisp/org-datetree.el (org-datetree--find-create): New function. > (org-datetree-find-year-create, org-datetree-find-month-create, > org-datetree-find-day-create): Removed functions > (org-datetree-find-date-create): Use `org-datetree--find-create' instead > of removed functions. Use calendar extract functions. > (org-datetree-insert-line): Do more formatting in `format-time-string' > since we call it anyway > * testing/lisp/test-org-datetree.el (test-org-datetree/find-date-create): > Test if new entries are put at the right place. Thank you. Minor comments follow. > --- > lisp/org-datetree.el | 77 +++++++++------------------------------ > testing/lisp/test-org-datetree.el | 9 +++++ > 2 files changed, 27 insertions(+), 59 deletions(-) > > diff --git a/lisp/org-datetree.el b/lisp/org-datetree.el > index a97a9d0..3620bbd 100644 > --- a/lisp/org-datetree.el > +++ b/lisp/org-datetree.el > @@ -64,67 +64,30 @@ (defun org-datetree-find-date-create (date &optional keep-restriction) > (org-get-valid-level (org-current-level) 1)) > (org-narrow-to-subtree))) > (goto-char (point-min)) > - (let ((year (nth 2 date)) > - (month (car date)) > - (day (nth 1 date))) > - (org-datetree-find-year-create year) > - (org-datetree-find-month-create year month) > - (org-datetree-find-day-create year month day)))) > - > -(defun org-datetree-find-year-create (year) > - "Find the YEAR datetree or create it." > - (let ((re "^\\*+[ \t]+\\([12][0-9]\\{3\\}\\)\\(\\s-*?\\([ \t]:[[:alnum:]:_@#%]+:\\)?\\s-*$\\)") > + (let ((year (calendar-extract-year date)) > + (month (calendar-extract-month date)) > + (day (calendar-extract-day date))) > + (org-datetree--find-create "^\\*+[ \t]+\\([12][0-9]\\{3\\}\\)\\(\\s-*?\\([ \t]:[[:alnum:]:_@#%%]+:\\)?\\s-*$\\)" > + year) > + (org-datetree--find-create "^\\*+[ \t]+%d-\\([01][0-9]\\) \\w+$" > + year month) > + (org-datetree--find-create "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" > + year month day)))) > + > +(defun org-datetree--find-create (regex year &optional month day) > + "Find the datetree matched by REGEX for YEAR, MONTH, or DAY." You should add you are expecting something special in matching group 1, for comparison. > + (let ((re (format regex year month day)) > 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))) > + (< (string-to-number (match-string 1)) (or day month 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) > - "Find the datetree for YEAR and MONTH or create it." > - (org-narrow-to-subtree) > - (let ((re (format "^\\*+[ \t]+%d-\\([01][0-9]\\) \\w+$" 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) > - "Find the datetree for YEAR, MONTH and DAY or create it." > - (org-narrow-to-subtree) > - (let ((re (format "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" 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)) > + (unless (bolp) (newline)) While you're at it: (unless (bolp) (insert "\n")) > diff --git a/testing/lisp/test-org-datetree.el b/testing/lisp/test-org-datetree.el > index d500130..0135ab9 100644 > --- a/testing/lisp/test-org-datetree.el > +++ b/testing/lisp/test-org-datetree.el > @@ -55,6 +55,15 @@ (ert-deftest test-org-datetree/find-date-create () > (let ((org-datetree-add-timestamp nil)) > (org-datetree-find-date-create '(3 29 2012))) > (org-trim (buffer-string))))) > + ;; Sort new entry in right place Missing full stop. Regards, -- Nicolas Goaziou ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 2/3] org-datetree.el: Add support for ISO week trees. [not found] <cover.1441180730.git.ruediger@c-plusplus.net> 2015-09-02 8:06 ` [PATCH 1/3] org-datetree.el: Code cleanup Rüdiger Sonderfeld @ 2015-09-02 8:06 ` Rüdiger Sonderfeld 2015-09-02 19:58 ` Nicolas Goaziou 2015-09-02 8:06 ` [PATCH " Rüdiger Sonderfeld 2 siblings, 1 reply; 20+ messages in thread From: Rüdiger Sonderfeld @ 2015-09-02 8:06 UTC (permalink / raw) To: emacs-orgmode * lisp/org-datetree.el (org-datetree-find-iso-date-create): New function. (org-datetree--find-create): Support fixed text for insert. (org-datetree-insert-line): Support fixed text for insert. * testing/lisp/test-org-datetree.el (test-org-datetree/find-iso-date-create): New test. ISO week trees order dates by week and not by month. --- lisp/org-datetree.el | 64 ++++++++++++++++++++++----- testing/lisp/test-org-datetree.el | 92 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 11 deletions(-) diff --git a/lisp/org-datetree.el b/lisp/org-datetree.el index 3620bbd..a5a542e 100644 --- a/lisp/org-datetree.el +++ b/lisp/org-datetree.el @@ -74,8 +74,48 @@ (defun org-datetree-find-date-create (date &optional keep-restriction) (org-datetree--find-create "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" year month day)))) -(defun org-datetree--find-create (regex year &optional month day) - "Find the datetree matched by REGEX for YEAR, MONTH, or DAY." +;;;###autoload +(defun org-datetree-find-iso-week-create (date &optional keep-restriction) + "Find or create an ISO week entry for DATE. +Compared to `org-datetree-find-date-create' this function creates +entries ordered by week instead of months. +If KEEP-RESTRICTION is non-nil, do not widen the buffer. When it +is nil, the buffer will be widened to make sure an existing date +tree can be found." + (org-set-local 'org-datetree-base-level 1) + (or keep-restriction (widen)) + (save-restriction + (let ((prop (org-find-property "DATE_WEEK_TREE"))) + (when prop + (goto-char prop) + (org-set-local 'org-datetree-base-level + (org-get-valid-level (org-current-level) 1)) + (org-narrow-to-subtree))) + (goto-char (point-min)) + (require 'cal-iso) + (let* ((year (calendar-extract-year date)) + (month (calendar-extract-month date)) + (day (calendar-extract-day date)) + (time (encode-time 0 0 0 day month year)) + (iso-date (calendar-iso-from-absolute + (calendar-absolute-from-gregorian date))) + (weekyear (nth 2 iso-date)) + (week (car iso-date)) + (weekday (cadr iso-date))) + ;; ISO 8601 week format is %G-W%V(-%u) + (org-datetree--find-create "^\\*+[ \t]+\\([12][0-9]\\{3\\}\\)\\(\\s-*?\\([ \t]:[[:alnum:]:_@#%%]+:\\)?\\s-*$\\)" + weekyear nil nil + (format-time-string "%G" time)) + (org-datetree--find-create "^\\*+[ \t]+%d-W\\([0-5][0-9]\\)$" + weekyear week nil + (format-time-string "%G-W%V" time)) + ;; For the actual day we use the regular date instead of ISO week. + (org-datetree--find-create "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" + year month day)))) + +(defun org-datetree--find-create (regex year &optional month day insert) + "Find the datetree matched by REGEX for YEAR, MONTH, or DAY. +If INSERT is non-nil insert the text if not found." (let ((re (format regex year month day)) match) (goto-char (point-min)) @@ -86,25 +126,27 @@ (defun org-datetree--find-create (regex year &optional month day) ((not match) (goto-char (point-max)) (unless (bolp) (newline)) - (org-datetree-insert-line year month day)) + (org-datetree-insert-line year month day insert)) ((= (string-to-number (match-string 1)) (or day month year)) (goto-char (point-at-bol))) (t (beginning-of-line 1) - (org-datetree-insert-line year month day))))) + (org-datetree-insert-line year month day insert))))) -(defun org-datetree-insert-line (year &optional month day) +(defun org-datetree-insert-line (year &optional month day text) (delete-region (save-excursion (skip-chars-backward " \t\n") (point)) (point)) (insert "\n" (make-string org-datetree-base-level ?*) " \n") (backward-char) (when month (org-do-demote)) (when day (org-do-demote)) - (insert (format "%d" year)) - (when month - (insert - (if day - (format-time-string "-%m-%d %A" (encode-time 0 0 0 day month year)) - (format-time-string "-%m %B" (encode-time 0 0 0 1 month year))))) + (if text + (insert text) + (insert (format "%d" year)) + (when month + (insert + (if day + (format-time-string "-%m-%d %A" (encode-time 0 0 0 day month year)) + (format-time-string "-%m %B" (encode-time 0 0 0 1 month year)))))) (when (and day org-datetree-add-timestamp) (save-excursion (insert "\n") diff --git a/testing/lisp/test-org-datetree.el b/testing/lisp/test-org-datetree.el index 0135ab9..9b839ca 100644 --- a/testing/lisp/test-org-datetree.el +++ b/testing/lisp/test-org-datetree.el @@ -113,5 +113,97 @@ (ert-deftest test-org-datetree/find-date-create () (org-datetree-find-date-create '(3 29 2012))) (buffer-substring (point) (line-end-position)))))) +(ert-deftest test-org-datetree/find-iso-date-create () + "Test `org-datetree-find-iso-date-create' specificaiton." + ;; When date is missing, create it. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\\'" + (org-test-with-temp-text "" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Do not create new year node when one exists. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\\'" + (org-test-with-temp-text "* 2015\n" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Do not create new month node when one exists. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\\'" + (org-test-with-temp-text "* 2015\n** 2015-W01" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Do not create new day node when one exists. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\\'" + (org-test-with-temp-text "* 2015\n** 2015-W01\n*** 2014-12-31 day" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Sort new entry in right place + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\n\n\\*\\* 2015-W36\n\\*\\*\\* 2015-09-01 .*\\'" + (org-test-with-temp-text "* 2015" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(9 1 2015)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; When `org-datetree-add-timestamp' is non-nil, insert a timestamp + ;; in entry. When set to `inactive', insert an inactive one. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* \\(2014-12-31\\) .*\n[ \t]*<\\1.*?>\\'" + (org-test-with-temp-text "* 2015\n" + (let ((org-datetree-add-timestamp t)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* \\(2014-12-31\\) .*\n[ \t]*\\[\\1.*?\\]\\'" + (org-test-with-temp-text "* 2015\n" + (let ((org-datetree-add-timestamp 'inactive)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Insert at top level, unless some node has DATE_WEEK_TREE + ;; property. In this case, date tree becomes one of its sub-trees. + (should + (string-match + "\\* 2015" + (org-test-with-temp-text "* Top" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + (should + (string-match + "\\*\\* H1.1\n:PROPERTIES:\n:DATE_WEEK_TREE: t\n:END:\n\\*\\*\\* 2015" + (org-test-with-temp-text + "* H1\n** H1.1\n:PROPERTIES:\n:DATE_WEEK_TREE: t\n:END:\n* H2" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Always leave point at beginning of day entry. + (should + (string-match + "\\*\\*\\* 2014-12-31" + (org-test-with-temp-text "* 2015\n** 2015-W01\n*** 2014-12-31 day" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (buffer-substring (point) (line-end-position))))) + (should + (string-match + "\\*\\*\\* 2014-12-31" + (org-test-with-temp-text "* 2015\n** 2015-W01\n*** 2014-12-31 day" + (let ((org-datetree-add-timestamp t)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (buffer-substring (point) (line-end-position)))))) + (provide 'test-org-datetree) ;;; test-org-datetree.el ends here -- 2.5.1 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 2/3] org-datetree.el: Add support for ISO week trees. 2015-09-02 8:06 ` [PATCH 2/3] org-datetree.el: Add support for ISO week trees Rüdiger Sonderfeld @ 2015-09-02 19:58 ` Nicolas Goaziou 2015-09-03 0:14 ` Rüdiger Sonderfeld 0 siblings, 1 reply; 20+ messages in thread From: Nicolas Goaziou @ 2015-09-02 19:58 UTC (permalink / raw) To: Rüdiger Sonderfeld; +Cc: emacs-orgmode Rüdiger Sonderfeld <ruediger@c-plusplus.net> writes: > +(defun org-datetree-find-iso-week-create (date &optional keep-restriction) > + "Find or create an ISO week entry for DATE. > +Compared to `org-datetree-find-date-create' this function creates > +entries ordered by week instead of months. > +If KEEP-RESTRICTION is non-nil, do not widen the buffer. When it > +is nil, the buffer will be widened to make sure an existing date > +tree can be found." > + (org-set-local 'org-datetree-base-level 1) > + (or keep-restriction (widen)) > + (save-restriction > + (let ((prop (org-find-property "DATE_WEEK_TREE"))) I don't think we need to introduce a new property for that. DATE_TREE is enough. > + (when prop > + (goto-char prop) > + (org-set-local 'org-datetree-base-level > + (org-get-valid-level (org-current-level) 1)) > + (org-narrow-to-subtree))) > + (goto-char (point-min)) > + (require 'cal-iso) > + (let* ((year (calendar-extract-year date)) > + (month (calendar-extract-month date)) > + (day (calendar-extract-day date)) > + (time (encode-time 0 0 0 day month year)) > + (iso-date (calendar-iso-from-absolute > + (calendar-absolute-from-gregorian date))) > + (weekyear (nth 2 iso-date)) > + (week (car iso-date)) > + (weekday (cadr iso-date))) Nitpick, since you used (nth 2 ...): car -> nth 0 cadr -> nth 1 > + ;; ISO 8601 week format is %G-W%V(-%u) > + (org-datetree--find-create "^\\*+[ \t]+\\([12][0-9]\\{3\\}\\)\\(\\s-*?\\([ \t]:[[:alnum:]:_@#%%]+:\\)?\\s-*$\\)" Isn't this line too long? > + weekyear nil nil > + (format-time-string "%G" time)) > + (org-datetree--find-create "^\\*+[ \t]+%d-W\\([0-5][0-9]\\)$" > + weekyear week nil > + (format-time-string "%G-W%V" time)) > + ;; For the actual day we use the regular date instead of ISO week. > + (org-datetree--find-create "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" > + year month day)))) > + > +(defun org-datetree--find-create (regex year &optional month day insert) > + "Find the datetree matched by REGEX for YEAR, MONTH, or DAY. Here you have expectations about REGEX, since you use (format regex year month day) Could you clarify that it should have three format placeholders in the docstring? > +If INSERT is non-nil insert the text if not found." Insert where? What text? Could you tweak docstring to specify that INSERT is a string and where it is going to be inserted? > (let ((re (format regex year month day)) > match) > (goto-char (point-min)) > @@ -86,25 +126,27 @@ (defun org-datetree--find-create (regex year &optional month day) > ((not match) > (goto-char (point-max)) > (unless (bolp) (newline)) > - (org-datetree-insert-line year month day)) > + (org-datetree-insert-line year month day insert)) > ((= (string-to-number (match-string 1)) (or day month year)) > (goto-char (point-at-bol))) While you're at it: (beginning-of-line) Regards, ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 2/3] org-datetree.el: Add support for ISO week trees. 2015-09-02 19:58 ` Nicolas Goaziou @ 2015-09-03 0:14 ` Rüdiger Sonderfeld 2015-09-03 5:55 ` Nicolas Goaziou 0 siblings, 1 reply; 20+ messages in thread From: Rüdiger Sonderfeld @ 2015-09-03 0:14 UTC (permalink / raw) To: Nicolas Goaziou; +Cc: emacs-orgmode, Rüdiger Sonderfeld On Wednesday 02 September 2015 21:58:17 Nicolas Goaziou wrote: > Rüdiger Sonderfeld <ruediger@c-plusplus.net> writes: > > + (let ((prop (org-find-property "DATE_WEEK_TREE"))) > > I don't think we need to introduce a new property for that. DATE_TREE is > enough. Since DATE_TREE and DATE_WEEK_TREE (or WEEK_TREE instead?) are structured differently it might make sense to keep the property separated. > > + ;; ISO 8601 week format is %G-W%V(-%u) > > + (org-datetree--find-create "^\\*+[ > > \t]+\\([12][0-9]\\{3\\}\\)\\(\\s-*?\\([ > > \t]:[[:alnum:]:_@#%%]+:\\)?\\s-*$\\)" > Isn't this line too long? What's the limit? Because if it's 80 char then I'd need to do some `concat' ugliness because the regex is over 80 char long. I've fixed the rest and will send updated patches. Cheers, Rüdiger ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 2/3] org-datetree.el: Add support for ISO week trees. 2015-09-03 0:14 ` Rüdiger Sonderfeld @ 2015-09-03 5:55 ` Nicolas Goaziou 2015-09-07 22:24 ` [PATCH v2 1/3] org-datetree.el: Code cleanup Rüdiger Sonderfeld ` (3 more replies) 0 siblings, 4 replies; 20+ messages in thread From: Nicolas Goaziou @ 2015-09-03 5:55 UTC (permalink / raw) To: Rüdiger Sonderfeld; +Cc: emacs-orgmode, Rüdiger Sonderfeld Rüdiger Sonderfeld <ruediger@c-plusplus.de> writes: > On Wednesday 02 September 2015 21:58:17 Nicolas Goaziou wrote: >> Rüdiger Sonderfeld <ruediger@c-plusplus.net> writes: >> > + (let ((prop (org-find-property "DATE_WEEK_TREE"))) >> >> I don't think we need to introduce a new property for that. DATE_TREE is >> enough. > > Since DATE_TREE and DATE_WEEK_TREE (or WEEK_TREE instead?) are structured > differently it might make sense to keep the property separated. If you want both a date tree and a week tree in the same, you probably want them to start at the same level, don't you? >> > + ;; ISO 8601 week format is %G-W%V(-%u) >> > + (org-datetree--find-create "^\\*+[ >> > \t]+\\([12][0-9]\\{3\\}\\)\\(\\s-*?\\([ >> > \t]:[[:alnum:]:_@#%%]+:\\)?\\s-*$\\)" >> Isn't this line too long? > > What's the limit? Because if it's 80 char then I'd need to do some `concat' > ugliness because the regex is over 80 char long. You can use continuation markup, i.e., "\\n". Regards, ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v2 1/3] org-datetree.el: Code cleanup. 2015-09-03 5:55 ` Nicolas Goaziou @ 2015-09-07 22:24 ` Rüdiger Sonderfeld 2015-09-07 22:24 ` [PATCH v2 2/3] org-datetree.el: Add support for ISO week trees Rüdiger Sonderfeld ` (2 subsequent siblings) 3 siblings, 0 replies; 20+ messages in thread From: Rüdiger Sonderfeld @ 2015-09-07 22:24 UTC (permalink / raw) To: emacs-orgmode; +Cc: Nicolas Goaziou * lisp/org-datetree.el (org-datetree--find-create): New function. (org-datetree-find-year-create, org-datetree-find-month-create, org-datetree-find-day-create): Removed functions (org-datetree-find-date-create): Use `org-datetree--find-create' instead of removed functions. Use calendar extract functions. (org-datetree-insert-line): Do more formatting in `format-time-string' since we call it anyway * testing/lisp/test-org-datetree.el (test-org-datetree/find-date-create): Test if new entries are put at the right place. --- lisp/org-datetree.el | 90 +++++++++++++-------------------------- testing/lisp/test-org-datetree.el | 9 ++++ 2 files changed, 38 insertions(+), 61 deletions(-) diff --git a/lisp/org-datetree.el b/lisp/org-datetree.el index a97a9d0..ea7afe7 100644 --- a/lisp/org-datetree.el +++ b/lisp/org-datetree.el @@ -64,70 +64,42 @@ (defun org-datetree-find-date-create (date &optional keep-restriction) (org-get-valid-level (org-current-level) 1)) (org-narrow-to-subtree))) (goto-char (point-min)) - (let ((year (nth 2 date)) - (month (car date)) - (day (nth 1 date))) - (org-datetree-find-year-create year) - (org-datetree-find-month-create year month) - (org-datetree-find-day-create year month day)))) - -(defun org-datetree-find-year-create (year) - "Find the YEAR datetree or create it." - (let ((re "^\\*+[ \t]+\\([12][0-9]\\{3\\}\\)\\(\\s-*?\\([ \t]:[[:alnum:]:_@#%]+:\\)?\\s-*$\\)") + (let ((year (calendar-extract-year date)) + (month (calendar-extract-month date)) + (day (calendar-extract-day date))) + (org-datetree--find-create + "^\\*+[ \t]+\\([12][0-9]\\{3\\}\\)\\(\\s-*?\ +\\([ \t]:[[:alnum:]:_@#%%]+:\\)?\\s-*$\\)" + year) + (org-datetree--find-create + "^\\*+[ \t]+%d-\\([01][0-9]\\) \\w+$" + year month) + (org-datetree--find-create + "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" + year month day)))) + +(defun org-datetree--find-create (regex year &optional month day) + "Find the datetree matched by REGEX for YEAR, MONTH, or DAY. +REGEX is passed to `format' with YEAR, MONTH, and DAY as +arguments. Match group 1 is compared against the specified date +component." + (when (or month day) + (org-narrow-to-subtree)) + (let ((re (format regex year month day)) 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))) + (< (string-to-number (match-string 1)) (or day month 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) - "Find the datetree for YEAR and MONTH or create it." - (org-narrow-to-subtree) - (let ((re (format "^\\*+[ \t]+%d-\\([01][0-9]\\) \\w+$" 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) - "Find the datetree for YEAR, MONTH and DAY or create it." - (org-narrow-to-subtree) - (let ((re (format "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" 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)) + (unless (bolp) (insert "\n")) (org-datetree-insert-line year month day)) - ((= (string-to-number (match-string 1)) day) - (goto-char (point-at-bol))) + ((= (string-to-number (match-string 1)) (or day month year)) + (beginning-of-line)) (t - (beginning-of-line 1) + (beginning-of-line) (org-datetree-insert-line year month day))))) (defun org-datetree-insert-line (year &optional month day) @@ -139,13 +111,9 @@ (defun org-datetree-insert-line (year &optional month day) (insert (format "%d" year)) (when month (insert - (format "-%02d" month) (if day - (format "-%02d %s" - day - (format-time-string "%A" (encode-time 0 0 0 day month year))) - (format " %s" - (format-time-string "%B" (encode-time 0 0 0 1 month year)))))) + (format-time-string "-%m-%d %A" (encode-time 0 0 0 day month year)) + (format-time-string "-%m %B" (encode-time 0 0 0 1 month year))))) (when (and day org-datetree-add-timestamp) (save-excursion (insert "\n") diff --git a/testing/lisp/test-org-datetree.el b/testing/lisp/test-org-datetree.el index d500130..bbc8e14 100644 --- a/testing/lisp/test-org-datetree.el +++ b/testing/lisp/test-org-datetree.el @@ -55,6 +55,15 @@ (ert-deftest test-org-datetree/find-date-create () (let ((org-datetree-add-timestamp nil)) (org-datetree-find-date-create '(3 29 2012))) (org-trim (buffer-string))))) + ;; Sort new entry in right place. + (should + (string-match + "\\`\\* 2012\n\\*\\* 2012-02 .*\n\\*\\*\\* 2012-02-01 .*\n\n\\*\\* 2012-03 .*\n\\*\\*\\* 2012-03-29 .*\\'" + (org-test-with-temp-text "* 2012\n** 2012-03 month\n*** 2012-03-29 day" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-date-create '(3 29 2012)) + (org-datetree-find-date-create '(2 1 2012))) + (org-trim (buffer-string))))) ;; When `org-datetree-add-timestamp' is non-nil, insert a timestamp ;; in entry. When set to `inactive', insert an inactive one. (should -- 2.5.1 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 2/3] org-datetree.el: Add support for ISO week trees. 2015-09-03 5:55 ` Nicolas Goaziou 2015-09-07 22:24 ` [PATCH v2 1/3] org-datetree.el: Code cleanup Rüdiger Sonderfeld @ 2015-09-07 22:24 ` Rüdiger Sonderfeld 2015-09-07 22:24 ` [PATCH v2 3/3] org-capture.el: Add support for " Rüdiger Sonderfeld 2015-09-07 22:27 ` [PATCH 2/3] org-datetree.el: Add support for ISO " Rüdiger Sonderfeld 3 siblings, 0 replies; 20+ messages in thread From: Rüdiger Sonderfeld @ 2015-09-07 22:24 UTC (permalink / raw) To: emacs-orgmode; +Cc: Nicolas Goaziou * lisp/org-datetree.el (org-datetree-find-iso-date-create): New function. (org-datetree--find-create): Support fixed text for insert. (org-datetree-insert-line): Support fixed text for insert. * testing/lisp/test-org-datetree.el (test-org-datetree/find-iso-date-create): New test. ISO week trees order dates by week and not by month. --- lisp/org-datetree.el | 68 ++++++++++++++++++++++++----- testing/lisp/test-org-datetree.el | 92 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 11 deletions(-) diff --git a/lisp/org-datetree.el b/lisp/org-datetree.el index ea7afe7..1c24927 100644 --- a/lisp/org-datetree.el +++ b/lisp/org-datetree.el @@ -78,11 +78,55 @@ (defun org-datetree-find-date-create (date &optional keep-restriction) "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" year month day)))) -(defun org-datetree--find-create (regex year &optional month day) +;;;###autoload +(defun org-datetree-find-iso-week-create (date &optional keep-restriction) + "Find or create an ISO week entry for DATE. +Compared to `org-datetree-find-date-create' this function creates +entries ordered by week instead of months. +If KEEP-RESTRICTION is non-nil, do not widen the buffer. When it +is nil, the buffer will be widened to make sure an existing date +tree can be found." + (org-set-local 'org-datetree-base-level 1) + (or keep-restriction (widen)) + (save-restriction + (let ((prop (org-find-property "WEEK_TREE"))) + (when prop + (goto-char prop) + (org-set-local 'org-datetree-base-level + (org-get-valid-level (org-current-level) 1)) + (org-narrow-to-subtree))) + (goto-char (point-min)) + (require 'cal-iso) + (let* ((year (calendar-extract-year date)) + (month (calendar-extract-month date)) + (day (calendar-extract-day date)) + (time (encode-time 0 0 0 day month year)) + (iso-date (calendar-iso-from-absolute + (calendar-absolute-from-gregorian date))) + (weekyear (nth 2 iso-date)) + (week (nth 0 iso-date)) + (weekday (nth 1 iso-date))) + ;; ISO 8601 week format is %G-W%V(-%u) + (org-datetree--find-create + "^\\*+[ \t]+\\([12][0-9]\\{3\\}\\)\\(\\s-*?\ +\\([ \t]:[[:alnum:]:_@#%%]+:\\)?\\s-*$\\)" + weekyear nil nil + (format-time-string "%G" time)) + (org-datetree--find-create + "^\\*+[ \t]+%d-W\\([0-5][0-9]\\)$" + weekyear week nil + (format-time-string "%G-W%V" time)) + ;; For the actual day we use the regular date instead of ISO week. + (org-datetree--find-create + "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" + year month day)))) + +(defun org-datetree--find-create (regex year &optional month day insert) "Find the datetree matched by REGEX for YEAR, MONTH, or DAY. REGEX is passed to `format' with YEAR, MONTH, and DAY as arguments. Match group 1 is compared against the specified date -component." +component. If INSERT is non-nil and there is no match then it is +inserted into the buffer." (when (or month day) (org-narrow-to-subtree)) (let ((re (format regex year month day)) @@ -95,25 +139,27 @@ (defun org-datetree--find-create (regex year &optional month day) ((not match) (goto-char (point-max)) (unless (bolp) (insert "\n")) - (org-datetree-insert-line year month day)) + (org-datetree-insert-line year month day insert)) ((= (string-to-number (match-string 1)) (or day month year)) (beginning-of-line)) (t (beginning-of-line) - (org-datetree-insert-line year month day))))) + (org-datetree-insert-line year month day insert))))) -(defun org-datetree-insert-line (year &optional month day) +(defun org-datetree-insert-line (year &optional month day text) (delete-region (save-excursion (skip-chars-backward " \t\n") (point)) (point)) (insert "\n" (make-string org-datetree-base-level ?*) " \n") (backward-char) (when month (org-do-demote)) (when day (org-do-demote)) - (insert (format "%d" year)) - (when month - (insert - (if day - (format-time-string "-%m-%d %A" (encode-time 0 0 0 day month year)) - (format-time-string "-%m %B" (encode-time 0 0 0 1 month year))))) + (if text + (insert text) + (insert (format "%d" year)) + (when month + (insert + (if day + (format-time-string "-%m-%d %A" (encode-time 0 0 0 day month year)) + (format-time-string "-%m %B" (encode-time 0 0 0 1 month year)))))) (when (and day org-datetree-add-timestamp) (save-excursion (insert "\n") diff --git a/testing/lisp/test-org-datetree.el b/testing/lisp/test-org-datetree.el index bbc8e14..dab54ba 100644 --- a/testing/lisp/test-org-datetree.el +++ b/testing/lisp/test-org-datetree.el @@ -113,5 +113,97 @@ (ert-deftest test-org-datetree/find-date-create () (org-datetree-find-date-create '(3 29 2012))) (buffer-substring (point) (line-end-position)))))) +(ert-deftest test-org-datetree/find-iso-week-create () + "Test `org-datetree-find-iso-date-create' specificaiton." + ;; When date is missing, create it. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\\'" + (org-test-with-temp-text "" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Do not create new year node when one exists. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\\'" + (org-test-with-temp-text "* 2015\n" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Do not create new month node when one exists. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\\'" + (org-test-with-temp-text "* 2015\n** 2015-W01" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Do not create new day node when one exists. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\\'" + (org-test-with-temp-text "* 2015\n** 2015-W01\n*** 2014-12-31 day" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Sort new entry in right place. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\n\n\\*\\* 2015-W36\n\\*\\*\\* 2015-09-01 .*\\'" + (org-test-with-temp-text "* 2015" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(9 1 2015)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; When `org-datetree-add-timestamp' is non-nil, insert a timestamp + ;; in entry. When set to `inactive', insert an inactive one. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* \\(2014-12-31\\) .*\n[ \t]*<\\1.*?>\\'" + (org-test-with-temp-text "* 2015\n" + (let ((org-datetree-add-timestamp t)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* \\(2014-12-31\\) .*\n[ \t]*\\[\\1.*?\\]\\'" + (org-test-with-temp-text "* 2015\n" + (let ((org-datetree-add-timestamp 'inactive)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Insert at top level, unless some node has DATE_WEEK_TREE + ;; property. In this case, date tree becomes one of its sub-trees. + (should + (string-match + "\\* 2015" + (org-test-with-temp-text "* Top" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + (should + (string-match + "\\*\\* H1.1\n:PROPERTIES:\n:DATE_WEEK_TREE: t\n:END:\n\\*\\*\\* 2015" + (org-test-with-temp-text + "* H1\n** H1.1\n:PROPERTIES:\n:DATE_WEEK_TREE: t\n:END:\n* H2" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Always leave point at beginning of day entry. + (should + (string-match + "\\*\\*\\* 2014-12-31" + (org-test-with-temp-text "* 2015\n** 2015-W01\n*** 2014-12-31 day" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (buffer-substring (point) (line-end-position))))) + (should + (string-match + "\\*\\*\\* 2014-12-31" + (org-test-with-temp-text "* 2015\n** 2015-W01\n*** 2014-12-31 day" + (let ((org-datetree-add-timestamp t)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (buffer-substring (point) (line-end-position)))))) + (provide 'test-org-datetree) ;;; test-org-datetree.el ends here -- 2.5.1 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 3/3] org-capture.el: Add support for week trees. 2015-09-03 5:55 ` Nicolas Goaziou 2015-09-07 22:24 ` [PATCH v2 1/3] org-datetree.el: Code cleanup Rüdiger Sonderfeld 2015-09-07 22:24 ` [PATCH v2 2/3] org-datetree.el: Add support for ISO week trees Rüdiger Sonderfeld @ 2015-09-07 22:24 ` Rüdiger Sonderfeld 2015-09-07 22:27 ` [PATCH 2/3] org-datetree.el: Add support for ISO " Rüdiger Sonderfeld 3 siblings, 0 replies; 20+ messages in thread From: Rüdiger Sonderfeld @ 2015-09-07 22:24 UTC (permalink / raw) To: emacs-orgmode; +Cc: Nicolas Goaziou * lisp/org-capture.el (org-capture-templates): Add file+weektree(+prompt) options. (org-capture-set-target-location): Add support for week trees. * doc/org.texi (Template elements): Document file+weektree(+prompt) options. --- doc/org.texi | 7 +++++++ lisp/org-capture.el | 26 +++++++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/doc/org.texi b/doc/org.texi index ed808be..d894f91 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -7187,6 +7187,13 @@ @item (file+datetree+prompt "path/to/file") Will create a heading in a date tree, but will prompt for the date. +@item (file+weektree "path/to/file") +Will create a heading in a week tree for today's date. Week trees are sorted +by week and not by month unlike datetrees. + +@item (file+weektree+prompt "path/to/file") +Will create a heading in a week tree, but will prompt for the date. + @item (file+function "path/to/file" function-finding-location) A function to find the right location in the file. diff --git a/lisp/org-capture.el b/lisp/org-capture.el index 93a7f2a..320954e 100644 --- a/lisp/org-capture.el +++ b/lisp/org-capture.el @@ -149,6 +149,12 @@ (defcustom org-capture-templates nil (file+datetree+prompt \"path/to/file\") Will create a heading in a date tree, prompts for date + (file+weektree \"path/to/file\") + Will create a heading in a week tree for today's date + + (file+weektree+prompt \"path/to/file\") + Will create a heading in a week tree, prompts for date + (file+function \"path/to/file\" function-finding-location) A function to find the right location in the file @@ -321,6 +327,12 @@ (defcustom org-capture-templates nil (list :tag "File & Date tree, prompt for date" (const :format "" file+datetree+prompt) (file :tag " File")) + (list :tag "File & Week tree" + (const :format "" file+weektree) + (file :tag " File")) + (list :tag "File & Week tree, prompt for date" + (const :format "" file+weektree+prompt) + (file :tag " File")) (list :tag "File & function" (const :format "" file+function) (file :tag " File ") @@ -895,21 +907,25 @@ (defun org-capture-set-target-location (&optional target) (setq target-entry-p (and (derived-mode-p 'org-mode) (org-at-heading-p)))) (error "No match for target regexp in file %s" (nth 1 target)))) - ((memq (car target) '(file+datetree file+datetree+prompt)) + ((memq (car target) '(file+datetree file+datetree+prompt file+weektree file+weektree+prompt)) (require 'org-datetree) (set-buffer (org-capture-target-buffer (nth 1 target))) (org-capture-put-target-region-and-position) (widen) - ;; Make a date tree entry, with the current date (or yesterday, - ;; if we are extending dates for a couple of hours) - (org-datetree-find-date-create + ;; Make a date/week tree entry, with the current date (or + ;; yesterday, if we are extending dates for a couple of hours) + (funcall + (cond + ((memq (car target) '(file+weektree file+weektree+prompt)) + #'org-datetree-find-iso-week-create) + (t #'org-datetree-find-date-create)) (calendar-gregorian-from-absolute (cond (org-overriding-default-time ;; use the overriding default time (time-to-days org-overriding-default-time)) - ((eq (car target) 'file+datetree+prompt) + ((memq (car target) '(file+datetree+prompt file+weektree+prompt)) ;; prompt for date (let ((prompt-time (org-read-date nil t nil "Date for tree entry:" -- 2.5.1 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 2/3] org-datetree.el: Add support for ISO week trees. 2015-09-03 5:55 ` Nicolas Goaziou ` (2 preceding siblings ...) 2015-09-07 22:24 ` [PATCH v2 3/3] org-capture.el: Add support for " Rüdiger Sonderfeld @ 2015-09-07 22:27 ` Rüdiger Sonderfeld 2015-09-08 15:53 ` Nicolas Goaziou 3 siblings, 1 reply; 20+ messages in thread From: Rüdiger Sonderfeld @ 2015-09-07 22:27 UTC (permalink / raw) To: Nicolas Goaziou; +Cc: emacs-orgmode, Rüdiger Sonderfeld On Thursday 03 September 2015 07:55:08 Nicolas Goaziou wrote: > Rüdiger Sonderfeld <ruediger@c-plusplus.de> writes: > > On Wednesday 02 September 2015 21:58:17 Nicolas Goaziou wrote: > >> Rüdiger Sonderfeld <ruediger@c-plusplus.net> writes: > >> > + (let ((prop (org-find-property "DATE_WEEK_TREE"))) > >> > >> I don't think we need to introduce a new property for that. DATE_TREE is > >> enough. > > > > Since DATE_TREE and DATE_WEEK_TREE (or WEEK_TREE instead?) are structured > > differently it might make sense to keep the property separated. > > If you want both a date tree and a week tree in the same, you probably > want them to start at the same level, don't you? I don't think that's necessarily true since both formats don't mix well. If anyone still wants it then they can simply add both properties. I've send updated versions of the patches as a reply to this message. Regards, Rüdiger ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 2/3] org-datetree.el: Add support for ISO week trees. 2015-09-07 22:27 ` [PATCH 2/3] org-datetree.el: Add support for ISO " Rüdiger Sonderfeld @ 2015-09-08 15:53 ` Nicolas Goaziou 2015-12-29 17:48 ` [PATCH v3 1/3] org-datetree.el: Code cleanup Rüdiger Sonderfeld ` (2 more replies) 0 siblings, 3 replies; 20+ messages in thread From: Nicolas Goaziou @ 2015-09-08 15:53 UTC (permalink / raw) To: Rüdiger Sonderfeld; +Cc: emacs-orgmode, Rüdiger Sonderfeld Hello, Rüdiger Sonderfeld <ruediger@c-plusplus.de> writes: > I don't think that's necessarily true since both formats don't mix well. If > anyone still wants it then they can simply add both properties. OK, then please document the property in the manual, and add an entry in ORG-NEWS. Otherwise, LGTM. Regards, -- Nicolas Goaziou ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v3 1/3] org-datetree.el: Code cleanup. 2015-09-08 15:53 ` Nicolas Goaziou @ 2015-12-29 17:48 ` Rüdiger Sonderfeld 2015-12-29 20:58 ` Nicolas Goaziou 2015-12-29 17:49 ` [PATCH v3 2/3] org-datetree.el: Add support for ISO week trees Rüdiger Sonderfeld 2015-12-29 17:49 ` [PATCH v3 3/3] org-capture.el: Add support for " Rüdiger Sonderfeld 2 siblings, 1 reply; 20+ messages in thread From: Rüdiger Sonderfeld @ 2015-12-29 17:48 UTC (permalink / raw) To: emacs-orgmode; +Cc: mail * lisp/org-datetree.el (org-datetree--find-create): New function. (org-datetree-find-year-create, org-datetree-find-month-create, org-datetree-find-day-create): Removed functions (org-datetree-find-date-create): Use `org-datetree--find-create' instead of removed functions. Use calendar extract functions. (org-datetree-insert-line): Do more formatting in `format-time-string' since we call it anyway * testing/lisp/test-org-datetree.el (test-org-datetree/find-date-create): Test if new entries are put at the right place. --- lisp/org-datetree.el | 90 +++++++++++++-------------------------- testing/lisp/test-org-datetree.el | 9 ++++ 2 files changed, 38 insertions(+), 61 deletions(-) diff --git a/lisp/org-datetree.el b/lisp/org-datetree.el index 6c4a410..2c9ffdf 100644 --- a/lisp/org-datetree.el +++ b/lisp/org-datetree.el @@ -64,70 +64,42 @@ (defun org-datetree-find-date-create (date &optional keep-restriction) (org-get-valid-level (org-current-level) 1)) (org-narrow-to-subtree))) (goto-char (point-min)) - (let ((year (nth 2 date)) - (month (car date)) - (day (nth 1 date))) - (org-datetree-find-year-create year) - (org-datetree-find-month-create year month) - (org-datetree-find-day-create year month day)))) - -(defun org-datetree-find-year-create (year) - "Find the YEAR datetree or create it." - (let ((re "^\\*+[ \t]+\\([12][0-9]\\{3\\}\\)\\(\\s-*?\\([ \t]:[[:alnum:]:_@#%]+:\\)?\\s-*$\\)") + (let ((year (calendar-extract-year date)) + (month (calendar-extract-month date)) + (day (calendar-extract-day date))) + (org-datetree--find-create + "^\\*+[ \t]+\\([12][0-9]\\{3\\}\\)\\(\\s-*?\ +\\([ \t]:[[:alnum:]:_@#%%]+:\\)?\\s-*$\\)" + year) + (org-datetree--find-create + "^\\*+[ \t]+%d-\\([01][0-9]\\) \\w+$" + year month) + (org-datetree--find-create + "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" + year month day)))) + +(defun org-datetree--find-create (regex year &optional month day) + "Find the datetree matched by REGEX for YEAR, MONTH, or DAY. +REGEX is passed to `format' with YEAR, MONTH, and DAY as +arguments. Match group 1 is compared against the specified date +component." + (when (or month day) + (org-narrow-to-subtree)) + (let ((re (format regex year month day)) 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))) + (< (string-to-number (match-string 1)) (or day month 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) - "Find the datetree for YEAR and MONTH or create it." - (org-narrow-to-subtree) - (let ((re (format "^\\*+[ \t]+%d-\\([01][0-9]\\) \\w+$" 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) - "Find the datetree for YEAR, MONTH and DAY or create it." - (org-narrow-to-subtree) - (let ((re (format "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" 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)) + (unless (bolp) (insert "\n")) (org-datetree-insert-line year month day)) - ((= (string-to-number (match-string 1)) day) - (goto-char (point-at-bol))) + ((= (string-to-number (match-string 1)) (or day month year)) + (beginning-of-line)) (t - (beginning-of-line 1) + (beginning-of-line) (org-datetree-insert-line year month day))))) (defun org-datetree-insert-line (year &optional month day) @@ -139,13 +111,9 @@ (defun org-datetree-insert-line (year &optional month day) (insert (format "%d" year)) (when month (insert - (format "-%02d" month) (if day - (format "-%02d %s" - day - (format-time-string "%A" (encode-time 0 0 0 day month year))) - (format " %s" - (format-time-string "%B" (encode-time 0 0 0 1 month year)))))) + (format-time-string "-%m-%d %A" (encode-time 0 0 0 day month year)) + (format-time-string "-%m %B" (encode-time 0 0 0 1 month year))))) (when (and day org-datetree-add-timestamp) (save-excursion (insert "\n") diff --git a/testing/lisp/test-org-datetree.el b/testing/lisp/test-org-datetree.el index d500130..bbc8e14 100644 --- a/testing/lisp/test-org-datetree.el +++ b/testing/lisp/test-org-datetree.el @@ -55,6 +55,15 @@ (ert-deftest test-org-datetree/find-date-create () (let ((org-datetree-add-timestamp nil)) (org-datetree-find-date-create '(3 29 2012))) (org-trim (buffer-string))))) + ;; Sort new entry in right place. + (should + (string-match + "\\`\\* 2012\n\\*\\* 2012-02 .*\n\\*\\*\\* 2012-02-01 .*\n\n\\*\\* 2012-03 .*\n\\*\\*\\* 2012-03-29 .*\\'" + (org-test-with-temp-text "* 2012\n** 2012-03 month\n*** 2012-03-29 day" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-date-create '(3 29 2012)) + (org-datetree-find-date-create '(2 1 2012))) + (org-trim (buffer-string))))) ;; When `org-datetree-add-timestamp' is non-nil, insert a timestamp ;; in entry. When set to `inactive', insert an inactive one. (should -- 2.6.4 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v3 1/3] org-datetree.el: Code cleanup. 2015-12-29 17:48 ` [PATCH v3 1/3] org-datetree.el: Code cleanup Rüdiger Sonderfeld @ 2015-12-29 20:58 ` Nicolas Goaziou 0 siblings, 0 replies; 20+ messages in thread From: Nicolas Goaziou @ 2015-12-29 20:58 UTC (permalink / raw) To: Rüdiger Sonderfeld; +Cc: emacs-orgmode Hello, Rüdiger Sonderfeld <ruediger@c-plusplus.net> writes: > * lisp/org-datetree.el (org-datetree--find-create): New function. > (org-datetree-find-year-create, org-datetree-find-month-create, > org-datetree-find-day-create): Removed functions > (org-datetree-find-date-create): Use `org-datetree--find-create' instead > of removed functions. Use calendar extract functions. > (org-datetree-insert-line): Do more formatting in `format-time-string' > since we call it anyway > * testing/lisp/test-org-datetree.el (test-org-datetree/find-date-create): > Test if new entries are put at the right place. Applied. Thank you. Regards, -- Nicolas Goaziou ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v3 2/3] org-datetree.el: Add support for ISO week trees. 2015-09-08 15:53 ` Nicolas Goaziou 2015-12-29 17:48 ` [PATCH v3 1/3] org-datetree.el: Code cleanup Rüdiger Sonderfeld @ 2015-12-29 17:49 ` Rüdiger Sonderfeld 2015-12-29 20:59 ` Nicolas Goaziou 2015-12-29 17:49 ` [PATCH v3 3/3] org-capture.el: Add support for " Rüdiger Sonderfeld 2 siblings, 1 reply; 20+ messages in thread From: Rüdiger Sonderfeld @ 2015-12-29 17:49 UTC (permalink / raw) To: emacs-orgmode; +Cc: mail * lisp/org-datetree.el (org-datetree-find-iso-date-create): New function. (org-datetree--find-create): Support fixed text for insert. (org-datetree-insert-line): Support fixed text for insert. * testing/lisp/test-org-datetree.el (test-org-datetree/find-iso-date-create): New test. ISO week trees order dates by week and not by month. --- lisp/org-datetree.el | 75 +++++++++++++++++++++++++------ testing/lisp/test-org-datetree.el | 92 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+), 14 deletions(-) diff --git a/lisp/org-datetree.el b/lisp/org-datetree.el index 2c9ffdf..5d52756 100644 --- a/lisp/org-datetree.el +++ b/lisp/org-datetree.el @@ -34,9 +34,10 @@ (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 (any value), the date tree will become a subtree under that entry, -so the base level will be properly adjusted.") +This is normally one, but if the buffer has an entry with a +DATE_TREE (or WEEK_TREE for ISO week entries) property (any +value), the date tree will become a subtree under that entry, so +the base level will be properly adjusted.") (defcustom org-datetree-add-timestamp nil "When non-nil, add a time stamp matching date of entry. @@ -78,11 +79,55 @@ (defun org-datetree-find-date-create (date &optional keep-restriction) "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" year month day)))) -(defun org-datetree--find-create (regex year &optional month day) +;;;###autoload +(defun org-datetree-find-iso-week-create (date &optional keep-restriction) + "Find or create an ISO week entry for DATE. +Compared to `org-datetree-find-date-create' this function creates +entries ordered by week instead of months. +If KEEP-RESTRICTION is non-nil, do not widen the buffer. When it +is nil, the buffer will be widened to make sure an existing date +tree can be found." + (org-set-local 'org-datetree-base-level 1) + (or keep-restriction (widen)) + (save-restriction + (let ((prop (org-find-property "WEEK_TREE"))) + (when prop + (goto-char prop) + (org-set-local 'org-datetree-base-level + (org-get-valid-level (org-current-level) 1)) + (org-narrow-to-subtree))) + (goto-char (point-min)) + (require 'cal-iso) + (let* ((year (calendar-extract-year date)) + (month (calendar-extract-month date)) + (day (calendar-extract-day date)) + (time (encode-time 0 0 0 day month year)) + (iso-date (calendar-iso-from-absolute + (calendar-absolute-from-gregorian date))) + (weekyear (nth 2 iso-date)) + (week (nth 0 iso-date)) + (weekday (nth 1 iso-date))) + ;; ISO 8601 week format is %G-W%V(-%u) + (org-datetree--find-create + "^\\*+[ \t]+\\([12][0-9]\\{3\\}\\)\\(\\s-*?\ +\\([ \t]:[[:alnum:]:_@#%%]+:\\)?\\s-*$\\)" + weekyear nil nil + (format-time-string "%G" time)) + (org-datetree--find-create + "^\\*+[ \t]+%d-W\\([0-5][0-9]\\)$" + weekyear week nil + (format-time-string "%G-W%V" time)) + ;; For the actual day we use the regular date instead of ISO week. + (org-datetree--find-create + "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" + year month day)))) + +(defun org-datetree--find-create (regex year &optional month day insert) "Find the datetree matched by REGEX for YEAR, MONTH, or DAY. REGEX is passed to `format' with YEAR, MONTH, and DAY as arguments. Match group 1 is compared against the specified date -component." +component. If INSERT is non-nil and there is no match then it is +inserted into the buffer." (when (or month day) (org-narrow-to-subtree)) (let ((re (format regex year month day)) @@ -95,25 +140,27 @@ (defun org-datetree--find-create (regex year &optional month day) ((not match) (goto-char (point-max)) (unless (bolp) (insert "\n")) - (org-datetree-insert-line year month day)) + (org-datetree-insert-line year month day insert)) ((= (string-to-number (match-string 1)) (or day month year)) (beginning-of-line)) (t (beginning-of-line) - (org-datetree-insert-line year month day))))) + (org-datetree-insert-line year month day insert))))) -(defun org-datetree-insert-line (year &optional month day) +(defun org-datetree-insert-line (year &optional month day text) (delete-region (save-excursion (skip-chars-backward " \t\n") (point)) (point)) (insert "\n" (make-string org-datetree-base-level ?*) " \n") (backward-char) (when month (org-do-demote)) (when day (org-do-demote)) - (insert (format "%d" year)) - (when month - (insert - (if day - (format-time-string "-%m-%d %A" (encode-time 0 0 0 day month year)) - (format-time-string "-%m %B" (encode-time 0 0 0 1 month year))))) + (if text + (insert text) + (insert (format "%d" year)) + (when month + (insert + (if day + (format-time-string "-%m-%d %A" (encode-time 0 0 0 day month year)) + (format-time-string "-%m %B" (encode-time 0 0 0 1 month year)))))) (when (and day org-datetree-add-timestamp) (save-excursion (insert "\n") diff --git a/testing/lisp/test-org-datetree.el b/testing/lisp/test-org-datetree.el index bbc8e14..dab54ba 100644 --- a/testing/lisp/test-org-datetree.el +++ b/testing/lisp/test-org-datetree.el @@ -113,5 +113,97 @@ (ert-deftest test-org-datetree/find-date-create () (org-datetree-find-date-create '(3 29 2012))) (buffer-substring (point) (line-end-position)))))) +(ert-deftest test-org-datetree/find-iso-week-create () + "Test `org-datetree-find-iso-date-create' specificaiton." + ;; When date is missing, create it. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\\'" + (org-test-with-temp-text "" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Do not create new year node when one exists. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\\'" + (org-test-with-temp-text "* 2015\n" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Do not create new month node when one exists. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\\'" + (org-test-with-temp-text "* 2015\n** 2015-W01" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Do not create new day node when one exists. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\\'" + (org-test-with-temp-text "* 2015\n** 2015-W01\n*** 2014-12-31 day" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Sort new entry in right place. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\n\n\\*\\* 2015-W36\n\\*\\*\\* 2015-09-01 .*\\'" + (org-test-with-temp-text "* 2015" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(9 1 2015)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; When `org-datetree-add-timestamp' is non-nil, insert a timestamp + ;; in entry. When set to `inactive', insert an inactive one. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* \\(2014-12-31\\) .*\n[ \t]*<\\1.*?>\\'" + (org-test-with-temp-text "* 2015\n" + (let ((org-datetree-add-timestamp t)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* \\(2014-12-31\\) .*\n[ \t]*\\[\\1.*?\\]\\'" + (org-test-with-temp-text "* 2015\n" + (let ((org-datetree-add-timestamp 'inactive)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Insert at top level, unless some node has DATE_WEEK_TREE + ;; property. In this case, date tree becomes one of its sub-trees. + (should + (string-match + "\\* 2015" + (org-test-with-temp-text "* Top" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + (should + (string-match + "\\*\\* H1.1\n:PROPERTIES:\n:DATE_WEEK_TREE: t\n:END:\n\\*\\*\\* 2015" + (org-test-with-temp-text + "* H1\n** H1.1\n:PROPERTIES:\n:DATE_WEEK_TREE: t\n:END:\n* H2" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Always leave point at beginning of day entry. + (should + (string-match + "\\*\\*\\* 2014-12-31" + (org-test-with-temp-text "* 2015\n** 2015-W01\n*** 2014-12-31 day" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (buffer-substring (point) (line-end-position))))) + (should + (string-match + "\\*\\*\\* 2014-12-31" + (org-test-with-temp-text "* 2015\n** 2015-W01\n*** 2014-12-31 day" + (let ((org-datetree-add-timestamp t)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (buffer-substring (point) (line-end-position)))))) + (provide 'test-org-datetree) ;;; test-org-datetree.el ends here -- 2.6.4 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v3 2/3] org-datetree.el: Add support for ISO week trees. 2015-12-29 17:49 ` [PATCH v3 2/3] org-datetree.el: Add support for ISO week trees Rüdiger Sonderfeld @ 2015-12-29 20:59 ` Nicolas Goaziou 0 siblings, 0 replies; 20+ messages in thread From: Nicolas Goaziou @ 2015-12-29 20:59 UTC (permalink / raw) To: Rüdiger Sonderfeld; +Cc: emacs-orgmode Hello, Rüdiger Sonderfeld <ruediger@c-plusplus.net> writes: > * lisp/org-datetree.el (org-datetree-find-iso-date-create): New function. > (org-datetree--find-create): Support fixed text for insert. > (org-datetree-insert-line): Support fixed text for insert. > * testing/lisp/test-org-datetree.el (test-org-datetree/find-iso-date-create): > New test. > > ISO week trees order dates by week and not by month. Applied. Thank you. Regards, -- Nicolas Goaziou ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v3 3/3] org-capture.el: Add support for week trees. 2015-09-08 15:53 ` Nicolas Goaziou 2015-12-29 17:48 ` [PATCH v3 1/3] org-datetree.el: Code cleanup Rüdiger Sonderfeld 2015-12-29 17:49 ` [PATCH v3 2/3] org-datetree.el: Add support for ISO week trees Rüdiger Sonderfeld @ 2015-12-29 17:49 ` Rüdiger Sonderfeld 2015-12-29 20:59 ` Nicolas Goaziou 2 siblings, 1 reply; 20+ messages in thread From: Rüdiger Sonderfeld @ 2015-12-29 17:49 UTC (permalink / raw) To: emacs-orgmode; +Cc: mail * lisp/org-capture.el (org-capture-templates): Add file+weektree(+prompt) options. (org-capture-set-target-location): Add support for week trees. * doc/org.texi (Template elements): Document file+weektree(+prompt) options. --- doc/org.texi | 7 +++++++ etc/ORG-NEWS | 13 +++++++++++++ lisp/org-capture.el | 26 +++++++++++++++++++++----- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/doc/org.texi b/doc/org.texi index 8f3e248..dfa989a 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -7176,6 +7176,13 @@ @item (file+datetree+prompt "path/to/file") Will create a heading in a date tree, but will prompt for the date. +@item (file+weektree "path/to/file") +Will create a heading in a week tree for today's date. Week trees are sorted +by week and not by month unlike datetrees. + +@item (file+weektree+prompt "path/to/file") +Will create a heading in a week tree, but will prompt for the date. + @item (file+function "path/to/file" function-finding-location) A function to find the right location in the file. diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 4ab48c4..b56add3 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -167,6 +167,19 @@ for details. *** org-bbdb-anniversaries-future Used like org-bbdb-anniversaries, it provides a few days warning for upcoming anniversaries (default: 7 days). +*** Support for ISO week trees +ISO week trees are an alternative date tree format that orders entries +by ISO week and not by month. + +For example: + +: * 2015 +: ** 2015-W35 +: ** 2015-W36 +: *** 2015-08-31 Monday + +They are supported in org-capture via ~file+weektree~ and +~file+weektree+prompt~ target specifications. ** New functions *** ~org-show-children~ It is a faster implementation of ~outline-show-children~. diff --git a/lisp/org-capture.el b/lisp/org-capture.el index f92ea35..13cbe9b 100644 --- a/lisp/org-capture.el +++ b/lisp/org-capture.el @@ -151,6 +151,12 @@ (defcustom org-capture-templates nil (file+datetree+prompt \"path/to/file\") Will create a heading in a date tree, prompts for date + (file+weektree \"path/to/file\") + Will create a heading in a week tree for today's date + + (file+weektree+prompt \"path/to/file\") + Will create a heading in a week tree, prompts for date + (file+function \"path/to/file\" function-finding-location) A function to find the right location in the file @@ -331,6 +337,12 @@ (defcustom org-capture-templates nil (list :tag "File & Date tree, prompt for date" (const :format "" file+datetree+prompt) (file :tag " File")) + (list :tag "File & Week tree" + (const :format "" file+weektree) + (file :tag " File")) + (list :tag "File & Week tree, prompt for date" + (const :format "" file+weektree+prompt) + (file :tag " File")) (list :tag "File & function" (const :format "" file+function) (file :tag " File ") @@ -908,21 +920,25 @@ (defun org-capture-set-target-location (&optional target) (setq target-entry-p (and (derived-mode-p 'org-mode) (org-at-heading-p)))) (error "No match for target regexp in file %s" (nth 1 target)))) - ((memq (car target) '(file+datetree file+datetree+prompt)) + ((memq (car target) '(file+datetree file+datetree+prompt file+weektree file+weektree+prompt)) (require 'org-datetree) (set-buffer (org-capture-target-buffer (nth 1 target))) (org-capture-put-target-region-and-position) (widen) - ;; Make a date tree entry, with the current date (or yesterday, - ;; if we are extending dates for a couple of hours) - (org-datetree-find-date-create + ;; Make a date/week tree entry, with the current date (or + ;; yesterday, if we are extending dates for a couple of hours) + (funcall + (cond + ((memq (car target) '(file+weektree file+weektree+prompt)) + #'org-datetree-find-iso-week-create) + (t #'org-datetree-find-date-create)) (calendar-gregorian-from-absolute (cond (org-overriding-default-time ;; use the overriding default time (time-to-days org-overriding-default-time)) - ((eq (car target) 'file+datetree+prompt) + ((memq (car target) '(file+datetree+prompt file+weektree+prompt)) ;; prompt for date (let ((prompt-time (org-read-date nil t nil "Date for tree entry:" -- 2.6.4 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v3 3/3] org-capture.el: Add support for week trees. 2015-12-29 17:49 ` [PATCH v3 3/3] org-capture.el: Add support for " Rüdiger Sonderfeld @ 2015-12-29 20:59 ` Nicolas Goaziou 0 siblings, 0 replies; 20+ messages in thread From: Nicolas Goaziou @ 2015-12-29 20:59 UTC (permalink / raw) To: Rüdiger Sonderfeld; +Cc: emacs-orgmode Hello, Rüdiger Sonderfeld <ruediger@c-plusplus.net> writes: > * lisp/org-capture.el (org-capture-templates): Add > file+weektree(+prompt) options. > (org-capture-set-target-location): Add support for week trees. > * doc/org.texi (Template elements): Document file+weektree(+prompt) > options. Applied. Thank you. Regards, -- Nicolas Goaziou ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 3/3] org-capture.el: Add support for week trees. [not found] <cover.1441180730.git.ruediger@c-plusplus.net> 2015-09-02 8:06 ` [PATCH 1/3] org-datetree.el: Code cleanup Rüdiger Sonderfeld 2015-09-02 8:06 ` [PATCH 2/3] org-datetree.el: Add support for ISO week trees Rüdiger Sonderfeld @ 2015-09-02 8:06 ` Rüdiger Sonderfeld 2015-09-02 19:59 ` Nicolas Goaziou 2 siblings, 1 reply; 20+ messages in thread From: Rüdiger Sonderfeld @ 2015-09-02 8:06 UTC (permalink / raw) To: emacs-orgmode * lisp/org-capture.el (org-capture-templates): Add file+weektree(+prompt) options. (org-capture-set-target-location): Add support for week trees. * doc/org.texi (Template elements): Document file+weektree(+prompt) options. --- doc/org.texi | 7 +++++++ lisp/org-capture.el | 26 +++++++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/doc/org.texi b/doc/org.texi index ed808be..d894f91 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -7187,6 +7187,13 @@ @item (file+datetree+prompt "path/to/file") Will create a heading in a date tree, but will prompt for the date. +@item (file+weektree "path/to/file") +Will create a heading in a week tree for today's date. Week trees are sorted +by week and not by month unlike datetrees. + +@item (file+weektree+prompt "path/to/file") +Will create a heading in a week tree, but will prompt for the date. + @item (file+function "path/to/file" function-finding-location) A function to find the right location in the file. diff --git a/lisp/org-capture.el b/lisp/org-capture.el index 93a7f2a..320954e 100644 --- a/lisp/org-capture.el +++ b/lisp/org-capture.el @@ -149,6 +149,12 @@ (defcustom org-capture-templates nil (file+datetree+prompt \"path/to/file\") Will create a heading in a date tree, prompts for date + (file+weektree \"path/to/file\") + Will create a heading in a week tree for today's date + + (file+weektree+prompt \"path/to/file\") + Will create a heading in a week tree, prompts for date + (file+function \"path/to/file\" function-finding-location) A function to find the right location in the file @@ -321,6 +327,12 @@ (defcustom org-capture-templates nil (list :tag "File & Date tree, prompt for date" (const :format "" file+datetree+prompt) (file :tag " File")) + (list :tag "File & Week tree" + (const :format "" file+weektree) + (file :tag " File")) + (list :tag "File & Week tree, prompt for date" + (const :format "" file+weektree+prompt) + (file :tag " File")) (list :tag "File & function" (const :format "" file+function) (file :tag " File ") @@ -895,21 +907,25 @@ (defun org-capture-set-target-location (&optional target) (setq target-entry-p (and (derived-mode-p 'org-mode) (org-at-heading-p)))) (error "No match for target regexp in file %s" (nth 1 target)))) - ((memq (car target) '(file+datetree file+datetree+prompt)) + ((memq (car target) '(file+datetree file+datetree+prompt file+weektree file+weektree+prompt)) (require 'org-datetree) (set-buffer (org-capture-target-buffer (nth 1 target))) (org-capture-put-target-region-and-position) (widen) - ;; Make a date tree entry, with the current date (or yesterday, - ;; if we are extending dates for a couple of hours) - (org-datetree-find-date-create + ;; Make a date/week tree entry, with the current date (or + ;; yesterday, if we are extending dates for a couple of hours) + (funcall + (cond + ((memq (car target) '(file+weektree file+weektree+prompt)) + #'org-datetree-find-iso-week-create) + (t #'org-datetree-find-date-create)) (calendar-gregorian-from-absolute (cond (org-overriding-default-time ;; use the overriding default time (time-to-days org-overriding-default-time)) - ((eq (car target) 'file+datetree+prompt) + ((memq (car target) '(file+datetree+prompt file+weektree+prompt)) ;; prompt for date (let ((prompt-time (org-read-date nil t nil "Date for tree entry:" -- 2.5.1 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 3/3] org-capture.el: Add support for week trees. 2015-09-02 8:06 ` [PATCH " Rüdiger Sonderfeld @ 2015-09-02 19:59 ` Nicolas Goaziou 0 siblings, 0 replies; 20+ messages in thread From: Nicolas Goaziou @ 2015-09-02 19:59 UTC (permalink / raw) To: Rüdiger Sonderfeld; +Cc: emacs-orgmode Rüdiger Sonderfeld <ruediger@c-plusplus.net> writes: > * lisp/org-capture.el (org-capture-templates): Add > file+weektree(+prompt) options. > (org-capture-set-target-location): Add support for week trees. > * doc/org.texi (Template elements): Document file+weektree(+prompt) > options. Looks good. Regards, ^ permalink raw reply [flat|nested] 20+ messages in thread
[parent not found: <cover.1441051750.git.ruediger@c-plusplus.net>]
* [PATCH 2/3] org-datetree.el: Add support for ISO week trees. [not found] <cover.1441051750.git.ruediger@c-plusplus.net> @ 2015-08-31 20:15 ` Rüdiger Sonderfeld 0 siblings, 0 replies; 20+ messages in thread From: Rüdiger Sonderfeld @ 2015-08-31 20:15 UTC (permalink / raw) To: emacs-orgmode * lisp/org-datetree.el (org-datetree-find-iso-date-create): New function. (org-datetree--find-create): Support fixed text for insert. (org-datetree-insert-line): Support fixed text for insert. * testing/lisp/test-org-datetree.el (test-org-datetree/find-iso-date-create): New test. ISO week trees order dates by week and not by month. --- lisp/org-datetree.el | 64 ++++++++++++++++++++++----- testing/lisp/test-org-datetree.el | 92 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 11 deletions(-) diff --git a/lisp/org-datetree.el b/lisp/org-datetree.el index 3620bbd..a5a542e 100644 --- a/lisp/org-datetree.el +++ b/lisp/org-datetree.el @@ -74,8 +74,48 @@ (defun org-datetree-find-date-create (date &optional keep-restriction) (org-datetree--find-create "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" year month day)))) -(defun org-datetree--find-create (regex year &optional month day) - "Find the datetree matched by REGEX for YEAR, MONTH, or DAY." +;;;###autoload +(defun org-datetree-find-iso-week-create (date &optional keep-restriction) + "Find or create an ISO week entry for DATE. +Compared to `org-datetree-find-date-create' this function creates +entries ordered by week instead of months. +If KEEP-RESTRICTION is non-nil, do not widen the buffer. When it +is nil, the buffer will be widened to make sure an existing date +tree can be found." + (org-set-local 'org-datetree-base-level 1) + (or keep-restriction (widen)) + (save-restriction + (let ((prop (org-find-property "DATE_WEEK_TREE"))) + (when prop + (goto-char prop) + (org-set-local 'org-datetree-base-level + (org-get-valid-level (org-current-level) 1)) + (org-narrow-to-subtree))) + (goto-char (point-min)) + (require 'cal-iso) + (let* ((year (calendar-extract-year date)) + (month (calendar-extract-month date)) + (day (calendar-extract-day date)) + (time (encode-time 0 0 0 day month year)) + (iso-date (calendar-iso-from-absolute + (calendar-absolute-from-gregorian date))) + (weekyear (nth 2 iso-date)) + (week (car iso-date)) + (weekday (cadr iso-date))) + ;; ISO 8601 week format is %G-W%V(-%u) + (org-datetree--find-create "^\\*+[ \t]+\\([12][0-9]\\{3\\}\\)\\(\\s-*?\\([ \t]:[[:alnum:]:_@#%%]+:\\)?\\s-*$\\)" + weekyear nil nil + (format-time-string "%G" time)) + (org-datetree--find-create "^\\*+[ \t]+%d-W\\([0-5][0-9]\\)$" + weekyear week nil + (format-time-string "%G-W%V" time)) + ;; For the actual day we use the regular date instead of ISO week. + (org-datetree--find-create "^\\*+[ \t]+%d-%02d-\\([0123][0-9]\\) \\w+$" + year month day)))) + +(defun org-datetree--find-create (regex year &optional month day insert) + "Find the datetree matched by REGEX for YEAR, MONTH, or DAY. +If INSERT is non-nil insert the text if not found." (let ((re (format regex year month day)) match) (goto-char (point-min)) @@ -86,25 +126,27 @@ (defun org-datetree--find-create (regex year &optional month day) ((not match) (goto-char (point-max)) (unless (bolp) (newline)) - (org-datetree-insert-line year month day)) + (org-datetree-insert-line year month day insert)) ((= (string-to-number (match-string 1)) (or day month year)) (goto-char (point-at-bol))) (t (beginning-of-line 1) - (org-datetree-insert-line year month day))))) + (org-datetree-insert-line year month day insert))))) -(defun org-datetree-insert-line (year &optional month day) +(defun org-datetree-insert-line (year &optional month day text) (delete-region (save-excursion (skip-chars-backward " \t\n") (point)) (point)) (insert "\n" (make-string org-datetree-base-level ?*) " \n") (backward-char) (when month (org-do-demote)) (when day (org-do-demote)) - (insert (format "%d" year)) - (when month - (insert - (if day - (format-time-string "-%m-%d %A" (encode-time 0 0 0 day month year)) - (format-time-string "-%m %B" (encode-time 0 0 0 1 month year))))) + (if text + (insert text) + (insert (format "%d" year)) + (when month + (insert + (if day + (format-time-string "-%m-%d %A" (encode-time 0 0 0 day month year)) + (format-time-string "-%m %B" (encode-time 0 0 0 1 month year)))))) (when (and day org-datetree-add-timestamp) (save-excursion (insert "\n") diff --git a/testing/lisp/test-org-datetree.el b/testing/lisp/test-org-datetree.el index 0135ab9..9b839ca 100644 --- a/testing/lisp/test-org-datetree.el +++ b/testing/lisp/test-org-datetree.el @@ -113,5 +113,97 @@ (ert-deftest test-org-datetree/find-date-create () (org-datetree-find-date-create '(3 29 2012))) (buffer-substring (point) (line-end-position)))))) +(ert-deftest test-org-datetree/find-iso-date-create () + "Test `org-datetree-find-iso-date-create' specificaiton." + ;; When date is missing, create it. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\\'" + (org-test-with-temp-text "" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Do not create new year node when one exists. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\\'" + (org-test-with-temp-text "* 2015\n" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Do not create new month node when one exists. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\\'" + (org-test-with-temp-text "* 2015\n** 2015-W01" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Do not create new day node when one exists. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\\'" + (org-test-with-temp-text "* 2015\n** 2015-W01\n*** 2014-12-31 day" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Sort new entry in right place + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* 2014-12-31 .*\n\n\\*\\* 2015-W36\n\\*\\*\\* 2015-09-01 .*\\'" + (org-test-with-temp-text "* 2015" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(9 1 2015)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; When `org-datetree-add-timestamp' is non-nil, insert a timestamp + ;; in entry. When set to `inactive', insert an inactive one. + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* \\(2014-12-31\\) .*\n[ \t]*<\\1.*?>\\'" + (org-test-with-temp-text "* 2015\n" + (let ((org-datetree-add-timestamp t)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + (should + (string-match + "\\`\\* 2015\n\\*\\* 2015-W01\n\\*\\*\\* \\(2014-12-31\\) .*\n[ \t]*\\[\\1.*?\\]\\'" + (org-test-with-temp-text "* 2015\n" + (let ((org-datetree-add-timestamp 'inactive)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Insert at top level, unless some node has DATE_WEEK_TREE + ;; property. In this case, date tree becomes one of its sub-trees. + (should + (string-match + "\\* 2015" + (org-test-with-temp-text "* Top" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + (should + (string-match + "\\*\\* H1.1\n:PROPERTIES:\n:DATE_WEEK_TREE: t\n:END:\n\\*\\*\\* 2015" + (org-test-with-temp-text + "* H1\n** H1.1\n:PROPERTIES:\n:DATE_WEEK_TREE: t\n:END:\n* H2" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (org-trim (buffer-string))))) + ;; Always leave point at beginning of day entry. + (should + (string-match + "\\*\\*\\* 2014-12-31" + (org-test-with-temp-text "* 2015\n** 2015-W01\n*** 2014-12-31 day" + (let ((org-datetree-add-timestamp nil)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (buffer-substring (point) (line-end-position))))) + (should + (string-match + "\\*\\*\\* 2014-12-31" + (org-test-with-temp-text "* 2015\n** 2015-W01\n*** 2014-12-31 day" + (let ((org-datetree-add-timestamp t)) + (org-datetree-find-iso-week-create '(12 31 2014))) + (buffer-substring (point) (line-end-position)))))) + (provide 'test-org-datetree) ;;; test-org-datetree.el ends here -- 2.5.1 ^ permalink raw reply related [flat|nested] 20+ messages in thread
end of thread, other threads:[~2015-12-29 20:57 UTC | newest] Thread overview: 20+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <cover.1441180730.git.ruediger@c-plusplus.net> 2015-09-02 8:06 ` [PATCH 1/3] org-datetree.el: Code cleanup Rüdiger Sonderfeld 2015-09-02 19:48 ` Nicolas Goaziou 2015-09-02 8:06 ` [PATCH 2/3] org-datetree.el: Add support for ISO week trees Rüdiger Sonderfeld 2015-09-02 19:58 ` Nicolas Goaziou 2015-09-03 0:14 ` Rüdiger Sonderfeld 2015-09-03 5:55 ` Nicolas Goaziou 2015-09-07 22:24 ` [PATCH v2 1/3] org-datetree.el: Code cleanup Rüdiger Sonderfeld 2015-09-07 22:24 ` [PATCH v2 2/3] org-datetree.el: Add support for ISO week trees Rüdiger Sonderfeld 2015-09-07 22:24 ` [PATCH v2 3/3] org-capture.el: Add support for " Rüdiger Sonderfeld 2015-09-07 22:27 ` [PATCH 2/3] org-datetree.el: Add support for ISO " Rüdiger Sonderfeld 2015-09-08 15:53 ` Nicolas Goaziou 2015-12-29 17:48 ` [PATCH v3 1/3] org-datetree.el: Code cleanup Rüdiger Sonderfeld 2015-12-29 20:58 ` Nicolas Goaziou 2015-12-29 17:49 ` [PATCH v3 2/3] org-datetree.el: Add support for ISO week trees Rüdiger Sonderfeld 2015-12-29 20:59 ` Nicolas Goaziou 2015-12-29 17:49 ` [PATCH v3 3/3] org-capture.el: Add support for " Rüdiger Sonderfeld 2015-12-29 20:59 ` Nicolas Goaziou 2015-09-02 8:06 ` [PATCH " Rüdiger Sonderfeld 2015-09-02 19:59 ` Nicolas Goaziou [not found] <cover.1441051750.git.ruediger@c-plusplus.net> 2015-08-31 20:15 ` [PATCH 2/3] org-datetree.el: Add support for ISO " Rüdiger Sonderfeld
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).