shiny icon indicating copy to clipboard operation
shiny copied to clipboard

Running rmarkdown::render() to PDF from shiny produces filepaths that confuse LaTeX on Windows

Open NickCH-K opened this issue 4 years ago • 1 comments

System details

Output of sessionInfo() (following library(shiny)):

R version 4.1.1 (2021-08-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19043)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] shiny_1.7.1

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.7       digest_0.6.28    later_1.3.0      mime_0.12        R6_2.5.1         lifecycle_1.0.1 
 [7] xtable_1.8-4     magrittr_2.0.1   evaluate_0.14    rlang_0.4.12     promises_1.2.0.1 ellipsis_0.3.2  
[13] rmarkdown_2.11   tools_4.1.1      httpuv_1.6.3     xfun_0.27        yaml_2.2.1       fastmap_1.1.0   
[19] compiler_4.1.1   htmltools_0.5.2  knitr_1.36      

Example application

I have a parameterized RMarkdown PDF report that I am running from a Shiny flexdashboard. Shiny flexdashboard code:

    ---
    title: "Company Report Frontend"
    output: 
      flexdashboard::flex_dashboard:
        orientation: columns
        vertical_layout: fill
    runtime: shiny
    ---
    
    ```{r global, include=FALSE}
    library(flexdashboard)
    library(shiny)
    ```
    
    ### Select Company
    
    ```{r}
    textInput('name', label ='Firm')
    ```
   
    ### Report
    
    ```{r}
      uiOutput("downloadUI")
      
      # Create the actual downloadButton
      output$downloadUI <- renderUI( {
          downloadButton("downBtn", "Download Report")
      })
      
      # Add download handling
      output$downBtn <- downloadHandler(
            filename = "full_report.pdf",
            content = function(file) {
              rmarkdown::render("test_report.Rmd", output_file = file,
                params = list(input=input),
                envir = new.env(parent = globalenv()), clean = FALSE,
                intermediates_dir = '.',
                output_dir = '.',
                knit_root_dir = '.'
              )
            }
      )
    ```

And the parameterized RMarkdown doc test_report.Rmd:

    ---
    title: "Report"
    header-includes: 
       \usepackage{graphicx}
       \usepackage{grffile}
       \usepackage{booktabs}
    params:
      input: NA
    output:
      pdf_document:
        latex_engine: xelatex
        keep_tex: true
    ---
    
    
    ```{r}
    input <- params$input 
    
    data(mtcars)
    plot(mtcars$hp, mtcars$mpg)
    title(input$name)
    ```

Describe the problem in detail

When I run the dashboard, enter a name, and hit Download on Windows, it successfully produces the .tex file but then can't compile it. When I try to compile the .tex file directly in a LaTeX editor, I get undefined control sequence and Missing endcsname defined errors on any \includegraphics lines like this one:

\includegraphics{C:/User/LONGUS~1/AppData/Local/Temp/Rtmpk1o7Q3/file1ec05b50167a_files/figure-latex/unnamed-chunk-1-1.pdf}

where LONGUS~1 is a shortened folder name from the actual Windows username LONGUSERNAME.

The error goes away, and the PDF compiles, if I replace LONGUS~1 with LONGUSERNAME, or just point it to the relative filepath. LaTeX does tend to get finicky about filepaths sometimes.

Notes from lots of troubleshooting (and from helpful tips that turned out not to work from Google or from asking this on Twitter, StackExchange, and RStudio Community):

  • The full absolute filepath in the LONGUS~1 is in the knitted MD file before it's translated into .tex, so it's unlikely to be a Pandoc issue
  • The problem does not appear if I run render('test_report.Rmd') from RStudio directly, or if I set a default input value and knit test_report.Rmd in Rstudio with the Knit button suggesting it is unlikely to be an RMarkdown issue either, but rather specifically a Shiny (or download button in Shiny) issue.
  • The problem does not occur on Macs, just Windows (haven't tested *nix).
  • Specifying a temporary directory filepath using a tempdir() or normalizePath(tempdir()) does not solve the problem, nor does any number of configurations of setting the _dir options in render() that I tried. Even feeding it a full, un-shortened path with normalizePath() produces the shortened version in the .md output and thus the .tex output

I think this counts as a bug (although if someone wants to point out an option I'm missing that could get around this I'd be very happy with that). Thank you!

NickCH-K avatar Nov 06 '21 05:11 NickCH-K

I am have a very similar issue, has anyone found a solution yet?

jochemvankempen avatar Feb 24 '22 11:02 jochemvankempen