lisp/org-element.el: Add repeater-deadline support to org-element
* lisp/org-element.el (org-element-timestamp-parser, org-element-timestamp-interpreter): Add support for repeater deadlines. Adds two new properties: ':repeater-deadline-value' and ':repeater-deadline-unit'. * testing/lisp/test-org-element.el (test-org-element/timestamp-parser, test-org-element/timestamp-interpreter): Test support for repeater deadlines. * etc/ORG-NEWS: Add relevant news.
This commit is contained in:
parent
ead3f99901
commit
66e307b411
16
etc/ORG-NEWS
16
etc/ORG-NEWS
|
@ -512,6 +512,22 @@ timestamp object. Possible values: ~timerange~, ~daterange~, ~nil~.
|
|||
~org-element-timestamp-interpreter~ takes into account this property
|
||||
and returns an appropriate timestamp string.
|
||||
|
||||
**** New properties =:repeater-deadline-value= and =:repeater-deadline-unit= for org-element timestamp object
|
||||
|
||||
~org-element-timestamp-parser~ now adds =:repeater-deadline-value= and
|
||||
=:repeater-deadline-unit= properties to each timestamp object that has
|
||||
a repeater deadline. For example, in =<2012-03-29 Thu ++1y/2y>=, =2y=
|
||||
is the repeater deadline with a value of =2= and unit of =y=. See
|
||||
"5.3.3 Tracking your habits" section in the manual.
|
||||
|
||||
Possible values for =:repeater-deadline-value=: ~positive integer~, ~nil~.
|
||||
|
||||
Possible values for =:repeater-deadline-unit=: ~hour~, ~day~, ~week~,
|
||||
~month~, ~year~.
|
||||
|
||||
~org-element-timestamp-interpreter~ takes into account these properties
|
||||
and returns an appropriate timestamp string.
|
||||
|
||||
**** =org-link= store functions are passed an ~interactive?~ argument
|
||||
|
||||
The ~:store:~ functions set for link types using
|
||||
|
|
|
@ -4288,12 +4288,13 @@ Assume point is at the target."
|
|||
"Parse time stamp at point, if any.
|
||||
|
||||
When at a time stamp, return a new syntax node of `timestamp' type
|
||||
containing `:type', `:range-type', `:raw-value', `:year-start', `:month-start',
|
||||
`:day-start', `:hour-start', `:minute-start', `:year-end',
|
||||
`:month-end', `:day-end', `:hour-end', `:minute-end',
|
||||
containing `:type', `:range-type', `:raw-value', `:year-start',
|
||||
`:month-start', `:day-start', `:hour-start', `:minute-start',
|
||||
`:year-end', `:month-end', `:day-end', `:hour-end', `:minute-end',
|
||||
`:repeater-type', `:repeater-value', `:repeater-unit',
|
||||
`:warning-type', `:warning-value', `:warning-unit', `:begin', `:end'
|
||||
and `:post-blank' properties. Otherwise, return nil.
|
||||
`:repeater-deadline-value', `:repeater-deadline-unit', `:warning-type',
|
||||
`:warning-value', `:warning-unit', `:begin', `:end' and `:post-blank'
|
||||
properties. Otherwise, return nil.
|
||||
|
||||
Assume point is at the beginning of the timestamp."
|
||||
(when (looking-at-p org-element--timestamp-regexp)
|
||||
|
@ -4326,20 +4327,38 @@ Assume point is at the beginning of the timestamp."
|
|||
(date-end 'daterange)
|
||||
(time-range 'timerange)
|
||||
(t nil)))
|
||||
(repeater-props
|
||||
(and (not diaryp)
|
||||
(string-match "\\([.+]?\\+\\)\\([0-9]+\\)\\([hdwmy]\\)"
|
||||
raw-value)
|
||||
(list
|
||||
:repeater-type
|
||||
(let ((type (match-string 1 raw-value)))
|
||||
(cond ((equal "++" type) 'catch-up)
|
||||
((equal ".+" type) 'restart)
|
||||
(t 'cumulate)))
|
||||
:repeater-value (string-to-number (match-string 2 raw-value))
|
||||
:repeater-unit
|
||||
(pcase (string-to-char (match-string 3 raw-value))
|
||||
(?h 'hour) (?d 'day) (?w 'week) (?m 'month) (_ 'year)))))
|
||||
(repeater-props
|
||||
(and (not diaryp)
|
||||
(string-match
|
||||
(rx
|
||||
(group-n 1 (or "+" "++" ".+"))
|
||||
(group-n 2 (+ digit))
|
||||
(group-n 3 (any "hdwmy"))
|
||||
(optional
|
||||
"/"
|
||||
(group-n 4 (+ digit))
|
||||
(group-n 5 (any "hdwmy"))))
|
||||
raw-value)
|
||||
(nconc
|
||||
(list
|
||||
:repeater-type
|
||||
(let ((type (match-string 1 raw-value)))
|
||||
(cond ((equal "++" type) 'catch-up)
|
||||
((equal ".+" type) 'restart)
|
||||
(t 'cumulate)))
|
||||
:repeater-value (string-to-number (match-string 2 raw-value))
|
||||
:repeater-unit
|
||||
(pcase (string-to-char (match-string 3 raw-value))
|
||||
(?h 'hour) (?d 'day) (?w 'week) (?m 'month) (_ 'year)))
|
||||
|
||||
(let ((repeater-deadline-value (match-string 4 raw-value))
|
||||
(repeater-deadline-unit (match-string 5 raw-value)))
|
||||
(when (and repeater-deadline-value repeater-deadline-unit)
|
||||
(list
|
||||
:repeater-deadline-value (string-to-number repeater-deadline-value)
|
||||
:repeater-deadline-unit
|
||||
(pcase (string-to-char repeater-deadline-unit)
|
||||
(?h 'hour) (?d 'day) (?w 'week) (?m 'month) (_ 'year))))))))
|
||||
(warning-props
|
||||
(and (not diaryp)
|
||||
(string-match "\\(-\\)?-\\([0-9]+\\)\\([hdwmy]\\)" raw-value)
|
||||
|
@ -4407,7 +4426,16 @@ Assume point is at the beginning of the timestamp."
|
|||
(let ((val (org-element-property :repeater-value timestamp)))
|
||||
(and val (number-to-string val)))
|
||||
(pcase (org-element-property :repeater-unit timestamp)
|
||||
(`hour "h") (`day "d") (`week "w") (`month "m") (`year "y"))))
|
||||
(`hour "h") (`day "d") (`week "w") (`month "m") (`year "y"))
|
||||
(when-let ((repeater-deadline-value
|
||||
(org-element-property :repeater-deadline-value timestamp))
|
||||
(repeater-deadline-unit
|
||||
(org-element-property :repeater-deadline-unit timestamp)))
|
||||
(concat
|
||||
"/"
|
||||
(number-to-string repeater-deadline-value)
|
||||
(pcase repeater-deadline-unit
|
||||
(`hour "h") (`day "d") (`week "w") (`month "m") (`year "y"))))))
|
||||
(range-type (org-element-property :range-type timestamp))
|
||||
(warning-string
|
||||
(concat
|
||||
|
|
|
@ -3208,11 +3208,18 @@ Outside list"
|
|||
(let ((timestamp (org-element-context)))
|
||||
(or (org-element-property :hour-end timestamp)
|
||||
(org-element-property :minute-end timestamp)))))
|
||||
;; With repeater, warning delay and both.
|
||||
;; With repeater, repeater deadline, warning delay and combinations.
|
||||
(should
|
||||
(eq 'catch-up
|
||||
(org-test-with-temp-text "<2012-03-29 Thu ++1y>"
|
||||
(org-element-property :repeater-type (org-element-context)))))
|
||||
(should
|
||||
(equal '(catch-up 2 year)
|
||||
(org-test-with-temp-text "<2012-03-29 Thu ++1y/2y>"
|
||||
(let ((ts (org-element-context)))
|
||||
(list (org-element-property :repeater-type ts)
|
||||
(org-element-property :repeater-deadline-value ts)
|
||||
(org-element-property :repeater-deadline-unit ts))))))
|
||||
(should
|
||||
(eq 'first
|
||||
(org-test-with-temp-text "<2012-03-29 Thu --1y>"
|
||||
|
@ -3223,6 +3230,14 @@ Outside list"
|
|||
(let ((ts (org-element-context)))
|
||||
(list (org-element-property :repeater-type ts)
|
||||
(org-element-property :warning-type ts))))))
|
||||
(should
|
||||
(equal '(cumulate all 2 year)
|
||||
(org-test-with-temp-text "<2012-03-29 Thu +1y/2y -1y>"
|
||||
(let ((ts (org-element-context)))
|
||||
(list (org-element-property :repeater-type ts)
|
||||
(org-element-property :warning-type ts)
|
||||
(org-element-property :repeater-deadline-value ts)
|
||||
(org-element-property :repeater-deadline-unit ts))))))
|
||||
;; :range-type property
|
||||
(should
|
||||
(eq
|
||||
|
@ -3963,7 +3978,7 @@ DEADLINE: <2012-03-29 thu.> SCHEDULED: <2012-03-29 thu.> CLOSED: [2012-03-29 thu
|
|||
;; Diary.
|
||||
(should (equal (org-test-parse-and-interpret "<%%diary-float t 4 2>")
|
||||
"<%%diary-float t 4 2>\n"))
|
||||
;; Timestamp with repeater interval, with delay, with both.
|
||||
;; Timestamp with repeater interval, repeater deadline, with delay, with combinations.
|
||||
(should
|
||||
(string-match "<2012-03-29 .* \\+1y>"
|
||||
(org-test-parse-and-interpret "<2012-03-29 thu. +1y>")))
|
||||
|
@ -3975,6 +3990,15 @@ DEADLINE: <2012-03-29 thu.> SCHEDULED: <2012-03-29 thu.> CLOSED: [2012-03-29 thu
|
|||
(:type active :year-start 2012 :month-start 3 :day-start 29
|
||||
:repeater-type cumulate :repeater-value 1 :repeater-unit year))
|
||||
nil)))
|
||||
(should
|
||||
(string-match
|
||||
"<2012-03-29 .* \\+1y/2y>"
|
||||
(org-element-timestamp-interpreter
|
||||
'(timestamp
|
||||
(:type active :year-start 2012 :month-start 3 :day-start 29
|
||||
:repeater-type cumulate :repeater-value 1 :repeater-unit year
|
||||
:repeater-deadline-value 2 :repeater-deadline-unit year))
|
||||
nil)))
|
||||
(should
|
||||
(string-match
|
||||
"<2012-03-29 .* -1y>"
|
||||
|
@ -3992,6 +4016,16 @@ DEADLINE: <2012-03-29 thu.> SCHEDULED: <2012-03-29 thu.> CLOSED: [2012-03-29 thu
|
|||
:warning-type all :warning-value 1 :warning-unit year
|
||||
:repeater-type cumulate :repeater-value 1 :repeater-unit year))
|
||||
nil)))
|
||||
(should
|
||||
(string-match
|
||||
"<2012-03-29 .* \\+1y/2y -1y>"
|
||||
(org-element-timestamp-interpreter
|
||||
'(timestamp
|
||||
(:type active :year-start 2012 :month-start 3 :day-start 29
|
||||
:warning-type all :warning-value 1 :warning-unit year
|
||||
:repeater-type cumulate :repeater-value 1 :repeater-unit year
|
||||
:repeater-deadline-value 2 :repeater-deadline-unit year))
|
||||
nil)))
|
||||
;; Timestamp range with repeater interval
|
||||
(should
|
||||
(string-match "<2012-03-29 .* \\+1y>--<2012-03-30 .* \\+1y>"
|
||||
|
|
Loading…
Reference in New Issue