It is not the man who has too little that is poor, but the one who hankers after more.
— Letters from a Stoic (Lucius Annaeus Seneca)
This talk is intended for
minimalists
hackers
I’ll accompany this talk with a blog post later: https://yihui.org/en/2023/01/minimal-r-markdown/
Examples:
.Rmd
-> .md
-> .html
/ .tex
/ .docx
.qmd
-> .md
-> .html
/ .tex
/ …We only talk about the second step today, i.e., converting .md
.
<html>
<head>
<title>Document Title</title>
</head>
<body>
Document body
</body>
</html>
Right-click on a web page, then “View Page Source”. You will see the HTML source code of a page.
\documentclass{article}
% preamble
\begin{document}
% body
\end{document}
Preamble/Metadata (<head>
in HTML, code before \begin{document}
in
LaTeX)
Body (<body>
in HTML, code after \begin{document}
in LaTeX)
Markdown also has these components:
---
title: Document Title
author: Yihui Xie
---
Document body.
Note that I’m talking about the markdown package, not rmarkdown! Usually “R Markdown” refers to the latter, which is much more powerful and widely known.
A little bit history about markdown:
Born in 2012 (a decade ago…): https://github.com/rstudio/markdown
Referred to as “the first generation of R Markdown”
The second generation of R Markdown, rmarkdown, was born in 2014
markdown has been almost retired since 2016 (when rmarkdown became mature)
Originally based on C library sundown; switched to commonmark two months ago
The development of the markdown package has almost stopped since 2014, but it can’t simply die on CRAN because many packages still use it.
In October last year, I got CRAN emails regarding some maintenance problems. I couldn’t afford time to fix the endless C problems any more in the deprecated sundown library, so I deleted all C code and switched to Jeroen Ooms’s commonmark.
I no longer have to maintain any C code! Thanks, Jeroen!
You can install the dev version of markdown with:
install.packages('markdown', repos = c(
rstudio = 'https://rstudio.r-universe.dev',
CRAN = 'https://cloud.r-project.org'
))
markdown::mark()
is based on commonmark. The latter can help us generate
the document body.
cat(markdown::mark('Hello **world**!', format = 'latex'))
#> Hello \textbf{world}!
cat(markdown::mark('Hello **world**!', format = 'html'))
#> <p>Hello <strong>world</strong>!</p>
We need a template, into which we insert the body and metadata. For example:
<html>
<head>
<title>$title$</title>
<style type="text/css">$css$</style>
</head>
<body>$body$</body>
</html>
Or a LaTeX template:
\documentclass{$documentclass$}
\title{$title$}
\author{$author$}
\date{$date$}
\begin{document}
\maketitle
$body$
\end{document}
Read the YAML metadata in Markdown and store them in a list of variables,
e.g., title
, author
, etc.
Convert the Markdown body to the target format and store in the body
variable
Read the template, and substitute the variable names with their values in above steps
#' @param text Markdown input
#' @param meta A list of metadata
#' @param template The template text
to_html <- function(text, meta = list(), template = '') {
meta$body <- commonmark::markdown_html(text)
output <- template # initialize output to be template text
for (i in names(meta)) {
variable <- paste0('$', i, '$') # e.g., $title$
output <- gsub(variable, meta[[i]], output, fixed = TRUE)
}
output
}
res <- to_html(
'Hello **world**!', meta = list(title = 'Try it'),
template = '<title>$title$</title>
<body>\n$body$</body>'
)
cat(res)
<title>Try it</title>
<body>
<p>Hello <strong>world</strong>!</p>
</body>
---
title: Try it
---
Hello **world**!
<html>
<head><title>Try it</title></head>
<body><p>Hello <strong>world</strong>!</p></body>
</html>
Both HTML and LaTeX examples
Metadata, Markdown options
---
output:
markdown::html_format:
options: ...
meta: ...
markdown::latex_format: ...
---
Two lines of CSS code:
html { scroll-snap-type: y mandatory; }
.slide { min-height: 100vh; scroll-snap-align: start; }
The key technique: CSS Scroll Snap
This may be the world’s simplest method to create HTML slides.
JavaScript is a lot of fun to me. You can manipulate anything on a web page (including your bank account balance—of course—only locally in your browser).
Example: implement keyboard shortcuts
document.addEventListener('keyup', (e) => {
e.key === 'f' && document.documentElement.requestFullscreen();
e.key === 'o' && document.body.classList.toggle('overview');
e.key === 'm' && document.body.classList.toggle('mirrored');
});
Slides: https://slides.yihui.org/2023-minimal-r-markdown.html
Video recording will be publicly available later
Questions?
Try Stack Overflow or RStudio Community
Then Github issues, e.g., https://github.com/rstudio/markdown/issues
If you want my public help, try https://github.com/yihui/yihui.org/discussions
If you must reach me privately: https://yihui.org/en/about/#contact-me