On 25/07/2026 09:29, Ihor Radchenko wrote:
Pedro Andres Aranda Gutierrez <[email protected]> writes:

Subject: [PATCH] ox-beamer.el: New Beamer LaTeX prelude sequence

* doc/org-manual.org: (*** Beamer specific export settings): Add note
about theme information in org-latex-classes.
* etc/ORG-NEWS: Announce new place of theme information in LaTeX prelude as
(potentially) breaking change.
* lisp/ox-beamer.el (org-beamer--insert-theme): New function to insert
theme information in header for document class beamer.  Will leave header
unaltered if it contains theme configuration or the class is not beamer.
(org-beamer-template):  Use (org-beamer--insert-theme) to add the theme
information to the LaTeX preamble.
* testing/lisp/test-ox-beamer.el (test-ox-beamer/beamer-theme-keep): New
test to check that the theme information in the class header provided by
(org-latex-classes) takes precedence over the BEAMER_... keywords.
Document class options are inserted correctly in all cases.
---
  doc/org-manual.org             |  5 ++++-
  etc/ORG-NEWS                   | 18 ++++++++++++++++++
  lisp/ox-beamer.el              | 30 ++++++++++++++++++++++--------
  testing/lisp/test-ox-beamer.el | 34 ++++++++++++++++++++++++++++++++++
  4 files changed, 78 insertions(+), 9 deletions(-)

diff --git a/doc/org-manual.org b/doc/org-manual.org
index cd8903a7e..cab2f200d 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -13159,9 +13159,12 @@ Beamer output.  These keywords work similar to the 
general options
  settings (see [[*Export Settings]]).

  #+texinfo: @noindent
-*Note:* Theme-related =BEAMER_...= keywords do not apply to =ltx-talk=
+*Note 1:* Theme-related =BEAMER_...= keywords do not apply to =ltx-talk=
  and will be ignored.

+*Note 2:* Theme-related =BEAMER_...= keywords will be ignored in the
+=beamer= class definition in ~org-latex-classes~ defines the Beamer theme.

Maybe "Theme-related =BEAMER_...= keywords will be ignored *if* the
=beamer= class definition in ~org-latex-classes~ contains =\usetheme{...}="

Changed to the agreed text>
+(defun org-beamer--insert-theme (header theme-info)
+  "Insert THEME-INFO right after `\\usepackage..{beamer}' in HEADER.

*documentclass

Fixed

+Return the resulting HEADER.
+
+If the class is not \"beamer\" or the header contains a theme declaration,
+return HEADER unaltered."
+  (save-match-data
+    ;; this is only match beamer... will not do anything for ltx-talk(!)
+    (when (string-match "\\documentclass\\(\\[.+?]\\)?{beamer}\n" header)
+      (let ((document-class (match-string 0 header)))
+        (unless  (string-match-p "\\usetheme\\(\\[.+?]\\)?{[^]]+}\n" header)
+          (setq header
+                (string-replace document-class
+                                (concat document-class theme-info) ;; 
theme-info ends with '\n'
+                                header))))))
+  header)
+
...
+     ;; Document class, theme and packages.
+     (org-beamer--insert-theme
+      (org-latex-make-preamble info)
+      (org-beamer--theme-header info))

org-latex-make-preamble will create the full preamble, including
#+LATEX_HEADER. So, something like
#+LATEX_HEADER: \usetheme{Madrid}
will also trigger #+BEAMER_... keywords being ignored.
Is it intentional?

See above. Documented as agreed.

Attached is the new version of the patch.

--
Pedro A. Aranda
ox-latex & ox-beamer maintainer

Sagen's Paradeiser! (ORF: Als Radiohören gefährlich war) => write BE!
IA: onomatopeya del rebuzno
2nd year of the New Koprocracy
From 8260b4398264a6c0238b21f081deadf1a2a5a792 Mon Sep 17 00:00:00 2001
From: "Pedro A. Aranda" <[email protected]>
Date: Sat, 25 Jul 2026 17:01:05 +0200
Subject: [PATCH] ox-beamer.el: New Beamer LaTeX prelude sequence

