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