Equivalent to `code-line-numbers` for output in Quarto for revealjs slides - r-markdown

I am using Quarto to produce some revealjs slides using RStudio and have been using the code-line-numbers option to selectively highlight lines of code. For instance:
```{r, echo = TRUE}
#| code-line-numbers: "1|3"
x <- 1
y <- 2
x + y
x * y
```
Allows me to highlight the first and third lines of code in the presentation.
I would like to additionally be able to highlight certain lines in the output. For instance, if I wanted to only highlight the result of x+y but not x*y, is there a way of doing so? I wondered if there was an option for output-line-number or similar that might have the desired effect, but couldn't find anything like this.
Any pointers appreciated!

A possible way to do this could be based on using pandoc Lua filter.
Here I have created a chunk-option output-line-numbers to specify which output lines to highlight (works just as code-line-numbers chunk option), but please note that you must have to use class-output: highlight to get this line specific highlighting on chunk output.
---
title: "Output Line highlight"
format: revealjs
filters:
- output-line-highlight.lua
---
```{r, echo = TRUE}
#| code-line-numbers: "1"
#| class-output: highlight
#| output-line-numbers: "2"
for (i in 1:3) {
print("This is some random line")
}
```
output-line-highlight.lua
function highlight(line_number)
local highlighter = {
CodeBlock = function(block)
if block.classes:includes('highlight') then
block.classes:insert('has-line-highlights')
block.attributes["code-line-numbers"] = line_number
return block
end
end
}
return highlighter
end
function Div(el)
if FORMAT == 'revealjs' then
if el.classes:includes('cell') then
line_number = tostring(el.attributes["output-line-numbers"])
return el:walk(highlight(line_number))
end
end
end

Related

Word count in Quarto

