After checking the documentation, DocumentMetadata can be used with any LaTeX compilers.
/PA -- Fragen sind nicht da, um beantwortet zu werden, Fragen sind da um gestellt zu werden Georg Kreisler "Sagen's Paradeiser" (ORF: Als Radiohören gefährlich war) => write BE! Year 2 of the New Koprocracy This was produced by a human (implied virtues and weaknesses acknowledged) I'd hate this being fed to any form of AS (sorry AI)...
From 3dedfaf8481494beca9dc237c2624a2e1d8e76a9 Mon Sep 17 00:00:00 2001 From: "Pedro A. Aranda" <[email protected]> Date: Sun, 28 Jun 2026 11:12:09 +0200 Subject: [PATCH] ox-latex.el: Add DocumentMetadata * doc/org-manual.org: Document LATEX_METADATA keyword. * etc/ORG-NEWS: Announce new LATEX_METADATA keyword. * lisp/ox-latex.el : (org-latex--make-template-from-info) function. Add LATEX_METADATA to info channel. (org-latex-doc-metadata): New variable to hold the default document metadata. (org-latex-make-preamble): Check for valid class before anything else. Insert LATEX_METADATA before LATEX_CLASS_PRE. * testing/lisp/test-ox-latex.el (test-ox-latex/pdf-metadata): Verify that the DocumentMetadata are inserted; and that they inserted before LATEX_CLASS_PRE --- doc/org-manual.org | 9 +++++++ etc/ORG-NEWS | 5 ++++ lisp/ox-latex.el | 44 ++++++++++++++++++++++++++--------- testing/lisp/test-ox-latex.el | 21 +++++++++++++++++ 4 files changed, 68 insertions(+), 11 deletions(-) diff --git a/doc/org-manual.org b/doc/org-manual.org index 9201a341a..d0efc26ab 100644 --- a/doc/org-manual.org +++ b/doc/org-manual.org @@ -14286,6 +14286,15 @@ general options (see [[*Export Settings]]). #+cindex: @samp{LATEX_CLASS_PRE}, keyword Arbitrary lines to prepend before the LaTeX preamble. +- =LATEX_METADATA= :: + + #+cindex: @samp{LATEX_METADATA}, keyword + #+vindex: org-latex-doc-metadata + Arbitrary lines with document metadata. When you set + ~org-latex-doc-metadata~ or you use ~#+LATEX_METADATA~, the + contents will be inserted into a LaTeX =\DocumentMetadata{}= command + that will be the very first LaTeX code in the preamble. + - =KEYWORDS= :: #+cindex: @samp{KEYWORDS}, keyword diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 03057cbd0..f3358406f 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -144,6 +144,11 @@ A current limitation is that export blocks and keywords are only implemented for events and todos, and not yet for calendar-wide properties. +*** New variable ~org-latex-doc-metadata~ and keyword ~#+LATEX_METADATA:~ + +The LaTeX exporter can include PDF metadata with the new variable +~org-latex-doc-metadata~ and the new keyword ~#+LATEX_METADATA:~. + ** New and changed options # Changes dealing with changing default values of customizations, diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el index 8e2f72209..a8690a697 100644 --- a/lisp/ox-latex.el +++ b/lisp/ox-latex.el @@ -125,6 +125,7 @@ (org-export-define-backend 'latex (:latex-header "LATEX_HEADER" nil nil newline) (:latex-header-extra "LATEX_HEADER_EXTRA" nil nil newline) (:latex-class-pre "LATEX_CLASS_PRE" nil nil newline) + (:latex-metadata "LATEX_METADATA" nil org-latex-doc-metadata newline) (:description "DESCRIPTION" nil nil parse) (:keywords "KEYWORDS" nil nil parse) (:subtitle "SUBTITLE" nil nil parse) @@ -652,6 +653,23 @@ (defcustom org-latex-hyperref-template (string :tag "Format string")) :safe #'string-or-null-p) +(defcustom org-latex-doc-metadata nil + "A string with the document metadata. + +These metadata can be used to add additional information in the PDF +to make it usable by onscreen readers and similar applications. + +This string will be inserted into a \"\\DocumentMetadata{}\" command +at the beginning of the generated LaTeX. + +Alternatively you can use LATEX_CLASS_PRE, but you will have to write +the complete LaTeX command as \"\\DocumentMetadata{...}\" yourself." + :version "31.1" + :package-version '(Org . "10") + :type '(choice (const :tag "No metadata" nil) + (string :tag "Metadata for the PDF output")) + :safe #'string-or-null-p) + ;;;; Headline (defcustom org-latex-format-headline-function @@ -2061,21 +2079,25 @@ (defun org-latex-make-preamble (info &optional template snippet?) specified in `org-latex-default-packages-alist' or `org-latex-packages-alist'." (let* ((class (plist-get info :latex-class)) + (doc-metadata (plist-get info :latex-metadata)) (class-template (or template (let* ((class-options (org-latex--mk-options (plist-get info :latex-class-options))) (header (nth 1 (assoc class (plist-get info :latex-classes))))) - (and (stringp header) - (mapconcat #'org-element-normalize-string - (list - (and (not snippet?) - (plist-get info :latex-class-pre)) - (if (not class-options) header - (replace-regexp-in-string - "^[ \t]*\\\\documentclass\\(\\(\\[[^]]*\\]\\)?\\)" - class-options header t nil 1))) - nil))) - (user-error "Unknown LaTeX class `%s'" class)))) + (unless (stringp header) + (user-error "Unknown LaTeX class `%s'" class)) + (mapconcat #'org-element-normalize-string + (list + (and (not snippet?) + doc-metadata + (format "\\DocumentMetadata{%s}\n" doc-metadata)) + (and (not snippet?) + (plist-get info :latex-class-pre)) + (if (not class-options) header + (replace-regexp-in-string + "^[ \t]*\\\\documentclass\\(\\(\\[[^]]*\\]\\)?\\)" + class-options header t nil 1))) + nil))))) (org-latex-guess-polyglossia-language (org-latex-guess-babel-language (org-latex-guess-inputenc diff --git a/testing/lisp/test-ox-latex.el b/testing/lisp/test-ox-latex.el index a804e281b..e2698783d 100644 --- a/testing/lisp/test-ox-latex.el +++ b/testing/lisp/test-ox-latex.el @@ -522,5 +522,26 @@ (ert-deftest test-ox-latex/subtree-export-with-language () (should (search-forward "\\usepackage[utf8]{inputenc} \\usepackage[french, english]{babel}"))) (kill-buffer export-buffer)))) +(ert-deftest test-ox-latex/pdf-metadata () + "Test that DocumentMetadaData are inserted *before* LATEX_CLASS_PRE." + (org-test-with-exported-text + 'latex + "#+TITLE: PDF Metadata +#+LANGUAGE: en-gb es +#+OPTIONS: toc:nil H:3 num:nil +#+LATEX_COMPILER: pdflatex +#+LATEX_METADATA: tagging = on +#+LATEX_CLASS_PRE: \\PassOptionsToPackage{dvipsnames}{xcolor} +#+LATEX_CLASS: report +* Testing + +Just to see that DocumentMetadata comes before PassOptions and documentclass +" + ;; (message "pdf-metadata: %s" (buffer-string)) + (goto-char (point-min)) + (should (search-forward "\\DocumentMetadata{tagging = on}" nil t)) + (should (search-forward "\\PassOptionsToPackage{dvipsnames}{xcolor}" nil t)) + (should (re-search-forward "^\\\\documentclass\\[.+?]{report}" nil t)))) + (provide 'test-ox-latex) ;;; test-ox-latex.el ends here -- 2.43.0
