When trying to knit a PDF using a template from package rticles output: rticles::acm_article I get the following error:
! LaTeX Error: Environment Shaded undefined.
See the LaTeX manual or LaTeX Companion for explanation.
Type H <return> for immediate help.
...
l.76 \begin{Shaded}
This appears to only happen when I include code chunks within the output document.
Reproducible example:
You will need to start a new R Markdown document using the New Document -> From Template -> Association for Computing Machinery. Here is the R Markdown file:
---
title: Short Paper
author:
- name: I Am Me
email: me#email.com
affiliation: Fictional University
abstract: |
This is the abstract.
It consists of two paragraphs.
output:
rticles::acm_article:
keep_tex: true
---
## Simple test
Code chuck follows:
```{r}
plot(rnorm(10))
```
This above example, however, works if I set echo=FALSE in the header. You won't get code in the output, but for an academic paper you probably don't need it anyway, an if you do you can display it in a different manner.
Notes:
R version 3.3.1 (2016-06-21)
Platform: x86_64-pc-linux-gnu (64-bit),
running Ubuntu 16:10
I made sure I have the texlive-latex-base, texlive-latex-recommended, and texlive-latex-extra package installed, but still no luck
I also tried generating a pdf from the intermediate .tex file, as suggested here, but I get the same error.
I considered this approach, but it didn't work, I still got an error (maybe I need to tweak to work in my context, but not sure how)
So, the issue here is the rticles templates sometimes omit a means for pandoc to inject code highlighting environments, e.g. Shaded. To get around this, you would have to insert into the template.tex preamble:
$if(highlighting-macros)$
$highlighting-macros$
$endif$
I struggled with fixing the error and actually raised another question which I was able to answer after quite some experimentation and searching for other related questions/answers.
In short the solution presented above by coatless works perfect given you know the location of the template.tex file. Obviously, I played around with the wrong files before I came across a related question on rticles and how to embed (missing) LATEX.
The longer answer can be found in my "another question". For reference here are the key steps:
locate the template.tex file in your R package rticles library. If you do not know where you have your package library use .libPaths() in your RStudio console. Then work your way to the resources subfolder of your rticle template. In my case:
R-3.5.0/library/rticles/rmarkdown/templates/ieee_article/resources.
add the fix proposed by coatless above in the preamble of the template.tex. The preamble is anything before the line \begin{document}:
$if(highlighting-macros)$
$highlighting-macros$
$endif$
save template.tex and go back to R/RStudio and hit the knit button. R code chunks are now nicely displayed, if you do not suppress their printing with echo = FALSE.
I know the post is old, but I'll put this here for reference for others who have the same problem.
The reason is that in the latex template the environment Shaded is trying to be redefined. However the environment only exists if you are using R chunks in your pdf. So if you don't have any r chunks in the pdf, it tries to redefine something which was never defined - causing the error.
The solution is to modify the \renewenvironment{Shaded} command in the latex template.
https://github.com/yihui/bookdown-chinese/commit/a3e392593b464ba31a7eceb0cd60f7e0bd112798
I found a work around. If I hide the code with chunk option echo = FALSE, a PDF is generated with no issues.
Reproducible example 1:
title: Short Paper
author:
- name: I Am Me
email: me#email.com
affiliation: Fictional University
abstract: |
This is the abstract.
It consists of two paragraphs.
bibliography: sigproc.bib
output:
rticles::acm_article:
keep_tex: true
---
## Simple test
Code chuck follows:
```{r}
plot(rnorm(10))
```
Knit to PDF fails with ! LaTeX Error: Environment Shaded undefined.
Example 2:
---
title: Short Paper
author:
- name: I Am Me
email: me#email.com
affiliation: Fictional University
abstract: |
This is the abstract.
It consists of two paragraphs.
bibliography: sigproc.bib
output:
rticles::acm_article:
keep_tex: true
---
## Simple test
Code chuck follows:
```{r echo=FALSE}
plot(rnorm(10))
```
Knit to PDF works!.
The only difference between the two examples is adding echo=FALSE to the code chunk header. You won't get code in the output, but for an academic paper you probably don't need it anyway, an if you do you can display it in a different manner.
The rticles templates typically do not directly allow shading of code. As a result,
the required $highlighting-macros$ which is used to control the shading is not included.
If for any reason, you cannot (or do not) want to directly edit the template.tex file as suggested by #coatless, you can alternatively consider include the code directly in the acm_proc_article-sp.cls file:
\usepackage{color}
\usepackage{fancyvrb}
\newcommand{\VerbBar}{|}
\newcommand{\VERB}{\Verb[commandchars=\\\{\}]}
\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}}
% Add ',fontsize=\small' for more characters per line
\usepackage{framed}
\definecolor{shadecolor}{RGB}{248,248,248}
\newenvironment{Shaded}{\begin{snugshade}}{\end{snugshade}}
\newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.13,0.29,0.53}{\textbf{#1}}}
\newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.13,0.29,0.53}{#1}}
\newcommand{\DecValTok}[1]{\textcolor[rgb]{0.00,0.00,0.81}{#1}}
\newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.00,0.00,0.81}{#1}}
\newcommand{\FloatTok}[1]{\textcolor[rgb]{0.00,0.00,0.81}{#1}}
\newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
\newcommand{\CharTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
\newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
\newcommand{\StringTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
\newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
\newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
\newcommand{\ImportTok}[1]{#1}
\newcommand{\CommentTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textit{#1}}}
\newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\OtherTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{#1}}
\newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
\newcommand{\VariableTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
\newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.13,0.29,0.53}{\textbf{#1}}}
\newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.81,0.36,0.00}{\textbf{#1}}}
\newcommand{\BuiltInTok}[1]{#1}
\newcommand{\ExtensionTok}[1]{#1}
\newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textit{#1}}}
\newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.77,0.63,0.00}{#1}}
\newcommand{\RegionMarkerTok}[1]{#1}
\newcommand{\InformationTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\WarningTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\AlertTok}[1]{\textcolor[rgb]{0.94,0.16,0.16}{#1}}
\newcommand{\ErrorTok}[1]{\textcolor[rgb]{0.64,0.00,0.00}{\textbf{#1}}}
\newcommand{\NormalTok}[1]{#1}
You may also wish to see my answer to a similar question, whereby the same code is put into a header.tex file in the same directory as your project.
Related
I'm having some trouble to compile an entire document from many Rmd files by using the bookdown approach.
If I knit individual .Rmd files then 'preamble.tex' included in YAML options is taken into account.
If I render the book (with both approaches described here), then 'preamble.tex' is ignored.
To make things concrete, consider the following mwe:
preamble.tex:
\usepackage{times}
index.Rmd:
---
title: "My paper"
site: "bookdown::bookdown_site"
output:
bookdown::pdf_document2:
includes:
in_header: "preamble.tex"
---
01-intro.Rmd:
# Introduction
This chapter is an overview of the methods that we propose to solve an **important problem**.
Then, by knitting 'index.Rmd' or '01-intro.Rmd' the font indicated in 'preamble.tex' is used.
However when rendering with bookdown::render_book('index.Rmd',"bookdown::pdf_book", new_session = T) it is simply ignored.
What is more, in my actual project there are other output options that end up ignored. For example, I use toc: false and it works when knitting single files, but fails when rendering the document.
In this simple example it would be okay to use a single file, but my actual project has many chapters with R chunks within each of them. Thus, building a single file doesn't seem a good idea.
I appreciate any hints on what I am missing here.
Thanks in advance.
What you are missing here is that in your YAML header, preamble.tex is included for the bookdown::pdf_document2 output format and not bookdown::pdf_book, the format you pass to the output_format argument in bookdown::render_book(). For this reason, other YAML options (like toc: true) do not work either.
Running
bookdown::render_book('index.Rmd', "bookdown::pdf_document2", new_session = T)
instead should work.
I'd like to include LaTeX environments (e.g., algorithmic from algorithmicx, mini from optidef, dcases from mathtools, etc.) in my .Rmd bookdown file. This is no problem for pdf output. But these do not render for html or docx output.
My current hack solution:
Generate the .pdf output.
Screen shot, edit, save images of interest as png
Include images conditional on output not being LaTeX
Downsides:
Obviously doesn't scale
Images are ugly in docx and html output
Screws with figure cross-referencing
There has to be a better approach, right? I was thinking that there's a way to tell rmarkdown/LaTeX that, when rendering as pdf, certain code chunks should be saved in some image format. That way they could be added back into the document as images conditional on the output document being docx or html. Is that even possible?
UPDATE: An answer to Standalone diagrams with TikZ suggests an approach involving the LaTeX standalone package. But unfortunately, it's discovered over at standalone does not work with algorithms that this does not work for the algorithm environment. Any ideas?
index.Rmd
---
title: "Bookdown"
header-includes:
- \usepackage{float}
- \floatplacement{figure}{!htb}
- \usepackage{algorithm}
- \usepackage{algpseudocode}
output:
bookdown::gitbook:
split_by: none
bookdown::pdf_book:
fig_caption: yes
keep_tex: yes
toc: no
bookdown::word_document2: default
site: bookdown::bookdown_site
---
```{r setup, include=FALSE, }
knitr::opts_chunk$set(echo = TRUE)
```
Hello zero
# First Chapter
Hello one
\begin{algorithm}
\caption{My Algo}
\begin{algorithmic}[1]
\State Do this.
\State Do that.
\end{algorithmic}
\end{algorithm}
```{r myalgo, echo=FALSE, eval = !knitr:::is_latex_output(), fig.cap="Must have text here. For cross-referencing to work."}
knitr::include_graphics("myalgo.png")
```
Hello two.
Check out this picture: \#ref(fig:myalgo)
myalgo.png
For math, R Markdown uses MathJax, and only a subset of LaTeX is available. This subset includes the basic math macros and environments, and allows you to define new macros, but doesn't support everything necessary to let you use arbitrary LaTeX packages. See http://docs.mathjax.org/en/latest/tex.html for details.
You might be able to create an environment that looks something like algorithm or algorithmic, but it's going to be a lot of work, and likely won't look as nice.
You should probably choose between PDF output with all of LaTeX available for formatting, or some flavour of HTML output with less style. For example, you could write your algorithm as
******
**Algorithm 1**: My algo
******
1. Do this.
2. Do that.
******
and it will display as
Algorithm 1: My algo
Do this.
Do that.
This question already has answers here:
Rstudio pdf knit fails with "Environment Shaded undefined" error
(5 answers)
Closed 4 years ago.
I am creating a report using the rticles package and I get the following error when knitting an rticle IEEE paper which includes code-chunks:
output file: rticles_IEEE.knit.md
! LaTeX Error: Environment Shaded undefined.
I tried to understand how to fix the issue and played around with this question/answer. But I fail to see where to put the fix into the files created by knitting (e.g. mydoc.tex, IEEE_trans.cls).
Here is my minimal example:
---
title: Cool IEEE ArticleS
author:
- name: Ray
abstract: |
The abstract of my first IEEE paper with rmarkdown
output: rticles::ieee_article
---
Introduction
=============
This is the introduction. And here comes a cool code chunk.
```{r}
x <- seq(-3,3,0.1)
y <- x^3
plot(x,y)
```
Notes:
It was commented that this is a potential duplicate of another question. The problem with the answers given in that thread is that it does not explain where to make the changes.
I fail to understand the pointer to Yihui's fix.
The aforementioned files, but also the knitted .tex does not come with labels of the form \makeatother or \makeatletter.
The overall issue was that displaying a code chunk in the rticles IEEE paper throws an error pointing at the undefined Shaded environment.
The solution given in the older post works, if you add the following to the underlying LaTeX template.tex. My problem was that I tried to edit the tex or cls template in the working directory. The Eureka-moment came when I stumbled over the following (related) stackoverflow question.
For the rticles package, the template.tex is not located in your directory you work on the article R Markdown file. Instead, they are stored within the package library folder (i.e. the folder that .libPaths() uses). The file can be found in rmarkdown/templates/ and search for the rticles folder you are using (in my case: ieee_article). In the resources sub-folder you will find the target template.tex. Make a copy of it, for recovery purposes.
Open the template.tex and insert the following anywhere before the LATEX command line \begin{document} (note: aka the preamble of that template.tex file). For example, I inserted it just before the \begin{document} line:
% code to insert to fix environment Shaded undefined issue with
% showing code chunks in rticle IEEE template.
$if(highlighting-macros)$
$highlighting-macros$
$endif$
\begin{document}
Save the change and go back to R/RStudio and your IEEE paper R Markdown file and hit the knit button. R code chunks will now be displayed (if you want to).
I have not tested it thoroughly, but this recipe should work for all rticle templates missing an environment definition for showing r-code chunks (i.e. environment{Shaded})
Rather than duplicating the template, you can put the required code for allowing the highlighting in a separate header.tex file. This is essentially what replaces $highlighting-macros$ when you include this in the template:
header.tex
\usepackage{color}
\usepackage{fancyvrb}
\newcommand{\VerbBar}{|}
\newcommand{\VERB}{\Verb[commandchars=\\\{\}]}
\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}}
% Add ',fontsize=\small' for more characters per line
\usepackage{framed}
\definecolor{shadecolor}{RGB}{248,248,248}
\newenvironment{Shaded}{\begin{snugshade}}{\end{snugshade}}
\newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.13,0.29,0.53}{\textbf{#1}}}
\newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.13,0.29,0.53}{#1}}
\newcommand{\DecValTok}[1]{\textcolor[rgb]{0.00,0.00,0.81}{#1}}
\newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.00,0.00,0.81}{#1}}
\newcommand{\FloatTok}[1]{\textcolor[rgb]{0.00,0.00,0.81}{#1}}
\newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
\newcommand{\CharTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
\newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
\newcommand{\StringTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
\newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
\newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.31,0.60,0.02}{#1}}
\newcommand{\ImportTok}[1]{#1}
\newcommand{\CommentTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textit{#1}}}
\newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\OtherTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{#1}}
\newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
\newcommand{\VariableTok}[1]{\textcolor[rgb]{0.00,0.00,0.00}{#1}}
\newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.13,0.29,0.53}{\textbf{#1}}}
\newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.81,0.36,0.00}{\textbf{#1}}}
\newcommand{\BuiltInTok}[1]{#1}
\newcommand{\ExtensionTok}[1]{#1}
\newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textit{#1}}}
\newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.77,0.63,0.00}{#1}}
\newcommand{\RegionMarkerTok}[1]{#1}
\newcommand{\InformationTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\WarningTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textbf{\textit{#1}}}}
\newcommand{\AlertTok}[1]{\textcolor[rgb]{0.94,0.16,0.16}{#1}}
\newcommand{\ErrorTok}[1]{\textcolor[rgb]{0.64,0.00,0.00}{\textbf{#1}}}
\newcommand{\NormalTok}[1]{#1}
Make a copy of this file in your directory and then refer to this header in the YAML:
---
title: Short Paper
output:
rticles::ieee_article:
includes:
in_header: header.tex
---
# Introduction
This is the introduction. And here comes a cool code chunk.
```{r}
x <- seq(-3,3,0.1)
y <- x^3
plot(x,y)
```
This approach should work for any template which includes the $header-includes$ tag in thetemplate.tex`
I am writing a paper in R markdown and need to format it with this .cls file supplied by an academic journal.
A minimal .tex file compiles perfectly well with the above cls file.
My .tex file (compiled on ShareLaTeX with clv3.cls saved in same directory):
\documentclass[shortpaper]{clv3}
\usepackage[utf8]{inputenc}
\title{Paper title}
\author{Name Surname}
\date{May 2018}
\begin{document}
\maketitle
\section{Introduction}
Some text.
\end{document}
However a comparable minimal document in R markdown, using the same cls file, fails to compile in Rstudio, with the following error: ! Package geometry Error: \paperwidth (0.0pt) too short.
My Rmd file (with clv3.cls file saved in same directory):
---
title: "Paper title"
author: "Name Surname"
documentclass: clv3
classoption: shortpaper
output: pdf_document
---
# Introduction
Some text.
Why is this error induced when I try to use this class file with an R markdown document and how may I fix it?
I've tried manually specifying a pagewidth setting in the YAML header, but I don't really know what I'm doing. This seems undesirable anyway, since the normal LaTeX document works fine without it (and surely page width is something that should be specified by a journal, not manually overwritten by an author).
I do not know where exactly the clv3.cls class and the default pandoc template clash. However, that template does so many things that do not make sense when writing with a specific style, that is best to use your own template. Using clv3-template.tex
\documentclass[shortpaper]{clv3}
\usepackage[utf8]{inputenc}
$if(title)$
\title{$title$}
$else$
\title{}
$endif$
$if(author)$
\author{$for(author)$$author$$sep$ \\ $endfor$}
$else$
\author{}
$endif$
\begin{document}
$if(title)$
\maketitle
$endif$
$body$
\end{document}
together with
---
title: "Paper title"
author: "Name Surname"
output:
pdf_document:
template:
clv3-template.tex
---
# Introduction
Some text.
should be a good starting point.
The accepted answer works perfectly for the minimal example presented. However it breaks again pretty quickly as the document is made more complex (for example, inserting a bibliography and in-text citations). I'd like to expand a little on my solution for the potential benefit of any future readers, as I found it a bit of steep learning curve:
The issue here is that Pandoc has a LaTeX template, which it uses to produce PDF documents. This is separate from a .cls class file, which defines a document class. Like Ralf Stubner says, something about my particular class file was not cooperating with Pandoc's default template. This is probably super basic and obvious to many, but I had not appreciated this extra step nor understood the distinction between these files.
If one does not wish to deal with raw LaTeX, it seems there are quite a few templates out there for various kinds of documents (see, for example, the rticle package). Using R Markdown to produce a PDF document in a particular custom format (such as for a particular journal) will require construction of a LaTeX template, however. This can be done by either of two ways:
Tinkering with an existing template until you get what you need, either by finding Pandoc's default template and starting from there (see comment by user2554330 for location) or by cloning someone else's template on Github etc.
Writing a template from scratch. In this case, Ralf Stubner's minimal example above plus this section of the Pandoc manual will be informative.
In my case, I went with the latter option. I have saved my eventual template as an R package which can be installed using devtools::install_github("JaydenM-C/CLtemplate"). So if anyone else would ever like to author a document for Computational Linguistics using this particular document style, this may save you some time.
I have a few Rmd documents that all have the same YAML frontmatter except for the title. How can I keep this frontmatter in one file and have it used for all the documents? It is getting rather large and I don't want to keep every file in step every time I tweak the frontmatter.
I want to still
use the Knit button/Ctrl+Shift+K shortcut in RStudio to do the compile
keep the whole setup portable: would like to avoid writing a custom output format or overriding rstudio.markdownToHTML (as this would require me to carry around a .Rprofile too)
Example
common.yaml:
author: me
date: "`r format (Sys.time(), format='%Y-%m-%d %H:%M:%S %z')`"
link-citations: true
reference-section-title: References
# many other options
an example document
----
title: On the Culinary Preferences of Anthropomorphic Cats
----
I do not like green eggs and ham. I do not like them, Sam I Am!
Desired output:
The compiled example document (ie either HTML or PDF), which has been compiled with the metadata in common.yaml injected in. The R code in the YAML (in this case, the date) would be compiled as a bonus, but it is not necessary (I only use it for the date which I don't really need).
Options/Solutions?
I haven't quite got any of these working yet.
With rmarkdown one can create a _output.yaml to put common YAML metadata, but this will put all of that metadata under output: in the YAML so is only good for options under html_document: and pdf_document:, and not for things like author, date, ...
write a knitr chunk to import the YAML, e.g.
----
title: On the Culinary Preferences of Anthropomorphic Cats
```{r echo=F, results='asis'}
cat(readLines('common.yaml'), sep='\n')
```
----
I do not like green eggs and ham. I do not like them, Sam I Am!
This works if I knitr('input.Rmd') and then pandoc the output, but not if I use the Knit button from Rstudio (which I assume calls render), because this parses the metadata first before running knitr, and the metadata is malformed until knitr has been run.
Makefile: if I was clever enough I could write a Makefile or something to inject common.yaml into input.Rmd, then run rmarkdown::render(), and somehow hook it up to the Knit button of Rstudio, and perhaps somehow save this Rstudio configuration into the .Rproj file so that the whole thing is portable without me needing to edit .Rprofile too. But I'm not clever enough.
EDIT: I had a go at this last option and hooked up a Makefile to the Build command (Ctrl+Shift+B). However, this will build the same target every time I use it via Ctrl+Shift+B, and I want to build the target that corresponds with the Rmd file I currently have open in the editor [as for Ctrl+Shift+K].
Have found two options to do this portably (ie no .Rprofile customisation needed, minimal duplication of YAML frontmatter):
You can provide common yaml to pandoc on the command-line! d'oh!
You can set the knit: property of the metadata to your own function to have greater control over what happens when you Ctrl+Shift+K.
Option 1: common YAML to command line.
Put all the common YAML in its own file
common.yaml:
---
author: me
date: "`r format (Sys.time(), format='%Y-%m-%d %H:%M:%S %z')`"
link-citations: true
reference-section-title: References
---
Note it's complete, ie the --- are needed.
Then in the document you can specify the YAML as the last argument to pandoc, and it'll apply the YAML (see this github issue)
in example.rmd:
---
title: On the Culinary Preferences of Anthropomorphic Cats
output:
html_document:
pandoc_args: './common.yaml'
---
I do not like green eggs and ham. I do not like them, Sam I Am!
You could even put the html_document: stuff in an _output.yaml since rmarkdown will take that and place it under output: for all the documents in that folder. In this way there can be no duplication of YAML between all documents using this frontmatter.
Pros:
no duplication of YAML frontmatter.
very clean
Cons:
the common YAML is not passed through knit, so the date field above will not be parsed. You will get the literal string "r format(Sys.time(), format='%Y-%m-%d %H:%M:%S %z')" as your date.
from the same github issue:
Metadata definitions seen first are kept and left unchanged, even if conflicting data is parsed at a later point.
Perhaps this could be a problem at some point depending on your setup.
Option 2: override the knit command
This allows for much greater control, though is a bit more cumbersome/tricky.
This link and this one mention an undocumented feature in rmarkdown: the knit: part of the YAML will be executed when one clicks the "Knit" button of Rstudio.
In short:
define a function myknit(inputFile, encoding) that would read the YAML, put it in to the RMD and call render on the result. Saved in its own file myknit.r.
in the YAML of example.rmd, add
knit: (function (...) { source('myknit.r'); myknit(...) })
It seems to have to be on one line. The reason for source('myknit.r') instead of just putting the function definition int he YAML is for portability. If I modify myknit.r I don't have to modify every document's YAML. This way, the only common YAML that all documents must repeat in their frontmatter is the knit line; all other common YAML can stay in common.yaml.
Then Ctrl+Shift+K works as I would hope from within Rstudio.
Further notes:
myknit could just be a system call to make if I had a makefile setup.
the injected YAML will be passed through rmarkdown and hence knitted, since it is injected before the call to render.
Preview window: so long as myknit produces a (single) message Output created: path/to/file.html, then the file will be shown in the preview window.
I have found that there can be only one such message in the output [not multiple], or you get no preview window. So if you use render (which makes an "Output created: basename.extension") message and the final produced file is actually elsewhere, you will need to suppress this message via either render(..., quiet=T) or suppressMessages(render(...)) (the former suppresses knitr progress and pandoc output too), and create your own message with the correct path.
Pros:
the YAML frontmatter is knitted
much more control than option 1 if you need to do custom pre- / post-processing.
Cons:
a bit more effort than option 1
the knit: line must be duplicated in each document (though by source('./myknit.r') at least the function definition may be stored in one central location)
Here is the setup for posterity. For portability, you only need to carry around myknit.r and common.yaml. No .Rprofile or project-specific config needed.
example.rmd:
---
title: On the Culinary Preferences of Anthropomorphic Cats
knit: (function (...) { source('myknit.r'); myknit(...) })
---
I do not like green eggs and ham. I do not like them, Sam I Am!
common.yaml [for example]:
author: me
date: "`r format (Sys.time(), format='%Y-%m-%d %H:%M:%S %z')`"
link-citations: true
reference-section-title: References
myknit.r:
myknit <- function (inputFile, encoding, yaml='common.yaml') {
# read in the YAML + src file
yaml <- readLines(yaml)
rmd <- readLines(inputFile)
# insert the YAML in after the first ---
# I'm assuming all my RMDs have properly-formed YAML and that the first
# occurence of --- starts the YAML. You could do proper validation if you wanted.
yamlHeader <- grep('^---$', rmd)[1]
# put the yaml in
rmd <- append(rmd, yaml, after=yamlHeader)
# write out to a temp file
ofile <- file.path(tempdir(), basename(inputFile))
writeLines(rmd, ofile)
# render with rmarkdown.
message(ofile)
ofile <- rmarkdown::render(ofile, encoding=encoding, envir=new.env())
# copy back to the current directory.
file.copy(ofile, file.path(dirname(inputFile), basename(ofile)), overwrite=T)
}
Pressing Ctrl+Shift+K/Knit from the editor of example.rmd will compile the result and show a preview. I know it is using common.yaml, because the result includes the date and author whereas example.rmd on its own does not have a date or author.
The first solution proposed by #mathematical.coffee is a good approach, but the example it gave did not work for me (maybe because the syntax had changed). As said so, this is possible by providing pandoc arguments in the YAML header. For example,
It's the content of a header.yaml file:
title: "Crime and Punishment"
author: "Fyodor Dostoevsky"
Add this to the beginning of the RMarkdown file:
---
output:
html_document:
pandoc_args: ["--metadata-file=header.yaml"]
---
See the pandoc manual for the --metadata-file argument.