[Tex/LaTex] Issue with LaTeX code in “header-includes” in R Markdown file after R and RStudio upgrade

errorsheader-footermarkdownpdfr

I use the following LaTeX code in the YAML of my R Markdown document (that produces, as output, a PDF):

---
output:
  pdf_document:
    latex_engine: xelatex
header-includes:
- |
  ```{=latex} 
  \usepackage{microtype}
  \usepackage{fontspec}
  \setmainfont{Times.otf}[
          BoldFont = TimesBold.otf]
  \usepackage{ragged2e}
  \renewcommand{\footnotesize}{\scriptsize \justify}
  \usepackage{setspace}
  \usepackage{xcolor}
  \definecolor{very-light-gray}{gray}{0.95}
  \pagenumbering{gobble}
  \makeatletter
  \def\MT@is@composite#1#2\relax{%
    \ifx\\#2\\\else
      \expandafter\def\expandafter\MT@char\expandafter{\csname\expandafter
                      \string\csname\MT@encoding\endcsname
                      \MT@detokenize@n{#1}-\MT@detokenize@n{#2}\endcsname}%
      % 3 lines added:
      \ifx\UnicodeEncodingName\@undefined\else
        \expandafter\expandafter\expandafter\MT@is@uni@comp\MT@char\iffontchar\else\fi\relax
      \fi
      \expandafter\expandafter\expandafter\MT@is@letter\MT@char\relax\relax
      \ifnum\MT@char@ < \z@
        \ifMT@xunicode
          \edef\MT@char{\MT@exp@two@c\MT@strip@prefix\meaning\MT@char>\relax}%
            \expandafter\MT@exp@two@c\expandafter\MT@is@charx\expandafter
              \MT@char\MT@charxstring\relax\relax\relax\relax\relax
        \fi
      \fi
    \fi
  }
  % new:
  \def\MT@is@uni@comp#1\iffontchar#2\else#3\fi\relax{%
    \ifx\\#2\\\else\edef\MT@char{\iffontchar#2\fi}\fi
  }
  \makeatother
---

I found such code on a post on StackExchange (that unfortunately I can't find anymore), and it has worked since now. After an update of R and RStudio (and some R packages) I always get the following LaTeX error:

! LaTeX Error: Missing \begin{document}.

To be more precise, this error it's not due to some problems in the rest of my code in the document. I isolated the issue and found out that it is related to the piece of code inside the "header-includes:" section.

Do you have any suggestion to make my code work again?

Thank you!

Best Answer

Welcome to TeX.SE. I changed the header-includes syntax and put the definition of the microtype macro, MT@is@composite, into a file called mystyles.sty and then just added mystyles.sty to the header-includes section. All those extra packages you are loading, and \definecolor and \pagenumber commands could be added to mystyles.sty if you wanted to do that. You might have to revert my change to \setmainfont since I changed this to what worked for me on a Windows system.

---
output:
  pdf_document:
    keep_tex: true
    latex_engine: xelatex
  html_document:
    df_print: paged
header-includes:
  - \usepackage{microtype}
  - \usepackage{fontspec}
  - \setmainfont{Times New Roman} #<- changed this
  - \usepackage{ragged2e}
  - \renewcommand{\footnotesize}{\scriptsize\justify}
  - \usepackage{setspace}
  - \usepackage{xcolor}
  - \definecolor{very-light-gray}{gray}{0.95}
  - \pagenumbering{gobble}
  - \input{mystyles.sty}
---

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

## R Markdown

This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see <http://rmarkdown.rstudio.com>.

When you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:

```{r cars}
summary(cars)
```

## Including Plots

You can also embed plots, for example:

```{r pressure, echo=FALSE}
plot(pressure)
```

Note that the `echo = FALSE` parameter was added to the code chunk to prevent printing of the R code that generated the plot.

This is the content of mystyles.sty:

\makeatletter
\def\MT@is@composite#1#2\relax{%
  \ifx\\#2\\\else
    \expandafter\def\expandafter\MT@char\expandafter{\csname\expandafter
                    \string\csname\MT@encoding\endcsname
                    \MT@detokenize@n{#1}-\MT@detokenize@n{#2}\endcsname}%
% 3 lines added:
    \ifx\UnicodeEncodingName\@undefined\else
      \expandafter\expandafter\expandafter\MT@is@uni@comp\MT@char\iffontchar\else\fi\relax
    \fi
    \expandafter\expandafter\expandafter\MT@is@letter\MT@char\relax\relax
    \ifnum\MT@char@ < \z@
      \ifMT@xunicode
        \edef\MT@char{\MT@exp@two@c\MT@strip@prefix\meaning\MT@char>\relax}%
          \expandafter\MT@exp@two@c\expandafter\MT@is@charx\expandafter
            \MT@char\MT@charxstring\relax\relax\relax\relax\relax
      \fi
    \fi
  \fi
 }
% new:
 \def\MT@is@uni@comp#1\iffontchar#2\else#3\fi\relax{%
  \ifx\\#2\\\else\edef\MT@char{\iffontchar#2\fi}\fi
}
\makeatother

Your header content then appears in the preamble of the .tex files, just as intended. I added keep_tex: true to the YAML to keep the intermediate .tex file that is produced so that we can see what's going on in the header.

\usepackage{microtype}
\usepackage{fontspec}
\setmainfont{Times New Roman}
\usepackage{ragged2e}
\renewcommand{\footnotesize}{\scriptsize\justify}
\usepackage{setspace}
\usepackage{xcolor}
\definecolor{very-light-gray}{gray}{0.95}
\pagenumbering{gobble}
\input{mystyles.sty}

enter image description here

If you are having trouble, make sure you Clear Knitr Cache before reexecuting the .Rmd file.