Search code examples
buttontextdownloadquarto

Download button in text Quarto


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.


Solution

  • 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;
    }
    
    

    demo screenshot of using shortcode

    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>
    

    download button embeded in paragraph


    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!