Ilya Chernyshov <ichernysho...@gmail.com> writes:

> Preserved old behavior for `org-element-timestamp-interpreter'
> function for :range-type set to `nil'. The new function
>
> The new function takes into account :range-type value when interpreting
> ranges and throws error when :range-type set for `active'/`inactive'
> types.

Thanks!

The patch looks good in general, but there is at least one test failing
when I run make test. May you please check?

Also, see the attached diff where I suggest some comments to explain the
code logic.
diff --git a/lisp/org-element.el b/lisp/org-element.el
index 203f45a33..baa605548 100644
--- a/lisp/org-element.el
+++ b/lisp/org-element.el
@@ -4152,6 +4152,8 @@ (defun org-element-timestamp-interpreter (timestamp _)
         (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
@@ -4184,39 +4186,82 @@ (defun org-element-timestamp-interpreter (timestamp _)
                      (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-format (when (and minute-start hour-start) t) 'no-brackets)
+                ;; `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))
-               (let((hour-end (org-element-property :hour-end timestamp))
-                    (minute-end (org-element-property :minute-end timestamp)))
+               ;; 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' use 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' will never assign end times here.
+                       ;; End time will always imply `active-range' or `inactive-range' TYPE.
+                       ;; But manually built timestamps may contain
+                       ;; anything, 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)))
-                      ((or `nil `daterange)
+                      ;; 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-format (when (and minute-end hour-end) t) 'no-brackets)
+                         ;; `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
 
And please provide an additional patch for WORG:
https://orgmode.org/worg/dev/org-element-api.html#org6ae377e

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>

Reply via email to