* doc/org-manual.org: (*** Beamer specific export settings): Add note
about theme information in org-latex-classes.
* etc/ORG-NEWS: Announce new place of theme information in LaTeX prelude as
(potentially) breaking change.
* lisp/ox-beamer.el (org-beamer--insert-theme): New function to insert
theme information in header for document class beamer.  Will leave header
unaltered if it contains theme configuration or the class is not beamer.
(org-beamer-template):  Use (org-beamer--insert-theme) to add the theme
information to the LaTeX preamble.
* testing/lisp/test-ox-beamer.el (test-ox-beamer/beamer-theme-keep): New
test to check that the theme information in the class header provided by
(org-latex-classes) takes precedence over the BEAMER_... keywords.
Document class options are inserted correctly in all cases.
---
 doc/org-manual.org             |  7 ++++++-
 etc/ORG-NEWS                   | 19 +++++++++++++++++++
 lisp/ox-beamer.el              | 31 +++++++++++++++++++++++--------
 testing/lisp/test-ox-beamer.el | 34 ++++++++++++++++++++++++++++++++++
 4 files changed, 82 insertions(+), 9 deletions(-)

diff --git a/doc/org-manual.org b/doc/org-manual.org
index cd8903a7e..a76671b62 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -13159,9 +13159,14 @@ Beamer output.  These keywords work similar to the general options
 settings (see [[*Export Settings]]).
 
 #+texinfo: @noindent
-*Note:* Theme-related =BEAMER_...= keywords do not apply to =ltx-talk=
+*Note 1:* Theme-related =BEAMER_...= keywords do not apply to =ltx-talk=
 and will be ignored.
 
+#+texinfo: @noindent
+*Note 2:* Theme-related =BEAMER_...= keywords will be ignored if
+you set the Beamer theme in the definition of the =beamer= class
+in ~org-latex-classes~ or using ~#+LATEX_HEADER~.
+
 - =BEAMER_THEME= ::
 
   #+cindex: @samp{BEAMER_THEME}, keyword
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index bb965c02a..f7beba098 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -154,6 +154,25 @@ Presentations written with Beamer and ltx-talk are mostly portable,
 except that Beamer theme information is ignored when using ltx-talk
 and some environments listed in the manual are not supported.
 
+*** ox-beamer.el: New place in the LaTeX prelude for the theme information
+
+The Beamer exporter now places the theme configuration immediately
+after the document class declaration when using the =beamer= class,
+unless ~org-latex-classes~ defines a document header for =beamer= that
+includes theme configuration. For example:
+
+#+BEGIN_SRC emacs-lisp
+(setq org-latex-classes
+      '(("beamer"
+         "\\documentclass[11pt]{beamer}
+\\usetheme{Madrid}"
+         ("\\section{%s}" . "\\section*{%s}")))
+#+END_SRC
+
+will make the Beamer exporter to ignore the ~#+BEAMER_...~ keywords
+in the document that are related to theme configuration.
+
+
 ** New and changed options
 
 # Changes dealing with changing default values of customizations,
diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index f72d15e41..e5ca636f1 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -877,9 +877,8 @@ (defun org-beamer-radio-target (radio-target text info)
 	  (org-export-get-reference radio-target info)
 	  text))
 
-;;;; Template
+ ;;;; Template
 ;;
-
 (defun org-beamer--theme-header (info)
   "Return the theme related configuration from INFO as a string."
   ;; Prepends :beamer-theme-pre if it exists
@@ -905,6 +904,24 @@ (defun org-beamer--theme-header (info)
 		           (:beamer-outer-theme "\\useoutertheme"))
 		         "")))))
 
