From cc3e1572e354d18ce57c6a7b89b7fdd96b7fe1a8 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. It 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. * lisp/org-lint.el (org-lint-beamer-frame): Check the body of each frame for an occurrence of \begin{orgframe} or \end{orgframe}, or whatever environment name is in `org-beamer-frame-environment' [4]. 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]. 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/ [4] https://list.orgmode.org/orgmode/87il38i5tb.fsf@localhost/T/ --- lisp/org-lint.el | 15 +++++++++++++++ lisp/ox-beamer.el | 43 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/lisp/org-lint.el b/lisp/org-lint.el index f68aeab01..7248f687d 100644 --- a/lisp/org-lint.el +++ b/lisp/org-lint.el @@ -1446,6 +1446,17 @@ AST is the buffer parse tree." ((memq (org-element-property :type deadline) '(inactive inactive-range)) (list (org-element-begin planning) "Inactive timestamp in DEADLINE will not appear in agenda.")) (t nil)))))) + +(defun org-lint-beamer-frame (ast) + "Check for occurrences of begin or end frame." + (org-with-point-at ast + (goto-char (point-min)) + (let (result) + (while (re-search-forward + (concat "\\\\\\(begin\\|end\\){" org-beamer-frame-environment "}") nil t) + (push (list (match-beginning 0) "Beamer frame name may cause error when exporting.") result)) + result))) + ;;; Checkers declaration @@ -1711,6 +1722,10 @@ AST is the buffer parse tree." "Report $ that might be treated as LaTeX fragment boundary." #'org-lint-LaTeX-$-ambiguous :categories '(markup) :trust 'low) +(org-lint-add-checker 'beamer-frame + "Report that frame text contains beamer frame environment." + #'org-lint-beamer-frame + :categories '(export) :trust 'low) (org-lint-add-checker 'timestamp-syntax "Report malformed timestamps." #'org-lint-timestamp-syntax diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el index 82c8841aa..65d8b06ef 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,16 @@ 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 (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 +493,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 +817,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=%1$s,#1]}{\\end{frame}}\n" frame)) + org-beamer--frame-environments)) + (setq org-beamer--frame-environments '()))) ;;;; Template ;; @@ -825,6 +852,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