Hi
I have split out this part from the general LaTeX/Beamer structure
discussion. The patch makes the code more readable (factored out function
that is called only when the class isn't lta-talk) and it provides use with
a fine-grain control (LaTeX code that must go immediately before
\usetheme{}).
With this in place, we can start talking about the high level sequence in
any LaTeX document (including presentations).
/PA
ox-latex & ox-beamer maintainer
--
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)...
From 61ca9eec6d3a496f7860e77f292c16d90e77a619 Mon Sep 17 00:00:00 2001
From: "Pedro A. Aranda" <[email protected]>
Date: Mon, 6 Jul 2026 08:19:19 +0200
Subject: [PATCH] ox-beamer: New keywork BEAMER_THEME_PRE
* doc/org-manual.org (Beamer specific export settings): Refine note on
THEME keywords. Add BEAMER_THEME_PRE. Fix language nit.
* etc/ORG-NEWS: Announce BEAMER_THEME_PRE.
* lisp/ox-beamer.el (exporter): Add BEAMER_THEME_PRE keyword.
(org-beamer--theme-header): Factor out BEAMER_THEME keyword handling and
prepend BEAMER_THEME_PRE to resulting string.
(org-beamer-template): Add result from (org-beamer--theme-header) for
LaTeX class "beamer" only.
* testing/lisp/test-ox-beamer.el (test-ox-beamer/beamer-theme-pre): New
test for BEAMER_THEME_PRE.
---
doc/org-manual.org | 17 +++++++++--
etc/ORG-NEWS | 6 ++++
lisp/ox-beamer.el | 52 +++++++++++++++++++++-------------
testing/lisp/test-ox-beamer.el | 29 +++++++++++++++++++
4 files changed, 81 insertions(+), 23 deletions(-)
diff --git a/doc/org-manual.org b/doc/org-manual.org
index bda84c49c..cd8903a7e 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -13156,8 +13156,11 @@ documentation]].
Beamer export backend has several additional keywords for customizing
Beamer output. These keywords work similar to the general options
-settings (see [[*Export Settings]]). *Note:* =BEAMER_..._THEME=
-keywords do not apply to =ltx-talk= and will be ignored.
+settings (see [[*Export Settings]]).
+
+#+texinfo: @noindent
+*Note:* Theme-related =BEAMER_...= keywords do not apply to =ltx-talk=
+and will be ignored.
- =BEAMER_THEME= ::
@@ -13183,6 +13186,14 @@ keywords do not apply to =ltx-talk= and will be ignored.
#+cindex: @samp{BEAMER_OUTER_THEME}, keyword
The Beamer outer theme.
+- =BEAMER_THEME_PRE= ::
+
+ #+cindex: @samp{BEAMER_THEME_PRE}, keyword
+ Arbitrary lines that must appear immediately before the Beamer theme
+ declaration:
+
+ : #+BEAMER_THEME_PRE: \usepackage[total={16cm,9cm}]{geometry}
+
- =BEAMER_HEADER= ::
#+cindex: @samp{BEAMER_HEADER}, keyword
@@ -13220,7 +13231,7 @@ keywords do not apply to =ltx-talk= and will be ignored.
#+cindex: @samp{LATEX_CLASS}, keyword
The LaTeX class to use. Implicitly set to =beamer=. Set it
- explicitly to =ltx-talk= to use this class:
+ explicitly to =ltx-talk= to use this class instead:
#+BEGIN_SRC org
,#+LATEX_CLASS: ltx-talk
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 5f5168e33..ad292de08 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -154,6 +154,12 @@ 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 keyword BEAMER_THEME_PRE
+
+The new keyword allows to add arbitrary lines just before the Beamer theme
+declaration. It allows you to fine-tune your Beamer theme settings
+further.
+
** 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 f5cf1a896..b4157bfe5 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -275,6 +275,7 @@ (org-export-define-derived-backend 'beamer 'latex
(:beamer-font-theme "BEAMER_FONT_THEME" nil nil t)
(:beamer-inner-theme "BEAMER_INNER_THEME" nil nil t)
(:beamer-outer-theme "BEAMER_OUTER_THEME" nil nil t)
+ (:beamer-theme-pre "BEAMER_THEME_PRE" nil nil newline)
(:beamer-header "BEAMER_HEADER" nil nil newline)
(:beamer-environments-extra nil nil org-beamer-environments-extra)
(:beamer-frame-default-options nil nil org-beamer-frame-default-options)
@@ -880,6 +881,33 @@ (defun org-beamer-radio-target (radio-target text info)
;;;; Template
;;
+;; Factored out
+(defun org-beamer--theme-header (info)
+ "Return the theme related configuration from INFO as a string."
+ ;; This function was factored out from org-beamer-template
+ ;; Prepends :beamer-theme-pre if it exists
+ (let ((theme-pre (plist-get info :beamer-theme-pre)))
+ (concat theme-pre
+ (and theme-pre "\n")
+ (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"))
+ "")))))
+;;
;; Template used is similar to the one used in `latex' backend,
;; excepted for the table of contents and Beamer themes.
@@ -905,26 +933,10 @@ (defun org-beamer-template (contents info)
(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.
- (unless (equal beamer-class "ltx-talk")
- (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 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 03e6d59d5..660af0854 100644
--- a/testing/lisp/test-ox-beamer.el
+++ b/testing/lisp/test-ox-beamer.el
@@ -281,5 +281,34 @@ (ert-deftest test-ox-beamer/beamer-verb-frame ()
(org-test-ignore-duplicate
(should (search-forward "\\end{frame}\n" nil t))))))
+(ert-deftest test-ox-beamer/beamer-theme-pre ()
+ "Test that the theme can be preceeded by arbitrary LaTeX
+using BEAMER_THEME_PRE."
+ (org-test-with-exported-text
+ 'beamer
+ "#+STARTUP: beamer
+#+OPTIONS: toc:nil H:2 title:t
+#+LATEX_CLASS_OPTIONS: [presentation,11pt,t]
+#+TITLE: Testing =BEAMER_THEME_PRE=
+#+BEAMER_THEME_PRE: \\usepackage[total={16cm,9cm},
+#+BEAMER_THEME_PRE: top=1.2in, left=0.9in, includefoot]{geometry}
+#+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 (search-forward "\\usepackage[total={16cm,9cm}," nil t))
+ (should (search-forward "top=1.2in, left=0.9in, includefoot]{geometry}" nil t))
+ (should (search-forward "\\usetheme{Boadilla}" nil t))
+ (should (search-forward "\\useinnertheme{circles}" nil t)))))
+
(provide 'test-ox-beamer)
;;; test-ox-beamer.el ends here
--
2.43.0