From d0117ca35405654c6adc003252eff5a1f629b67a Mon Sep 17 00:00:00 2001 From: Leo Butler Date: Thu, 25 Jan 2024 09:48:20 -0600 Subject: [PATCH] lisp/ox-beamer.el: customize the beamer frame environment name * lisp/ox-beamer.el (org-beamer-frame-environment): A new customize variable that contains the name of an environment that serves as an alias for the beamer frame environment. (org-beamer--format-frame): Introduce the new property, :BEAMER_FRAME. If set in the headline, use that as name of the frame environment. Otherwise, in frames marked as fragile, the name of the frame environment is taken from `org-beamer--frame-environment'. In all other frames, the default name is frame. Unless the frame name is "frame", the name is added to the list `org-beamer--frame-environments'. (org-beamer--frame-environments): New variable and function. The variable holds a list of names of frame environments found while formatting frames. The function generates the LaTeX code to define each new frame environment. (org-beamer-template): Add a call to `org-beamer--frame-environments' to insert the environment definitions into the beamer document. Rationale: Code with \begin{frame} or \end{frame} cannot be embedded in a verbatim environment inside a beamer frame due to a design decision made by the beamer developers [1]. As suggested in that report, defining an alias for the beamer frame environment will allow such verbatim examples to compile correctly [2]. Since the frame environment name is customize-able, beamer code generated by ox-beamer can be included inside the verbatim environment, simply by changing the frame environment name via the :BEAMER_FRAME property. This solution also works with instances of \againframe. Refs: [1] https://github.com/josephwright/beamer/issues/360 [2] https://github.com/josephwright/beamer/issues/360#issuecomment-708705250 [3] https://list.orgmode.org/orgmode/87le8eg1hs.fsf@localhost/T/ --- lisp/ox-beamer.el | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el index 82c8841aa..4a1e09b85 100644 --- a/lisp/ox-beamer.el +++ b/lisp/ox-beamer.el @@ -149,9 +149,17 @@ which is replaced with the subtitle." :package-version '(Org . "8.3") :type '(string :tag "Format string")) +(defcustom org-beamer-frame-environment "orgframe" + "Name of the beamer frame environment." + :group 'org-export-beamer + :type '(string :tag "Beamer frame")) + ;;; Internal Variables +(defvar org-beamer--frame-environments '() + "List of beamer frame environments.") + (defconst org-beamer-column-widths "0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 0.0 :ETC" "The column widths that should be installed as allowed property values.") @@ -409,12 +417,17 @@ used as a communication channel." "Format HEADLINE as a frame. CONTENTS holds the contents of the headline. INFO is a plist used as a communication channel." - (let ((fragilep - ;; FRAGILEP is non-nil when HEADLINE contains an element - ;; among `org-beamer-verbatim-elements'. - (org-element-map headline org-beamer-verbatim-elements 'identity - info 'first-match))) - (concat "\\begin{frame}" + (let* ((fragilep + ;; FRAGILEP is non-nil when HEADLINE contains an element + ;; among `org-beamer-verbatim-elements'. + (org-element-map headline org-beamer-verbatim-elements 'identity + info 'first-match)) + (frame (or (org-element-property :BEAMER_FRAME headline) + (and fragilep org-beamer-frame-environment) + "frame"))) + (unless (string= frame "frame") + (add-to-list 'org-beamer--frame-environments frame)) + (concat "\\begin{" frame "}" ;; Overlay specification, if any. When surrounded by ;; square brackets, consider it as a default ;; specification. @@ -481,7 +494,7 @@ used as a communication channel." ;; output. (if (not fragilep) contents (replace-regexp-in-string "\\`\n*" "\\& " (or contents ""))) - "\\end{frame}"))) + "\\end{" frame "}"))) (defun org-beamer--format-block (headline contents info) "Format HEADLINE as a block. @@ -805,6 +818,21 @@ contextual information." (org-export-get-reference radio-target info) text)) +;;;; Frame Environments +;; +;; Define any needed frame environments. + +(defun org-beamer--frame-environments () + "Define beamer frame environments. +This function is called once from `org-beamer-template'. As a +side-effect, it resets `org-beamer--frame-environments' to nil." + (prog1 + (string-join + (mapcar + #'(lambda(frame) + (format "\\newenvironment<>{%s}[1][]{\\begin{frame}[environment=%s,#1]}{\\end{frame}}\n" frame frame)) + org-beamer--frame-environments)) + (setq org-beamer--frame-environments '()))) ;;;; Template ;; @@ -825,6 +853,8 @@ holding export options." (org-latex--insert-compiler info) ;; Document class and packages. (org-latex-make-preamble info) + ;; Define the frame environments, if needed. + (org-beamer--frame-environments) ;; Insert themes. (let ((format-theme (lambda (prop command) -- 2.43.0