In recent years, it has been possible to add numbering to the figure captions on R chunks in html_document2, as outlined in Yihui Xie's online text for bookdown. However, it has been more difficult to preserve this numbering while also having custom figures output from these chunks. For example, trying to create the custom figures using CSS flexbox from Carson Sievert's online text.
There are several other threads that discuss numbering HTML Rmd figures and using hooks or CSS counters to add custom numbering. However, I could not find a solution that allowed for a custom figure as well as html_document2 numbering to be preserved.
In the example below, I want a side-by-side plotly graphic to be reactive to screen size but also have the same figure caption and numbering.
---
output:
bookdown::html_document2:
self-contained: TRUE
---
```{css, echo=FALSE}
#dualpanel {
width: 50%
}
#media screen and (max-width: 500px) {
#dualpanel {
width: 100%
}}
```
```{r chunk1, echo=FALSE, htmlcap='FIRST FIGURE CAP'}
temp <- plotly::plot_ly(mtcars, x = ~cyl, y=~mpg)
shiny::div(class = 'figure',
style = "display: flex; flex-wrap: wrap; justify-content: center",
shiny::div(temp, id = 'dualpanel'),
shiny::div(temp, id = 'dualpanel'))
```
```{r chunk2, echo=FALSE, fig.cap='SECOND FIGURE CAP'}
plot(mtcars$cyl, mtcars$mpg)
```
This creates an output like this:
In order to address this issue, it is important to know that knitr uses #fig:label in pandoc in order to create the automated numbering in the output. You can see this when you examine the markdown temporary output from the knitr process:
<div class="figure">
<img src="web_tiles_v2_files/figure-html/otherchunk-1.png" alt="SECOND FIGURE CAP" />
<p class="caption">(\#fig:SPECIFICCHUNKOFINTEREST)SECOND FIGURE CAP</p>
</div>
As such, one should be able to maintain the customized figure output by adjusting the custom hook seen in other solutions. This would look like the following, just make sure you have the right chunk label included:
```{r}
knit_hooks$set(customcap= function(before, options, envir) {
if(!before) {
paste('<p class="caption"> (\\#fig:chunk1)',options$customcap,"</p>",sep="")
}
})
```
One could also use some of the internal knitr functions to automatically grab the fig.lp and label: paste('<p class="caption">', knitr:::create_label(options$fig.lp, options$label), options$customcap,"</p>", sep="")
The entire code would look like:
---
output:
bookdown::html_document2:
self-contained: TRUE
---
```{css, echo=FALSE}
#dualpanel {
width: 50%
}
#media screen and (max-width: 500px) {
#dualpanel {
width: 100%
}}
```
```{r}
knit_hooks$set(customcap= function(before, options, envir) {
if(!before) {
paste('<p class="caption"> (\\#fig:chunk1)',options$customcap,"</p>",sep="")
}
})
```
```{r chunk1, echo=FALSE, customcap='FIRST FIGURE CAP'}
temp <- plotly::plot_ly(mtcars, x = ~cyl, y=~mpg)
shiny::div(class = 'figure',
style = "display: flex; flex-wrap: wrap; justify-content: center",
shiny::div(temp, id = 'dualpanel'),
shiny::div(temp, id = 'dualpanel'))
```
```{r chunk2, echo=FALSE, fig.cap='SECOND FIGURE CAP'}
plot(mtcars$cyl, mtcars$mpg)
```
This produces an output that has the dynamic elements and maintains labeling.
Related
I am playing around with Quarto and really like it. One feature is to change the color of inline text with the following below syntax (the word chemical will show up in red color)
[chemical]{style="color: red"}
My question is how to change the color of the text if we assign a color to name rather than the color code or built in color code? The below will not work
var="#28A569"
[chemical]{style="color: var"}
Not sure whether Quarto offers a more straightforward approach. But one option would be to use some inline code or following the R Markdown Cookbook use a small custom function.
---
title: "Untitled"
format: html
---
[chemical]{style="color: #28A569"}
```{r, echo=FALSE}
var <- "#28A569"
```
`r sprintf('[chemical]{style="color: %s"}', var)`
```{r}
colorize <- function(x, color) {
sprintf('[%s]{style="color: %s"}', x, color)
}
```
`r colorize("chemical", var)`
An easy option would be to do this using CSS variable.
---
title: CSS variable in Inline Style
format: html
engine: knitr
---
```{css, echo=FALSE}
:root {
--color1: #28A569;
--color2: yellow;
}
```
[chemical]{style="color: var(--color1);"}
[This has colored background]{style="background-color: var(--color1);"}
[This has yellow background]{style="background-color: var(--color2);"}
This is my Rmarkdown code:
---
title: "Tutorial"
output:learnr::tutorial:
code_folding: hide
runtime: shiny_prerendered
---
```{r setup}
library(learnr)
knitr::opts_chunk$set(echo = FALSE)
```
## Topic 1
### Exercise
*Here's a simple exercise with an empty code chunk provided for entering the answer.*
Write the R code required to add two plus two:
```{r two-plus-two, exercise=TRUE}
library(tidyverse)
mtcars %>% select(cyl, mpg)
```
### Exercise with Code
*Here's an exercise with some prepopulated code as well as `exercise.lines = 5` to provide a bit more initial room to work.*
Now write a function that adds any two numbers and then call it:
```{r add-function, exercise=TRUE, exercise.lines = 5}
add <- function() {
}
```
I already tried all the identation options , but its not working. Any help?
As seems, code-folding option doesn't work for output "learnr".
For html_doc - yes. F.e.:
output:
html_document:
code_folding: hide
But you can try next solution with details:
CSS:
<style>
details {
border: 1px solid;
border-radius: 10px;
padding: .1em .5em 0;
text-align: right;
}
</style>
Using:
<details>
<summary>Show/hide code</summary>
```{r two-plus-two, exercise=TRUE}
library(tidyverse)
mtcars %>% select(cyl, mpg)
```
</details>
Output:
P.S. If you need a support to IE/Edge - look there
I have an RMarkdown document outputting to HTML of the same form as the below example. What do I add where to apply unique CSS ids or classes to each plot output?
---
title: "RMarkdown"
author: "Me"
date: "Friday, March 27, 2015"
output:
html_document:
theme: null
css: style.css
---
```{r plot1, echo=FALSE, warning=FALSE, message=FALSE}
library(ggplot2)
x <- ggplot(some_r_code)
print(x)
```
```{r plot2, echo=FALSE, warning=FALSE, message=FALSE}
y <- ggplot(some_more_r_code)
print(y)
```
I've read the info page at http://rmarkdown.rstudio.com/html_document_format.html that went a ways to answering this question but didn't get me there. I have a similar question referencing the material in that page in it's comment section, and would appreciate an answer on either.
Thanks!
You can tell knitr (which is used under the hood) with results="asis" to embed a chunk's output directly into the html. Within the chunk you can use cat to simply write a style tag including your css definitions:
```{r results="asis"}
cat("
<style>
h1 {
color: red;
}
</style>
")
```
See http://yihui.name/knitr/options/#chunk_options for details.
Declaring custom css in RMarkdown
Add css between <style> and </style> tags in the regular body of the RMarkdown (i.e. not in R code area), like so:
<style>
.pad {
padding-top: 200px;
}
</style>
# This heading will be padded {.pad}
Another option is to declare css: "style.css" in yaml and store styles in a separate file (style sheet) in the same directory
Or css can be generated and applied via R code (excellent example here)
Open the resultant HTML in a browser with a Developer Tools option and look at the generated HTML. Then apply you styling to the appropriate tags/classes. For example, put the following into style.css, knit the file and you should see a red border on the plots:
img {
background-color: red;
padding: 2px;
border: 1px solid red;
border-radius: 3px;
margin: 0 5px;
max-width: 100%;
}
I am trying to figure out how to use xtable when creating html pages with knitr.
My main reason to work with xtable is because I want to be able to rotate column names and/or rownames.
This is my .rmd document:
---
output: html_document
---
```{r, echo=FALSE}
library(xtable)
data(tli)
tli.table <- xtable(tli[1:10,])
align(tli.table) <- "|r|r|lp{3cm}l|r|"
tt1 <- print(tli.table, rotate.rownames=TRUE,
rotate.colnames=TRUE, type = "html")
```
```{r, echo=FALSE, results = 'asis'}
tt1
```
When I knit this document to html with knit2html, the row and column names are messed up and the html code is echoed as well. What am I doing wrong? (or is there a better way to construct nicely laid out html tables through knitr?)
Peter,
I am also frustrated with the odd behaviour of xtable when recreating tables that used to work before but not in the new R Markdow v2 using pandoc for the conversion to html.
The most I could do with your table was make it render pretty but no local column alignment or column header rotation. To do this put all the code in one r chunk with the option results='asis'.
This worked for me using RStudio 0.98.1103, R version 3.1.3 (2015-03-09), Platform: x86_64-pc-linux-gnu (64-bit), Running under: Ubuntu precise (12.04.5 LTS), knitr_1.9, rmarkdown_0.5.1, and xtable_1.7-4:
Since you mention using knit2html (not available for R 3.1.3) please try my code in your installation and see if it still works.
If so this might be a reason not to get latest versions just yet.
Using Knitr's Kable the headings appear consistent with the default alignment of right-justified for numeric columns and left-justified otherwise. Xtable's headings appear always to be centred and I can't find the option for changing this behaviour.
---
output:
html_document:
self_contained: false
theme: flatly
keep_md: true
---
<style type="text/css">
table { max-width: 200%;
border: 1px solid #ccc; }
th { background-color: #000000;
color: #ffffff;
width: 2.5cm; }
td { background-color: #dcdcdc }
</style>
```{r, echo=FALSE, results = 'asis'}
library(xtable)
data(tli)
tli.table <- xtable(tli[1:10,])
align(tli.table) <- "|r|r|lp{3cm}l|r|"
print(tli.table,
rotate.rownames=F,
rotate.colnames=F,
type="html",
include.rownames = F)
```
```{r via kable, echo=FALSE, results='markup'}
require(knitr)
kable(tli.table, format = "html",
padding = 0,
row.names=F,
caption = "Via kable")
```
In knitr, the size option works fine in a .Rnw file, the following code generates:
\documentclass{article}
\begin{document}
<<chunk1, size="huge">>=
summary(mtcars)
#
\end{document}
However, I can't get it to work in Rmarkdown. The following code does not change the font size, as it did in .rnw file. The same thing happens when trying to set options with opts_chunk$set(size="huge").
Is this the expected behavior? How does one change the chunk code font size? (I mean using knitr options, not by adding \huge before the code)
---
title: "Untitled"
output: pdf_document
---
```{r, size="huge"}
summary(mtcars)
```
I am using RStudio Version 0.98.987, knitr 1.6 and rmarkdown 0.2.68.
Picking up the idea to alter a knitr hook we can do the following:
def.chunk.hook <- knitr::knit_hooks$get("chunk")
knitr::knit_hooks$set(chunk = function(x, options) {
x <- def.chunk.hook(x, options)
ifelse(options$size != "normalsize", paste0("\n \\", options$size,"\n\n", x, "\n\n \\normalsize"), x)
})
This snippet modifies the default chunk hook. It simply checks if the chunk option size is not equal to its default (normalsize) and if so, prepends the value of options$size to the output of the code chunk (including the source!) and appends \\normalsize in order to switch back.
So if you would add size="tiny" to a chunk, then all the output generated by this chunk will be printed that way.
All you have to do is to include this snippet at the beginning of your document.
\tiny
```{r}
summary(mtcars)
```
\normalsize
available options for size in descending order are:
Huge > huge > LARGE > Large > large > normalsize > small > footnotesize > scriptsize > tiny
Per this Gist, you have to define the font size using css:
<style type="text/css">
body, td {
font-size: 14px;
}
code.r{
font-size: 20px;
}
pre {
font-size: 20px
}
</style>
code.r will control the font size for R code echoed from the code chunk, while pre will apply to any R results output from the code.
A complete working .Rmd file might look like:
---
title: "FontTest"
author: "Thomas Hopper"
date: "January 13,2016"
output: html_document
---
<style type="text/css">
body, td {
font-size: 14px;
}
code.r{
font-size: 20px;
}
pre {
font-size: 20px
}
</style>
```{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)
```
The resulting html renders as:
You can define you own document format by exporting something based on the following function from your package my_package:
my_report <- function(...) {
fmt <- rmarkdown::pdf_document(...)
fmt$knitr$knit_hooks$size = function(before, options, envir) {
if (before) return(paste0("\n \\", options$size, "\n\n"))
else return("\n\n \\normalsize \n")
}
return(fmt)
}
This will define a knitr chunk hook size that will put the appropriate latex command before the chunk, and \normalsize after the chunk.
Anyway, with the following R markdown you can check if it's working:
---
output: my_package::my_report
---
Test text for comparison
```{r}
print(1)
```
The next code chunk has `size = 'tiny'` in the chunk options.
```{r, size = 'tiny'}
print(1)
```
I get the following result from `markdown::render():
See also the issue I opened on github:
https://github.com/yihui/knitr/issues/1296
Following up on #Martin Schmelzer's output, here's a solution in the case you want to change the code and output default font size for the whole document, but not the size of the text.
def.chunk.hook <- knitr::knit_hooks$get("chunk")
knitr::knit_hooks$set(chunk = function(x, options) {
x <- def.chunk.hook(x, options)
paste0("\n \\", "size_of_the_code_and_output","\n\n", x, "\n\n \\size_of_the_text")
})
For instance,
---
output: pdf_document
---
```{r setup, include=FALSE}
def.chunk.hook <- knitr::knit_hooks$get("chunk")
knitr::knit_hooks$set(chunk = function(x, options) {
x <- def.chunk.hook(x, options)
paste0("\n \\", "footnotesize","\n\n", x, "\n\n \\Huge")
})
```
# Section 1
```{r}
summary(cars)
```
Text.
# Section 2
```{r}
print(1)
```
This works for every chunks.
gives this: