Jens Lechtenboerger <lech...@wi.uni-muenster.de> writes:
> Hi Timothy, Hi Jens! Thanks for responding. > yes, I agree that org-html--build-meta-info needs work, and the HTML > backend would benefit from more documentation. Back then [1], I > wondered which parts of meta data need to be treated how. That was > continued in thread [2]. I haven't really considered changing the output of the function (other than removing keywords). Reading the email you've linked to, it looks like a change to `org-html-encode-plain-text' would be a good idea though. > As pointed out back then, using org-export-data on the title is > wrong as it creates nested elements, leading to invalid HTML. > > Currently, org-element-interpret-data is applied for author > information, while description and keywords are treated differently. > Your patch goes for org-html-encode-plain-text in the new function > org-html--build-meta-entry, which (if I’m not mistaken) produces > author and description. Did you think about using > org-element-interpret-data instead? What if that was used? > I believe this to be an important question as it might affect > backward compatibility and should be documented. I was not aware of org-element-interpret-data, and I can't say I can really tell what it does. If you'd care to elaborate that would be helpful. > Does this really work for you? For the author, first > org-html--build-meta-entry gets called from the new defcustom. The > result is assigned with setq to form, which then is non-nil so that > org-html--build-meta-entry is applied again, leading to an error > here. Ooops, I forgot to remove org-html--build-meta-entry from the defcustom. (I didn't notice because I overwrite it anyway in my personal config). > Besides, did you forget keywords or remove them on purpose? This is a deliberate omission. My impression is that the value of keywords in HTML documents has evaporated over the past decade, see: https://yoast.com/meta-keywords/ Let me know if you know otherwise. > Best wishes > Jens Thanks for your feedback! Timothy. ----- Updated patch: >From 3a02e4d3bce5f7f0cbdb34c98f4267cea40eec3e Mon Sep 17 00:00:00 2001 From: TEC <t...@tecosaur.com> Subject: [PATCH] lisp/ox-html.el: make html meta func nicer * lisp/ox-html.el (org-html--build-meta-info): Multi-line repeated structure extracted to new function `org-html--build-meta-entry'. The opportunity was taken to extract most metadata info to custom variable `org-html-meta-tags', allowing for easy end-user modification. --- lisp/ox-html.el | 111 ++++++++++++++++++++++++++---------------------- 1 file changed, 61 insertions(+), 50 deletions(-) diff --git a/lisp/ox-html.el b/lisp/ox-html.el index d2f24f5c6..df7da1a68 100644 --- a/lisp/ox-html.el +++ b/lisp/ox-html.el @@ -1425,6 +1425,28 @@ not be modified." ;;;; Template :: Styles +(defcustom org-html-meta-tags + '((lambda (_title author _info) + (when (org-string-nw-p author) + (list "name" "author" author))) + (lambda (_title _author info) + (when (org-string-nw-p (plist-get info :description)) + (list "name" "description" + (plist-get info :description)))) + ("name" "generator" "Org Mode")) + "A list of arguments to be passed to `org-html--build-meta-entry'. +Each argument can either be an list which is applied, or a function which +generates such a list with signature (TITLE AUTHOR INFO) where TITLE and AUTHOR +are strings, and INFO a communication plist." + :group 'org-export-html + :package-version '(Org . "9.5") + :type '(repeat + (choice + (list (string :tag "Meta label") + (string :tag "label value") + (string :tag "Content value")) + function))) + (defcustom org-html-head-include-default-style t "Non-nil means include the default style in exported HTML files. The actual style is defined in `org-html-style-default' and @@ -1835,23 +1857,31 @@ INFO is a plist used as a communication channel." ;;; Template +(defun org-html--build-meta-entry (label identity &optional content-format &rest content-formatters) + "Construct <meta> tag with LABEL=\"IDENTITY\" and content from CONTENT-FORMAT and CONTENT-FORMATTER." + (concat "<meta " + (format "%s=\"%s" label identity) + (when content-format + (concat "\" content=\"" + (replace-regexp-in-string + "\"" """ + (org-html-encode-plain-text + (if content-formatters + (apply #'format content-format content-formatters) + content-format))))) + "\" />\n")) + (defun org-html--build-meta-info (info) "Return meta tags for exported document. INFO is a plist used as a communication channel." - (let* ((protect-string - (lambda (str) - (replace-regexp-in-string - "\"" """ (org-html-encode-plain-text str)))) - (title (org-export-data (plist-get info :title) info)) + (let* ((title (org-html-encode-plain-text (plist-get info :title) info)) ;; Set title to an invisible character instead of leaving it ;; empty, which is invalid. (title (if (org-string-nw-p title) title "‎")) (author (and (plist-get info :with-author) (let ((auth (plist-get info :author))) - ;; Return raw Org syntax. + ;; Return raw Org syntax. (and auth (org-element-interpret-data auth))))) - (description (plist-get info :description)) - (keywords (plist-get info :keywords)) (charset (or (and org-html-coding-system (fboundp 'coding-system-get) (coding-system-get org-html-coding-system @@ -1863,50 +1893,31 @@ INFO is a plist used as a communication channel." (concat "<!-- " (plist-get info :html-metadata-timestamp-format) " -->\n"))) - (format - (if (org-html-html5-p info) - (org-html-close-tag "meta" "charset=\"%s\"" info) - (org-html-close-tag - "meta" "http-equiv=\"Content-Type\" content=\"text/html;charset=%s\"" - info)) - charset) "\n" + + (if (org-html-html5-p info) + (org-html--build-meta-entry "charset" charset) + (org-html--build-meta-entry "http-equiv" "Content-Type" + (concat "text/html;charset=" charset))) + (let ((viewport-options - (cl-remove-if-not (lambda (cell) (org-string-nw-p (cadr cell))) - (plist-get info :html-viewport)))) - (and viewport-options - (concat - (org-html-close-tag - "meta" - (format "name=\"viewport\" content=\"%s\"" - (mapconcat - (lambda (elm) (format "%s=%s" (car elm) (cadr elm))) - viewport-options ", ")) - info) - "\n"))) + (cl-remove-if-not (lambda (cell) (org-string-nw-p (cadr cell))) + (plist-get info :html-viewport)))) + (if viewport-options + (org-html--build-meta-entry "name" "viewport" + (mapconcat + (lambda (elm) (format "%s=%s" (car elm) (cadr elm))) + viewport-options ", ")))) + (format "<title>%s</title>\n" title) - (org-html-close-tag "meta" "name=\"generator\" content=\"Org mode\"" info) - "\n" - (and (org-string-nw-p author) - (concat - (org-html-close-tag "meta" - (format "name=\"author\" content=\"%s\"" - (funcall protect-string author)) - info) - "\n")) - (and (org-string-nw-p description) - (concat - (org-html-close-tag "meta" - (format "name=\"description\" content=\"%s\"\n" - (funcall protect-string description)) - info) - "\n")) - (and (org-string-nw-p keywords) - (concat - (org-html-close-tag "meta" - (format "name=\"keywords\" content=\"%s\"" - (funcall protect-string keywords)) - info) - "\n"))))) + + (apply #'concat + (mapcar + (lambda (form) + (when (functionp form) + (setq form (funcall form title author info))) + (when form + (apply #'org-html--build-meta-entry form))) + org-html-meta-tags))))) (defun org-html--build-head (info) "Return information for the <head>..</head> of the HTML output. -- 2.28.0