tidyverse / reprex

Render bits of R code for sharing, e.g., on GitHub or StackOverflow.

Home Page:https://reprex.tidyverse.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Path quoting would be helpful when using reprex with venue="rtf" on Windows

pieterjanvc opened this issue · comments

commented

Hi,

Let me start by saying the reprex package is AWESOME and I use it on a daily basis as an RStudio Community Forum sustainer!

Now for the issue: I'm getting an error when running reprex(venue="rtf") . I did install the highlight package successfully on my Windows 10 machine and was able to run it from command line. However, when trying to use it in the reprex function I get the following error

ISSUE

i Rendering reprex...
highlight: Output path equals input path: "C:/Users/PJ".
Error in `reprex_highlight()`:
! `highlight` call unsuccessful.
Backtrace:
    x
 1. \-reprex::reprex(...)
 2.   \-reprex:::reprex_impl(...)
 3.     \-reprex:::reprex_render_impl(...)
 4.       \-reprex:::pp_highlight(pp_md_to_r(md_file, comment = comment))
 5.         \-reprex:::reprex_highlight(r_file_rendered(input), rtf_file)
 6.           \-rlang::abort("`highlight` call unsuccessful.")
Warning message:
In shell(cmd) :
  'highlight  -i C:/Users/PJ Van Camp/AppData/Local/Temp/RtmpqEtOYh/reprex-32e06047533c-stuck-crane/stuck-crane_reprex_r.R --out-format=rtf --no-trailing-nl --encoding=UTF-8 --style darkbone --font "Courier Regular" --font-size 50  -o C:/Users/PJ Van Camp/AppData/Local/Temp/RtmpqEtOYh/reprex-32e06047533c-stuck-crane/stuck-crane_reprex_r.rtf' execution failed with error code 1

I figured out that the reason for this error is that my home folder unfortunately has spaces in it C:/Users/PJ Van Camp/ and the highlight tool is cutting the path after the first space producing the above error.

PROPOSED SOLUTION
In the source code when calling the highlight tool, make sure to quote the input and output path and all should be solved. I tried this running the actual command reported in the error with proper quotes like this ...

highlight  -i "C:/Users/PJ Van Camp/AppData/Local/Temp/RtmpqEtOYh/reprex-32e06047533c-stuck-crane/stuck-crane_reprex_r.R" \
--out-format=rtf --no-trailing-nl --encoding=UTF-8 --style darkbone --font "Courier Regular" --font-size 50  \
-o "C:/Users/PJ Van Camp/AppData/Local/Temp/RtmpqEtOYh/reprex-32e06047533c-stuck-crane/stuck-crane_reprex_r.rtf"

... and the correct file was generated without error!

I hope you could implement this so I (and other Windows users with spaces in their path names) could use the rtf functionality in reprex.

Thanks!
PJ

Yes, I agree quoting seems to be necessary. I recall that constructing and executing this highlight command was not completely trivial on Windows. (Although part of the pain I'm remembering is probably also related to getting RTF onto the Windows clipboard.)

I can't even read the help on shell() from macOS. It's one of those functions that's specific to R on Windows. But if someone motivated, on Windows, wants to work out what needs to be done, I'd be happy to review a PR.

Help page for shell() can be found online here: https://rdrr.io/r/base/windows/shell.html

The space is definitely the culprit as often on Windows. shQuote() would the solution: https://rdrr.io/r/base/shQuote.html

Could you try #410 to see if that works ok for you ? Thanks!

remotes::install_github("tidyverse/reprex#410")
commented

Hi,

Thanks for the reply and the update. I tested your new version, but unfortunately got the same error. However, I think it is because only the input path was quoted and not the output path

i Rendering reprex...
highlight: Could not write output file:
C:/Users/PJ
Error in `reprex_highlight()`:
! Call to the highlight command line tool was unsuccessful.

Warning message:
In shell(cmd) :
  'highlight  -i "C:/Users/PJ Van Camp/AppData/Local/Temp/RtmpW4U1ZO/reprex-3dc0470bfcb-sly-agama/sly-agama_reprex_r.R" \
--out-format=rtf --no-trailing-nl --encoding=UTF-8 --style darkbone --font "Courier Regular" --font-size 50  \
-o C:/Users/PJ Van Camp/AppData/Local/Temp/RtmpW4U1ZO/reprex-3dc0470bfcb-sly-agama/sly-agama_reprex_r.rtf' execution failed with error code 1

You can see above that -i is quoted but -o is not. So I think that should be an easy fix!

Thanks again for the help, I really appreciate it
PJ

Oh yes thanks. I only tested with space in input, but obviously it could also be in output. I updated the PR.

commented

Hi,

Yes we are cooking with gas now :)

