Hello org-mode users, Here's a patch that adds the ability to specify :html-head as a function. I think this is a logical change because:
1. It provides a wider range of options for how to use :html-head (before :html-head could only be a string, now it can also be a function.) 2. It is consistent with the behavior of :html-preamble and :html-postamble, which can both either be a string or a function. I probably did this wrong but anyway here's my attempt at a patch submission. Please let me know if you need any additional information or have any questions. Thanks, -Nate
From a4c5d3e648898c91858643c27ff6d56cde7af3be Mon Sep 17 00:00:00 2001 From: Nate Nichols <nathannichols...@gmail.com> Date: Sun, 12 May 2024 19:53:09 -0400 Subject: [PATCH] Squashed commit of the following: commit 8160b298a544642881fd10c651fd4e736517cf2f Author: Nate Nichols <nathannichols...@gmail.com> Date: Sun May 12 19:03:25 2024 -0400 Added ability to specify :html-head as a function --- lisp/org-element.el | 20 ++++++++++++--- lisp/ox-html.el | 59 +++++++++++++++++++-------------------------- 2 files changed, 42 insertions(+), 37 deletions(-) diff --git a/lisp/org-element.el b/lisp/org-element.el index cf0982f18..63222c2cc 100644 --- a/lisp/org-element.el +++ b/lisp/org-element.el @@ -5578,9 +5578,8 @@ If there is no affiliated keyword, return the empty string." ;; global indentation from the contents of the current element. (defun org-element-normalize-string (s) - "Ensure string S ends with a single newline character. - -If S isn't a string return it unchanged. If S is the empty + "Return S, or evaluate to a string ending with a single newline character. +If S isn't a string or a function, return it unchanged. If S is the empty string, return it. Otherwise, return a new string with a single newline character at its end." (cond @@ -5589,6 +5588,21 @@ newline character at its end." (t (and (string-match "\\(\n[ \t]*\\)*\\'" s) (replace-match "\n" nil nil s))))) + +(defun org-element-normalize-str-or-fn (input &rest trailing) + "If INPUT is a string, it is passed to `org-element-normalize-string'. +If INPUT is a function, it is applied to arguments TRAILING, and the result is +passed to `org-element-normalize-string'." + (let ((s (if (functionp input) (format "%s" (apply input trailing)) input))) + (org-element-normalize-string s))) + + +;; Test cases for `org-element-normalize-str-or-fn' +(cl-assert (string= (org-element-normalize-str-or-fn (lambda (_res) "abcdefg") nil) "abcdefg\n")) +(cl-assert (string= (org-element-normalize-str-or-fn "abcdefg") "abcdefg\n") nil) +(cl-assert (= (org-element-normalize-str-or-fn 123 nil) 123)) + + (defun org-element-normalize-contents (element &optional ignore-first) "Normalize plain text in ELEMENT's contents. diff --git a/lisp/ox-html.el b/lisp/ox-html.el index ec0add65e..72a8590c4 100644 --- a/lisp/ox-html.el +++ b/lisp/ox-html.el @@ -131,7 +131,11 @@ (:html-equation-reference-format "HTML_EQUATION_REFERENCE_FORMAT" nil org-html-equation-reference-format t) (:html-postamble nil "html-postamble" org-html-postamble) (:html-preamble nil "html-preamble" org-html-preamble) - (:html-head "HTML_HEAD" nil org-html-head newline) + ;; You should be able to use multiple headline properties "#+EXPORT_HTML_HEAD" in a file. + ;; The results of each occurrence will be joined by a newline to form the final string + ;; included in the <head> section. + ;; TODO: Test/verify this works still. See: `org-export-options-alist'. + (:html-head "HTML_HEAD" "html-head" org-html-head newline) (:html-head-extra "HTML_HEAD_EXTRA" nil org-html-head-extra newline) (:subtitle "SUBTITLE" nil nil parse) (:html-head-include-default-style @@ -1402,6 +1406,24 @@ This option can also be set on with the CREATOR keyword." :package-version '(Org . "8.0") :type '(string :tag "Creator string")) + +;;;; Template :: Head + +(defcustom org-html-head "" + "When set to a string, include that string in the HTML header. +When set to a function, apply this function and insert the +returned string. The function takes the property list of export +options as its only argument. + +Setting :html-preamble in publishing projects will take +precedence over this variable." + :group 'org-export-html + :type '(choice (const :tag "Default (empty)" "") + (string :tag "Fixed string") + (function :tag "Function (must return a string)"))) + + + ;;;; Template :: Preamble (defcustom org-html-preamble t @@ -1525,38 +1547,7 @@ style information." ;;;###autoload (put 'org-html-head-include-default-style 'safe-local-variable 'booleanp) -(defcustom org-html-head "" - "Org-wide head definitions for exported HTML files. - -This variable can contain the full HTML structure to provide a -style, including the surrounding HTML tags. You can consider -including definitions for the following classes: title, todo, -done, timestamp, timestamp-kwd, tag, target. - -For example, a valid value would be: - - <style> - p { font-weight: normal; color: gray; } - h1 { color: black; } - .title { text-align: center; } - .todo, .timestamp-kwd { color: red; } - .done { color: green; } - </style> - -If you want to refer to an external style, use something like - <link rel=\"stylesheet\" type=\"text/css\" href=\"mystyles.css\" /> - -As the value of this option simply gets inserted into the HTML -<head> header, you can use it to add any arbitrary text to the -header. - -You can set this on a per-file basis using #+HTML_HEAD:, -or for publication projects using the :html-head property." - :group 'org-export-html - :version "24.4" - :package-version '(Org . "8.0") - :type 'string) ;;;###autoload (put 'org-html-head 'safe-local-variable 'stringp) @@ -2008,8 +1999,8 @@ INFO is a plist used as a communication channel." (concat (when (plist-get info :html-head-include-default-style) (org-element-normalize-string org-html-style-default)) - (org-element-normalize-string (plist-get info :html-head)) - (org-element-normalize-string (plist-get info :html-head-extra)) + (org-element-normalize-str-or-fn (plist-get info :html-head) info) + (org-element-normalize-str-or-fn (plist-get info :html-head-extra) info) (when (and (plist-get info :html-htmlized-css-url) (eq org-html-htmlize-output-type 'css)) (org-html-close-tag "link" -- 2.34.1