org-element: Improve timestamps parsing

* lisp/org-element.el (org-element-timestamp-parser): Modify timestamp
  objects properties.
(org-element-headline-parser, org-element-inlinetask-parser): Remove
`:timestamp' and `:clock' property.  Add `:clockedp' property.  Also,
set `:closed', `:deadline' and `:scheduled' values to timestamp
objects, not strings.  Small refactoring.
(org-element-clock-parser): Rename `:time' property into `:duration'.
Also, set `:value' value as a timestamp object, not a string.
(org-element-planning-parser): Set `:closed', `:deadline' and
`:scheduled' values to timestamp objects, not strings.
(org-element-clock-interpreter, org-element-planning-interpreter)
(org-element-timestamp-interpreter): Update interpreters.
(org-element--current-element): Tiny refactoring.
* testing/lisp/test-org-element.el: Add tests.
This commit is contained in:
Nicolas Goaziou 2012-09-28 14:50:21 +02:00
parent 2f2a80fe06
commit c1e3aaece3
2 changed files with 374 additions and 152 deletions

View File

@ -116,6 +116,8 @@
(eval-when-compile (require 'cl))
(require 'org)
(declare-function org-clocking-buffer "org-clock" ())
;;; Definitions And Rules
@ -711,9 +713,8 @@ Return a list whose CAR is `headline' and CDR is a plist
containing `:raw-value', `:title', `:begin', `:end',
`:pre-blank', `:hiddenp', `:contents-begin' and `:contents-end',
`:level', `:priority', `:tags', `:todo-keyword',`:todo-type',
`:scheduled', `:deadline', `:timestamp', `:clock', `:category',
`:quotedp', `:archivedp', `:commentedp' and `:footnote-section-p'
keywords.
`:scheduled', `:deadline', `:closed', `:clockedp', `:quotedp',
`:archivedp', `:commentedp' and `:footnote-section-p' keywords.
The plist also contains any property set in the property drawer,
with its name in lowercase, the underscores replaced with hyphens
@ -745,23 +746,36 @@ Assume point is at beginning of the headline."
(string= org-footnote-section raw-value)))
;; Normalize property names: ":SOME_PROP:" becomes
;; ":some-prop".
(standard-props (let (plist)
(mapc
(lambda (p)
(let ((p-name (downcase (car p))))
(while (string-match "_" p-name)
(setq p-name
(replace-match "-" nil nil p-name)))
(setq p-name (intern (concat ":" p-name)))
(setq plist
(plist-put plist p-name (cdr p)))))
(org-entry-properties nil 'standard))
plist))
(time-props (org-entry-properties nil 'special "CLOCK"))
(scheduled (cdr (assoc "SCHEDULED" time-props)))
(deadline (cdr (assoc "DEADLINE" time-props)))
(clock (cdr (assoc "CLOCK" time-props)))
(timestamp (cdr (assoc "TIMESTAMP" time-props)))
(standard-props
(let (plist)
(mapc
(lambda (p)
(setq plist
(plist-put plist
(intern (concat ":"
(replace-regexp-in-string
"_" "-" (downcase (car p)))))
(cdr p))))
(org-entry-properties nil 'standard))
plist))
(time-props
;; Read time properties on the line below the headline.
(save-excursion
(when (progn (forward-line)
(looking-at org-planning-or-clock-line-re))
(let ((end (line-end-position)) plist)
(while (re-search-forward
org-keyword-time-not-clock-regexp end t)
(goto-char (match-end 1))
(skip-chars-forward " \t")
(let ((keyword (match-string 1))
(time (org-element-timestamp-parser)))
(cond ((equal keyword org-scheduled-string)
(setq plist (plist-put plist :scheduled time)))
((equal keyword org-deadline-string)
(setq plist (plist-put plist :deadline time)))
(t (setq plist (plist-put plist :closed time))))))
plist))))
(begin (point))
(end (save-excursion (goto-char (org-end-of-subtree t t))))
(pos-after-head (progn (forward-line) (point)))
@ -773,7 +787,13 @@ Assume point is at beginning of the headline."
(progn (goto-char end)
(skip-chars-backward " \r\t\n")
(forward-line)
(point)))))
(point))))
(clockedp (and (eq (org-clocking-buffer)
(or (buffer-base-buffer) (current-buffer)))
(save-excursion
(goto-char (marker-position org-clock-marker))
(org-back-to-heading t)
(= (point) begin)))))
;; Clean RAW-VALUE from any quote or comment string.
(when (or quotedp commentedp)
(let ((case-fold-search nil))
@ -803,10 +823,6 @@ Assume point is at beginning of the headline."
:tags tags
:todo-keyword todo
:todo-type todo-type
:scheduled scheduled
:deadline deadline
:timestamp timestamp
:clock clock
:post-blank (count-lines
(if (not contents-end) pos-after-head
(goto-char contents-end)
@ -815,8 +831,10 @@ Assume point is at beginning of the headline."
end)
:footnote-section-p footnote-section-p
:archivedp archivedp
:clockedp clockedp
:commentedp commentedp
:quotedp quotedp)
time-props
standard-props))))
(org-element-put-property
headline :title
@ -880,7 +898,7 @@ Return a list whose CAR is `inlinetask' and CDR is a plist
containing `:title', `:begin', `:end', `:hiddenp',
`:contents-begin' and `:contents-end', `:level', `:priority',
`:raw-value', `:tags', `:todo-keyword', `:todo-type',
`:scheduled', `:deadline', `:timestamp', `:clock' and
`:scheduled', `:deadline', `:clockedp', `:closed' and
`:post-blank' keywords.
The plist also contains any property set in the property drawer,
@ -904,27 +922,45 @@ Assume point is at beginning of the inline task."
(raw-value (or (nth 4 components) ""))
;; Normalize property names: ":SOME_PROP:" becomes
;; ":some-prop".
(standard-props (let (plist)
(mapc
(lambda (p)
(let ((p-name (downcase (car p))))
(while (string-match "_" p-name)
(setq p-name
(replace-match "-" nil nil p-name)))
(setq p-name (intern (concat ":" p-name)))
(setq plist
(plist-put plist p-name (cdr p)))))
(org-entry-properties nil 'standard))
plist))
(time-props (org-entry-properties nil 'special "CLOCK"))
(scheduled (cdr (assoc "SCHEDULED" time-props)))
(deadline (cdr (assoc "DEADLINE" time-props)))
(clock (cdr (assoc "CLOCK" time-props)))
(timestamp (cdr (assoc "TIMESTAMP" time-props)))
(standard-props
(let (plist)
(mapc
(lambda (p)
(setq plist
(plist-put plist
(intern (concat ":"
(replace-regexp-in-string
"_" "-" (downcase (car p)))))
(cdr p))))
(org-entry-properties nil 'standard))
plist))
(time-props
;; Read time properties on the line below the inlinetask
;; opening string.
(save-excursion
(when (progn (forward-line)
(looking-at org-planning-or-clock-line-re))
(let ((end (line-end-position)) plist)
(while (re-search-forward
org-keyword-time-not-clock-regexp end t)
(goto-char (match-end 1))
(skip-chars-forward " \t")
(let ((keyword (match-string 1))
(time (org-element-timestamp-parser)))
(cond ((equal keyword org-scheduled-string)
(setq plist (plist-put plist :scheduled time)))
((equal keyword org-deadline-string)
(setq plist (plist-put plist :deadline time)))
(t (setq plist (plist-put plist :closed time))))))
plist))))
(task-end (save-excursion
(end-of-line)
(and (re-search-forward "^\\*+ END" limit t)
(match-beginning 0))))
(clockedp (and (eq (org-clocking-buffer)
(or (buffer-base-buffer) (current-buffer)))
(let ((clock (marker-position org-clock-marker)))
(and (> clock begin) (< clock task-end)))))
(contents-begin (progn (forward-line)
(and task-end (< (point) task-end) (point))))
(hidden (and contents-begin (org-invisible-p2)))
@ -950,11 +986,9 @@ Assume point is at beginning of the inline task."
:tags tags
:todo-keyword todo
:todo-type todo-type
:scheduled scheduled
:deadline deadline
:timestamp timestamp
:clock clock
:clockedp clockedp
:post-blank (count-lines before-blank end))
time-props
standard-props
(cadr keywords)))))
(org-element-put-property
@ -1427,13 +1461,13 @@ as keywords."
(let* ((case-fold-search nil)
(begin (point))
(value (progn (search-forward org-clock-string (line-end-position) t)
(org-skip-whitespace)
(looking-at "\\[.*\\]")
(org-match-string-no-properties 0)))
(time (and (progn (goto-char (match-end 0))
(looking-at " +=> +\\(\\S-+\\)[ \t]*$"))
(org-match-string-no-properties 1)))
(status (if time 'closed 'running))
(skip-chars-forward " \t")
(org-element-timestamp-parser)))
(duration (and (search-forward " => " (line-end-position) t)
(progn (skip-chars-forward " \t")
(looking-at "\\(\\S-+\\)[ \t]*$"))
(org-match-string-no-properties 1)))
(status (if duration 'closed 'running))
(post-blank (let ((before-blank (progn (forward-line) (point))))
(skip-chars-forward " \r\t\n" limit)
(skip-chars-backward " \t")
@ -1443,7 +1477,7 @@ as keywords."
(list 'clock
(list :status status
:value value
:time time
:duration duration
:begin begin
:end end
:post-blank post-blank)))))
@ -1452,13 +1486,14 @@ as keywords."
"Interpret CLOCK element as Org syntax.
CONTENTS is nil."
(concat org-clock-string " "
(org-element-property :value clock)
(let ((time (org-element-property :time clock)))
(and time
(org-element-timestamp-interpreter
(org-element-property :value clock) nil)
(let ((duration (org-element-property :duration clock)))
(and duration
(concat " => "
(apply 'format
"%2s:%02s"
(org-split-string time ":")))))))
(org-split-string duration ":")))))))
;;;; Comment
@ -2049,13 +2084,11 @@ and `:post-blank' keywords."
(end (point))
closed deadline scheduled)
(goto-char begin)
(while (re-search-forward org-keyword-time-not-clock-regexp
(line-end-position) t)
(while (re-search-forward org-keyword-time-not-clock-regexp end t)
(goto-char (match-end 1))
(org-skip-whitespace)
(let ((time (buffer-substring-no-properties
(1+ (point)) (1- (match-end 0))))
(keyword (match-string 1)))
(skip-chars-forward " \t" end)
(let ((keyword (match-string 1))
(time (org-element-timestamp-parser)))
(cond ((equal keyword org-closed-string) (setq closed time))
((equal keyword org-deadline-string) (setq deadline time))
(t (setq scheduled time)))))
@ -2073,13 +2106,18 @@ CONTENTS is nil."
(mapconcat
'identity
(delq nil
(list (let ((closed (org-element-property :closed planning)))
(when closed (concat org-closed-string " [" closed "]")))
(let ((deadline (org-element-property :deadline planning)))
(when deadline (concat org-deadline-string " <" deadline ">")))
(list (let ((deadline (org-element-property :deadline planning)))
(when deadline
(concat org-deadline-string " "
(org-element-timestamp-interpreter deadline nil))))
(let ((scheduled (org-element-property :scheduled planning)))
(when scheduled
(concat org-scheduled-string " <" scheduled ">")))))
(concat org-scheduled-string " "
(org-element-timestamp-interpreter scheduled nil))))
(let ((closed (org-element-property :closed planning)))
(when closed
(concat org-closed-string " "
(org-element-timestamp-interpreter closed nil))))))
" "))
@ -3358,39 +3396,168 @@ Assume point is at the beginning of the timestamp."
(save-excursion
(let* ((begin (point))
(activep (eq (char-after) ?<))
(main-value
(raw-value
(progn
(looking-at "[<[]\\(\\(%%\\)?.*?\\)[]>]\\(?:--[<[]\\(.*?\\)[]>]\\)?")
(match-string-no-properties 1)))
(range-end (match-string-no-properties 3))
(type (cond ((match-string 2) 'diary)
((and activep range-end) 'active-range)
(looking-at "\\([<[]\\(%%\\)?.*?\\)[]>]\\(?:--\\([<[].*?[]>]\\)\\)?")
(match-string-no-properties 0)))
(date-start (match-string-no-properties 1))
(date-end (match-string 3))
(diaryp (match-beginning 2))
(type (cond (diaryp 'diary)
((and activep date-end) 'active-range)
(activep 'active)
(range-end 'inactive-range)
(date-end 'inactive-range)
(t 'inactive)))
(post-blank (progn (goto-char (match-end 0))
(skip-chars-forward " \t")))
(end (point)))
(end (point))
(with-time-p (string-match "[012]?[0-9]:[0-5][0-9]" date-start))
(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
(case (string-to-char (match-string 3 raw-value))
(?h 'hour) (?d 'day) (?w 'week) (?m 'month) (t 'year)))))
time-range year-start month-start day-start hour-start minute-start
year-end month-end day-end hour-end minute-end)
;; Extract time range, if any, and remove it from date start.
(setq time-range
(and (not diaryp)
(string-match
"[012]?[0-9]:[0-5][0-9]\\(-\\([012]?[0-9]\\):\\([0-5][0-9]\\)\\)"
date-start)
(cons (string-to-number (match-string 2 date-start))
(string-to-number (match-string 3 date-start)))))
(when time-range
(setq date-start (replace-match "" nil nil date-start 1)))
;; Parse date-start.
(unless diaryp
(let ((date (org-parse-time-string date-start)))
(setq year-start (nth 5 date)
month-start (nth 4 date)
day-start (nth 3 date)
hour-start (and with-time-p (nth 2 date))
minute-start (and with-time-p (nth 1 date)))))
;; Compute date-end. It can be provided directly in time-stamp,
;; or extracted from time range. Otherwise, it defaults to the
;; same values as date-start.
(unless diaryp
(let ((date (and date-end (org-parse-time-string date-end))))
(setq year-end (or (nth 5 date) year-start)
month-end (or (nth 4 date) month-start)
day-end (or (nth 3 date) day-start)
hour-end (or (nth 2 date) (car time-range) hour-start)
minute-end (or (nth 1 date) (cdr time-range) minute-start))))
(list 'timestamp
(list :type type
:value main-value
:range-end range-end
:begin begin
:end end
:post-blank post-blank)))))
(nconc (list :type type
:raw-value raw-value
:year-start year-start
:month-start month-start
:day-start day-start
:hour-start hour-start
:minute-start minute-start
:year-end year-end
:month-end month-end
:day-end day-end
:hour-end hour-end
:minute-end minute-end
:begin begin
:end end
:post-blank post-blank)
repeater-props)))))
(defun org-element-timestamp-interpreter (timestamp contents)
"Interpret TIMESTAMP object as Org syntax.
CONTENTS is nil."
(let ((type (org-element-property :type timestamp) ))
(concat
(format (if (memq type '(inactive inactive-range)) "[%s]" "<%s>")
(org-element-property :value timestamp))
(let ((range-end (org-element-property :range-end timestamp)))
(when range-end
(concat "--"
(format (if (eq type 'inactive-range) "[%s]" "<%s>")
range-end)))))))
;; Use `:raw-value' if specified.
(or (org-element-property :raw-value timestamp)
;; Otherwise, build timestamp string.
(let ((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 repeat-string)
(let ((ts (format-time-string
(funcall (if with-time-p 'cdr 'car)
org-time-stamp-formats)
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))))
(when (org-string-nw-p repeat-string)
(setq ts (concat (substring ts 0 -1)
" "
repeat-string
(substring ts -1))))
;; Return value.
ts)))
(type (org-element-property :type timestamp)))
(case type
((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
(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)
(concat (case (org-element-property :repeater-type timestamp)
(cumulate "+") (catch-up "++") (restart ".+"))
(org-element-property :repeater-value timestamp)
(org-element-property :repeater-unit timestamp)))))
((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 (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
(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)))))))))
(defun org-element-timestamp-successor (limit)
"Search for the next timestamp object.
@ -3539,7 +3706,7 @@ element it has to parse."
;; a footnote definition: next item is always a paragraph.
((not (bolp)) (org-element-paragraph-parser limit (list (point))))
;; Planning and Clock.
((and (looking-at org-planning-or-clock-line-re))
((looking-at org-planning-or-clock-line-re)
(if (equal (match-string 1) org-clock-string)
(org-element-clock-parser limit)
(org-element-planning-parser limit)))

View File

@ -278,22 +278,24 @@ Some other text
;; Running clock.
(let* ((org-clock-string "CLOCK:")
(clock (org-test-with-temp-text "CLOCK: [2012-01-01 sun. 00:01]"
(org-element-map
(org-element-parse-buffer) 'clock 'identity nil t))))
(org-element-at-point))))
(should (eq (org-element-property :status clock) 'running))
(should (equal (org-element-property :value clock)
"[2012-01-01 sun. 00:01]"))
(should-not (org-element-property :time clock)))
(should
(equal (org-element-property :raw-value
(org-element-property :value clock))
"[2012-01-01 sun. 00:01]"))
(should-not (org-element-property :duration clock)))
;; Closed clock.
(let* ((org-clock-string "CLOCK:")
(clock (org-test-with-temp-text "
CLOCK: [2012-01-01 sun. 00:01]--[2012-01-01 sun. 00:02] => 0:01"
(org-element-map
(org-element-parse-buffer) 'clock 'identity nil t))))
(clock
(org-test-with-temp-text
"CLOCK: [2012-01-01 sun. 00:01]--[2012-01-01 sun. 00:02] => 0:01"
(org-element-at-point))))
(should (eq (org-element-property :status clock) 'closed))
(should (equal (org-element-property :value clock)
(should (equal (org-element-property :raw-value
(org-element-property :value clock))
"[2012-01-01 sun. 00:01]--[2012-01-01 sun. 00:02]"))
(should (equal (org-element-property :time clock) "0:01"))))
(should (equal (org-element-property :duration clock) "0:01"))))
;;;; Code
@ -1382,26 +1384,29 @@ Outside list"
(ert-deftest test-org-element/planning-parser ()
"Test `planning' parser."
(should
(equal
(org-element-property
:closed
(org-test-with-temp-text "CLOSED: [2012-03-29 thu.]"
(org-element-map (org-element-parse-buffer) 'planning 'identity nil t)))
"2012-03-29 thu."))
(equal "[2012-03-29 thu.]"
(org-element-property
:raw-value
(org-element-property
:closed
(org-test-with-temp-text "CLOSED: [2012-03-29 thu.]"
(org-element-at-point))))))
(should
(equal
(org-element-property
:deadline
(org-test-with-temp-text "DEADLINE: <2012-03-29 thu.>"
(org-element-map (org-element-parse-buffer) 'planning 'identity nil t)))
"2012-03-29 thu."))
(equal "<2012-03-29 thu.>"
(org-element-property
:raw-value
(org-element-property
:deadline
(org-test-with-temp-text "DEADLINE: <2012-03-29 thu.>"
(org-element-at-point))))))
(should
(equal
(org-element-property
:scheduled
(org-test-with-temp-text "SCHEDULED: <2012-03-29 thu.>"
(org-element-map (org-element-parse-buffer) 'planning 'identity nil t)))
"2012-03-29 thu.")))
(equal "<2012-03-29 thu.>"
(org-element-property
:raw-value
(org-element-property
:scheduled
(org-test-with-temp-text "SCHEDULED: <2012-03-29 thu.>"
(org-element-at-point)))))))
;;;; Property Drawer
@ -1707,27 +1712,41 @@ Outside list"
;; Active timestamp.
(should
(org-test-with-temp-text "<2012-03-29 16:40>"
(eq (org-element-property :type
(org-element-map
(org-element-parse-buffer)
'timestamp 'identity nil t))
'active)))
(eq (org-element-property :type (org-element-context)) 'active)))
(should
(equal '(2012 3 29 16 40)
(org-test-with-temp-text "<2012-03-29 16:40>"
(let ((object (org-element-context)))
(list (org-element-property :year-start object)
(org-element-property :month-start object)
(org-element-property :day-start object)
(org-element-property :hour-start object)
(org-element-property :minute-start object))))))
;; Inactive timestamp.
(should
(org-test-with-temp-text "[2012-03-29 16:40]"
(eq (org-element-property :type
(org-element-map
(org-element-parse-buffer)
'timestamp 'identity nil t))
'inactive)))
(eq (org-element-property :type (org-element-context)) 'inactive)))
;; Time range.
(should
(equal '(2012 3 29 16 40 7 30)
(org-test-with-temp-text "<2012-03-29 7:30-16:40>"
(let ((object (org-element-context)))
(list (org-element-property :year-end object)
(org-element-property :month-end object)
(org-element-property :day-end object)
(org-element-property :hour-end object)
(org-element-property :minute-end object)
(org-element-property :hour-start object)
(org-element-property :minute-start object))))))
;; Date range.
(should
(org-test-with-temp-text "[2012-03-29 16:40]--[2012-03-29 16:41]"
(eq (org-element-property :type
(org-element-map
(org-element-parse-buffer)
'timestamp 'identity nil t))
'inactive-range)))
(eq (org-element-property :type (org-element-context)) 'inactive-range)))
;; With repeater.
(should
(eq 'catch-up
(org-test-with-temp-text "<2012-03-29 ++1y>"
(org-element-property :repeater-type (org-element-context)))))
;; Timestamps are not planning elements.
(should-not
(org-test-with-temp-text "SCHEDULED: <2012-03-29 16:40>"
@ -2102,9 +2121,9 @@ CLOCK: [2012-01-01 sun. 00:01]--[2012-01-01 sun. 00:02] => 0:01"))
(equal
(org-test-parse-and-interpret
"* Headline
CLOSED: [2012-01-01] DEADLINE: <2012-01-01> SCHEDULED: <2012-01-01>")
DEADLINE: <2012-01-01> SCHEDULED: <2012-01-01> CLOSED: [2012-01-01]")
"* Headline
CLOSED: [2012-01-01] DEADLINE: <2012-01-01> SCHEDULED: <2012-01-01>\n"))))
DEADLINE: <2012-01-01> SCHEDULED: <2012-01-01> CLOSED: [2012-01-01]\n"))))
(ert-deftest test-org-element/property-drawer-interpreter ()
"Test property drawer interpreter."
@ -2159,25 +2178,61 @@ CLOSED: [2012-01-01] DEADLINE: <2012-01-01> SCHEDULED: <2012-01-01>\n"))))
(ert-deftest test-org-element/timestamp-interpreter ()
"Test timestamp interpreter."
;; Active.
(should (equal (org-test-parse-and-interpret "<2012-03-29 16:40>")
"<2012-03-29 16:40>\n"))
(should (equal (org-test-parse-and-interpret "<2012-03-29 thu. 16:40>")
"<2012-03-29 thu. 16:40>\n"))
(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)) nil)))
;; Inactive.
(should (equal (org-test-parse-and-interpret "[2012-03-29 16:40]")
"[2012-03-29 16:40]\n"))
(should (equal (org-test-parse-and-interpret "[2012-03-29 thu. 16:40]")
"[2012-03-29 thu. 16:40]\n"))
(should
(string-match
"\\[2012-03-29 .* 16:40\\]"
(org-element-timestamp-interpreter
'(timestamp
(:type inactive :year-start 2012 :month-start 3 :day-start 29
:hour-start 16 :minute-start 40)) nil)))
;; Active range.
(should (equal (org-test-parse-and-interpret
"<2012-03-29 16:40>--<2012-03-29 16:41>")
"<2012-03-29 16:40>--<2012-03-29 16:41>\n"))
"<2012-03-29 thu. 16:40>--<2012-03-29 thu. 16:41>")
"<2012-03-29 thu. 16:40>--<2012-03-29 thu. 16:41>\n"))
(should
(string-match
"<2012-03-29 .* 16:40>--<2012-03-29 .* 16:41>"
(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 41)) nil)))
;; Inactive range.
(should (equal (org-test-parse-and-interpret
"[2012-03-29 16:40]--[2012-03-29 16:41]")
"[2012-03-29 16:40]--[2012-03-29 16:41]\n"))
"[2012-03-29 thu. 16:40]--[2012-03-29 thu. 16:41]")
"[2012-03-29 thu. 16:40]--[2012-03-29 thu. 16:41]\n"))
(should
(string-match
"\\[2012-03-29 .* 16:40\\]--\\[2012-03-29 .* 16:41\\]"
(org-element-timestamp-interpreter
'(timestamp
(: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)))
;; Diary.
(should (equal (org-test-parse-and-interpret "<%%org-float t 4 2>")
"<%%org-float t 4 2>\n"))
(should (equal (org-test-parse-and-interpret "<%%(org-float t 4 2)>")
"<%%(org-float t 4 2)>\n"))
;; Timestamp with repeater interval.
(should (equal (org-test-parse-and-interpret "<2012-03-29 +1y>")
"<2012-03-29 +1y>\n")))
(should (equal (org-test-parse-and-interpret "<2012-03-29 thu. +1y>")
"<2012-03-29 thu. +1y>\n"))
(should
(string-match
"<2012-03-29 .* \\+1y>"
(org-element-timestamp-interpreter
'(timestamp
(:type active :year-start 2012 :month-start 3 :day-start 29
:repeater-type cumulate :repeater-value "1y")) nil))))
(ert-deftest test-org-element/verse-block-interpreter ()
"Test verse block interpretation."