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
