Bladeren bron

org-element: Change to timestamp interpreter

* lisp/org-element.el (org-element-timestamp-interpreter):
  Ignore :raw-value and build timestamp from numeric properties
  instead.
* testing/lisp/test-org-element.el: Update tests.
* testing/lisp/test-ox.el: Update tests.

This change allow to modify and update a timestamp easily without
requiring to reset :raw-value first, which was not intuitive.
Nicolas Goaziou 11 jaren geleden
bovenliggende
commit
fc95ee2768
3 gewijzigde bestanden met toevoegingen van 144 en 139 verwijderingen
  1. 91 94
      lisp/org-element.el
  2. 32 25
      testing/lisp/test-org-element.el
  3. 21 20
      testing/lisp/test-ox.el

+ 91 - 94
lisp/org-element.el

@@ -3550,100 +3550,97 @@ Assume point is at the beginning of the timestamp."
 (defun org-element-timestamp-interpreter (timestamp contents)
   "Interpret TIMESTAMP object as Org syntax.
 CONTENTS is nil."
-  ;; Use `:raw-value' if specified.
-  (or (org-element-property :raw-value timestamp)
-      ;; Otherwise, build timestamp string.
-      (let* ((repeat-string
-	      (concat
-	       (case (org-element-property :repeater-type timestamp)
-		 (cumulate "+") (catch-up "++") (restart ".+"))
-	       (let ((val (org-element-property :repeater-value timestamp)))
-		 (and val (number-to-string val)))
-	       (case (org-element-property :repeater-unit timestamp)
-		 (hour "h") (day "d") (week "w") (month "m") (year "y"))))
-	     (warning-string
-	      (concat
-	       (case (org-element-property :warning-type timestamp)
-		 (first "--")
-		 (all "-"))
-	       (let ((val (org-element-property :warning-value timestamp)))
-		 (and val (number-to-string val)))
-	       (case (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
-			   (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))))
-		  (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)))
-	(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))))
-	  ((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)))))))))
+  (let* ((repeat-string
+	  (concat
+	   (case (org-element-property :repeater-type timestamp)
+	     (cumulate "+") (catch-up "++") (restart ".+"))
+	   (let ((val (org-element-property :repeater-value timestamp)))
+	     (and val (number-to-string val)))
+	   (case (org-element-property :repeater-unit timestamp)
+	     (hour "h") (day "d") (week "w") (month "m") (year "y"))))
+	 (warning-string
+	  (concat
+	   (case (org-element-property :warning-type timestamp)
+	     (first "--")
+	     (all "-"))
+	   (let ((val (org-element-property :warning-value timestamp)))
+	     (and val (number-to-string val)))
+	   (case (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
+		       (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))))
+	      (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)))
+    (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))))
+      ((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 ()
   "Search for the next timestamp object.

+ 32 - 25
testing/lisp/test-org-element.el

@@ -2211,16 +2211,17 @@ Outside list"
   "Test clock interpreter."
   ;; Running clock.
   (should
-   (equal (let ((org-clock-string "CLOCK:"))
-	    (org-test-parse-and-interpret "CLOCK: [2012-01-01 sun. 00:01]"))
-	  "CLOCK: [2012-01-01 sun. 00:01]\n"))
+   (string-match
+    "CLOCK: \\[2012-01-01 .* 00:01\\]"
+    (let ((org-clock-string "CLOCK:"))
+      (org-test-parse-and-interpret "CLOCK: [2012-01-01 sun. 00:01]"))))
   ;; Closed clock.
   (should
-   (equal
+   (string-match
+    "CLOCK: \\[2012-01-01 .* 00:01\\]--\\[2012-01-01 .* 00:02\\] =>  0:01"
     (let ((org-clock-string "CLOCK:"))
       (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\n")))
+CLOCK: [2012-01-01 sun. 00:01]--[2012-01-01 sun. 00:02] =>  0:01")))))
 
 (ert-deftest test-org-element/comment-interpreter ()
   "Test comment interpreter."
@@ -2320,12 +2321,12 @@ CLOCK: [2012-01-01 sun. 00:01]--[2012-01-01 sun. 00:02] =>  0:01"))
 	(org-deadline-string "DEADLINE:")
 	(org-scheduled-string "SCHEDULED:"))
     (should
-     (equal
+     (string-match
+      "\\* Headline
+DEADLINE: <2012-03-29 .*?> SCHEDULED: <2012-03-29 .*?> CLOSED: \\[2012-03-29 .*?\\]"
       (org-test-parse-and-interpret
        "* Headline
-DEADLINE: <2012-01-01> SCHEDULED: <2012-01-01> CLOSED: [2012-01-01]")
-      "* Headline
-DEADLINE: <2012-01-01> SCHEDULED: <2012-01-01> CLOSED: [2012-01-01]\n"))))
+DEADLINE: <2012-03-29 thu.> SCHEDULED: <2012-03-29 thu.> CLOSED: [2012-03-29 thu.]")))))
 
 (ert-deftest test-org-element/property-drawer-interpreter ()
   "Test property drawer interpreter."
@@ -2395,8 +2396,9 @@ DEADLINE: <2012-01-01> SCHEDULED: <2012-01-01> CLOSED: [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 thu. 16:40>")
-		 "<2012-03-29 thu. 16:40>\n"))
+  (should
+   (string-match "<2012-03-29 .* 16:40>"
+		 (org-test-parse-and-interpret "<2012-03-29 thu. 16:40>")))
   (should
    (string-match "<2012-03-29 .* 16:40>"
 		 (org-element-timestamp-interpreter
@@ -2404,8 +2406,9 @@ DEADLINE: <2012-01-01> SCHEDULED: <2012-01-01> CLOSED: [2012-01-01]\n"))))
 		    (: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 thu. 16:40]")
-		 "[2012-03-29 thu. 16:40]\n"))
+  (should
+   (string-match "\\[2012-03-29 .* 16:40\\]"
+		 (org-test-parse-and-interpret "[2012-03-29 thu. 16:40]")))
   (should
    (string-match
     "\\[2012-03-29 .* 16:40\\]"
@@ -2414,9 +2417,10 @@ DEADLINE: <2012-01-01> SCHEDULED: <2012-01-01> CLOSED: [2012-01-01]\n"))))
        (: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 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-test-parse-and-interpret
+		  "<2012-03-29 thu. 16:40>--<2012-03-29 thu. 16:41>")))
   (should
    (string-match
     "<2012-03-29 .* 16:40>--<2012-03-29 .* 16:41>"
@@ -2426,9 +2430,10 @@ DEADLINE: <2012-01-01> SCHEDULED: <2012-01-01> CLOSED: [2012-01-01]\n"))))
 	      :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 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-test-parse-and-interpret
+		  "[2012-03-29 thu. 16:40]--[2012-03-29 thu. 16:41]")))
   (should
    (string-match
     "\\[2012-03-29 .* 16:40\\]--\\[2012-03-29 .* 16:41\\]"
@@ -2441,8 +2446,9 @@ DEADLINE: <2012-01-01> SCHEDULED: <2012-01-01> CLOSED: [2012-01-01]\n"))))
   (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.
-  (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-test-parse-and-interpret "<2012-03-29 thu. +1y>")))
   (should
    (string-match
     "<2012-03-29 .* \\+1y>"
@@ -2469,9 +2475,10 @@ DEADLINE: <2012-01-01> SCHEDULED: <2012-01-01> CLOSED: [2012-01-01]\n"))))
 	      :repeater-type cumulate :repeater-value 1 :repeater-unit year))
      nil)))
   ;; Timestamp range with repeater interval
-  (should (equal (org-test-parse-and-interpret
-		  "<2012-03-29 Thu +1y>--<2012-03-30 Thu +1y>")
-		 "<2012-03-29 Thu +1y>--<2012-03-30 Thu +1y>\n"))
+  (should
+   (string-match "<2012-03-29 .* \\+1y>--<2012-03-30 .* \\+1y>"
+		 (org-test-parse-and-interpret
+		  "<2012-03-29 Thu +1y>--<2012-03-30 Thu +1y>")))
   (should
    (string-match
     "<2012-03-29 .* \\+1y>--<2012-03-30 .* \\+1y>"

+ 21 - 20
testing/lisp/test-ox.el

@@ -400,11 +400,11 @@ Paragraph"
 		       nil nil nil '(:with-archived-trees t))))))
   ;; Clocks.
   (should
-   (equal "CLOCK: [2012-04-29 sun. 10:45]\n"
-	  (let ((org-clock-string "CLOCK:"))
-	    (org-test-with-temp-text "CLOCK: [2012-04-29 sun. 10:45]"
-	      (org-export-as (org-test-default-backend)
-			     nil nil nil '(:with-clocks t))))))
+   (string-match "CLOCK: \\[2012-04-29 .* 10:45\\]"
+		 (let ((org-clock-string "CLOCK:"))
+		   (org-test-with-temp-text "CLOCK: [2012-04-29 sun. 10:45]"
+		     (org-export-as (org-test-default-backend)
+				    nil nil nil '(:with-clocks t))))))
   (should
    (equal ""
 	  (let ((org-clock-string "CLOCK:"))
@@ -464,11 +464,12 @@ Paragraph"
 			 nil nil nil '(:with-inlinetasks nil)))))))
   ;; Plannings.
   (should
-   (equal "CLOSED: [2012-04-29 sun. 10:45]\n"
-	  (let ((org-closed-string "CLOSED:"))
-	    (org-test-with-temp-text "CLOSED: [2012-04-29 sun. 10:45]"
-	      (org-export-as (org-test-default-backend)
-			     nil nil nil '(:with-planning t))))))
+   (string-match
+    "CLOSED: \\[2012-04-29 .* 10:45\\]"
+    (let ((org-closed-string "CLOSED:"))
+      (org-test-with-temp-text "CLOSED: [2012-04-29 sun. 10:45]"
+	(org-export-as (org-test-default-backend)
+		       nil nil nil '(:with-planning t))))))
   (should
    (equal ""
 	  (let ((org-closed-string "CLOSED:"))
@@ -505,8 +506,8 @@ Paragraph"
   "Test `org-export-with-timestamps' specifications."
   ;; t value.
   (should
-   (equal
-    "[2012-04-29 sun. 10:45]<2012-04-29 sun. 10:45>\n"
+   (string-match
+    "\\[2012-04-29 .*? 10:45\\]<2012-04-29 .*? 10:45>"
     (org-test-with-temp-text "[2012-04-29 sun. 10:45]<2012-04-29 sun. 10:45>"
       (org-export-as (org-test-default-backend)
 		     nil nil nil '(:with-timestamps t)))))
@@ -519,24 +520,24 @@ Paragraph"
 		     nil nil nil '(:with-timestamps nil)))))
   ;; `active' value.
   (should
-   (equal
-    "<2012-03-29 Thu>\n\nParagraph <2012-03-29 Thu>[2012-03-29 Thu]"
+   (string-match
+    "<2012-03-29 .*?>\n\nParagraph <2012-03-29 .*?>\\[2012-03-29 .*?\\]"
     (org-test-with-temp-text
 	"<2012-03-29 Thu>[2012-03-29 Thu]
 
 Paragraph <2012-03-29 Thu>[2012-03-29 Thu]"
-      (org-trim (org-export-as (org-test-default-backend)
-			       nil nil nil '(:with-timestamps active))))))
+      (org-export-as (org-test-default-backend)
+		     nil nil nil '(:with-timestamps active)))))
   ;; `inactive' value.
   (should
-   (equal
-    "[2012-03-29 Thu]\n\nParagraph <2012-03-29 Thu>[2012-03-29 Thu]"
+   (string-match
+    "\\[2012-03-29 .*?\\]\n\nParagraph <2012-03-29 .*?>\\[2012-03-29 .*?\\]"
     (org-test-with-temp-text
 	"<2012-03-29 Thu>[2012-03-29 Thu]
 
 Paragraph <2012-03-29 Thu>[2012-03-29 Thu]"
-      (org-trim (org-export-as (org-test-default-backend)
-			       nil nil nil '(:with-timestamps inactive)))))))
+      (org-export-as (org-test-default-backend)
+		     nil nil nil '(:with-timestamps inactive))))))
 
 (ert-deftest test-org-export/comment-tree ()
   "Test if export process ignores commented trees."