I managed to render the reprex, though there is still a warning again related to another path hidden somewhere in the code I think, though this time I'm not sure where to find it :)

i Rendering reprex...
Get-Content : A positional parameter cannot be found that accepts argument 'C:/Users/PJ'.
At line:2 char:2
+ (Get-Content -Raw C:/Users/PJ Van Camp/AppData/Local/Temp/RtmpkXvNZR/ ...
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-Content], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.GetContentCommand
 
x Failed to put RTF on the Windows clipboard :(
√ Reprex output is on the clipboard.

Hope you can figure this one out too :)

Thanks a lot,
PJ

Oh it is probably in the code that put the content into clipboard 🤔 this one seems to use Powershell.

write_clip_windows_rtf <- function(path) {
cmd <- glue('
powershell -Command "\\
Add-Type -AssemblyName System.Windows.Forms | Out-Null;\\
[Windows.Forms.Clipboard]::SetText(
(Get-Content -Raw {path}),\\
[Windows.Forms.TextDataFormat]::Rtf
)"')
res <- system(cmd)
if (res > 0) {
# abort("Failed to put RTF on the Windows clipboard")
reprex_danger("Failed to put RTF on the Windows clipboard :(")
invisible(FALSE)
} else {
invisible(TRUE)
}
}

Internal documentation exist for this past work if you are curious: https://github.com/tidyverse/reprex/blob/2c7f565d8067246798ae51a488c03e552bde2f73/internal/write-clipboard-rtf-windows.md

I'll adapt the code there too then. Thanks for the testing.

I have pushed a change. Unfortunately, shQuote() has no special behavior for Powershell. However, adding double quotes like for cmd should be ok for file path in Powershell. Can you retest to see if shQuote() does the job ?

Thanks

commented

Hi,

No luck I'm afraid, I get the same error. I double checked that I'm working with the latest version.

i Rendering reprex...
Get-Content : A positional parameter cannot be found that accepts argument 'C:/Users/PJ'.
At line:2 char:2
+ (Get-Content -Raw C:/Users/PJ Van Camp/AppData/Local/Temp/RtmpKWH9cR/ ...
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-Content], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.GetContentCommand
 
x Failed to put RTF on the Windows clipboard :(
√ Reprex output is on the clipboard.

I read a bit online and found this topic
https://stackoverflow.com/questions/61222520/get-content-errors-with-raw-not-parameter-only-when-path-has-spaces

It seems that the -raw argument is ignoring any quotes and will fail with spaces (they say it's a bug). I do not fully understand their workaround, but maybe it might set you on the right path.

Again, I really appreciate you helping me out on this!

PJ

Oh this is tricky. Thanks a lot for the information.

After a few tests, I came up with the solution of just properly escaping space for powershell (by adding backslash `)

Another solution would have been to use -LiteralPath and add single quote around the path.

diff --git a/R/utils-clipboard.R b/R/utils-clipboard.R
index 5fae08e..a1cc5f7 100644
--- a/R/utils-clipboard.R
+++ b/R/utils-clipboard.R
@@ -9,12 +9,12 @@ ingest_clipboard <- function() {
 }

 write_clip_windows_rtf <- function(path) {
-  path <- gsub("\\s", "` ", path)
+  path <- single_quote(path)
   cmd <- glue('
     powershell -Command "\\
     Add-Type -AssemblyName System.Windows.Forms | Out-Null;\\
     [Windows.Forms.Clipboard]::SetText(
-    (Get-Content -Raw {path}),\\
+    (Get-Content -LiteralPath {path} -Raw),\\
     [Windows.Forms.TextDataFormat]::Rtf
     )"')
   res <- system(cmd)

but it may have more side effect that just escaping space.

You could try the updated PR to see if it works for you too. Thanks.

Resources on powershell and quoting:

commented

You did it!!

Great job and thanks for seeing this through. I don't get any more errors and if I paste into Word I get the formatted rtf. I can now start playing around with it :)

Thanks again,
PJ