Attached is what I thought of doing...

It passes all  latex and beamer tests and, more importantly,
it does break my LaTeX exports and Beamer(tm).

Comments and further tests highly appreciated.

Best, /PA

On Sun, 5 Apr 2026 at 19:29, Pedro Andres Aranda Gutierrez <
[email protected]> wrote:

> Yup… looking at doing that without breaking the rest…
>
> PA
> Enviado desde mi iPhone
>
> > El 5 abr 2026, a las 18:15, Ihor Radchenko <[email protected]>
> escribió:
> >
> > Pedro Andres Aranda Gutierrez <[email protected]> writes:
> >
> >> I would have a use case for that keyword, though.
> >>
> >> Say we reshuffle, which is not too difficult and end up with
> >>
> >> <<anything in LATEX_CLASS_PRE>>
> >> \documentclass[...]{beamer}
> >> \usetheme{whatever}
> >>
> >> OK? Now...
> >>
> >> I have a couple of presentations where I needed to fix the geometry
> >> *before* declaring the theme.
> >> Or take the full process described in
> >>
> https://tex.stackexchange.com/questions/54577/how-do-i-customize-beamer-template
> >> They (and I) do insert stuff between documentclass and usetheme.
> >> Therefore I don't think BEAMER_THEME_PRE is an overkill.
> >
> > Got it.
> >
> > Still, do you suggest moving the theme definition on top?
> >
> > --
> > Ihor Radchenko // yantar92,
> > Org mode maintainer,
> > Learn more about Org mode at <https://orgmode.org/>.
> > Support Org development at <https://liberapay.com/org-mode>,
> > or support my work at <https://liberapay.com/yantar92>
>


-- 
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
From 76bd135bf2d8f4e1f560d568788269e74dccca2c Mon Sep 17 00:00:00 2001
From: "Pedro A. Aranda" <[email protected]>
Date: Mon, 6 Apr 2026 12:11:40 +0200
Subject: [PATCH 3/3] Remove the beamer-theme header creation from
 (org-beamer-template)

lisp/ox-beamer.el: (org-beamer-template): Don't
call (org-beamer-theme-header) here.
lisp/ox-latex.el: import (org-bameer-theme-header) and use it
in (org-latex-make-preamble) as part of the header creation code.
testing/lisp/test-ox-beamer.el: print resulting latex
in (ox-beamer/org-beamer-theme-pre) to check the resulting code
visually.
---
 lisp/ox-beamer.el              | 2 --
 lisp/ox-latex.el               | 7 ++++++-
 testing/lisp/test-ox-beamer.el | 2 +-
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index 3aa95d477..152af2cdf 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -904,8 +904,6 @@ holding export options."
      (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 header.
-     (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/lisp/ox-latex.el b/lisp/ox-latex.el
index f39240cd8..e284b3c54 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -45,6 +45,8 @@
 (declare-function engrave-faces-latex-gen-preamble-line "ext:engrave-faces-latex")
 (declare-function engrave-faces-get-theme "ext:engrave-faces")
 
+(declare-function org-beamer-theme-header "ox-beamer" (info))
+
 (defvar engrave-faces-latex-output-style)
 (defvar engrave-faces-current-preset-style)
 (defvar engrave-faces-latex-mathescape)
@@ -2054,7 +2056,10 @@ specified in `org-latex-default-packages-alist' or
 		                 (if (not class-options) header
 		                   (replace-regexp-in-string
 			            "^[ \t]*\\\\documentclass\\(\\(\\[[^]]*\\]\\)?\\)"
-			            class-options header t nil 1)))
+			            class-options header t nil 1))
+                                 (and (not snippet?)
+                                      (string= "beamer" class)
+                                      (org-beamer-theme-header info)))
                                 nil)))
 	      (user-error "Unknown LaTeX class `%s'" class))))
     (org-latex-guess-polyglossia-language
diff --git a/testing/lisp/test-ox-beamer.el b/testing/lisp/test-ox-beamer.el
index b4fadcf58..384e75fbf 100644
--- a/testing/lisp/test-ox-beamer.el
+++ b/testing/lisp/test-ox-beamer.el
@@ -118,7 +118,7 @@ Here is a second example:
 #+BEAMER_THEME: Boadilla
 * A frame
 Here is an example:"
-   ;; (message "--> %s" (buffer-string))
+   (message "--> %s" (buffer-string))
    (goto-char (point-min))
    (should (search-forward "\\usepackage{geometry}\n\\usetheme{Boadilla}\n"))))
 
-- 
2.43.0

From 0c4e1acda2b7c564cc1e7244a9ad79462b43448a Mon Sep 17 00:00:00 2001
From: "Pedro A. Aranda" <[email protected]>
Date: Mon, 6 Apr 2026 09:26:16 +0200
Subject: [PATCH 2/3] ox-beamer: fix typo and add test for BEAMER_THEME_PRE

lisp/ox-beamer.el: Stupid typo
testing/lisp/test-ox-beamer.el: (ox-beamer/org.beamer-theme-pre) test
the new keyword is correctly added.
---
 lisp/ox-beamer.el              |  2 +-
 testing/lisp/test-ox-beamer.el | 13 +++++++++++++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index 10fb1b403..3aa95d477 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -905,7 +905,7 @@ holding export options."
        (format "\\newenvironment<>{%s}[1][]{\\begin{frame}#2[environment=%1$s,#1]}{\\end{frame}}\n"
                org-beamer-frame-environment))
      ;; Insert theme header.
