lisp/org-element.el: Add new timestamp property :range-type
The new property is needed to reduce ambiguity when interpreting the parsed data. * lisp/org-element.el (org-element-timestamp-interpreter): Preserve old behavior when :range-type is `nil'. Take into account :range-type value when interpreting ranges. When :range-type is `timerange', return a timerange (<YYYY-mm-DD HH:MM-HH:MM>). If :range-type is `daterange' return a daterange (<...>--<...>). When :range-type is nil, return a daterange (as it was before). When :range-type is `daterange' or `timerange' and :type is `active'/`inactive', throw an error. (org-element-timestamp-parser): Add :range-type property. * lisp/org.el (org-timestamp-split-range): Make sure that :range-type is nil for a split timestamp. * testing/lisp/test-org-element.el (test-org-element/timestamp-interpreter): Add new tests. (test-org-element/timestamp-parser): Add tests for :range-type property. * etc/ORG-NEWS (Major changes and additions to Org API): Add news about this property. Link: https://list.orgmode.org/orgmode/87y1ot6dqz.fsf@gmail.com/
This commit is contained in:
parent
67e819d6ee
commit
c74c4ab18d
|
@ -200,6 +200,13 @@ a newly created one.
|
|||
Previously, one had to use
|
||||
|
||||
: (apply #'org-element-create 'section nil (org-element-contents node))
|
||||
**** New property ~:range-type~ for org-element timestamp object
|
||||
|
||||
~org-element-timestamp-parser~ now adds =:range-type= property to each
|
||||
timestamp object. Possible values: ~timerange~, ~daterange~, ~nil~.
|
||||
|
||||
~org-element-timestamp-interpreter~ takes into account this property
|
||||
and returns an appropriate timestamp string.
|
||||
|
||||
*** ~org-priority=show~ command no longer adjusts for scheduled/deadline
|
||||
|
||||
|
|
|
@ -4043,7 +4043,7 @@ 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', `:raw-value', `:year-start', `:month-start',
|
||||
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',
|
||||
|
@ -4077,6 +4077,10 @@ Assume point is at the beginning of the timestamp."
|
|||
(activep 'active)
|
||||
((or date-end time-range) 'inactive-range)
|
||||
(t 'inactive)))
|
||||
(range-type (cond
|
||||
(date-end 'daterange)
|
||||
(time-range 'timerange)
|
||||
(t nil)))
|
||||
(repeater-props
|
||||
(and (not diaryp)
|
||||
(string-match "\\([.+]?\\+\\)\\([0-9]+\\)\\([hdwmy]\\)"
|
||||
|
@ -4123,6 +4127,7 @@ Assume point is at the beginning of the timestamp."
|
|||
(org-element-create
|
||||
'timestamp
|
||||
(nconc (list :type type
|
||||
:range-type range-type
|
||||
:raw-value raw-value
|
||||
:year-start year-start
|
||||
:month-start month-start
|
||||
|
@ -4142,99 +4147,123 @@ Assume point is at the beginning of the timestamp."
|
|||
|
||||
(defun org-element-timestamp-interpreter (timestamp _)
|
||||
"Interpret TIMESTAMP object as Org syntax."
|
||||
(let* ((repeat-string
|
||||
(concat
|
||||
(pcase (org-element-property :repeater-type timestamp)
|
||||
(`cumulate "+") (`catch-up "++") (`restart ".+"))
|
||||
(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"))))
|
||||
(warning-string
|
||||
(concat
|
||||
(pcase (org-element-property :warning-type timestamp)
|
||||
(`first "--") (`all "-"))
|
||||
(let ((val (org-element-property :warning-value timestamp)))
|
||||
(and val (number-to-string val)))
|
||||
(pcase (org-element-property :warning-unit timestamp)
|
||||
(`hour "h") (`day "d") (`week "w") (`month "m") (`year "y"))))
|
||||
(build-ts-string
|
||||
;; Build an Org timestamp string from TIME. ACTIVEP is
|
||||
;; non-nil when time stamp is active. If WITH-TIME-P is
|
||||
;; non-nil, add a time part. HOUR-END and MINUTE-END
|
||||
;; specify a time range in the timestamp. REPEAT-STRING is
|
||||
;; the repeater string, if any.
|
||||
(lambda (time activep &optional with-time-p hour-end minute-end)
|
||||
(let ((ts (format-time-string
|
||||
(org-time-stamp-format with-time-p)
|
||||
time)))
|
||||
(when (and hour-end minute-end)
|
||||
(string-match "[012]?[0-9]:[0-5][0-9]" ts)
|
||||
(setq ts
|
||||
(replace-match
|
||||
(format "\\&-%02d:%02d" hour-end minute-end)
|
||||
nil nil ts)))
|
||||
(unless activep (setq ts (format "[%s]" (substring ts 1 -1))))
|
||||
(dolist (s (list repeat-string warning-string))
|
||||
(when (org-string-nw-p s)
|
||||
(setq ts (concat (substring ts 0 -1)
|
||||
" "
|
||||
s
|
||||
(substring ts -1)))))
|
||||
;; Return value.
|
||||
ts)))
|
||||
(type (org-element-property :type timestamp)))
|
||||
(pcase type
|
||||
((or `active `inactive)
|
||||
(let* ((minute-start (org-element-property :minute-start timestamp))
|
||||
(minute-end (org-element-property :minute-end timestamp))
|
||||
(hour-start (org-element-property :hour-start timestamp))
|
||||
(hour-end (org-element-property :hour-end timestamp))
|
||||
(time-range-p (and hour-start hour-end minute-start minute-end
|
||||
(or (/= hour-start hour-end)
|
||||
(/= minute-start minute-end)))))
|
||||
(funcall
|
||||
build-ts-string
|
||||
(org-encode-time 0
|
||||
(or minute-start 0)
|
||||
(or hour-start 0)
|
||||
(org-element-property :day-start timestamp)
|
||||
(org-element-property :month-start timestamp)
|
||||
(org-element-property :year-start timestamp))
|
||||
(eq type 'active)
|
||||
(and hour-start minute-start)
|
||||
(and time-range-p hour-end)
|
||||
(and time-range-p minute-end))))
|
||||
((or `active-range `inactive-range)
|
||||
(let ((minute-start (org-element-property :minute-start timestamp))
|
||||
(minute-end (org-element-property :minute-end timestamp))
|
||||
(hour-start (org-element-property :hour-start timestamp))
|
||||
(hour-end (org-element-property :hour-end timestamp)))
|
||||
(concat
|
||||
(funcall
|
||||
build-ts-string (org-encode-time
|
||||
0
|
||||
(or minute-start 0)
|
||||
(or hour-start 0)
|
||||
(org-element-property :day-start timestamp)
|
||||
(org-element-property :month-start timestamp)
|
||||
(org-element-property :year-start timestamp))
|
||||
(eq type 'active-range)
|
||||
(and hour-start minute-start))
|
||||
"--"
|
||||
(funcall build-ts-string
|
||||
(org-encode-time
|
||||
0
|
||||
(or minute-end 0)
|
||||
(or hour-end 0)
|
||||
(org-element-property :day-end timestamp)
|
||||
(org-element-property :month-end timestamp)
|
||||
(org-element-property :year-end timestamp))
|
||||
(eq type 'active-range)
|
||||
(and hour-end minute-end)))))
|
||||
(_ (org-element-property :raw-value timestamp)))))
|
||||
|
||||
|
||||
(let((type (org-element-property :type timestamp)))
|
||||
(if (member type '(active inactive inactive-range active-range))
|
||||
(let ((day-start (org-element-property :day-start timestamp))
|
||||
(month-start (org-element-property :month-start timestamp))
|
||||
(year-start (org-element-property :year-start timestamp)))
|
||||
;; Return nil when start date is not available. Could also
|
||||
;; throw an error, but the current behavior is historical.
|
||||
(when (and day-start month-start year-start)
|
||||
(let* ((repeat-string
|
||||
(concat
|
||||
(pcase (org-element-property :repeater-type timestamp)
|
||||
(`cumulate "+") (`catch-up "++") (`restart ".+"))
|
||||
(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"))))
|
||||
(range-type (org-element-property :range-type timestamp))
|
||||
(warning-string
|
||||
(concat
|
||||
(pcase (org-element-property :warning-type timestamp)
|
||||
(`first "--") (`all "-"))
|
||||
(let ((val (org-element-property :warning-value timestamp)))
|
||||
(and val (number-to-string val)))
|
||||
(pcase (org-element-property :warning-unit timestamp)
|
||||
(`hour "h") (`day "d") (`week "w") (`month "m") (`year "y"))))
|
||||
(hour-start (org-element-property :hour-start timestamp))
|
||||
(minute-start (org-element-property :minute-start timestamp))
|
||||
(brackets
|
||||
(if (member
|
||||
type
|
||||
'(inactive inactive-range))
|
||||
(cons "[" "]")
|
||||
(cons "<" ">")))
|
||||
(timestamp-end
|
||||
(concat
|
||||
(and (org-string-nw-p repeat-string) (concat " " repeat-string))
|
||||
(and (org-string-nw-p warning-string) (concat " " warning-string))
|
||||
(cdr brackets))))
|
||||
(concat
|
||||
;; Opening backet: [ or <
|
||||
(car brackets)
|
||||
;; Starting date/time: YYYY-MM-DD DAY[ HH:MM]
|
||||
(format-time-string
|
||||
;; `org-time-stamp-formats'.
|
||||
(org-time-stamp-format
|
||||
;; Ignore time unless both HH:MM are available.
|
||||
;; Ignore means (car org-timestamp-formats).
|
||||
(and minute-start hour-start)
|
||||
'no-brackets)
|
||||
(org-encode-time
|
||||
0 (or minute-start 0) (or hour-start 0)
|
||||
day-start month-start year-start))
|
||||
;; Range: -HH:MM or TIMESTAMP-END--[YYYY-MM-DD DAY HH:MM]
|
||||
(let ((hour-end (org-element-property :hour-end timestamp))
|
||||
(minute-end (org-element-property :minute-end timestamp)))
|
||||
(pcase type
|
||||
((or `active `inactive)
|
||||
;; `org-element-timestamp-parser' uses this type
|
||||
;; when no time/date range is provided. So,
|
||||
;; should normally return nil in this clause.
|
||||
(pcase range-type
|
||||
(`nil
|
||||
;; `org-element-timestamp-parser' assigns end
|
||||
;; times for `active'/`inactive' TYPE if start
|
||||
;; time is not nil. But manually built
|
||||
;; timestamps may not contain end times, so
|
||||
;; check for end times anyway.
|
||||
(when (and hour-start hour-end minute-start minute-end
|
||||
(or (/= hour-start hour-end)
|
||||
(/= minute-start minute-end)))
|
||||
;; Could also throw an error. Return range
|
||||
;; timestamp nevertheless to preserve
|
||||
;; historical behavior.
|
||||
(format "-%02d:%02d" hour-end minute-end)))
|
||||
((or `timerange `daterange)
|
||||
(error "`:range-type' must be `nil' for `active'/`inactive' type"))))
|
||||
;; Range must be present.
|
||||
((or `active-range `inactive-range)
|
||||
(pcase range-type
|
||||
;; End time: -HH:MM.
|
||||
;; Fall back to start time if end time is not defined (arbitrary historical choice).
|
||||
;; Error will be thrown if both end and begin time is not defined.
|
||||
(`timerange (format "-%02d:%02d" (or hour-end hour-start) (or minute-end minute-start)))
|
||||
;; End date: TIMESTAMP-END--[YYYY-MM-DD DAY HH:MM
|
||||
((or `daterange
|
||||
;; Should never happen in the output of `org-element-timestamp-parser'.
|
||||
;; Treat as an equivalent of `daterange' arbitrarily.
|
||||
`nil)
|
||||
(concat
|
||||
;; repeater + warning + closing > or ]
|
||||
;; This info is duplicated in date ranges.
|
||||
timestamp-end
|
||||
"--" (car brackets)
|
||||
(format-time-string
|
||||
;; `org-time-stamp-formats'.
|
||||
(org-time-stamp-format
|
||||
;; Ignore time unless both HH:MM are available.
|
||||
;; Ignore means (car org-timestamp-formats).
|
||||
(and minute-end hour-end)
|
||||
'no-brackets)
|
||||
(org-encode-time
|
||||
;; Closing HH:MM missing is a valid scenario.
|
||||
0 (or minute-end 0) (or hour-end 0)
|
||||
;; YEAR/MONTH/DAY-END will always be present
|
||||
;; for `daterange' range-type, as parsed by
|
||||
;; `org-element-timestamp-parser'.
|
||||
;; For manually constructed timestamp
|
||||
;; object, arbitrarily fall back to starting
|
||||
;; date.
|
||||
(or (org-element-property :day-end timestamp) day-start)
|
||||
(or (org-element-property :month-end timestamp) month-start)
|
||||
(or (org-element-property :year-end timestamp) year-start)))))))))
|
||||
;; repeater + warning + closing > or ]
|
||||
;; This info is duplicated in date ranges.
|
||||
timestamp-end))))
|
||||
;; diary type.
|
||||
(org-element-property :raw-value timestamp))))
|
||||
;;;; Underline
|
||||
|
||||
(defun org-element-underline-parser ()
|
||||
|
|
|
@ -20043,6 +20043,7 @@ Return a new timestamp object."
|
|||
;; Set new type.
|
||||
(org-element-put-property
|
||||
split-ts :type (if (eq type 'active-range) 'active 'inactive))
|
||||
(org-element-put-property split-ts :range-type nil)
|
||||
;; Copy start properties over end properties if END is
|
||||
;; non-nil. Otherwise, copy end properties over `start' ones.
|
||||
(let ((p-alist '((:minute-start . :minute-end)
|
||||
|
|
|
@ -3138,8 +3138,73 @@ Outside list"
|
|||
(org-test-with-temp-text "<2012-03-29 Thu +1y -1y>"
|
||||
(let ((ts (org-element-context)))
|
||||
(list (org-element-property :repeater-type ts)
|
||||
(org-element-property :warning-type ts)))))))
|
||||
|
||||
(org-element-property :warning-type ts))))))
|
||||
;; :range-type property
|
||||
(should
|
||||
(eq
|
||||
(org-test-with-temp-text "<2023-07-02 Sun>"
|
||||
(org-element-property :range-type (org-element-timestamp-parser)))
|
||||
nil))
|
||||
(should
|
||||
(eq
|
||||
(org-test-with-temp-text "<2023-07-02 Sun 12:00>"
|
||||
(org-element-property :range-type (org-element-timestamp-parser)))
|
||||
nil))
|
||||
(should
|
||||
(eq
|
||||
(org-test-with-temp-text "<2023-07-02 Sun 12:00-13:00>"
|
||||
(org-element-property :range-type (org-element-timestamp-parser)))
|
||||
'timerange))
|
||||
(should
|
||||
(eq
|
||||
(org-test-with-temp-text "<2023-07-02 Sun 12:00-12:00>"
|
||||
(org-element-property :range-type (org-element-timestamp-parser)))
|
||||
'timerange))
|
||||
(should
|
||||
(eq
|
||||
(org-test-with-temp-text "<2023-07-02 Sun>--<2023-07-02 Sun>"
|
||||
(org-element-property :range-type (org-element-timestamp-parser)))
|
||||
'daterange))
|
||||
(should
|
||||
(eq
|
||||
(org-test-with-temp-text "<2023-07-02 Sun>--<2023-07-03 Mon>"
|
||||
(org-element-property :range-type (org-element-timestamp-parser)))
|
||||
'daterange))
|
||||
(should
|
||||
(eq
|
||||
(org-test-with-temp-text "<2023-07-02 Sun 12:00>--<2023-07-02 Sun 12:00>"
|
||||
(org-element-property :range-type (org-element-timestamp-parser)))
|
||||
'daterange))
|
||||
(should
|
||||
(eq
|
||||
(org-test-with-temp-text "<2023-07-02 Sun 12:00>--<2023-07-03 Mon 13:00>"
|
||||
(org-element-property :range-type (org-element-timestamp-parser)))
|
||||
'daterange))
|
||||
(should
|
||||
(eq
|
||||
(org-test-with-temp-text "<2023-07-02 Sun 12:00>--<2023-07-02 Sun>"
|
||||
(org-element-property :range-type (org-element-timestamp-parser)))
|
||||
'daterange))
|
||||
(should
|
||||
(eq
|
||||
(org-test-with-temp-text "<2023-07-02 Sun 12:00>--<2023-07-03 Mon>"
|
||||
(org-element-property :range-type (org-element-timestamp-parser)))
|
||||
'daterange))
|
||||
(should
|
||||
(eq
|
||||
(org-test-with-temp-text "<2023-07-02 Sun 12:00>--<2023-07-02 Sun 13:00>"
|
||||
(org-element-property :range-type (org-element-timestamp-parser)))
|
||||
'daterange))
|
||||
(should
|
||||
(eq
|
||||
(org-test-with-temp-text "<2023-07-02 Sun 12:00>--<2023-07-02 Sun>"
|
||||
(org-element-property :range-type (org-element-timestamp-parser)))
|
||||
'daterange))
|
||||
(should
|
||||
(eq
|
||||
(org-test-with-temp-text "<2023-07-02 Sun 12:00 +5d>--<2023-07-02 Sun 13:00>"
|
||||
(org-element-property :range-type (org-element-timestamp-parser)))
|
||||
'daterange)))
|
||||
|
||||
;;;; Underline
|
||||
|
||||
|
@ -3685,6 +3750,14 @@ DEADLINE: <2012-03-29 thu.> SCHEDULED: <2012-03-29 thu.> CLOSED: [2012-03-29 thu
|
|||
'(timestamp
|
||||
(:type active :year-start 2012 :month-start 3 :day-start 29
|
||||
:hour-start 16 :minute-start 40)) nil)))
|
||||
(should
|
||||
(string-match
|
||||
"<2012-03-29 .* 16:40>"
|
||||
(org-element-timestamp-interpreter
|
||||
'(timestamp
|
||||
(:type active :year-start 2012 :month-start 3 :day-start 29
|
||||
:hour-start 16 :minute-start 40 :year-end 2012 :month-end 3
|
||||
:day-end 29 :hour-end 16 :minute-end 40)) nil)))
|
||||
;; Inactive.
|
||||
(should
|
||||
(string-match "\\[2012-03-29 .* 16:40\\]"
|
||||
|
@ -3696,11 +3769,45 @@ DEADLINE: <2012-03-29 thu.> SCHEDULED: <2012-03-29 thu.> CLOSED: [2012-03-29 thu
|
|||
'(timestamp
|
||||
(:type inactive :year-start 2012 :month-start 3 :day-start 29
|
||||
:hour-start 16 :minute-start 40)) nil)))
|
||||
;; Active range.
|
||||
;; Active daterange.
|
||||
(should
|
||||
(string-match "<2012-03-29 .* 16:40>--<2012-03-29 .* 16:41>"
|
||||
(org-test-parse-and-interpret
|
||||
"<2012-03-29 thu. 16:40>--<2012-03-29 thu. 16:41>")))
|
||||
;;; No end time, dates are not equal
|
||||
(should
|
||||
;; Expected result: "<2012-03-29 Thu 16:40>--<2012-03-30 Fri>"
|
||||
(string=
|
||||
(format
|
||||
"<%s>--<%s>"
|
||||
(format-time-string (cdr org-time-stamp-formats) (org-encode-time 0 40 16 29 03 2012))
|
||||
(format-time-string (car org-time-stamp-formats) (org-encode-time 0 0 0 30 03 2012)))
|
||||
(org-element-timestamp-interpreter
|
||||
'(timestamp
|
||||
(:type active-range :year-start 2012 :month-start 3 :day-start 29
|
||||
:hour-start 16 :minute-start 40 :year-end 2012 :month-end 3
|
||||
:day-end 30)) nil)))
|
||||
;;; No start time, dates are not equal
|
||||
(should
|
||||
;; Expected result: "<2012-03-29 Thu>--<2012-03-30 Fri 16:40>"
|
||||
(string=
|
||||
(format
|
||||
"<%s>--<%s>"
|
||||
(format-time-string (car org-time-stamp-formats) (org-encode-time 0 0 0 29 03 2012))
|
||||
(format-time-string (cdr org-time-stamp-formats) (org-encode-time 0 40 16 30 03 2012)))
|
||||
(org-element-timestamp-interpreter
|
||||
'(timestamp
|
||||
(:type active-range :year-start 2012 :month-start 3 :day-start 29
|
||||
:hour-end 16 :minute-end 40 :year-end 2012 :month-end 3
|
||||
:day-end 30)) nil)))
|
||||
(should
|
||||
(string-match
|
||||
"<2012-03-29 .* 16:40>--<2012-03-29 .* 16:40>"
|
||||
(org-element-timestamp-interpreter
|
||||
'(timestamp
|
||||
(:type active-range :year-start 2012 :month-start 3 :day-start 29
|
||||
:hour-start 16 :minute-start 40 :year-end 2012 :month-end 3
|
||||
:day-end 29 :hour-end 16 :minute-end 40)) nil)))
|
||||
(should
|
||||
(string-match
|
||||
"<2012-03-29 .* 16:40>--<2012-03-29 .* 16:41>"
|
||||
|
@ -3709,7 +3816,7 @@ DEADLINE: <2012-03-29 thu.> SCHEDULED: <2012-03-29 thu.> CLOSED: [2012-03-29 thu
|
|||
(:type active-range :year-start 2012 :month-start 3 :day-start 29
|
||||
:hour-start 16 :minute-start 40 :year-end 2012 :month-end 3
|
||||
:day-end 29 :hour-end 16 :minute-end 41)) nil)))
|
||||
;; Inactive range.
|
||||
;; Inactive daterange.
|
||||
(should
|
||||
(string-match "\\[2012-03-29 .* 16:40\\]--\\[2012-03-29 .* 16:41\\]"
|
||||
(org-test-parse-and-interpret
|
||||
|
@ -3722,6 +3829,11 @@ DEADLINE: <2012-03-29 thu.> SCHEDULED: <2012-03-29 thu.> CLOSED: [2012-03-29 thu
|
|||
(:type inactive-range :year-start 2012 :month-start 3 :day-start 29
|
||||
:hour-start 16 :minute-start 40 :year-end 2012 :month-end 3
|
||||
:day-end 29 :hour-end 16 :minute-end 41)) nil)))
|
||||
;; Active timerange
|
||||
(should
|
||||
(string-match "<2012-03-29 .* 16:40-16:41>"
|
||||
(org-test-parse-and-interpret
|
||||
"<2012-03-29 thu. 16:40-16:41>")))
|
||||
;; Diary.
|
||||
(should (equal (org-test-parse-and-interpret "<%%diary-float t 4 2>")
|
||||
"<%%diary-float t 4 2>\n"))
|
||||
|
@ -3767,7 +3879,116 @@ DEADLINE: <2012-03-29 thu.> SCHEDULED: <2012-03-29 thu.> CLOSED: [2012-03-29 thu
|
|||
(:type active-range :year-start 2012 :month-start 3 :day-start 29
|
||||
:year-end 2012 :month-end 3 :day-end 30 :repeater-type cumulate
|
||||
:repeater-value 1 :repeater-unit year))
|
||||
nil))))
|
||||
nil)))
|
||||
;; Tests for :range-type property
|
||||
;;; Errors
|
||||
(should-error
|
||||
(org-element-timestamp-interpreter
|
||||
'(timestamp
|
||||
(:range-type timerange
|
||||
:type active
|
||||
:year-start 2023 :month-start 7 :day-start 10
|
||||
:year-end 2023 :month-end 7 :day-end 10
|
||||
:hour-start 17 :minute-start 30
|
||||
:hour-end 17 :minute-end 30))
|
||||
nil))
|
||||
(should-error
|
||||
(org-element-timestamp-interpreter
|
||||
'(timestamp
|
||||
(:range-type daterange
|
||||
:type active :year-start 2023 :month-start 7 :day-start 10
|
||||
:hour-start 17 :minute-start 30)) nil))
|
||||
(should-error
|
||||
(org-element-timestamp-interpreter
|
||||
'(timestamp
|
||||
(:range-type timerange
|
||||
:type inactive
|
||||
:year-start 2023 :month-start 7 :day-start 10
|
||||
:year-end 2023 :month-end 7 :day-end 10
|
||||
:hour-start 17 :minute-start 30
|
||||
:hour-end 17 :minute-end 30))
|
||||
nil))
|
||||
(should-error
|
||||
(org-element-timestamp-interpreter
|
||||
'(timestamp
|
||||
(:range-type daterange
|
||||
:type inactive :year-start 2023 :month-start 7 :day-start 10
|
||||
:hour-start 17 :minute-start 30)) nil))
|
||||
|
||||
;;; End part is nil
|
||||
(should
|
||||
;; Expected result: "<2023-07-10 Mon>--<2023-07-10 Mon>"
|
||||
(string=
|
||||
(format
|
||||
"<%s>--<%s>"
|
||||
(format-time-string (car org-time-stamp-formats) (org-encode-time 0 0 0 10 7 2023))
|
||||
(format-time-string (car org-time-stamp-formats) (org-encode-time 0 0 0 10 7 2023)))
|
||||
(org-element-timestamp-interpreter
|
||||
'(timestamp
|
||||
(:range-type daterange
|
||||
:type active-range :year-start 2023 :month-start 7 :day-start 10)) nil)))
|
||||
(should
|
||||
(string-match "<2023-07-10 .* 17:30-17:30>"
|
||||
(org-element-timestamp-interpreter
|
||||
'(timestamp
|
||||
(:range-type timerange
|
||||
:type active-range :year-start 2023 :month-start 7 :day-start 10
|
||||
:hour-start 17 :minute-start 30)) nil)))
|
||||
(should
|
||||
;; Expected result: "<2023-07-10 Mon 17:30>--<2023-07-10 Mon>"
|
||||
(string=
|
||||
(format
|
||||
"<%s>--<%s>"
|
||||
(format-time-string (cdr org-time-stamp-formats) (org-encode-time 0 30 17 10 7 2023))
|
||||
(format-time-string (car org-time-stamp-formats) (org-encode-time 0 0 0 10 7 2023)))
|
||||
(org-element-timestamp-interpreter
|
||||
'(timestamp
|
||||
(:range-type daterange
|
||||
:type active-range :year-start 2023 :month-start 7 :day-start 10
|
||||
:hour-start 17 :minute-start 30)) nil)))
|
||||
;;; End is equal to start
|
||||
(should
|
||||
(string-match "<2023-07-10 .* 17:30-17:30>"
|
||||
(org-element-timestamp-interpreter
|
||||
'(timestamp
|
||||
(:range-type timerange
|
||||
:type active-range
|
||||
:year-start 2023 :month-start 7 :day-start 10
|
||||
:year-end 2023 :month-end 7 :day-end 10
|
||||
:hour-start 17 :minute-start 30
|
||||
:hour-end 17 :minute-end 30)) nil)))
|
||||
(should
|
||||
(string-match "<2023-07-10 .* 17:30>--<2023-07-10 .* 17:30>"
|
||||
(org-element-timestamp-interpreter
|
||||
'(timestamp
|
||||
(:range-type daterange
|
||||
:type active-range
|
||||
:year-start 2023 :month-start 7 :day-start 10
|
||||
:year-end 2023 :month-end 7 :day-end 10
|
||||
:hour-start 17 :minute-start 30
|
||||
:hour-end 17 :minute-end 30)) nil)))
|
||||
;;;; End date is not equal to start date, but interpret the object as a timerange (:range-type 'timerange)
|
||||
(should
|
||||
(string-match "<2023-07-10 .* 17:30-18:30>"
|
||||
(org-element-timestamp-interpreter
|
||||
'(timestamp
|
||||
(:range-type timerange
|
||||
:type active-range
|
||||
:year-start 2023 :month-start 7 :day-start 10
|
||||
:year-end 2023 :month-end 8 :day-end 10
|
||||
:hour-start 17 :minute-start 30
|
||||
:hour-end 18 :minute-end 30)) nil)))
|
||||
;;;; End date is not equal to start date, interpret the object as a daterange (:range-type 'daterange)
|
||||
(should
|
||||
(string-match "<2023-07-10 .* 17:30>--<2023-08-10 .* 18:30>"
|
||||
(org-element-timestamp-interpreter
|
||||
'(timestamp
|
||||
(:range-type daterange
|
||||
:type active-range
|
||||
:year-start 2023 :month-start 7 :day-start 10
|
||||
:year-end 2023 :month-end 8 :day-end 10
|
||||
:hour-start 17 :minute-start 30
|
||||
:hour-end 18 :minute-end 30)) nil))))
|
||||
|
||||
(ert-deftest test-org-element/verse-block-interpreter ()
|
||||
"Test verse block interpretation."
|
||||
|
|
Loading…
Reference in New Issue