Allow clock elements without timestamp, like CLOCK: => 12:00

This syntax has been introduced in Org 4.78, but not supported later,
when Org element parser have been created.  Fix this omission to not
remove an existing (and announced!) feature.

This kind of clock is of limited use though - all the customizations
relying upon knowing _when_ clocking time was recorded, like ranges in
clock tables or limits on the displayed clocked-in time, will include
such clocks unconditionally.  So, not adding this to the manual, as it
is not very clear how to use it in actual workflow.

* lisp/org-element.el (org-element-clock-line-re): Update the regexp.
(org-element-clock-parser): Do not assume that timestamp always
follows CLOCK: line.
* testing/lisp/test-org-element.el (test-org-element/clock-parser):
(test-org-element/clock-interpreter): Add tests checking parser and
interpreter output of clocks without timestamps.

Link: https://orgmode.org/list/87frvpyzrf.fsf@localhost
This commit is contained in:
Ihor Radchenko 2024-04-14 15:46:15 +03:00
parent b42867b5a1
commit 17072a4690
No known key found for this signature in database
GPG Key ID: 6470762A7DA11D8B
2 changed files with 34 additions and 14 deletions

View File

@ -126,17 +126,24 @@ Key is located in match group 1.")
Style, if any, is located in match group 1.")
(defconst org-element-clock-line-re
(rx-to-string
`(seq
line-start (0+ (or ?\t ?\s))
"CLOCK: "
(regexp ,org-ts-regexp-inactive)
(opt "--"
(regexp ,org-ts-regexp-inactive)
(1+ (or ?\t ?\s)) "=>" (1+ (or ?\t ?\s))
(1+ digit) ":" digit digit)
(0+ (or ?\t ?\s))
line-end))
(let ((duration ; "=> 212:12"
'(seq
(1+ (or ?\t ?\s)) "=>" (1+ (or ?\t ?\s))
(1+ digit) ":" digit digit)))
(rx-to-string
`(seq
line-start (0+ (or ?\t ?\s))
"CLOCK:"
(or
(seq
(1+ (or ?\t ?\s))
(regexp ,org-ts-regexp-inactive)
(opt "--"
(regexp ,org-ts-regexp-inactive)
,duration))
,duration)
(0+ (or ?\t ?\s))
line-end)))
"Regexp matching a clock line.")
(defconst org-element-comment-string "COMMENT"
@ -2295,7 +2302,7 @@ Return a new syntax node of `clock' type containing `:status',
(value (progn (search-forward "CLOCK:" (line-end-position))
(skip-chars-forward " \t")
(org-element-timestamp-parser)))
(duration (and (search-forward " => " (line-end-position) t)
(duration (and (search-forward "=> " (line-end-position) t)
(progn (skip-chars-forward " \t")
(looking-at "\\(\\S-+\\)[ \t]*$"))
(match-string-no-properties 1)))

View File

@ -1175,7 +1175,15 @@ CLOCK: [2023-10-13 Fri 14:40]--[2023-10-13 Fri 14:51] => 0:11"
(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 :duration clock) "0:01"))))
(should (equal (org-element-property :duration clock) "0:01")))
;; Closed clock without timestamp.
(let ((clock
(org-test-with-temp-text
"CLOCK: => 0:11"
(org-element-at-point))))
(should (eq (org-element-property :status clock) 'closed))
(should-not (org-element-property :value clock))
(should (equal (org-element-property :duration clock) "0:11"))))
;;;; Code
@ -3682,7 +3690,12 @@ Outside list"
(string-match
"CLOCK: \\[2012-01-01 .* 00:01\\]--\\[2012-01-01 .* 00:02\\] => 0:01"
(org-test-parse-and-interpret "
CLOCK: [2012-01-01 sun. 00:01]--[2012-01-01 sun. 00:02] => 0:01"))))
CLOCK: [2012-01-01 sun. 00:01]--[2012-01-01 sun. 00:02] => 0:01")))
;; Closed clock without timestamp.
(should
(string-match
"CLOCK: => 0:01"
(org-test-parse-and-interpret "CLOCK: => 0:01"))))
(ert-deftest test-org-element/comment-interpreter ()
"Test comment interpreter."