On Fri, Jan 26 2024, Ihor Radchenko <yanta...@posteo.net> wrote:

> Leo Butler <leo.but...@umanitoba.ca> writes:
>
>>> Apparently, LaTeX has really hard time processing verbatim code inside
>>> beamer frames.
>>
>> I looked again at the solution here:
>> https://tex.stackexchange.com/questions/140719/verbatim-in-beamer-showing-error-file-ended-while-scanning-use-of-xverbatim
>>
>> and it errors out with a recent version of pdflatex:
>>
>>    This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Debian) 
>> (preloaded format=pdflatex)
>>
>> This is, apparently, a known problem:
>>
>> https://github.com/josephwright/beamer/issues/360
>>
>> The end of that issue report includes a work-around that we might apply
>> in org. I have attached a patch for your feedback. The example that
>> stimulated this discussion compiles with the patch and the testsuite
>> shows no errors related to it.
>
> Thanks!
> I have concerns about your approach though.
>
> You are replacing all the frame environments with custom environment
> unconditionally. However, custom environment has downsides. For example,
> \againframe will stop working, as pointed earlier in the linked beamer
> thread
> https://github.com/josephwright/beamer/issues/360#issuecomment-708705250

The comment that you are citing shows how to define the custom
environment so that \againframe works correctly. See the attachment
`beamer-example-againframe.tex' and pdf. You can see that \againframe
works with the custom environment.

>
> Since the problem appears only when the frame contents contains
> \end{frame}, it may be sufficient to replace the standard frame
> environment with the workaround only in such scenario.

Yes, that might be true. But my feeling is that it would be simpler and
more robust to use the custom frame environment in most cases.

>
>> +;; Needed to set-up Beamer export.
>> +(defconst org-beamer--frame-environment
>> +  (concat "orgframe" (org-id-uuid))
>> +  "Name of the beamer frame environment.
>> +This is randomized to prevent collisions.")
>
> Please use constant name. (org-id-uuid) makes export randomized for no
> good reason.

There is a good reason to randomize (or at least make customize-able)
the environment name: so that beamer code generated by ox-beamer can be
safely inserted into org files and exported by ox-beamer. With a fixed
name for the environment, we will have just recreated the original
source of the bug report. As a compromise, in the attached patch, I have
made the environment name customize-able.

>
>>  ;; Install a default set-up for Beamer export.
>>  (unless (assoc "beamer" org-latex-classes)
>>    (add-to-list 'org-latex-classes
>> -           '("beamer"
>> -             "\\documentclass[presentation]{beamer}"
>> +           `("beamer"
>> +             ,(concat "\\documentclass[presentation]{beamer}\n"
>> +                          ;; Define an alias for the beamer frame 
>> environment
>> +                         "\\newenvironment<>{"
>> +                         org-beamer--frame-environment
>> +                         "}[1][]{\\begin{frame}[environment="
>> +                         org-beamer--frame-environment
>> +                         ",#1]}{\\end{frame}}")
>
> Please use `org-beamer-template' rather than modifying the class.
> Modifying the class may confuse users.

Ok, I have done so.

The docstring of `org-latex-classes' says:

    The HEADER-STRING is the header that will be inserted into the
    LaTeX file.  It should contain the \documentclass macro, and
    anything else that is needed for this setup.

>From that, I figured that would be the correct place to put that
\newenvironment command. I have moved it, as requested.

Please see the revised patch. I believe that I have taken into account
your suggestions.

Leo

% Created 2024-01-26 Fri 11:42
% Intended LaTeX compiler: lualatex
\documentclass[bigger]{beamer}
\newenvironment<>{OrgFrame}[1][]{\begin{frame}[environment=OrgFrame,#1]}{\end{frame}}
\usetheme{default}

\begin{document}
\begin{OrgFrame}[label=repeatit,fragile]{Verbatim inside a Special Frame Environment}
\tiny
\begin{verbatim}
\begin{frame}[label={sec:org8bc49cc}]{Two columns}
\begin{columns}
\begin{column}{0.4\columnwidth}
\begin{itemize}
\item this slide consists of two columns
\item the first (left) column has no heading and consists of text
\item the second (right) column has an image and is enclosed in an
\alert{example} block
\end{itemize}
\end{column}
\end{verbatim}
\end{OrgFrame}

\againframe<2>{repeatit}
\end{document}

Attachment: beamer-example-againframe.pdf
Description: beamer-example-againframe.pdf

From bfd182b9ca86c2db5cd514cad0a11fd3f5bd8934 Mon Sep 17 00:00:00 2001
From: Leo Butler <leo.but...@umanitoba.ca>
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): new customize
variable that contains the name of an environment that serves as an
alias for the beamer frame environment.  The environment's definition
is appended to the set-up for beamer export.

(org-beamer--format-frame):  Replace the occurrence of \begin{frame}
and \end{frame} with the new environment's name.

(org-beamer-template): Add LaTeX code to define the new frame
environment.

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.

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 | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index 82c8841aa..bab9ae089 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -45,7 +45,6 @@
 		 ("\\subsection{%s}" . "\\subsection*{%s}")
 		 ("\\subsubsection{%s}" . "\\subsubsection*{%s}"))))
 
-
 
 ;;; User-Configurable Variables
 
@@ -149,6 +148,11 @@ 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
 
@@ -414,7 +418,7 @@ used as a communication channel."
 	 ;; among `org-beamer-verbatim-elements'.
 	 (org-element-map headline org-beamer-verbatim-elements 'identity
 			  info 'first-match)))
-    (concat "\\begin{frame}"
+    (concat "\\begin{" org-beamer-frame-environment "}"
 	    ;; Overlay specification, if any. When surrounded by
 	    ;; square brackets, consider it as a default
 	    ;; specification.
@@ -481,7 +485,7 @@ used as a communication channel."
 	    ;; output.
 	    (if (not fragilep) contents
 	      (replace-regexp-in-string "\\`\n*" "\\& " (or contents "")))
-	    "\\end{frame}")))
+	    "\\end{" org-beamer-frame-environment "}")))
 
 (defun org-beamer--format-block (headline contents info)
   "Format HEADLINE as a block.
@@ -825,6 +829,12 @@ holding export options."
      (org-latex--insert-compiler info)
      ;; Document class and packages.
      (org-latex-make-preamble info)
+     ;; Define the frame environment.
+     "\\newenvironment<>{"
+     org-beamer-frame-environment
+     "}[1][]{\\begin{frame}[environment="
+     org-beamer-frame-environment
+     ",#1]}{\\end{frame}}\n"
      ;; Insert themes.
      (let ((format-theme
 	    (lambda (prop command)
-- 
2.43.0

#+startup: beamer
#+LaTeX_CLASS: beamer

* A frame with =verbatim= contents
#+begin_example
\begin{frame}
  Here is a beamer frame.
\end{frame}
#+end_example

Reply via email to