Search code examples
rlatexr-markdownmarkdownbeamer

How to adapt a LaTex beamer theme to apply it in an rmarkdown::beamer_presentation


I would like to apply a LaTex beamer theme in an rmarkdown::beamer_presentation. The custom themes contains a beamerthemeTHEMENAME.sty, beamercolorthemeTHEMENAME.sty, beamerfontthemeTHEMENAME.sty, beamerinnerthemeTHEMENAME.sty, beamerouterthemeTHEMENAME.sty. If the template is sourced within my YAML header, the knitted presentation does not look very close to a beamer presentation generated straight from LaTex by applying the custom theme.

Thus, which contents of the beamertheme*.sty to modify or enhance the presentation require modification or need to be moved from the beamer theme, e.g. to template.tex and includes*?

In particular, I am struggling on using the following frame templates defined in beamerouterthemeTHEMENAME.sty: \titleframe, \tocframe, \closingframe

For the footline defined in beamerouterthemeTHEMENAME.sty, it would be very nice to have a hyperlink from the logo to the table of contents slide (like the page numbers are linked to the appendix). An MWE is provided below. Any help is greatly appreciated.

MWE.Rmd

---
title: "MWE"
subtitle: "Beamer presnetation with R-markdown"
institute: "some place"
date: "`r format(Sys.time(), '%B %d, %Y')`"
output:
  # beamer_presentation: default
  bookdown::pdf_book:
    base_format: rmarkdown::beamer_presentation
    # includes:
    #  - in_header: preamble.tex
    theme: "THEMENAME"
    latex_engine: xelatex
    toc: false
    slide_level: 2
---


​```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
​```

# Random presentation

## TOC - Table of Contents {.unnumbered}

\tableofcontents
\label{contents}

## Slide with Bullets

- Bullet 1
- Bullet 2
- Bullet 3

## Apendix
\appendix

beamerthemeTHEMENAME.sty

\usepackage[utf8]{inputenc}

% Tizk, textpos, graphics
\RequirePackage{tikz}
\RequirePackage{textpos}
\RequirePackage{xcolor}
\RequirePackage{booktabs}

% Beamer settings
\usecolortheme{THEMENAME}
\useoutertheme{THEMENAME}
\setbeamertemplate{navigation symbols}{}

\mode<all>

beamercolorthemeTHEMENAME.sty

\mode<presentation>
\definecolor{THEMECOL}{RGB}{162,48,47}  % red
\definecolor{THEMEgray}{RGB}{110,110,101}% gray

\colorlet{titlefgcolor}{THEMECOL} % color of box
\colorlet{titlebgcolor}{THEMEgray} % color of box

\setbeamercolor*{title}{fg=THEMECOL}    % presentation title 
\setbeamercolor*{author}{fg=THEMECOL}   % author
\setbeamercolor*{date}{fg=THEMECOL} % date
\mode<all>

beamerouterthemeTHEMENAME.sty

\mode<presentation>

% Redefine \insertshortinstitute to allow multiple lines
\makeatletter
\renewcommand{\insertshortinstitute}{\beamer@shortinstitute}
\makeatother

