branch: externals/org
commit 8bd3c91920cb6e20f351b86a3cc5e88e70e2bb4d
Author: Pedro A. Aranda <[email protected]>
Commit: Ihor Radchenko <[email protected]>

    ox-beamer: New keyword 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                   |  8 +++++++
 lisp/ox-beamer.el              | 51 +++++++++++++++++++++++++-----------------
 testing/lisp/test-ox-beamer.el | 28 +++++++++++++++++++++++
 4 files changed, 81 insertions(+), 23 deletions(-)

diff --git a/doc/org-manual.org b/doc/org-manual.org
index bda84c49c56..cd8903a7e0e 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 5f5168e3362..bb965c02acf 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -160,6 +160,14 @@ and some environments listed in the manual are not 
supported.
 # adding new customizations, or changing the interpretation of the
 # existing customizations.
 
+*** ox-beamer.el: New keyword BEAMER_THEME_PRE
+
+The new keyword allows adding arbitrary lines just before the Beamer
+theme declaration.  For example, setting slide geometry needs to be
+done before loading theme:
+
+: #+BEAMER_THEME_PRE: \usepackage[total={16cm,9cm}]{geometry}
+
 *** New variable ~org-latex-doc-metadata~ and keyword ~#+LATEX_DOC_METADATA:~
 
 The LaTeX exporter can include PDF metadata with the new variable
diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index f5cf1a89629..4548d77bf0c 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -275,6 +275,7 @@ Return overlay specification, as a string, or nil."
     (: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,32 @@ contextual information."
 
 ;;;; Template
 ;;
+
+(defun org-beamer--theme-header (info)
+  "Return the theme related configuration from INFO as a string."
+  ;; 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 +932,10 @@ 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.
-     (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 03e6d59d5c6..ccc536e5ecb 100644
--- a/testing/lisp/test-ox-beamer.el
+++ b/testing/lisp/test-ox-beamer.el
@@ -281,5 +281,33 @@ print(\"Hello, beamer!\", file=sys.stderr)
      (org-test-ignore-duplicate
       (should (search-forward "\\end{frame}\n" nil t))))))
 
+(ert-deftest test-ox-beamer/beamer-theme-pre ()
+  "Test BEAMER_THEME_PRE keyword."
+  (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

Reply via email to