branch: externals/org
commit fa1cc2085eca8d2720c9e80b902970d424d874c4
Author: Lukas Epple <em...@lukasepple.de>
Commit: Ihor Radchenko <yanta...@posteo.net>

    lisp/ox-html.el: Use time element for timestamps in fancy html5
    
    * ox-html.el (org-html--format-timestamp): Use time html element and its
    datetime attribute when `org-html--html5-fancy-p'.
    (org-html-datetime-formats): Add custom value that allows the user to
    modify how `org-html--format-timestamp' renders the timestamp in the
    HTML5 datetime attribute without affecting how it is displayed.
    * testing/lisp/test-ox-html.el (ox-html/html5-fancy-timestamps): Add
    simple test for the changed behavior (which only covers the behavior of
    `org-html-timestamp').
    * ORG-NEWS: Describe changed behavior of timestamp formatting with fancy
    HTML5 rendering.
---
 etc/ORG-NEWS                 |  9 +++++++++
 lisp/ox-html.el              | 37 +++++++++++++++++++++++++++++++------
 testing/lisp/test-ox-html.el | 18 ++++++++++++++++++
 3 files changed, 58 insertions(+), 6 deletions(-)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 5b59086292..375a0c4241 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -676,6 +676,15 @@ will be defined as empty and not produce any metadata if 
their
 corresponding ~org-latex-with-author~, ~org-latex-with-title~, or
 ~org-latex-with-creator~ option is set to ~nil~.
 
+*** Fancy HTML5 export uses ~<time>~ element for timestamps
+Previously, timestamps would always be rendered inside a ~<span
+class="timestamp">~. Now, if both ~org-html-doctype~ is ~html5~ and
+~org-html-html5-fancy~ is enabled, org will use the semantic
+~<time>~ element. This will also have the ~timestamp~ class, but
+additionally set the ~datetime~ attribute with a machine readable
+variant of the timestamp. The format used for the attribute can be
+customized using ~org-html-datetime-formats~.
+
 * Version 9.7
 
 ** Important announcements and breaking changes
diff --git a/lisp/ox-html.el b/lisp/ox-html.el
index 9eeb6a1a78..be66f6bb3e 100644
--- a/lisp/ox-html.el
+++ b/lisp/ox-html.el
@@ -1168,6 +1168,19 @@ See `format-time-string' for more information on its 
components."
   :package-version '(Org . "8.0")
   :type 'string)
 
+(defcustom org-html-datetime-formats '("%F" . "%FT%T")
+  "Formats used for the timestamp added as metadata to the time HTML element.
+This only has an effect when `org-html-html5-fancy' is enabled, but
+does not affect how the timestamp is displayed.  The format in CAR
+represents the timestamp used for timestamps without a time component,
+CDR the one for the full date and time.  Note that the HTML standard
+restricts what timestamp formats are considered valid for the datetime
+attribute.  See `format-time-string' for more information on its
+components."
+  :type '(cons string string)
+  :group 'org-export-html
+  :package-version '(Org . "9.8"))
+
 ;;;; Template :: Mathjax
 
 (defcustom org-html-mathjax-options
@@ -1811,12 +1824,24 @@ a value to `org-html-standalone-image-predicate'."
   "Format given TIMESTAMP for inclusion in an HTML document.
 INFO is a plist used as a communication channel.  Formatted timestamp
 will be wrapped in an element with class timestamp."
-  (replace-regexp-in-string
-   "--"
-   "&ndash;"
-   (format "<span class=\"timestamp\">%s</span>"
-           (org-html-plain-text (org-timestamp-translate timestamp)
-                                info))))
+  (let ((html-tag (if (org-html--html5-fancy-p info) "time" "span"))
+        (html-attrs (concat "class=\"timestamp\""
+                            (when (org-html--html5-fancy-p info)
+                              (format " datetime=\"%s\""
+                                      (org-format-timestamp
+                                       timestamp
+                                       (if (org-timestamp-has-time-p timestamp)
+                                           (cdr org-html-datetime-formats)
+                                           (car 
org-html-datetime-formats))))))))
+    (replace-regexp-in-string
+     "--"
+     "&ndash;"
+     (format "<%s %s>%s</%s>"
+             html-tag
+             html-attrs
+             (org-html-plain-text (org-timestamp-translate timestamp)
+                                  info)
+             html-tag))))
 
 ;;;; Table
 
diff --git a/testing/lisp/test-ox-html.el b/testing/lisp/test-ox-html.el
index 3d786629a0..15b09a31fa 100644
--- a/testing/lisp/test-ox-html.el
+++ b/testing/lisp/test-ox-html.el
@@ -954,6 +954,24 @@ SCHEDULED: <2025-03-26 Wed> DEADLINE: <2025-03-27 Thu 
13:00> CLOSED: [2025-03-25
                 "<span class=\"timestamp-kwd\">DEADLINE:</span> <span 
class=\"timestamp\">&lt;2025-03-27 Thu 13:00&gt; </span>"
                 "<span class=\"timestamp-kwd\">SCHEDULED:</span> <span 
class=\"timestamp\">&lt;2025-03-26 Wed&gt; </span>"))))))
 
+(ert-deftest ox-html/html5-fancy-timestamps ()
+  "Test rendering of timestamps with fancy HTML5 enabled"
+  (org-test-with-temp-text "
+[2025-06-25 Wed]
+<2025-06-25 Wed 19:10>
+"
+   (let ((export-buffer "*Test HTML Export")
+         (org-export-show-temporary-buffer nil)
+         (org-html-doctype "html5")
+         (org-html-html5-fancy t))
+     (org-export-to-buffer 'html export-buffer
+       nil nil nil t)
+     (with-current-buffer export-buffer
+       (mapc (lambda (s)
+               (should (= 1 (how-many (rx-to-string s)))))
+             '("<span class=\"timestamp-wrapper\"><time class=\"timestamp\" 
datetime=\"2025-06-25\">[2025-06-25 Wed]</time></span>"
+               "<span class=\"timestamp-wrapper\"><time class=\"timestamp\" 
datetime=\"2025-06-25T19:10:00\">&lt;2025-06-25 Wed 
19:10&gt;</time></span>"))))))
+
 
 ;;; Postamble Format
 

Reply via email to