Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

output_file relative path causes render function fatal error in Windows #2464

Closed
5 tasks done
cloudy-sfu opened this issue Mar 20, 2023 · 6 comments
Closed
5 tasks done

Comments

@cloudy-sfu
Copy link

cloudy-sfu commented Mar 20, 2023

In the Windows system, assume there is an R markdown file lab_1/main.Rmd relative to your working directory. Write anything in it. Then, run these codes in the R command line (in your working directory):

rmd_path = 'lab_1/main.Rmd'
library(rmarkdown)
html_path = with_ext(rmd_path, 'html')
render(rmd_path, output_file = html_path)

It says Error: The directory 'lab_1' does not not exist. (The error message has two "not", it's not my typo, and you can address the line causing the problem easily).

My debug attempt is shown as follows. In Lines 54-57 of render function:

    if (!is.null(output_dir)) {
        if (!dir_exists(output_dir)) 
            dir.create(output_dir, recursive = TRUE)
        output_dir <- normalize_path(output_dir)
    }

If output_dir is the default value null, it doesn't cause any problem. But if we assign a relative path to output_dir, the normalize_path will convert it to something like this:

C:/Users/Administrator/Documents/lab_1/main.Rmd

In Lines 153-155:

    output_dir <- dirname(output_file)
    if (!dir_exists(output_dir)) {
        stop2("The directory '", output_dir, "' does not not exist.")
    }

The dir_exists function returns FALSE for any path which uses slash in Windows, whereas dir_exists thinks a path should use backslash!

The session information:

R version 4.2.3 (2023-03-15 ucrt)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19044)

Locale:
  LC_COLLATE=English_United States.utf8 
  LC_CTYPE=English_United States.utf8   
  LC_MONETARY=English_United States.utf8
  LC_NUMERIC=C                          
  LC_TIME=English_United States.utf8    

Package version:
  base64enc_0.1.3 bslib_0.4.2     cachem_1.0.7    cli_3.6.0      
  digest_0.6.31   ellipsis_0.3.2  evaluate_0.20   fastmap_1.1.1  
  fs_1.6.1        glue_1.6.2      graphics_4.2.3  grDevices_4.2.3
  highr_0.10      htmltools_0.5.4 jquerylib_0.1.4 jsonlite_1.8.4 
  knitr_1.42      lifecycle_1.0.3 magrittr_2.0.3  memoise_2.0.1  
  methods_4.2.3   mime_0.12       R6_2.5.1        rappdirs_0.3.3 
  rlang_1.1.0     rmarkdown_2.20  sass_0.4.5      stats_4.2.3    
  stringi_1.7.12  stringr_1.5.0   tinytex_0.44    tools_4.2.3    
  utils_4.2.3     vctrs_0.6.0     xfun_0.37       yaml_2.3.7     

Pandoc version: 3.1.1

Checklist

When filing a bug report, please check the boxes below to confirm that you have provided us with the information we need. Have you:

  • formatted your issue so it is easier for us to read?

  • included a minimal, self-contained, and reproducible example?

  • pasted the output from xfun::session_info('rmarkdown') in your issue?

  • upgraded all your packages to their latest versions (including your versions of R, the RStudio IDE, and relevant R packages)?

  • installed and tested your bug with the development version of the rmarkdown package using remotes::install_github("rstudio/rmarkdown")?

cderv added a commit that referenced this issue Mar 23, 2023
@cderv
Copy link
Collaborator

cderv commented Mar 23, 2023

First, Thanks for the typo finding !

Regarding your main issue here, I believe this is directly related to #2370

See my answer there #2370 (comment) about output_dir and output_file

@cloudy-sfu
Copy link
Author

Thanks!

However, I think not only the documentation, but the code may need some modifications. Because besides issue #2370 , adjusting its behavior in Windows is also important. Also, it's quite redundant that the function uses both output_dir and output_file.

@cderv
Copy link
Collaborator

cderv commented Mar 23, 2023

The dir_exists function returns FALSE for any path which uses slash in Windows, whereas dir_exists thinks a path should use backslash!

Are you refering to this that needs fixing ? dir_exists() works with slash on Windows too

> dir.create("dummy/examples", recursive = TRUE)
> rmarkdown:::dir_exists("dummy/examples")
[1] TRUE
> unlink("dummy", recursive = TRUE)

In your example, render(rmd_path, output_file = html_path) you only called output_file and not output_dir so this part of the code where you mentioned dir_exists is not run

    if (!is.null(output_dir)) {
        if (!dir_exists(output_dir)) 
            dir.create(output_dir, recursive = TRUE)
        output_dir <- normalize_path(output_dir)
    }

What exactly do you think the issue is ?

Also, it's quite redundant that the function uses both output_dir and output_file.

Maybe, but this will not change. Paths handling is quite complicated already - output_dir and output_file needs to be used together depending on what to do. Also doing path operation (renaming, moving, copying) after render() is still the best way to avoid any issue. Sorry for that.

We tried to explained in the doc of argugments https://rmarkdown.rstudio.com/docs/reference/render.html

output_file
The name of the output file. If using NULL then the output filename will be based on filename for the input file. If a filename is provided, a path to the output file can also be provided. Note that the output_dir option allows for specifying the output file path as well, however, if also specifying the path, the directory must exist. If output_file is specified but does not have a file extension, an extension will be automatically added according to the output format. To avoid the automatic file extension, put the output_file value in I(), e.g., I('my-output').

output_dir
The output directory for the rendered output_file. This allows for a choice of an alternate directory to which the output file should be written (the default output directory of that of the input file). If a path is provided with a filename in output_file the directory specified here will take precedence. Please note that any directory path provided will create any necessary directories if they do not exist.

@cloudy-sfu
Copy link
Author

cloudy-sfu commented Mar 23, 2023

I now understand, I previously believe the issue is that windows backslash is not recognized.

Now I find the actual reason: the output_file is relative to input! In my example, rmd_path is the argument of input, and output_file is relative to it. After I change the output_file relative to input, it works. Please mention the relationship of output_file and input in the document, and no code modification is needed.

@cderv
Copy link
Collaborator

cderv commented Mar 23, 2023

Please mention the relationship of output_file and input

Yes this is #2370 we'll do that.

Thanks !

@cderv cderv closed this as completed Mar 23, 2023
@github-actions
Copy link

This old thread has been automatically locked. If you think you have found something related to this, please open a new issue by following the issue guide (https://yihui.org/issue/), and link to this old issue if necessary.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants