Hi

attached is a patch to add multi-lang declaration for the PDF document
metadata. It's a first step towards multi-lang for polyglossia and babel.

Best, /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

*IA: onomatopeya del rebuznar*

This was produced by a human (implied virtues and weaknesses acknowledged)
Don't feed your ArtStup (SKA AI) with this. It won't make YOU smarter...
From 4674d496ee32569c86d3867d1aa8a13fb1d57d30 Mon Sep 17 00:00:00 2001
From: "Pedro A. Aranda" <[email protected]>
Date: Sat, 12 Sep 2026 18:03:43 +0200
Subject: [PATCH] Add OTHER_LANGUAGES to the metadata

* doc/org-manual.org : Document the OTHER_LANGUAGES keyword.
* lisp/ox-latex.el (backend): New keyword OTHER_LANGUAGES.
(org-latex-doc-metadata-other-languages): New variable for the secondary
languages list.
(org-latex--build-metadata-string): New function to build the metadata
from the INFO channel.  Treat shorthand DOC_LANGS to ease defining
multiple languages for a document.
(org-latex-make-preamble): Use new function instead of extracting from
the INFO channel directly.
* testing/lisp/test-ox-latex.el (org-latex-make-preamble): Silence first
Metadata test.
(test-ox-latex/metadata-langs): New test, checking the OTHER_LANGUAGES
keyword and the DOC_LANGS shorthand.

Rationale: this is the first step towards adding the new generation
multi-language support with the babel and polyglossia
packages. DocumentMetadata provides a good playground to test language
coding, which might need additions.
---
 doc/org-manual.org            | 30 ++++++++++++++++++++++++++++++
 lisp/ox-latex.el              | 34 +++++++++++++++++++++++++++++++++-
 testing/lisp/test-ox-latex.el | 24 +++++++++++++++++++++++-
 3 files changed, 86 insertions(+), 2 deletions(-)

diff --git a/doc/org-manual.org b/doc/org-manual.org
index 2a5ca1fcf..d42228abe 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -14420,6 +14420,36 @@ general options (see [[*Export Settings]]).
                '("AUTO" "polyglossia" t ("xelatex" "lualatex")))
   #+end_src
 
+- =OTHER_LANGUAGES= ::
+
+  #+cindex: @samp{OTHER_LANGUAGES}, keyword
+  #+vindex: org-latex-doc-metadata-other-languages
+  #+vindex: org-latex-doc-metadata
+
+  This is the list of secondary languages you want to declare in the
+  document metadata.  When the document metadata include the shorthand
+  ~DOC_LANGS~, it will be replaced by the main language declared with
+  the ~LANGUAGE~ keyword and this list.
+
+  For example:
+  #+begin_src org
+,#+LANGUAGE: en
+,#+OTHER_LANGUAGES: es, fr
+,#+LATEX_DOC_METADATA: tagging = on, DOC_LANGS
+  #+end_src
+
+  will result in
+  #+BEGIN_SRC latex
+\DocumentMetadata{tagging=on, language=en, other-languages={es, fr}}
+  #+END_SRC
+  as the first line of the LaTeX preamble *before* the document class
+  declaration.
+
+  *NOTE:* In the absence of a declaration for ~OTHER_LANGUAGES~, the
+  language declared with the ~LANGUAGE~ keyword will be the only one
+  added to the metadata, when ~DOC_LANGS~ is found in
+  ~LATEX_DOC_METADATA~.
+
 - =LATEX_CLASS= ::
 
   #+cindex: @samp{LATEX_CLASS}, keyword
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 9e7b52306..d1ada7c6e 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -174,6 +174,7 @@ (org-export-define-backend 'latex
     (:latex-use-sans nil "latex-use-sans" org-latex-use-sans)
     (:latex-fontspec-config nil nil org-latex-fontspec-config)
     ;; Redefine regular options.
+    (:other-languages "OTHER_LANGUAGES" nil org-latex-doc-metadata-other-languages t)
     (:date "DATE" nil "\\today" parse)))
 
 
