The second step towards multi-language,multi-package font handling.
In this patch, we enhance the LANGUAGE keyword for the LaTeX exporter
and allow it to have multiple values. This is previous to checking the
document's configuration WRT LaTeX compiler, locale handling and font
configuration.
Best, /PA
On 08/07/2026 11:07, Pedro Andrés Aranda Gutierrez wrote:
Hi all,
As discussed already, I would like to introduce fontspec configuration
and fallback fonts incrementally.
My main justification is that the mother of all solutions covering all
kinds of corner cases can only be achieved if we start introducing
things little by little and test them against *real life* use cases, ie.
documents we all use on a daily basis.
So... what is this first patch about ?
If you use lualatex, Org mode will include fontspec in the LaTeX
preamble, unless you tell it not to.
So, my take is that if it is there, we can use this hint to activate
font definitions à la fontspec and fallback fonts if needed.
All definitions are placed *before* the LaTeX header, so anything you
have there re. fonts will hopefully prevail.
** Next steps:
1. Examine the combinations of fontspec, babel and polyglossia and
determine which are viable and which not to warn the user.
2. If the configuration is viable and we are using polyglossia or babel,
put the fonts and localisation info as soon as possible in the latex
preamble and clean up redundancies.
This second part will come after the summer break.
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
This was produced by a human (implied virtues and weaknesses acknowledged)
I'd hate this being fed to any form of AS (sorry AI)...
--
ox-latex and ox-beamer maintainer
Sagen's Paradeiser! (ORF: Als Radiohören gefährlich war) => write BE!
2nd year of the New Koprocracy
From d4d7d24447feaf9e71f19ed0ecfa110eab16f01a Mon Sep 17 00:00:00 2001
From: "Pedro A. Aranda" <[email protected]>
Date: Thu, 9 Jul 2026 07:45:18 +0200
Subject: [PATCH] ox-latex: LANGUAGE accepting multiple languages
* doc/org-manual.org (*** LaTeX specific export settings): Document that
LANGUAGE accepts a list of language codes, the first being the main
locale the document is intended for. Split the Emacs Lisp snippet; not
doing so main result in a user selecting *both* babel and polyglossia.
Remark that AUTO will be replaced by the main locale.
* etc/ORG-NEWS: Announce the change in the LANGUAGE keyword
* lisp/ox-latex.el (Export backend): LANGUAGE is included in the INFO
channel under property :languages
* lisp/ox.el (org-export--annotate-info): Generate property :language
for backends that generate :languages for the INFO channel.
* testing/lisp/test-ox-latex.el
(test-ox-latex/lualatex-fontspec-latex-header-not-lost): Add ("AUTO"
"babel") to org-latex-packages-alist. Check that en-gb is taken for the
options passed to babel.
---
doc/org-manual.org | 20 ++++++++++++++------
etc/ORG-NEWS | 12 ++++++++++++
lisp/ox-latex.el | 1 +
lisp/ox.el | 11 +++++++++++
testing/lisp/test-ox-latex.el | 11 ++++++++---
5 files changed, 46 insertions(+), 9 deletions(-)
diff --git a/doc/org-manual.org b/doc/org-manual.org
index e04417dfe..59afa3835 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -14318,8 +14318,10 @@ general options (see [[*Export Settings]]).
#+vindex: org-latex-language-alist
#+vindex: org-export-default-language
- Language code of the primary document language. When =LANGUAGE=
- keyword is not specified use the value of
+ Code or list of codes of Org languages that are used as locales in
+ the whole document or parts of it. When =LANGUAGE= is a list of
+ codes, the first language designates the main locale of the
+ document. When =LANGUAGE= keyword is not specified use the value of
~org-export-default-language~ (by default - =en=, American English)
The list of language codes supported by Org is stored in the
@@ -14328,17 +14330,23 @@ general options (see [[*Export Settings]]).
In order to be effective, the =babel= or =polyglossia=
packages---according to the LaTeX compiler used---must be loaded
with the appropriate language as argument. This can be accomplished
- by modifying the ~org-latex-packages-alist~ variable, e.g., with the
- following snippet (note that =polyglossia= does not work with
- pdfLaTeX):
+ by modifying the ~org-latex-packages-alist~ variable, e.g., with
+ either of the following snippets (note that =polyglossia= does not
+ work with pdfLaTeX):
#+begin_src emacs-lisp
(add-to-list 'org-latex-packages-alist
- '("AUTO" "babel" t ("pdflatex" "xelatex" "lualatex")))
+ '("AUTO" "babel" t))
+ #+end_src
+ or
+ #+begin_src emacs-lisp
(add-to-list 'org-latex-packages-alist
'("AUTO" "polyglossia" t ("xelatex" "lualatex")))
#+end_src
+ =AUTO= will be replaced with the main language code as expected by
+ the selected package.
+
- =LATEX_CLASS= ::
#+cindex: @samp{LATEX_CLASS}, keyword
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index f81450f89..a909e294a 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -159,6 +159,18 @@ and some environments listed in the manual are not supported.
# Changes dealing with changing default values of customizations,
# adding new customizations, or changing the interpretation of the
# existing customizations.
+*** ox-latex.el: Keyword LANGUAGE accepts a list of Org languages
+
+The LANGUAGE keyword accepts a list of Org languages when exporting to
+LaTeX (or Beamer). The *first* language is designated as the main
+language of the document:
+
+#+BEGIN_SRC org
+,#+LANGUAGE: es en-gb
+#+END_SRC
+
+marks Spanish to be the main locale of a document that also uses the
+British English locale in some passages.
*** ox-beamer.el: New keyword BEAMER_THEME_PRE
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 403428c33..53f18b946 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -130,6 +130,7 @@ (org-export-define-backend 'latex
(:description "DESCRIPTION" nil nil parse)
(:keywords "KEYWORDS" nil nil parse)
(:subtitle "SUBTITLE" nil nil parse)
+ (:languages "LANGUAGE" org-export-default-language nil split)
;; Other variables.
(:latex-active-timestamp-format nil nil org-latex-active-timestamp-format)
(:latex-caption-above nil nil org-latex-caption-above)
diff --git a/lisp/ox.el b/lisp/ox.el
index 90c853d76..0394cd13c 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -3102,6 +3102,7 @@ (defun org-export--annotate-info (backend info &optional subtreep visible-only e
;; Run first hook with current backend's name as argument.
(run-hook-with-args 'org-export-before-processing-functions
(org-export-backend-name backend))
+ ;; Before the first hook:
(org-export-expand-include-keyword nil nil nil nil (plist-get info :expand-links))
(org-export--delete-comment-trees)
(when org-export-replace-macros
@@ -3138,6 +3139,16 @@ (defun org-export--annotate-info (backend info &optional subtreep visible-only e
(setq info
(org-combine-plists
info (org-export-get-environment backend subtreep ext-plist)))
+ ;; Language(s): Derived from `org-export-default-language' and the
+ ;; #+LANGUAGE: keyword. Re. the INFO channel:
+ ;; 1. All exporters want a string with a language in INFO :language
+ ;; 2. The LaTeX exporters additionally expect a list of languages in INFO :languages
+ (when-let* ((doc-languages (plist-get info :languages))) ; just in case
+ (if (listp doc-languages)
+ (setq info (plist-put info :language (car doc-languages)))
+ (progn
+ (setq info (plist-put info :languages (list doc-languages)))
+ (setq info (plist-put info :language doc-languages)))))
;; Pre-process citations environment, i.e. install
;; bibliography list, and citation processor in INFO.
(when (plist-get info :with-cite-processors)
diff --git a/testing/lisp/test-ox-latex.el b/testing/lisp/test-ox-latex.el
index 3f5cabb02..5172226d2 100644
--- a/testing/lisp/test-ox-latex.el
+++ b/testing/lisp/test-ox-latex.el
@@ -596,10 +596,12 @@ (ert-deftest test-ox-latex/lualatex-fontspec-latex-header-not-lost ()
"Test that org-latex-fontspec-config is recognised for lualatex.
It will be placed *before* LATEX_HEADER, so that any font configuration
-there will prevail."
+there will prevail. Additionally test multiple languages in LANGUAGE.
+This anticipates the changes for multi-lang."
(let ((org-latex-fontspec-config
'(("main" :font "FreeSerif")
- ("sans" :font "FreeSans"))))
+ ("sans" :font "FreeSans")))
+ (org-latex-packages-alist '(("AUTO" "babel"))))
(org-test-with-exported-text
'latex
"#+TITLE: LuaLaTeX fonts
@@ -612,11 +614,14 @@ (ert-deftest test-ox-latex/lualatex-fontspec-latex-header-not-lost ()
Just to see that I get the fonts Iwant...
"
- ;; (message "fontspec: latex-header\n%s" (buffer-string))
+ (message "fontspec: latex-header\n%s" (buffer-string))
(goto-char (point-min))
(should (search-forward "\\usepackage{fontspec}" nil t))
(should (search-forward "\\setmainfont{FreeSerif}" nil t))
(should (search-forward "\\setsansfont{FreeSans}" nil t))
+ ;; This comes from `org-latex-packages-alist'
+ (should (search-forward "\\usepackage[british]{babel}" nil t))
+ ;; And this from LATEX_HEADER
(should (search-forward "\\setsansfont{TeX Gyre Heros}" nil t)))))
(provide 'test-ox-latex)
--
2.43.0