+;;
+(defun org-beamer--insert-theme (header theme-info)
+  "Insert THEME-INFO right after `\\documentclass..{beamer}' in HEADER.
+Return the resulting HEADER.
+
+If the class is not \"beamer\" or the header contains a theme declaration,
+return HEADER unaltered."
+  (save-match-data
+    ;; this is only match beamer... will not do anything for ltx-talk(!)
+    (when (string-match "\\documentclass\\(\\[.+?]\\)?{beamer}\n" header)
+      (let ((document-class (match-string 0 header)))
+        (unless  (string-match-p "\\usetheme\\(\\[.+?]\\)?{[^]]+}\n" header)
+          (setq header
+                (string-replace document-class
+                                (concat document-class theme-info) ;; theme-info ends with '\n'
+                                header))))))
+  header)
+
 ;; Template used is similar to the one used in `latex' backend,
 ;; excepted for the table of contents and Beamer themes.
 
@@ -924,16 +941,14 @@ (defun org-beamer-template (contents info)
 	  (format-time-string "%% Created %Y-%m-%d %a %H:%M\n"))
      ;; LaTeX compiler
      (org-latex--insert-compiler info)
-     ;; Document class and packages.
-     (org-latex-make-preamble info)
+     ;; Document class, theme and packages.
+     (org-beamer--insert-theme
+      (org-latex-make-preamble info)
+      (org-beamer--theme-header info))
      ;; Define the alternative frame environment, if needed.
      (when (plist-get info :beamer-define-frame)
        (format "\\newenvironment<>{%s}[1][]{\\begin{frame}#2[environment=%1$s,#1]}{\\end{frame}}\n"
                org-beamer-frame-environment))
-     ;; Insert theme info when class is "beamer".
-     ;; ltx-talk themes seem to be regular classes.
-     (and (not (equal beamer-class "ltx-talk"))
-          (org-beamer--theme-header info))
      ;; Possibly limit depth for headline numbering.
      (let ((sec-num (plist-get info :section-numbers)))
        (when (integerp sec-num)
diff --git a/testing/lisp/test-ox-beamer.el b/testing/lisp/test-ox-beamer.el
index ccc536e5e..93b8713d9 100644
--- a/testing/lisp/test-ox-beamer.el
+++ b/testing/lisp/test-ox-beamer.el
@@ -309,5 +309,39 @@ (ert-deftest test-ox-beamer/beamer-theme-pre ()
      (should (search-forward "\\usetheme{Boadilla}" nil t))
      (should (search-forward "\\useinnertheme{circles}" nil t)))))
 
+(ert-deftest test-ox-beamer/beamer-theme-keep ()
+  "The theme information in `org-latex-classes' takes precedence.
+
+When we have theme information in the beamer entry in `org-latex-classes',
+the BEAMER..._THEME keywords should be ignored."
+
+  (let ((org-latex-classes
+         '(("beamer"
+            "\\documentclass{beamer}
+\\usetheme{Madrid}
+\\useinnertheme{rectangles}"
+            ("\\section{%s}" . "\\section*{%s}")))))
+    (org-test-with-exported-text
+     'beamer
+     "#+STARTUP: beamer
+#+OPTIONS: toc:nil H:2 title:t
+#+LATEX_CLASS_OPTIONS: presentation,11pt,t
+#+BEAMER_THEME: Boadilla
+#+BEAMER_INNER_THEME: circles
+
+* A section
+** A frame
+- First
+- Second
+- Third
+"
+   ;; (message "--> \n%s" (buffer-string))
+   (goto-char (point-min))
+   (save-excursion
+     (should (search-forward "\\documentclass[presentation,11pt,t]{beamer}" nil t))
+     (should-not (search-forward "\\usetheme{Boadilla}" nil t)))
+   (should (search-forward "\\usetheme{Madrid}" nil t))
+   (should (search-forward "\\useinnertheme{rectangles}" nil t)))))
+
 (provide 'test-ox-beamer)
 ;;; test-ox-beamer.el ends here
-- 
2.43.0

Reply via email to