From 055b3b76f8cd9903d6dc26d6778e2cfad1d72364 Mon Sep 17 00:00:00 2001
From: Derek Chen-Becker <oss@chen-becker.org>
Date: Thu, 21 May 2026 07:22:59 -0600
Subject: [PATCH] Fix LaTeX babel language detection regex

* lisp/ox-latex.el (org-latex-guess-babel-language): Replace a greedy regex
used to extract a language from a "\usepackage[...]{babel}" block with one
that strictly limits the capture to the language inside of the square
brackets.

* testing/lisp/test-ox-latex.el: (test-ox-latex/subtree-export-with-language):
Add a regression test to exercise capture of babel language from latex
headers.

The regex being used to capture the language out of the babel header would
capture more than just the language if multiple headers were set for a
given export because the greedy match would start on one header and extend
until it reached the babel header.
---
 lisp/ox-latex.el              |  2 +-
 testing/lisp/test-ox-latex.el | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index cddec1774..8e2f72209 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1739,7 +1739,7 @@ Return the new header."
 	 ;; exclusively through ini files, return HEADER as-is.
 	 (header (if (or language-ini-only
 			 (not (stringp language-code))
-			 (not (string-match "\\\\usepackage\\[\\(.*\\)\\]{babel}" header)))
+			 (not (string-match "\\\\usepackage\\[\\([^]]*\\)\\]{babel}" header)))
 		     header
 		   (let ((options (save-match-data
 				    (org-split-string (match-string 1 header) ",[ \t]*"))))
diff --git a/testing/lisp/test-ox-latex.el b/testing/lisp/test-ox-latex.el
index 584164f91..442c73716 100644
--- a/testing/lisp/test-ox-latex.el
+++ b/testing/lisp/test-ox-latex.el
@@ -503,5 +503,24 @@ How do you do?
 \\end{itemize}
 ")))))
 
+(ert-deftest test-ox-latex/subtree-export-with-language ()
+  "Test export of subtrees with language detection."
+  ;; We can't use `org-test-with-exported-text' because we need a subtree export
+  (let ((export-buffer (generate-new-buffer "Org temporary export")))
+    (org-test-with-temp-text
+     "* subtree
+:PROPERTIES:
+:EXPORT_LATEX_HEADER: \\usepackage[utf8]{inputenc}
+:EXPORT_LATEX_HEADER+: \\usepackage[french]{babel}
+:END:
+
+<point>"
+     (org-export-to-buffer 'latex export-buffer nil t)
+     (with-current-buffer export-buffer
+       (goto-char (point-min))
+       ;; This is somewhat redundant since the reported issue triggers an error on export
+       (should (search-forward "\\usepackage[utf8]{inputenc} \\usepackage[french]{babel}")))
+     (kill-buffer export-buffer))))
+
 (provide 'test-ox-latex)
 ;;; test-ox-latex.el ends here
-- 
2.39.5

