Add a CSS class to single code chunks in RMarkdown - css

Is it possible to add a CSS class to a certain code chunk?
Assume the following file:
---
title: "Untitled"
output: html_document
---
```{r cars}
summary(cars)
```
I want to give the chunk labeled 'cars' a certain CSS class, e.g. .myClass.
Is there any possibility like
```{r cars} {.myClass}
summary(cars)
```
or so? I am aware of hacks like wrapping the whole chunk in another <div>. I am interested in a straight forward solution.

Edit: this feature was introduced in knitr v.1.16 (05/18/17)
class.source and class.output options apply additional HTML classes to source and output chunks (see knitr documentation).
To add myClass to source chunk:
```{r cars, class.source='myClass'}
summary(cars)
```
Previous answer that inspired the class.source options (see here)
You can add a class using the fenced_code_attributes pandoc's extension (which is intended to add attributes to the <pre> tag, see here) and a knitr output hook.
The following example works fine:
---
title: "Untitled"
output:
html_document:
md_extensions: +fenced_code_attributes
---
```{r, include=FALSE}
knitr::knit_hooks$set(source = function(x, options) {
return(paste0(
"```{.r",
ifelse(is.null(options$class),
"",
paste0(" .", gsub(" ", " .", options$class))
),
"}\n",
x,
"\n```"
))
})
```
```{r cars, class="myClass1 myClass2"}
summary(cars)
```
After knitting this .Rmd file, the HTML document looks like this:
<pre class="r myClass1 myClass2">
<code>
summary(cars)
</code>
</pre>
The fenced_code_attributes extension is enabled by default: in standard cases, you don't need to include the line md_extensions: +fenced_code_attributes in your YAML header.
I don't know if there's more straightforward solution using knitr.

Related

Undesired PDF format from particular R Markdown YAML configuration

In R Studio, my R Markdown document begins like this:
---
title: 'ST 412: Homework 3'
author: "Camden White"
documentclass: amsart
geometry: margin=1in
output: pdf_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## 1. Read Data Set and Define Variables
```{r, message=FALSE, warning=FALSE}
library(tidyverse)
library(magrittr)
```
When I do not include documentclass: amsart, everything works fine, but when I do include it, the library section is placed before the ## 1. Read Data Set and Define Variables header.
When there is text between the two components, the order is the same order in the code, but without it, the library section comes first. This does not happen with the default article document class, and I do not know why this occurs. How can I use the amsart document class and fix this ordering issue?
The problem seems to be that a subsection in amsart is basically what a paragraph is in normal classes: an unnumbered bold piece of text without an new paragraph after it. The text will just continue in the same line. As the grey box with the source code spans a whole line, it can't be placed there and shows up above. You can reproduce this with normal article class like this:
\documentclass{article}
\usepackage{framed}
\begin{document}
\paragraph{1. Read Data Set and Define}
\begin{framed}
test
\end{framed}
\end{document}
You can avoid the problem by making sure the source code isn't the first text in the subsection, e.g. by adding something invisible:
---
title: 'ST 412: Homework 3'
author: "Camden White"
documentclass: amsart
geometry: margin=1in
output: pdf_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## 1. Read Data Set and Define Variables
\mbox{}
```{r, message=FALSE, warning=FALSE}
library(tidyverse)
library(magrittr)
```

How to create R markdown with empty code chunk?

How can I add an empty code chunk in R markdown? I have found several options to manipulate the html to give more white space. But I would like to present some empty lines in the well known gray code box in order to indicate space for assigments.
---
title: "Untitled"
author: "Author"
output: html_document
---
## R Markdown
```{r cars}
summary(cars)
```
## Homework
Please calculate the mean of the `speed` variable in `cars`.
```{r}
```
A hacky way... almost there:
```{r, code="'\n\n\n\n'", results=F}
```
A possible solution using results = 'asis' and relying on chunck HTML class:
```{r, results='asis', echo=F}
cat(
'<pre class="r">
<code class = "hlsj"> <span class="hljs-string"> <br> <br> </span> </code>
</pre>
')
```
Just add <br> to increase the number of lines.
There does not seem to be a way to get knitr to recognise a completely empty chunk as a chunk. It will always omit it, regardless of the chunk options.
You have to insert something to get it to render, for example a comment. So you can put the empty lines between two comments:
---
output: html_document
---
## Homework
Please calculate the mean of the `speed` variable in `cars`.
```{r}
# Insert code here
# End
```
Or with the strip.white=FALSE chunk option we can use a single comment line, but strangely this only works for leading, not trailing, whitespace:
---
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(strip.white = FALSE)
```
## Homework
Please calculate the mean of the `speed` variable in `cars`.
```{r}
# Insert code above
```

LaTeX {itemize} in R Markdown

How do I include the following LaTeX {itemize} in my R Markdown? It simply doesn't work when I try and knitr the HTML.
---
title: "Untitled"
author: "March 2019"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
\[x = R + E\]
where:
\begin{itemize}
\item[R=] is Racoon
\item[E=] is Elephant
\end{itemize}
Just use either + or - at the beginning of sentences which you wish to itemize, it works for both html and pdf output of Rmarkdown
eg
use the statement in between '$' symbol
$+ this statement will be itemized in rmd$
R Markdown doesn't use LaTeX when producing HTML. The code you used would work if output was to pdf_document, but not to html_document.
If you really want the labelled list in HTML, you're going to have to insert HTML code, not LaTeX code. I don't know if there's anything visually equivalent to LaTeX's \item[R=], but you could do this, which is logically equivalent:
---
title: "Untitled"
author: "March 2019"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
\[x = R + E\]
where:
<dl>
<dt>R=</dt>
<dd>is Racoon</dd>
<dt>E=</dt>
<dd>is Elephant</dd>
</dl>
This displays as
Perhaps CSS could be crafted to make it visually equivalent.
Edited to add: And of course it is possible, and has been done. It's easy to follow https://stackoverflow.com/a/13371522/2554330, since R Markdown uses the Bootstrap framework. Just add a class to the first tag:
<dl class="dl-horizontal">
<dt>R=</dt>
<dd>is Racoon</dd>
<dt>E=</dt>
<dd>is Elephant</dd>
</dl>
and it produces
If the styling is still not satisfactory, look at some of the other discussion related to https://stackoverflow.com/a/13371522/2554330.

Code in Columns in RMarkdown presentation

Often when I include r code in a rmarkdown pdf presentation, I want to use the space of the whole slide and therefore want to present the code and the output side-by-side.
In pure LaTex I would go for \begin{columns}...\end{columns} and then include the code/output manually using lstlistings or some other code-highlighting library. But that proves tedious if I exceed a couple of code examples.
Now I want to use RMarkdown for the presentations and would like to achieve a similar result.
However, the following code throws an error:
## This is slide 1
\begin{columns}[t]
\begin{column}{0.5\textwidth}
```{r, eval=F}
plot(1:10)
```
\end{column}
\begin{column}{0.5\textwidth}
```{r, echo=F}
plot(1:10)
```
\end{column}
\end{columns}
Leaving out the knitr code-chunks and replacing them with text works.
I am aware that it has something to do with the pandoc engine (see here), but wanted to ask if anybody has found a way around this issue.
Well, I may should have looked with a wider focus.
Here is a solution that works for Python, but can easily be adapted to Rmarkdown: https://stackoverflow.com/a/26069751/3048453
I ended up with this code:
in header.tex
\newcommand{\columnsbegin}{\begin{columns}}
\newcommand{\columnsend}{\end{columns}}
in presentation.Rmd
---
title: "Two-column codes in RMarkdown"
author: "My Name"
date: "February 4, 2017"
output:
beamer_presentation:
includes:
in_header: header.tex
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## Testslide with Columns
\columnsbegin
\column{.5\textwidth}
```{r, eval=F}
plot(mtcars[, 1:3])
```
\column{.5\textwidth}
```{r, echo=F}
plot(mtcars[, 1:3])
```
\columnsend
Which results in this

Conditionally display block of markdown text using knitr

I would like to edit a single rmarkdown (Rmd) document with a list of "problems", each followed by its solution. Each solution may contain the results of the R console, but also some explaining (markdown and LaTeX formatted) text. Besides, I would like use knitr in 2 versions: with and without the solutions, changing the source as less as possible, and compiling.
I know that I can use a logical variable in order to conditionally evaluate R code and show plots and R output, but I don't know how to show/hide blocks of (markdown and LaTeX) formatted text, unless I put all that text into R character vectors, which seems hard for keeping things clean and readable.
I found this old question,
Conditionally display a block of text in R Markdown
where the solution was given for simple short text, which was included as an argument of the R print() function.
This other old question,
insert portions of a markdown document inside another markdown document using knitr
was for having a father document and child documents which were conditionally compiled, but I don't want to slice my document into so many pieces.
You could use the asis engine to conditionally include/exclude arbitrary text in knitr, e.g.
```{asis, echo=FALSE}
Some arbitrary text.
1. item
2. item
Change echo=TRUE or FALSE to display/hide this chunk.
```
But I just discovered a bug in this engine and fixed it. Unless you use knitr >= 1.11.6, you can create a simple asis engine by yourself, e.g.
```{r setup, include=FALSE}
library(knitr)
knit_engines$set(asis = function(options) {
if (options$echo && options$eval) paste(options$code, collapse = '\n')
})
```
If you want to include inline R expressions in the text, you will have to knit the text, e.g.
```{r setup, include=FALSE}
library(knitr)
knit_engines$set(asis = function(options) {
if (options$echo && options$eval) knit_child(text = options$code)
})
```
There is a way to hide parts of the document (including text and chunks): to comment them out with html comment marks.
And comment marks can be generated by R in a block according to a variable that can be set at the beginning of the document.
```{r results='asis', echo=FALSE}
if (hide) {cat("<!---")}
```
```{r results='asis', echo=FALSE}
if (hide) {cat("-->")}
```
And just to show a complete working example, in the example below the middle section of the document can be shown or hidden by setting the hide variable to FALSE or TRUE. That might be useful in case there are several sections to hide or show at once - for example, solutions of course problems.
---
title: "Untitled"
date: "15/10/2020"
output:
word_document: default
html_document: default
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
hide <- TRUE #TRUE to comment out part of the document, FALSE to show.
```
## Start
Always shown.
```{r}
hide
```
```{r results='asis', echo=FALSE}
if (hide) {cat("<!---")}
```
## To hide or not to hide
To be hidden or shown according to *hide* variable.
```{r}
"Also to be hidden according to 'hide' variable"
hist(rnorm(10))
```
```{r results='asis', echo=FALSE}
if (hide) {cat("-->")}
```
<!--
Never shown.
-->
## End
Always shown.
Just a caveat: in html output the hidden parts are kept as comments and can be seen just by viewing the source. On the other hand, PDF (LaTex) and Word outputs ignore html comments and the hidden parts aren't included in the knitted documents.
Therefore, when the hidden parts are supposed to be somehow confidential (e.g. exam solutions) PDF or Word output should be used instead of html.
For those looking for a solution when knitting to pdf through LaTex, the answer from #Pere won't work for you (because LaTex doesn't understand the <!--- --> pair as indicating a comment).
Below is one possible workaround:
---
output:
pdf_document
---
\newcommand{\ignore}[1]{}
```{r echo=FALSE}
include <- TRUE
```
```{r results='asis', echo=FALSE}
if(!include){cat("\\ignore{")}
```
Included bla bla
```{r results='asis', echo=FALSE}
if(!include){cat("}")}
```
```{r echo=FALSE}
include <- FALSE
```
```{r results='asis', echo=FALSE}
if(!include){cat("\\ignore{")}
```
NOT Included bla bla
```{r results='asis', echo=FALSE}
if(!include){cat("}")}
```

Resources