Download button in text Quarto - button

I would like to have a download button in the middle of a sentence to a pdf or csv document for example. This means there should be a small button in the sentence suggesting that you can download a document, not in a navigation or side bar. Here is some reproducible code:
---
title: "Download button in text Quarto"
format:
html:
code-fold: true
engine: knitr
---
I would like to have a download button [here]() for pdf or CSV document for example.
I am not sure if it is possible to implement a clean button in a sentence using downloadthis package because it should be in the middle of a sentence with text around.

Update
I have create quarto shortcode extension downloadthis that provides a shortcode to embed a download button more easily (in comparison to my old answer) and doesn't require to use an R package (but of course, this extension is inspired by {downloadthis})
So after installing that shortcode, we can use the shortcode as following,
---
title: "Download button in text Quarto"
format:
html:
css: style.css
engine: knitr
---
The following button is a download button for matcars data {{< downloadthis mtcars.csv
label="Download data" dname=mtcars id=mtcars-btn >}} You can download the mtcars data as csv file by clicking on it.
style.css
#mtcars-btn {
font-size: xx-small;
padding: 0.2rem 0.3rem !important;
}
#down-btn {
margin-right: 2px;
margin-left: 2px;
}
a:has(#mtcars-btn) {
text-decoration: none !important;
}
Explore here for more options and live demos.
Old Answer
Using a bit of CSS and javascript, it is possible to do very easily.
---
title: "Download button in text Quarto"
format:
html:
code-fold: true
include-after-body: add_button.html
engine: knitr
---
```{r}
#| echo: false
library(downloadthis)
mtcars %>%
download_this(
output_name = "mtcars dataset",
output_extension = ".csv",
button_label = "Download data",
button_type = "default",
self_contained = TRUE,
has_icon = TRUE,
icon = "fa fa-save",
id = "mtcars-btn"
)
```
The following button is a download button for matcars data <span id="down-btn"></span> You can download the mtcars data as csv file by clicking on it.
add_button.html
<style>
#mtcars-btn {
font-size: xx-small;
padding: 0.2rem 0.3rem !important;
}
#down-btn {
margin-right: 2px;
margin-left: 2px;
}
a:has(#mtcars-btn) {
text-decoration: none !important;
}
#mtcars-btn:focus,
#mtcars-btn:active {
box-shadow: none !important;
}
#mtcars-btn:hover {
transition: 0.2s;
filter: brightness(0.90);
}
#mtcars-btn:active {
filter: brightness(0.80);
}
</style>
<script>
function add_button() {
/* get the R generated button by its id */
let mtcars_btn = document.querySelector("a:has(#mtcars-btn)");
mtcars_btn.href = '#mtcars-btn';
/* get the placeholder where you want to put this button */
let down_btn = document.querySelector("span#down-btn");
/* append the R generated button to the placeholder*/
down_btn.appendChild(mtcars_btn)
}
window.onload = add_button();
</script>
Explanation
So what I have done here
At first, created a download button using the downloadthis with an id=mtcars-btn so that we can get hold of this generated button with js code using this #mtcars-btn id selector
Then created a placeholder inside the paragraph text using <span></span>, where I want the download button to be and also in this case, assigned an id down-btn to that span, so that we can target this span using #down-btn.
Then using js, simply appended that generated download button to placeholder span tag so that the button is in the place where we wanted it to be.
Lastly, used some css to make this button smaller, reduced button padding, created a bit left and right margin and removed the underline.
Thats it!

Related

How can I add arbitrary elements to the Table of Contents in Bookdown?

