2

I have a rmarkdown file which is built around the {pagedreport} package (an add-on to pagedown). This creates a html and them uses pagedown::chrome_print to convert the html to pdf.

The rmarkdown file i have works as planned when I have the parameters manually entered on the rmarkdown file, but I want to be able to pick my parameters from a shiny app.

I currently have tried this approach

    output$report <- downloadHandler(
    # For PDF output, change this to "report.pdf"
    filename =  "new_report.pdf",
    content = function(file) {
    # Copy the report file to a temporary directory before processing it, in
    # case we don't have write permissions to the current working dir (which
    # can happen when deployed).
    tempReport <- file.path("../temp/", "myRmarkdown.Rmd")
    file.copy("myRmarkdown.Rmd", tempReport, overwrite = TRUE)
    
    # Set up parameters to pass to Rmd document
    params <- list(A = input$A, B = input$B)
    
    # Knit the document, passing in the `params` list, and eval it in a
    # child of the global environment (this isolates the code in the document
    # from the code in this app).
                  
                     
     library(rmarkdown)
     render(tempReport,  params = params,
                   envir = new.env(parent = globalenv()))

            
          }

and I get the result:

    Output created: MyRmarkdown.html

but there is no pdf created. Pagedown uses chrome_print to convert - and this is in the yaml of the Rmarkdown.

This is the YAML of my Rmarkdown file

    output:
    pagedreport::paged_windmill:
    img_to_dark: TRUE
    logo_to_white: TRUE
    knit: pagedown::chrome_print
    #toc: TRUE
    toc-title: "Table of Contents"
    #toc_depth: 1
    main-color: "#264653"
    secondary-color: "#2a9d8f"
    google-font: TRUE
    main-font: "Raleway" 
    header-font: "Roboto"
    params:
        A: NA
        B: NA
    editor_options: 
    markdown: 
        wrap: 72

I know there is an issue between shiny and chrome_print() where you need to add chrome_print(..., async = TRUE), but I don't know where to put this argument in my shiny app?

  • I have written a demo Shiny app to show how to use `pagedown::chrome_print()` in Shiny, see https://github.com/RLesur/chrome_print_shiny. – RLesur May 03 '21 at 22:13

1 Answers1

2

I am pretty sure you have to make sure that your render function creates a file at the location given by the argument file. In your current appraoch render uses defaults, which won't work. Thus, it should be as simple as adding the output_file argument to render. The following code snippets works for me:

test.Rmd

---
title: "Untitled"
output: html_document
params:
   title: "Test"
   heading: "Header"
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
```

```{r results="asis"}
cat("## ", params$title)
```

You passed in argument `r cat(params$heading)`

app.R

library(shiny)
library(rmarkdown)

ui <- fluidPage(textInput("heading", "Heading"), 
                textInput("title", "Title"), 
                downloadButton("download_ok", "Works"),
                downloadButton("download_nok", "Does not Work"))

server <- function(input, output) {
   output$download_ok <- downloadHandler(
      filename = function() {
         paste("data-", Sys.Date(), ".html", sep="")
      },
      content = function(file) {
         p <- list(title = input$title,
                        heading = input$heading)
         render("test.Rmd", output_file = file, params = p)
      }
   )
   
   output$download_nok <- downloadHandler(
      filename = function() {
         paste("data-", Sys.Date(), ".html", sep="")
      },
      content = function(file) {
         p <- list(title = input$title,
                        heading = input$heading)
         render("test.Rmd", params = p)
      }
   )
}

shinyApp(ui, server)

This snippet shows how this works now in principle, I do not know pagedreport. If there is an option in the YAML to produce pdfs right away (without the manual call to whatever function) this should work in the same way.

If you absolutely need to call the function, you can do that in the downloadHandler after the render assuming that the function can deal with input file names and create output files at the given location (again you need to create the file at the given location [as per argument file])


After reading the docs of pagedown::chrome_print you can adapt your downloadHandler as follows:

output$report <- downloadHandler(
      filename =  "new_report.pdf",
      content = function(file) {
         tempReport <- file.path("../temp/", "myRmarkdown.Rmd")
         file.copy("myRmarkdown.Rmd", tempReport, overwrite = TRUE)
         params <- list(A = input$A, B = input$B)
         html_fn <- rmarkdown::render(tempReport,  params = params,
                envir = new.env(parent = globalenv()))
         
         pagedown::chrome_print(html_fn, file)
      }

thothal
  • 16,690
  • 3
  • 36
  • 71