0

I find myself using \begin{frame}[t]\end{frame} all the time. All my attempts to create a macro for it have failed. Is there a way?

epR8GaYuh
  • 2,432
  • 2
    Welcome. No, there isn't. Why would you obfuscate your code? – egreg Jul 29 '20 at 22:49
  • Actually, I meant it this way \end{fra Sorry.me}\begin{frame}[t]. – latexatha Jul 29 '20 at 22:50
  • 5
    If \begin{frame}[t]\end{frame} is too much for you to type, just set one of the editor's shortcuts to insert it for you, most of the editors I know of can do this. – AboAmmar Jul 29 '20 at 23:41
  • This has been asked like a million times and it is not only answered on this site but also in the official documentation. – Henri Menke Jul 30 '20 at 08:34
  • https://tex.stackexchange.com/questions/422868/creating-a-beginframefragile-macro – Henri Menke Jul 30 '20 at 08:35
  • https://tex.stackexchange.com/questions/156242/how-to-create-a-macro-for-a-customized-frame-in-beamer – Henri Menke Jul 30 '20 at 08:35
  • 1
    If you want to set t for all frames, use \documentclass[t]{beamer} (see beamer manual, sec. 8.1). If you prefer command to environment, use \frame{<contents of frame env>}. – muzimuzhi Z Jul 30 '20 at 23:26

2 Answers2

1

If you are not into the underlying LaTeX mechanics and would like to seek for a simplistic way, you can just save your command into a file (e.g. cmd.tex) and declare a macro to \input it.

cmd.tex

\begin{frame}[t]\end{frame}

main document

\documentclass{beamer}

\begin{document}

\newcommand{\newframe}{\input{cmd.tex}}

\newframe \newframe \newframe \newframe

\end{document}

Edit: making use of files

As other answers have pointed out, there is no easy way of defining a macro as \end{frame}\begin{frame}[t], because of LaTeX's parsing mechanism. The (only) way to escape from this dilemma is to make use of files, as I have pointed out before. To support what you want, we can design a (crazy) workaround:

  1. Save your TeX source code to file1.
  2. Suppose the macro your designed is \framesep. We read file1 line by line and replace \framesep to \end{frame}\begin{frame}[t]. The result is saved as file2.
  3. Read file2.

The code is shown as below.

\documentclass{beamer}
\usepackage[T1]{fontenc}
\usepackage{expl3}
\usepackage{xparse}
\usepackage{fancyvrb}
\usepackage{datetime2}

\begin{document}

\begin{VerbatimOut}{\jobname.myverb1} \begin{frame}[t] frame1 \framesep frame2 \framesep frame3 \end{frame} \end{VerbatimOut}

\ExplSyntaxOn

% replace this regex... \str_new:N \l_framesep_str \str_set:Nn \l_framesep_str {\framesep} % to... \str_new:N \l_framecmd_str \str_set:Nn \l_framecmd_str {\end{frame}\begin{frame}[t]}

\ior_new:N \l_infile_ior \ior_open:Nn \l_infile_ior {\jobname.myverb1} \iow_new:N \l_outfile_iow \iow_open:Nn \l_outfile_iow {\jobname.myverb2}

\cs_generate_variant:Nn \regex_replace_all:nnN {ooN}

\ior_str_map_variable:NNn \l_infile_ior \l_tmpa_str { \regex_replace_all:ooN {\l_framesep_str} {\l_framecmd_str} \l_tmpa_str \iow_now:Nx \l_outfile_iow {\l_tmpa_str} }

\ior_close:N \l_infile_ior \iow_close:N \l_outfile_iow

\ExplSyntaxOff

\input{\jobname.myverb2}

\end{document}

Note that this can also be done by calling a pre-processor before compiling your TeX source. For example, you can have a Python script doing the replacement first and then calling latex.

Alan Xiang
  • 5,227
  • Thank you! It works fine. Now, I try \end{frame}\begin{frame}[t] ad it does not work! I get ! Extra }, or forgotten \endgroup. \endframe ->\egroup \begingroup \def @currenvir {frame} l.1 \end{frame} \begin{frame}[t] Thank you again! latexatha – – latexatha Jul 30 '20 at 18:46
1

If your aim is to substitute the combination

\end{frame}
\begin{frame}[t]

with, say

\breakframe

then the answer is no, you can't.

As beamer is implememented, it needs to absorb the complete frame code before processing it for making overlays and all other things. So LaTeX needs to see an explicit \end{frame} not buried into a macro. After processing \begin{frame} it looks forward until it finds \end{frame} doing no macro expansion, but simply absorbing tokens as it goes.

Yes, one might think to set up the presentation like

\startframes
...
\breakframe
...
\breakframe
...
\breakframe
\stopframes

but, unless you're wanting to absorb the whole presentation in one big swoop, the final part should be something as described above.

Is this so different from

\begin{frame}[t]
...
\end{frame}
\begin{frame}[t]
...
\end{frame}
\begin{frame}[t]
...
\end{frame}

to go into the burden of rewriting code already working?

A good text editor can spare you the typing and produce

\begin{frame}[t]

\end{frame}

with the pression of a couple of keys, also placing the cursor in the blank space.

egreg
  • 1,121,712