Remove colon in figure caption using pandoc and bookdown in R Markdown - r

I am changing the font of a figure caption in my R Markdown and am using bookdown and pandoc to do so. My question is closely related to: How to change the figure caption format in bookdown?. I was able to get correct figure numbering and was able to alter the format of the "Figure 1" portion of the caption. However, I cannot figure out how to remove the colon in the output (i.e., "Figure 1:. ").
Minimal Example
Pandoc Function (taken from here)
function Image (img)
img.caption[1] = pandoc.Strong(img.caption[1])
img.caption[3] = pandoc.Strong(img.caption[3])
img.caption[4] = pandoc.Strong(". ")
return img
end
To use function Image in the R Markdown, save the file as "figure_caption_patch.lua", which will be called in pandoc_args in the YAML metadata.
R Markdown
---
title: Hello World
author: "Somebody"
output:
bookdown::word_document2:
fig_caption: yes
number_sections: FALSE
pandoc_args: ["--lua-filter", "figure_caption_patch.lua"]
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
# Test
Some text (Figure \#ref(fig:Xray)). Some text followed by a figure:
```{r Xray, fig.cap="Single-crystal X-ray structure of some text", echo=FALSE}
plot(cars)
```
Output
Figure 1:. This is a caption.
Desired Output
Figure 1. This is a caption.
In the pandoc function, I tried to subset the string of img.caption[3], but it did not work. I tried the following:
img.caption[3] = pandoc.Strong(string.sub(img.caption[3], 1, 1))
I know that if I was using R, then I could do something like:
a = c("words", "again")
substring(a, 1, 1)[1]
#output
[1] "w"
But unsure, how to do this with pandoc.

Looks like there was a change in rmarkdown which adds a colon by default. Also the reason why the answer in the linked post does not work anymore. For more on this and a solution see https://community.rstudio.com/t/how-to-change-the-figure-table-caption-style-in-bookdown/110397.
Besides the solution offered there you could achieve your desired result by replacing the colon by a dot. Adapting the lua filter provided by https://stackoverflow.com/a/59301855/12993861 this could done like so:
function Image (img)
img.caption[1] = pandoc.Strong(img.caption[1])
img.caption[3] = pandoc.Strong(pandoc.Str(string.gsub(img.caption[3].text, ":", ".")))
return img
end

Related

How to combine endfloat, markdown formatting and wordwrap in bookdown::pdf_document2 table

I am writing a Rmarkdown document using bookdown::pdf_document2 for which I have a table that needs to do several very specific things, but I simply cannot find the solution to get all of them to work at the same time:
The table needs to float to the end of the document as it would with the latex endfloat package.
The table elements have Markdown bold and italics formatting that should appear correctly in the final PDF document
One of the columns of the table has a lot of text that I would like to wrap within the table cell.
I have tried to get these three options to work with all sorts of combinations of knitr::kable, kableExtra::column_spec and pander, but I cannot find a way to get them all going at once. Below I am pasting an example Rmarkdown document with various tests, none of which fully works.
Is there a simple way to get the table to do what I want? Even a good workaround would be acceptable...
Thanks,
David
---
title: "Test table formatting"
author: "David M. Kaplan"
date: "5/24/2020"
output: bookdown::pdf_document2
header-includes:
- \usepackage[tablesfirst]{endfloat}
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(tidyverse)
```
# Data
```{r}
df.long = data.frame(
char = c('*this is some very long text with lots of words that will cause problems with word wrap if it is not properly handled with something like kableExtra*','**b**','~~c~~'),
num = c(1,2,3))
```
# Kable with format=pandoc
```{r}
knitr::kable(df.long,caption="test1",format="pandoc")
```
**Result:** Handles formatting, but table does not float and no wordwrap.
# Kable with booktab
```{r}
knitr::kable(df.long,caption="test2",booktab=TRUE)
```
**Result:** Floats, but does not handle formatting or do wordwrap.
# kableExtra for wordwrap
```{r}
knitr::kable(df.long,caption="test3",booktab=TRUE) %>%
kableExtra::column_spec(1,width="30em")
```
**Result:** Table floats and has wordwrap, but does not handle formatting.
# Pander
```{r}
pander::panderOptions("table.alignment.default","left")
pander::pander(df.long,caption="test4")
```
**Result:** Wordwrap and formatting, but does not float.
I found a solution to this problem. It basically consists of:
In the YAML header, add a header-includes entry declaring longtable to be a float flavor using some LaTeX magic I found here.
Use pander to format the table to get wordwrap
Specifically, I have the following in the YAML header:
header-includes:
- \usepackage[tablesfirst]{endfloat}
- \DeclareDelayedFloatFlavour*{longtable}{table}
and then the table can be generated with pander:
pander::panderOptions("table.alignment.default","left")
pander::pander(df.long,caption="test pander",split.cell=50)

Format Code As a Code Block in R Markdown

Is there anyway to format code in the "code" format offered by many websites like Stackoverflow in R Markdown.
I want to be able to do something like the following:
Any model that takes the form income ~ education + parental_income
...
I want to emulate that greyed out text in R markdown for ease of readability when I eventually knit the document.
One can use backticks or indenting by 4 spaces to generate the equivalent of the HTML <code> </code> tag block. Here is an Rmd document illustrating this behavior.
---
title: "Sample Document"
author: "bigNumber"
date: "12/5/2017"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## R Markdown
here is some example code written in R Markdown. If we want to enter a code block we use the backtick, such as `inc ~ ed + occ`.
If we want a code block with multiple lines, indenting by 4 spaces also works
# first line of code
for(i in 1:100) {
# do something here
}
More text after the code block ends.
...and the output. Unfortunately I have to include an image to show that it renders correctly.
```
If you'd rather not
indent your code block by four spaces, you can use
triple back-ticks on separate lines.
```
https://bookdown.org/yihui/rmarkdown/markdown-syntax.html#block-level-elements
html could work if you want to have a string with gray color as a background
Changing chunk background color in RMarkdown

dis-able automatic figure numbering in knitr

I am writing a HTML document with knitr. My settings are:
---
fontsize: 12pt
output:
html_document:
fig_height: 7
fig_width: 9
keep_md: yes
smart: no
---
```{r global_options, include = FALSE}
knitr::opts_chunk$set(comment = NA)
```
I have a few code chunks that produce figures. Each of these chunks produces a single figure. I label the chunks with the understanding that, when I knit the document, the chunk labels become the file-names of the figures. For example, the chunk that I label "mtcar_histogram" should produce the file "mtcar_histogram.png".
But when I navigate to the "figure-html" sub-directory of the directory containing my document, I see that all the figures have an automatic numerical suffix. For example, I see "mtcar_histogram-1.png" instead of "mtcar_histogram.png".
When I checked the knitr options documentation, I read that:
"Note any number of plots can be recorded in a single code chunk, and this package does not need to know how many plots are in a chunk in advance -- it can figure out automatically, and name these images as fig.path-label-i where i is incremental from 1"
But as I stated earlier, none of my chunks produce multiple plots, so the numbering is un-necessary for me.
Is there a means of dis-abling the numbering?
Late answer, but might be useful. Taken from here:
https://github.com/yihui/knitr/issues/505
add this option to your setup chunk
knitr::opts_chunk$set(
fig.process = function(x) {
x2 = sub('-\\d+([.][a-z]+)$', '\\1', x)
if (file.rename(x, x2)) x2 else x
}
)
This will remove the suffix. To be used with caution.

Format text inside R code chunk

I am making some slides inside Rstudio following instructions here:
http://rmarkdown.rstudio.com/beamer_presentation_format.html
How do I define text size, colors, and "flow" following numbers into two columns?
```{r,results='asis', echo=FALSE}
rd <- sample(x=1e6:1e7, size = 10, replace = FALSE)
cat(rd, sep = "\n")
```
Output is either HTML (ioslides) or PDF (Beamer)
Update:
Currently the code above will only give something like the following
6683209
1268680
8412827
9688104
6958695
9655315
3255629
8754025
3775265
2810182
I can't do anything to change text size, color or put them into a table. The output of R codechunk is just plain text. Maybe it is possible to put them in a table indeed, as mentioned at this post:
http://tex.aspcode.net/view/635399273629833626273734/dynamically-format-labelscolumns-of-a-latex-table-generated-in-rknitrxtable
But I don't know about text size and color.
Update 2:
The idea weaving native HTML code to R output is very useful. I haven't thought of that. This however only works if I want to output HTML. For PDF output, I have to weave the native Latex code with R output. For example, the code following works using "knitr PDF" output:
```{r,results='asis', echo=FALSE}
cat("\\textcolor{blue}{")
rd <- sample(x=1e6:1e7, size = 10, replace = FALSE)
for (n in rd) {
cat(paste0(n, '\\newline \n')) }
cat("}")
```
You are using results='asis', hence, you can simply use print() and formatting markup. If you want your text to be red, simply do:
```{r,results='asis', echo=FALSE}
print("<div class='red2'>")
rd <- sample(x=1e6:1e7, size = 10, replace = FALSE)
cat(rd, sep = "\n")
print("</div>")
```
Hope it helps.
It sounds as if you want the output to be either PDF or HTML.
One possibility is the xtable package. It produces tables either in PDF or HTML format. There's no (output-independent) way to specify colour, however. Here's an example.
xt <- xtable(data.frame(a=1:10))
print(xt, type="html")
print(xt) # Latex default
Another option is the pandoc.table function from the pander package. You need the pandoc binary installed. If you have RStudio, you have this already. The function spits out some markdown which then can be converted to HTML or PDF by pandoc.
Here's how you could use this from RStudio. Create an RMarkdown document like this:
---
title: "Untitled"
author: "You"
date: "20 November 2014"
output: html_document
---
```{r, results='asis'}
library(pander)
tmp <- data.frame(a=1:10,b=1:10)
pandoc.table(tmp)
```
When you click "knit HTML", it will spit out a nice HTML document. If you change output to pdf_document, it will spit out a nice PDF. You can edit the options to change output - e.g.
pandoc.table(tmp, emphasize.strong.rows=c(2,4,6,8,10))
and this will work both in PDF or HTML. (Still no options to change colour though. Homework task: fix pandoc.table to allow arbitrary colours.)
Under the hood, knitr is writing markdown, and pandoc is converting the markdown to whatever you like.

figure captions, references using knitr and markdown to html

I'm writing an Rmd file, to be processed by knitr into HTML. It contains some R chunks that generate figures, which get stored as data URIs in HTML.
1) How do I add a caption to such an image? I'd like to have a caption that says something like "Figure 3: blah blah blah", where the "3" is automatically generated.
2) How do I later on reference this image, i.e., "as you can see in Figure 3, blah blah".
I'm late to the party, but I wanted to mention a small package I recently built to do figure captioning and cross-referencing with knitr. It is called kfigr and you can install it using devtools::install_github('mkoohafkan/kfigr'). It is still in active development but the main functionality is there. Be sure to check out the vignette, it shows some usage examples and defines some hooks for figure captions and anchors (I may later choose to have the package import knitr and define those hooks on load).
EDIT: kfigr is now available on CRAN!
You can create the figure numbers with a simple counter in R; see one example here. The problem is whether the markdown renderer will render the figure caption for you: R Markdown v1 won't, but v2 (based on Pandoc) will.
I do not know. There is no direct way to insert a label as an identifier for figures, so it is probably not possible to cross reference figures with pure Markdown. Once you've got issues like this, think (1) do I really need it? (2) if it is intended to be a document with a complicated structure, I think it is better to use LaTeX directly (Rnw documents).
Also very late to the party I changed Yihuis suggestion here that he also linked above to do referencing.
```{r functions, include=FALSE}
# A function for captioning and referencing images
fig <- local({
i <- 0
ref <- list()
list(
cap=function(refName, text) {
i <<- i + 1
ref[[refName]] <<- i
paste("Figure ", i, ": ", text, sep="")
},
ref=function(refName) {
ref[[refName]]
})
})
```
```{r cars, echo=FALSE, fig.cap=fig$cap("cars", "Here you see some interesting stuff about cars and such.")}
plot(cars)
```
What you always wanted to know about cars is shown in figure `r fig$ref("cars")`
One way to do both of these is described here: http://rmflight.github.io/posts/2012/10/papersinRmd.html
Another is described here (but I don't know if it does your #2). http://gforge.se/2014/01/fast-track-publishing-using-knitr-part-iii/
Another solution:
https://github.com/adletaw/captioner
From the README:
captioner() returns a captioner function for each set of figures, tables, etc. that you want to create. See the help files for more details.
For example:
> fig_nums <- captioner()
> fig_nums("my_pretty_figure", "my pretty figure's caption")
"Figure 1: my pretty figure's caption"
> fig_nums("my_pretty_figure", cite = TRUE)
I did both (figure numbers + references) with bookdown. I added in output section in the header of the file:
output:
bookdown::html_document2:
fig_caption : TRUE
Then I created a figure in a R code chunk like follows:
{r, my-fig-label,echo=F, eval=T, fig.align = 'center', fig.cap="This is my caption"}
knitr::include_graphics(here::here("images", "my_image.png"))
This produces an automatic number under your figure. You can refer to it with \#ref(fig:my-fig-label).
Using the official bookdown documentation 4.10 Numbered figure captions:
---
output: bookdown::html_document2
---
```{r cars, fig.cap = "An amazing plot"}
plot(cars)
```
```{r mtcars, fig.cap = "Another amazing plot"}
plot(mpg ~ hp, mtcars)
```

Resources