I am making a book via bookdown.
I know it is possible to omit headings from the Table of Contents by adding the attributes {.unlisted .unnumbered}, as shown in Section 4.18 of the R Markdown Cookbook.
However, how can I add arbitrary content to the Table of Contents?
If I only needed to add this for the PDF output, I could use (e.g.) the LaTeX command \addcontentsline, but I need this to show in the HTML contents sidebar as well.
For example, if you set up a new default bookdown project from RStudio, it includes the file 01-intro.Rmd.
The first few lines are
# Introduction {#intro}
You can label chapter and section titles using `{#label}` after them, e.g., we can reference Chapter \#ref(intro). If you do not manually label them, there will be automatic labels anyway, e.g., Chapter \#ref(methods).
Figures and tables with captions will be placed in `figure` and `table` environments, respectively.
I need to be able to create arbitrary divs that are added to the table of contents, like so:
# Introduction {#intro}
You can label chapter and section titles using `{#label}` after them, e.g., we can reference Chapter \#ref(intro). If you do not manually label them, there will be automatic labels anyway, e.g., Chapter \#ref(methods).
::: {#arbitrary-header <some other attribute?>}
Figures and tables with captions will be placed in `figure` and `table` environments, respectively.
:::
Which would add the sentence "Figures and tables with captions will be placed in figure and table environments, respectively." in both the LaTeX Table of Contents and the sidebar on the HTML output.
The context of this problem is that I need to place a header inside another custom div that formats the content within a colorbox to make it stand out.
Otherwise, I could of course just add another heading via ## before the sentence above.
We could use an R function that prints a colored box and adds the title to the TOC depending on the output format. For gitbook output, this is easily done using HTML and markdown. For pdf_book we may use a LaTeX environment for colored boxes like tcolorbox.
Here is the function (define in a code block in .Rmd file):
block_toc <- function(title, level, content, output) {
if(output == "html") {
title <- paste(paste(rep("#", level), collapse = ""), title, "{-}")
cat('<div class = "myblock">', title, '<p>', content, '</p>\n</div>', sep = "\n")
} else {
level <- c("part", "chapter", "section")[level]
cat('\\addcontentsline{toc}{', level, '}{', title, '}',
'\n\\begin{mybox}\n\\textbf{\\noindent ', title, '}\n\\medskip\n\n', content,
'\n\n\\end{mybox}', sep = "")
}
}
Depending on the output format, block_toc() concatenates and prints the code for the blocks and, of course, also ensures that the title is added to the TOC. You can set the level of the TOC where the box title is added using level.
Use block_toc() like this in a chunk:
```{r, results='asis', echo=F, eval=T}
block_toc(
title = "Central Limit Theorem",
level = 2
content = "The CLT states that, as $n$ goes to infinity,
the sample average $\\bar{X}$ converges in distribution
to $\\mathcal{N}(\\mu,\\sigma^2/n)$.",
output = knitr::opts_knit$get("rmarkdown.pandoc.to")
)
```
output = knitr::opts_knit$get("rmarkdown.pandoc.to") will get and pass the current output format to the function when building the book.
Some styles for appealing boxes
Add to preamble.tex (for colored box in PDF output -- include file in YAML header). This will define a tcolorbox environment for generating blue boxes.
\usepackage{tcolorbox}
\definecolor{blue}{HTML}{D7DDEF}
\definecolor{darkblue}{HTML}{2B4E70}
\newtcolorbox{mybox}{colback=blue, colframe=darkblue}
Add to style.css (styles for HTML colored box) or include in a ```{css} code chunk:
.myblock {
background-color: #d7ddef;
border: solid #2b4e70;
border-radius: 15px;
}
.myblock p, .myblock h2, .myblock h3 {
padding: 5px 5px 5px 20px;
margin-top: 0px !important;
}
For HTML output (gitbook) this yields
and for LaTeX output (pdf_book) it looks like this
with a corresponding entry at the section level in the TOC.
Maybe this solution?
CSS-file:
k1 {
font-family: 'Times New Roman', Times, serif;
font-size: 12pt;
text-align: justify;
}
#TOC {
color:black;
background-color: white;
position: fixed;
top: 0;
left: 0;
width: 250px;
padding: 10px;
overflow:auto;
margin-left: -5px;
}
body {
max-width: 800px;
margin-left:300px;
line-height: 20px;
}
div#TOC li {
list-style:none;
}
h2#toc-title {
font-size: 24px;
color: Red;
}
Rmd-file:
---
title: "Arbitrary elements"
author: "Me"
date: "`r Sys.Date()`"
output:
bookdown::html_document2:
toc: true
css: "arb.css"
toc-title: "Contents"
---
# My question is it: "..."
# Introduction of our story ...
# It was a strange person ...
## The Flame was in his body ...
# <k1> Figures and tables with captions will be placed in `figure` and `table` environments, respectively. </k1> {-}
## Where is the love, friends?
We'll be using a Lua filter for this, as those are a good way to modify R Markdown behavior. The "Bookdown Cookbook" has an excellent overview and includes a description of how to use Lua filters.
The way we are doing this is to side-step the normal TOC generator and rewrite it in Lua. Then we add our new TOC as a meta value named table-of-contents (and toc, for compatibility), which is enough to be included in the output.
So first let's dump the code to create a normal TOC:
_ENV = pandoc
local not_empty = function (x) return #x > 0 end
local section_to_toc_item
local function to_toc_item (number, text, id, subcontents)
if number then
text = Span({Str(number),Space()} .. text, {class='toc-section-number'})
end
local header_link = id == '' and text or Link(text, '#' .. id)
local subitems = subcontents:map(section_to_toc_item):filter(not_empty)
return List{Plain{header_link}} ..
(#subitems == 0 and {} or {BulletList(subitems)})
end
section_to_toc_item = function (div)
-- bail if this is not a section wrapper
if div.t ~= 'Div' or not div.content[1] or div.content[1].t ~= 'Header' then
return {}
end
local heading = div.content:remove(1)
local number = heading.attributes.number
-- bail if this is not supposed to be included in the toc
if not number and heading.classes:includes 'unlisted' then
return {}
end
return to_toc_item(number, heading.content, div.identifier, div.content)
end
-- return filter
return {
{ Pandoc = function (doc)
local sections = utils.make_sections(true, nil, doc.blocks)
local toc_items = sections:map(section_to_toc_item):filter(not_empty)
doc.meta['table-of-contents'] = {BulletList(toc_items)}
doc.meta.toc = doc.meta['table-of-contents']
return doc
end
},
}
The code makes a few minor simplifications, but should produce an identical TOC for most documents. Now we can go on and modify the code to our liking. For example, to include divs with the class toc-line, the section_to_toc_item could be modified by adding this code at the start of the function:
section_to_toc_item = function (div)
if div.t == 'Div' and div.classes:includes('toc-line') then
return to_toc_item(nil, utils.blocks_to_inlines(div.content), div.identifier)
end
⋮
end
Modify the code as you see fit.
Also, if you want to exclude the extra TOC lines from the normal output, you'll have to filter them out. Let the script return a second filter to do that:
return {
{ Pandoc = function (doc) ... end },
{ Div = function (div) return div.classes:includes 'toc-line' and {} or nil end }
}

YAML title font and color in Rmarkdown

Is there a way to change the font and color in the YAML title in a R markdown flexdashboard?
Here is the code for the YAML header I am trying to change:
---
title: "Greenhouse gases and weather data"
fontsize: 30
output:
flexdashboard::flex_dashboard:
orientation: rows
vertical_layout: fill
social: menu
source_code: embed
theme: readable
---
The other option would be to add a CSS code chunk anywhere in the dashboard
```{css}
body > div.navbar.navbar-inverse.navbar-fixed-top > div > div.navbar-header > span.navbar-brand {
font-size: 26px;
color: red;
}
```
as Kat said, the color is set by CSS , therefore you can change the behaviour in the .rmd file itself, or in the underlying theme template .css file.
somewhere located at:
/home/user/R/x86_64-pc-linux-gnu-library/4.0/flexdashboard/rmarkdown/templates/flex_dashboard/resources
add (to the rmd) or look for and change (the .css) to :
<style>
.navbar {
background-color:white;
border-color:blue;
}
.navbar-brand {
color:blue!important;
}
</style>
This will revert the default color scheme of the top navbar
at the moment i dont know a simple YAML - argument solution for this
( but looking into css will gain you much more
versatility along the way, than relying on the YAML options)

Add page numbers to pdf using pagedown::chrome_print (R package)?

I am using pagedown::chrome_print() to convert slidy presentations created with Rmarkdown to pdf -- it does a better job than saving as PDF from Chrome. However, despite studying the help file, I cannot figure out how to add page numbers. Is there a way to do this?
(Note that pagedown here refers to the R package, not the JavaScript markdown previewer.)
Sorry if the help page is not clear on this point.
It is possible to pass header/footer options to Chrome using pagedown::chrome_print().
These options are the ones defined by the Chrome DevTools Protocol for the Page.printToPDF method.
You can customise the header and the footer with an HTML template. Chrome also offers the following values: date, title, url, pageNumber and totalPages.
Following the explanations on this help page, here is an example to print the page numbers:
library(htmltools)
footer <- div(
style = "font-size: 8pt; text-align: right; width: 100%; padding-right: 12pt;",
span(class = "pageNumber"), "/", span(class = "totalPages")
)
pagedown::chrome_print(
"slidy.Rmd",
options = list(
landscape = TRUE,
displayHeaderFooter = TRUE,
footerTemplate = format(footer, indent = FALSE),
marginTop = 0,
marginBottom = 0.4
)
)
I got it to work with a custom CSS file. I created a file called custom.css and included in that file was
#page {
#bottom-right {
content: counter(page);
}
}
Then I used that along with the other pagedown defaults with a header like this
title: "My Report"
output:
pagedown::html_paged:
css: ["custom.css", "default-fonts", "default"]

R markdown: how to change style with internal css?

I know how to change R markdown style with a custom css file. However, when the changes are minor, I prefer internal or even inline css, to save trouble from managing two files. I googled and haven't find a solution for this. Below is a simple example of changing style with an external css file. Is there a way to do it with internal or inline css?
The R markdown file:
---
title: "test"
output:
html_document:
css: test.css
---
## Header 1 {#header1}
But how to change style with internal css?
The test.css file:
#header1 {
color: red;
}
Markdown accepts raw HTML and passes it through unaltered, so define your "styled" elements as HTML:
<h2 style="color: red;">Header 1</h2>
Of course, some tools don't actually allow the raw HTML to be passed through (for security reasons or because the final output is not HTML), so your mileage may vary.
Depending on the Markdown implementation you are using, you may be able to define styles in the attribute list (if it supports arbitrary keys):
## Header 1 {style="color: red;"}
However, that is the least likely to work.
And remember, HTML <style> tags do not need to be in the document <head> to work. If you can use raw HTML, you can include a <style> element in the body of your document (as pointed out by #user5219763 in a comment):
---
title: "test"
output:
html_document
---
<style>
#header1 {
color: red;
}
</style>
## Header 1 {#header1}
But how to change style with internal css?
If you don't want to create an external .css file, but would like to define several styles and would rather keep your code less crowded, another possibility is to use a css chunk at the beginning of your R markdown:
---
title: "test"
output: html_document
---
```{css, echo = FALSE}
#header1 {
color: red;
}
```
## Header 1 {#header1}
In the css chunk, you can control multiple styles, as you would do in an external .css file.
Another, sort of hacky option is to specify a css file in the script, then create it in the first chunk.
e.g. the first 18 lines of your .Rmd file:
---
title: "Something Important"
output:
html_document:
css: mystyle.css
---
```{r b, echo=F}
writeLines("td, th { padding : 6px }
th { background-color : coral ;
color : white;
border : 1px solid white; }
td { color : black ;
border : 1px solid skyblue }
h1, h2, h3, h4, h5, p { font-family: consolas; ",
con = "mystyle.css")
```
In the above, I first reference the file mystyle.css in the header block of markdown. Then, I create the file using writeLines(), and save it to the file specified with con = ....
Personally, I think the best option is to just throw your code in between some <script></script> tags if it's a one-off R script.
However, if you do want to create an external file, but don't want to edit a separate file, the above method provides a workaround. It just feels odd.

How to customize a css for markdown + knitr in Rstudio?

I want to change the default style sheet for the KnitHTML function in RStudio 0.96.331.
I follow the instructions in this post.
First I copy past the original markdown.css from here . As a test I change the first few lines from:
body, td {
font-family: sans-serif;
background-color: white;
font-size: 12px;
margin: 8px;
}
to red background
body, td {
font-family: sans-serif;
background-color: red;
font-size: 12px;
margin: 8px;
}
and save it as mymd.css in my working directory. I then create a style.R file as follows:
options(rstudio.markdownToHTML =
function(inputFile, outputFile) {
require(markdown)
markdownToHTML(inputFile, outputFile, stylesheet='mymd.css')
}
)
Finally, I source the style.R file by clicking source and then go back to the .Rmd file and knit it to HTML. I get the red background, but the math is not compiled e.g. $\alpha$
AFAIK,MathJax service was down yesterday due to the GoDaddy outage. Can you confirm the math problem was not due to that?
So I may have a work around for you, but it involves using pandoc:
Suppose your style sheet is called style.css
Source the following code:
options(rstudio.markdownToHTML = function(inputFile, outputFile) {
system(paste("pandoc -c style.css", shQuote(inputFile),
"-o", shQuote(outputFile)))
}
)
This is maybe a new feature that was not available at the time the question was asked. However, there is a simple solution I found here:
https://bookdown.org/yihui/rmarkdown/html-document.html#appearance-and-style
In the preamble of your .Rmd, just write this:
---
title: "Your title"
output:
html_document:
css: yourstylefile.css
---

Resources