% Title frame
\def\titlefigure{img/my_bg}
\newlength\titleboxwidth
\setlength{\titleboxwidth}{0.33\textwidth}
\newcommand{\titleframe}{%
    {
        \setbeamertemplate{background}{
            \begin{tikzpicture}
            \useasboundingbox (0,0) rectangle(\the\paperwidth,\the\paperheight);
            \ifx\titlefigure\empty
                \fill[titlebgcolor] (6.3mm,6.4mm) rectangle (\the\paperwidth-8.3mm,\the\paperheight-13mm);
            \else
                \node at (current page.center) [anchor=center,yshift=-3.5mm] {\includegraphics[width=\the\paperwidth-19mm]{\titlefigure}};
            \fi
            \node at (current page.north east) [anchor=base east, xshift=-8.3mm, yshift=-6.3mm, align=left, inner sep=0mm, font=\fontsize{5.5}{6.6}\selectfont] {
                \insertshortinstitute
            }; 
            \node at (current page.north west) [anchor=south west, inner sep=0mm, xshift=8.3mm, yshift=-8.6mm] {
                \includegraphics[height=3.8mm]{img/my_logo}
            }; 
            \end{tikzpicture}
        }
        \setbeamertemplate{footline}{}
        \begin{frame}[noframenumbering]
            \begin{tikzpicture}
                \useasboundingbox (0,0) rectangle(\the\paperwidth,\the\paperheight);
                \node [
                    shift={(-11.5mm,-1.8mm)},
                    fill=titlefgcolor,
                    minimum width=0.46\paperwidth,
                    minimum height=18mm,
                    anchor=west,
                    inner sep=4mm
                    ] at (current page.west) {
                        \hspace*{9mm}
                        \begin{minipage}{\titleboxwidth}
                            \raggedright
                            \usebeamerfont{title}\usebeamercolor[fg]{title}\inserttitle\\[3mm]
                            \usebeamerfont{author}\usebeamercolor[fg]{author}\insertauthor\\
                            \usebeamerfont{date}\usebeamercolor[fg]{date}\insertdate
                        \end{minipage}          
                    };
            \end{tikzpicture}
        \end{frame}
    }
}

% TOC frame
\newcommand{\tocframe}{%
    \begin{frame}
      \frametitle{Outline}
      \tableofcontents
    \end{frame}
}

% Section title frame
\AtBeginSection[]
{
    \begin{frame}
      \frametitle{Outline}
      \large
      \tableofcontents[currentsection] 
    \end{frame}
}

\newenvironment{closingframe}{
    \setbeamertemplate{background}{
        \begin{tikzpicture}
        \useasboundingbox (0,0) rectangle(\the\paperwidth,\the\paperheight);
        \node at (current page.north west) [anchor=base west, xshift=8mm, yshift=-10mm, align=left] {
            \includegraphics[width=23mm]{img/my_logo.png}
        }; 
        \end{tikzpicture}
    }
    \setbeamertemplate{footline}{}
    \addtolength{\headsep}{10mm}
    \begin{frame}[noframenumbering]
}%
{
    \end{frame}
}%

% Footline
\setbeamertemplate{footline}{
    \leavevmode%
    \hyperlink{contents}{\includegraphics[width=12mm,trim=0mm 0.4mm 0mm 0mm]{img/my_logo.png}}
    \hfill
    \hyperlinkappendixstart{\insertframenumber/\inserttotalframenumber}
    \vspace{3mm}
}

\mode<all>