I would love a convenient and easy way to print my word count automatically in quarto and stumbled across this nice add-in from Ben Marwick:
https://github.com/benmarwick/wordcountaddin
It is sound for rmarkdown and I presumed it should be no issue with quarto too. However, when I use the add-in, though it can count out the number of words within my RStudio session, it doesn't print it in my final pdf format and just returns [1] NA.
{r, #wordcountdev, message = FALSE, warning = FALSE, echo = FALSE}
wordstats <- wordcountaddin:::text_stats('CMI Write Up.qmd')
words <- substr(wordstats[3], start=19, stop=30)
print(words)
I don't understand what is going on here, it is seemingly simple, would anyone know of a better way to achieve what I'm trying?
You could take a look at the wordcounts pandoc filter, e.g. as a starting point it prints the number of words in the body to the console while rendering:
---
format: html
filters: [wordcounts.lua]
---
Hello there, how many words are in the body?
Or: You can use the development version (devtools::install_github("benmarwick/wordcountaddin", type = "source", dependencies = TRUE)) of the above mentioned package:
---
format: html
---
```{r}
#| echo: false
#| label: wordstats
#| warning: false
#| message: false
wordcount <- wordcountaddin::text_stats('wordcount.qmd')
words <- substr(wordcount[3], start=19, stop=30)
```
Hello there, how many words are in the body?
There are `r words` words in the whole document.

Rmarkdown officer / officedown / flextables problem

I have the following rmd script. I've spent a few days trying to get this to work but I am failing miserably. Basically I need help with three things. I am happy to post three separate questions if needed.
The multicolumn options/code are completely ignored. The corporatetable.docx is in landscape and has a typical corporate style. I need to have a full width landscape -> two column landscape -> full width landscape. If I could get the two column landscape setup to work, the remaining style would be inherited by corporatetable.docx. If I could get help with only one - I would need this.
When I run the rmd it generates a word file but none of the corporate styles are in there. It just uses my word's default colors etc. The difference is very clear - no landscape, single column and blue instead of red. How do I correctly pass the officedown::rdocx_document: to reference my word file because it's clearly not picking it up and no warning or error is generated?
If you see in the second chunk I am using flextable to show two pictures (which are passed through params) in the word report and align them with some information. myft works but it prints the (temporary/volatile) path instead of showing the pictures in the report. For reference if I use knitr::include_graphics(c(params$x1,params$x2)) it works fine.
I'm really stuck on these. Any help is welcome.
---
title: "Title"
subtitle:
params:
x1: x1
x1_name: x1_name
x1_email : x1_email
x2: x2
x2_name: x2_name
x2_email : x2_name
output:
officedown::rdocx_document:
reference_docx: corporatetemplate.docx
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(officedown)
library(officer)
library(flextable)
knitr::opts_chunk$set(out.width = '100%', dpi=300)
```
<!---BLOCK_MULTICOL_START--->
This text is on column 1. Please work
```{r somecodechunk, echo=FALSE, out.width="75px", include=TRUE, strip.white=TRUE}
library(flextable)
# this works but prefer to use flextable
# if(all(!is.null(params))) {
# knitr::include_graphics(c(params$x1,params$x2))} else {
# }
myft <- data.frame(
"pic1" = rep("",3),
"details1" = c(params$x1_name,"+X XXX XXX X",params$x1_email),
"pic2" = rep("",3),
"details2" = c(params$x2_name,"+X XXX XXX X",params$x2_email)
)
myft <- flextable(myft)
myft <- merge_at(myft, i = 1:3, j = 1 )
myft <- merge_at(myft, i = 1:3, j = 3 )
myft <- compose(myft,i = 1, j = 1, value = as_paragraph(as_image(params$x1), part = "body"))
myft <- compose(myft,i = 1, j = 3, value = as_paragraph(as_image(params$x2), part = "body"))
autofit(myft)
#Ok this does not work because the pics are not shown
```
`r run_columnbreak()`
This text is on column 2. Please work
This text is on column 2. Please work
`r run_linebreak()`
<!---BLOCK_MULTICOL_STOP{widths: [4,4], space: 0.2, sep: true}--->
\pagebreak
Back to full width with some text
\pagebreak

How do I escape an RMarkdown chunk?

I am trying to render the syntax for chunks of code in RMarkdown to a pdf. The final output should look like
```{r}
#some code
```
Rather than just
#some code
The best options to answer this can be found on the RStudio website. See the article on getting verbatim R chunks into rmarkdown http://rmarkdown.rstudio.com/articles_verbatim.html
My preferred solution is to add an inline R code at the end of the first line to make the chunk appear correctly in the output like so:
```{r eval=TRUE}` r ''`
seq(1, 10)
```
Which produces
```{r eval=TRUE}
seq(1:10)
```
Rather than
## [1] 1 2 3 4 5 6 7 8 9 10
Another way to do the same thing is treat the code chunk as a string (I don't usually use the -> operator but in this case I think this improves readability):
```{r comment = ""}
"{r eval=TRUE}
seq(1, 10)
" -> my_code_string
cat("```", my_code_string, "```", sep = "")
```
Which outputs:
```{r eval=TRUE}
seq(1, 10)
```
This question is also a possible duplicate of How to embed and escape R Markdown code in a R Markdown document

Make R Markdown code blocks into math mode

I would love to use R Markdown to generate homework and exam solutions, but I would prefer to have them more readable to non-coders.
I there a way that I can pass the ECHO output through math mode? That is I would love to have an ECHO that looks more "inline" and less like code. I can see how to hide it, but in the R Markdown Reference Guide I don't see an option to remove the "code block" and wrap each line in $$ (or wrap in anything). Is there a way to do this?
Here is an example. This solution has all the meat, but may be a little intimdating to some students (this is not an R course).
8-22 ...
a. ...
```{r part_a}
D_0 = 2.40
g = 0.06
r = 0.12
V = D_0*(1 + g)/(r - g)
V
```
Instead, I would love to see something more like the following.^[I appreciate that I can generate this output with some cutting and pasting and a text editor, I am just trying to find the most efficient solution, since this is likely something that I will do more than once or twice.]
8.22 ...
a. ...
$$ D_0 = 2.40 $$
$$ g = 0.06 $$
$$ r = 0.12 $$
$$ V = D_0 \times (1 + g)/(r - g) = 2.40 \times (1 + 0.06)/(0.12 - 0.06) = `r V`$$
I have a partial answer. I don't yet know how to replace variable x with its value so that a can print the formula with variables, replaced by numbers. But I can generate the "math code" block so that I can solve the problem and generate the pretty solution without a lot of cut and paste.
Here is an example .Rmd file.
---
author: Richard Herron
title: Homework Solutions
---
8-22 ...
a. ...
There are three parts to this solution.
1. write the equations to solve the problem in R-readable strings.
2. loop over the list and `eval(parse())` the equation strings
3. wrap strings in `$$ $$` with `cat(paste0())`
Chunks should be set to `echo=FALSE` and `results="asis`. You may need to suppress some function output with `invisible()`.
```{r part_a, echo=FALSE, results="asis"}
# just to make sure my eval below works
rm(list=ls())
# store solution as a list of character equations
solution <- list(
"D_0 = 2.40",
"g = 0.06",
"r = 0.12",
"V = D_0*(1 + g)/(r - g)"
)
# "solve" problem
for (i in seq_along(solution)) eval(parse(text=solution[[i]]))
# display solution as math
cat(paste0("$$", solution, "$$"), sep="\n")
```
Because of the `eval()` loop in the first chunk I can say that $V = `r V`$ in the text that follows.
And here is an outer file that convert each .Rmd file into a .pdf.
# load `render` and set working directory
setwd("C:/Users/Richard/Dropbox/Babson College/SME 2021 for 2015 fall/Homework")
# loop over all Rmd files
require(rmarkdown)
require(tools)
files <- list.files(path=".", pattern="*.Rmd")
roots <- sapply(files, file_path_sans_ext)
namesIn <- paste0("", roots, ".pdf")
namesOut <- paste0("", roots, ".pdf")
# solutions
myPdf <- pdf_document(
fig_caption=TRUE,
keep_tex=TRUE,
pandoc_args=c(
"--variable=classoption:fleqn",
"--variable=classoption:twocolumn",
paste0("--metadata=date:", format(Sys.time(), "%B %d, %Y"))
)
)
lapply(files, FUN=render, output_format=myPdf)
mapply(file.rename, namesIn, namesOut)
Which yields this pdf.

Adjust the output width of R Markdown HTML output

I am producing an HTML output but I am having issues with the output width of R code output.
I'm able to adjust the figure width with no difficulty but when I try to write a data table or the factor loadings, R is outputting at a fixed width which is only about a third of my screen width. This results in the columns of the table being split up rather than all of the columns displayed in a single table.
Here is a reproducible example:
---
output: html_document
---
# Title
```{r echo = FALSE, fig.width=16, fig.height=6}
x = matrix(rnorm(100),ncol=10)
x
plot(x)
```
Add this at the start of your document:
```{r set-options, echo=FALSE, cache=FALSE}
options(width = SOME-REALLY-BIG-VALUE)
```
Obviously, replace SOME-REALLY-BIG-VALUE with a number. But do you really want to do all that horizontal scrolling?
Your output is probably being wrapped somewhere around 80 characters or so.
Also, you can temporarily change the local R options for a code chunk:
```{r my-chunk, R.options = list(width = SOME-BIG-VALUE)}
```