-     (prg-beamer-theme-header info)
+     (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 24550ec62..b4fadcf58 100644
--- a/testing/lisp/test-ox-beamer.el
+++ b/testing/lisp/test-ox-beamer.el
@@ -109,5 +109,18 @@ Here is a second example:
      (should (search-forward (concat "\\end{frame}") nil t))
      (should (search-forward (concat "\\end{" org-beamer-frame-environment "}"))))))
 
+(ert-deftest ox-beamer/org-beamer-theme-pre ()
+  "Test that BEAMER_THEME_PRE is prepended to use theme."
+  (org-test-with-exported-text
+   'beamer
+   "#+OPTIONS: toc:nil
+#+BEAMER_THEME_PRE: \\usepackage{geometry}
+#+BEAMER_THEME: Boadilla
+* A frame
+Here is an example:"
+   ;; (message "--> %s" (buffer-string))
+   (goto-char (point-min))
+   (should (search-forward "\\usepackage{geometry}\n\\usetheme{Boadilla}\n"))))
+
 (provide 'test-ox-beamer)
 ;;; test-ox-beamer.el ends here
-- 
2.43.0

From a0565ee3cf2c96d85322025206886312cb7bf5ea Mon Sep 17 00:00:00 2001
From: "Pedro A. Aranda" <[email protected]>
Date: Mon, 6 Apr 2026 08:58:15 +0200
Subject: [PATCH 1/3] ox-beamer: Factor out theme configuration and add
 BEAMER_THEME_PRE

lisp/ox-beamer.el: (org-beamer-theme-header) Factored out code to
generate the beamer theme header.  Add BEAMER_THEME_PRE handling here.
(org-beamer-make-preamble): Use the factored out function
etc/ORG-NEWS: Announce BEAMER_THEME_PRE keyword
doc/org-manual.org: Document BEAMER_THEME_PRE keyword
---
 doc/org-manual.org | 11 +++++++++++
 etc/ORG-NEWS       |  5 +++++
 lisp/ox-beamer.el  | 48 ++++++++++++++++++++++++++++------------------
 3 files changed, 45 insertions(+), 19 deletions(-)

diff --git a/doc/org-manual.org b/doc/org-manual.org
index b7c45ff7e..9b131a9b7 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -13147,6 +13147,17 @@ settings (see [[*Export Settings]]).
 
   : #+BEAMER_THEME: Rochester [height=20pt]
 
+- =BEAMER_THEME_PRE= ::
+
+  #+cindex: @samp{BEAMER_THEME_PRE}, keyword
+  LaTeX code needed before the Beamer theme is declared.  For example:
+
+  : #+BEAMER_THEME_PRE: \usepage{geometry}
+  : #+BEAMER_THEME_PRE: \geometry{paperwidth=160mm, paperheight=90mm}
+  : #+BEAMER_THEME: Boadilla
+
+  would fix the page size to 160mm x 90mm before loading the theme.
+
 - =BEAMER_FONT_THEME= ::
 
   #+cindex: @samp{BEAMER_FONT_THEME}, keyword
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 2712d7589..64e484985 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -135,6 +135,11 @@ header argument will be updated. This allows for the cache feature to
 still work when a block is evaluated indirectly to resolve a reference
 in another block.
 
+*** New option BEAMER_THEME_PRE
+
+New option BEAMER_THEME_PRE allows inserting LaTeX code before the
+Beamer theme is defined.
+
 ** New functions and changes in function arguments
 
 # This also includes changes in function behavior from Elisp perspective.
diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index 72fe18acd..10fb1b403 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -261,6 +261,7 @@ Return overlay specification, as a string, or nil."
     (:latex-class "LATEX_CLASS" nil "beamer" t)
     (:beamer-subtitle-format nil nil org-beamer-subtitle-format)
     (:beamer-column-view-format "COLUMNS" nil org-beamer-column-view-format)
+    (:beamer-theme-pre "BEAMER_THEME_PRE" nil nil newline)
     (:beamer-theme "BEAMER_THEME" nil org-beamer-theme)
     (:beamer-color-theme "BEAMER_COLOR_THEME" nil nil t)
     (:beamer-font-theme "BEAMER_FONT_THEME" nil nil t)
@@ -856,6 +857,32 @@ contextual information."
 
 ;;;; Template
 ;;
+;; Create the beamer theme related section
+(defun org-beamer-theme-header (info)
+  (let ((pre-header (plist-get info :beamer-theme-pre))
+        (format-theme
+	 (lambda (prop command)
+	   (let ((theme (plist-get info prop)))
+	     (when theme
+	       (concat command
+		       (if (not (string-match "\\[.*\\]" theme))
+			   (format "{%s}\n" theme)
+			 (format "%s{%s}\n"
+				 (match-string 0 theme)
+				 (org-trim
+				  (replace-match "" nil nil theme))))))))))
+    (when pre-header
+      (setq pre-header (concat pre-header "\n")))
+    (concat
+     pre-header
+     (mapconcat (lambda (args) (apply format-theme args))
+	        '((:beamer-theme "\\usetheme")
+		  (:beamer-color-theme "\\usecolortheme")
+		  (:beamer-font-theme "\\usefonttheme")
+		  (:beamer-inner-theme "\\useinnertheme")
+		  (:beamer-outer-theme "\\useoutertheme"))
+	        ""))))
+
 ;; Template used is similar to the one used in `latex' backend,
 ;; excepted for the table of contents and Beamer themes.
 
@@ -877,25 +904,8 @@ holding export options."
      (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 themes.
-     (let ((format-theme
-	    (lambda (prop command)
-	      (let ((theme (plist-get info prop)))
-		(when theme
-		  (concat command
-			  (if (not (string-match "\\[.*\\]" theme))
-			      (format "{%s}\n" theme)
-			    (format "%s{%s}\n"
-				    (match-string 0 theme)
-				    (org-trim
-				     (replace-match "" nil nil theme))))))))))
-       (mapconcat (lambda (args) (apply format-theme args))
-		  '((:beamer-theme "\\usetheme")
-		    (:beamer-color-theme "\\usecolortheme")
-		    (:beamer-font-theme "\\usefonttheme")
-		    (:beamer-inner-theme "\\useinnertheme")
-		    (:beamer-outer-theme "\\useoutertheme"))
-		  ""))
+     ;; Insert theme header.
+     (prg-beamer-theme-header info)
      ;; Possibly limit depth for headline numbering.
      (let ((sec-num (plist-get info :section-numbers)))
        (when (integerp sec-num)
-- 
2.43.0

Reply via email to