Solution

  • You can make the following dirty hacks to the markdown document:

    • Instead of the yaml title, use \AtBeginDocument{\title{MWE}\titleframe} to suppress the annoying automatic title markdown inserts (which does not even uses \maketitle, so one can't make any reasonable modifications) and add your custom title command

    • \AtEndDocument{\begin{closingframe}lalala\end{closingframe}} to add your closing frame [replace lalala with whatever text you like]

    • add \makeatletter\beamer@ignorenonframefalse\makeatother to suppress options markdown annoyingly automatically uses and which don't allow any wrappers for frames

    • you can use

      ``` {=latex}
      \end{frame}
      \tocframe
      \begin{frame}
      ```
      

      to use your \tocframe macro, however I don't see much use for this, as markdown will automatically insert such frames at all reasonable places (and then a couple of more at all unreasonable places as well, just because it seems to enjoy being annoying...)


    ---
    subtitle: "Beamer presnetation with R-markdown"
    institute: "some place"
    date: "`r format(Sys.time(), '%B %d, %Y')`"
    author: "Donald Duck"
    output:
      # beamer_presentation: default
      bookdown::pdf_book:
        base_format: rmarkdown::beamer_presentation
        # includes:
        #   in_header: preamble.tex
        theme: "THEMENAME"
        latex_engine: xelatex
        toc: false
        slide_level: 2
        keep_tex: true 
    header-includes:
      - \AtBeginDocument{\title{MWE}\titleframe}    
      - \AtEndDocument{\begin{closingframe}lalala\end{closingframe}}
      - \makeatletter\beamer@ignorenonframefalse\makeatother
    ---
    
    # Random presentation
    
    ## TOC - Table of Contents {.unnumbered}
    
    \tableofcontents
    \label{contents}
    
    ``` {=latex}
    \end{frame}
    \tocframe
    \begin{frame}
    ```
    
    ## Slide with Bullets
    
    - Bullet 1
    - Bullet 2
    - Bullet 3
    
    ``` {=latex}
    \end{frame}
    \appendix
    \begin{frame}
    ```
    ## Apendix
    

    Now to the theme:

    • if your tex distribution has been updated at one point since the dinosaurs gone extinction, then you don't need \usepackage[utf8]{inputenc}. That's the default in current latex distributions. Also rmarkdown will automatically insert this.

    • you don't need \RequirePackage{xcolor}. Not only does beamer already load this automatically, but it will also be included in this annoyingly long list of unsuitable packages rmarkdown automatically adds to the document.

    • The \titleframe macro also needs a couple of modifications because the theme does abuse \\ for line breaks and does not test if title, author and date macros are actually filled. Combined this will fail spectacularly...

    • you might also want to use different colours for the background and the font of the title box.... I mixed a bit of white to the background to make the font visible

    \newcommand{\titleframe}{%
        {
            \setbeamertemplate{background}{
                \begin{tikzpicture}
                \useasboundingbox (0,0) rectangle(\the\paperwidth,\the\paperheight);
                \ifx\titlefigure\empty
                    \fill[titlebgcolor] (6.3mm,6.4mm) rectangle (\the\paperwidth-8.3mm,\the\paperheight-13mm);
                \else
                    \node at (current page.center) [anchor=center,yshift=-3.5mm] {\includegraphics[width=\the\paperwidth-19mm]{\titlefigure}};
                \fi
                \node at (current page.north east) [anchor=base east, xshift=-8.3mm, yshift=-6.3mm, align=left, inner sep=0mm, font=\fontsize{5.5}{6.6}\selectfont] {
                    \insertshortinstitute
                }; 
                \node at (current page.north west) [anchor=south west, inner sep=0mm, xshift=8.3mm, yshift=-8.6mm] {
                    \includegraphics[height=3.8mm]{example-image}
                }; 
                \end{tikzpicture}
            }
            \setbeamertemplate{footline}{}
            \begin{frame}[noframenumbering]
                \begin{tikzpicture}
                    \useasboundingbox (0,0) rectangle(\the\paperwidth,\the\paperheight);
                    \node [
                        shift={(-11.5mm,-1.8mm)},
                        fill=titlefgcolor!50!white,
                        minimum width=0.46\paperwidth,
                        minimum height=18mm,
                        anchor=west,
                        inner sep=4mm
                        ] at (current page.west) {
                            \hspace*{9mm}
                            \begin{minipage}{\titleboxwidth}
                                \raggedright
                                \usebeamerfont{title}\usebeamercolor[fg]{title}\inserttitle\par
                                \usebeamerfont{author}\usebeamercolor[fg]{author}\insertauthor\par
                                \usebeamerfont{date}\usebeamercolor[fg]{date}\insertdate
                            \end{minipage}          
                        };
                \end{tikzpicture}
            \end{frame}
        }
    }
    

    For the footline, use the hyperlink target that is created by your toc section

    % Footline
    \setbeamertemplate{footline}{
        \leavevmode%
        \hyperlink{toc---table-of-contents}{\includegraphics[width=12mm,trim=0mm 0.4mm 0mm 0mm]{example-image}}
        \hfill
        \hyperlinkappendixstart{\insertframenumber/\inserttotalframenumber}
        \vspace{3mm}
    }
    

    [I guess the number of times I used annoying in this answer shows how much more difficult rmarkdown makes a job that would have taken 2 seconds in a normal beamer document]