@@ -665,6 +666,37 @@ (defcustom org-latex-doc-metadata nil
 		 (string :tag "Metadata for the PDF output"))
   :safe #'string-or-null-p)
 
+(defcustom org-latex-doc-metadata-other-languages nil
+  "A string with a comma separated list of language codes.
+
+This list will be inserted as \"other-languages = {<list>}\" in
+the document metadata (along with the export language defined in the
+#+LANGUAGE: keyword as \"language = {<lang>}\"), when the shorthand
+DOC_LANGS is included in `org-latex-doc-metadata'."
+
+  :package-version '(Org . "10")
+  :type '(choice (const :tag "No other languages" nil)
+		 (string :tag "Other languages declared in the metadata."))
+  :safe #'string-or-null-p)
+
+(defun org-latex--build-metadata-string (info)
+  "Extract the document metadata from INFO and handle language info.
+
+When metadata are defined and contain the keyword DOC_LANGS, replace it with
+\"language=<main>[, other-languages={<other>}]\", where <main> is defined in
+#+LANGUAGE and <other> is defined in #+OTHER_LANGUAGES. Omit the other-languages
+if not defined.
+
+Cf. URL `https://latex3.github.io/babel/news/whats-new-in-babel-26.9.html'."
+  (let ((doc-metadata (plist-get info :latex-doc-metadata)))
+    (when (and doc-metadata
+               (string-match-p "DOC_LANGS" doc-metadata))
+      (let* ((replace-other (plist-get info :other-languages))
+             (replace-langs (concat "language=" (plist-get info :language)
+                                    (and replace-other (concat ", other-languages={" replace-other "}")))))
+        (setq doc-metadata (string-replace "DOC_LANGS" replace-langs doc-metadata))))
+    doc-metadata))
+
 ;;;; Headline
 
 (defcustom org-latex-format-headline-function
@@ -2247,7 +2279,7 @@ (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-doc-metadata))
+         (doc-metadata (org-latex--build-metadata-string info))
 	 (class-template
 	  (or template
 	      (let* ((class-options (org-latex--mk-options (plist-get info :latex-class-options)))
diff --git a/testing/lisp/test-ox-latex.el b/testing/lisp/test-ox-latex.el
index 9cd83d509..844a4d7e2 100644
--- a/testing/lisp/test-ox-latex.el
+++ b/testing/lisp/test-ox-latex.el
@@ -537,12 +537,34 @@ (ert-deftest test-ox-latex/pdf-metadata ()
 
 Just to see that DocumentMetadata comes before PassOptions and documentclass
 "
-   (message "pdf-metadata: %s" (buffer-string))
+   ;; (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))))
 
+(ert-deftest test-ox-latex/metadata-langs ()
+  "Test that DocumentMetadata treat the DOC_LANGS keyword correctly."
+  (org-test-with-exported-text
+   'latex
+   "#+TITLE: PDF Metadata with languages
+#+LANGUAGE: en
+#+OTHER_LANGUAGES: es, fr
+#+OPTIONS: toc:nil H:3 num:nil
+#+LATEX_COMPILER: pdflatex
+#+LATEX_DOC_METADATA: tagging = on,
+#+LATEX_DOC_METADATA: DOC_LANGS
+#+LATEX_CLASS: report
+* Testing
+
+Just to see that DocumentMetadata has the right languages
+"
+   ;; (message "pdf-metadata: %s" (buffer-string))
+   (goto-char (point-min))
+   (should (search-forward "\\DocumentMetadata{tagging = on," nil t))
+   (should (search-forward "language=en, other-languages={es, fr}}" nil t))
+   (should (re-search-forward "^\\\\documentclass\\[.+?]{report}" nil t))))
+
 (ert-deftest test-ox-latex/example-env-options ()
   "We can set and override the options in an EXAMPLE block."
   (let ((org-latex-default-example-environment "Verbatim")
-- 
2.43.0

Reply via email to