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

incorrect use of backslashes in .Rd files #967

Closed
achubaty opened this issue Nov 14, 2019 · 5 comments · Fixed by #986
Labels
Milestone

Comments

@achubaty
Copy link

@achubaty achubaty commented Nov 14, 2019

The latest version (7.0.0) breaks one of my .Rd files containing the following code in an example:

paths <- list("./aaa/zzz",
              "./aaa/zzz/",
              ".//aaa//zzz",
              ".//aaa//zzz/",
              ".\\aaa\\zzz",
              ".\\aaa\\zzz\\", ## <- the double backslashes should convert to quad-backslashes
              file.path(".", "aaa", "zzz"))

gets converted to this in the .Rd:

paths <- list("./aaa/zzz",
              "./aaa/zzz/",
              ".//aaa//zzz",
              ".//aaa//zzz/",
              ".\\\\aaa\\\\zzz",
              ".\\\\aaa\\\\zzz\\\", ## <- note the 3 trailing backslashes instead of 4
              file.path(".", "aaa", "zzz"))

this has the effect of escaping the closing quotation mark, which results in the warning

Warning: newline within quoted string 

As a workaround, I have commented out the offending line in the example, but this is a temporary solution.
PredictiveEcology/reproducible@fbf8bf6

@gaborcsardi

This comment was marked as outdated.

Copy link
Member

@gaborcsardi gaborcsardi commented Nov 14, 2019

Thanks! Would you mind creating a reproducible example like this: https://github.com/r-lib/roxygen2/blob/master/.github/SUPPORT.md#making-a-reprex

@achubaty

This comment was marked as outdated.

Copy link
Author

@achubaty achubaty commented Nov 14, 2019

reprex:

  1. create the example file (e.g., /tmp/reprex-967.R) containing the following:

    paths <- list("./aaa/zzz",
                  "./aaa/zzz/",
                  ".//aaa//zzz",
                  ".//aaa//zzz/",
                  ".\\aaa\\zzz",
                  ".\\aaa\\zzz\\",
                  file.path(".", "aaa", "zzz"))
  2. generate the broken Rd file:

    library(roxygen2)
    setwd("/tmp")
    
    roc_proc_text(rd_roclet(), "
      #' Title
      #' @param x xfoo
      #'
      #' @export
      #' @example reprex-967.R
      foo <- function(x) { return(x) }
    ")

which produces:

$foo.Rd
% Generated by roxygen2: do not edit by hand
% Please edit documentation in ./<text>
\name{foo}
\alias{foo}
\title{Title}
\usage{
foo(x)
}
\arguments{
\item{x}{xfoo}
}
\description{
Title
}
\examples{
paths <- list("./aaa/zzz",
              "./aaa/zzz/",
              ".//aaa//zzz",
              ".//aaa//zzz/",
              ".\\\\aaa\\\\zzz",
              ".\\\\aaa\\\\zzz\\\",
              file.path(".", "aaa", "zzz"))
}
@gaborcsardi

This comment was marked as outdated.

Copy link
Member

@gaborcsardi gaborcsardi commented Nov 14, 2019

Self-contained reprex:

library(roxygen2)

tmp <- tempfile()
cat("paths <- list(\".\\aaa\\zzz\\\\\",\n \"foobar\")", file = tmp)

setwd(dirname(tmp))
roc_proc_text(rd_roclet(), sprintf("
  #' Title
  #'
  #' @example %s
  foo <- function() NULL
", basename(tmp)))
#> $foo.Rd
#> % Generated by roxygen2: do not edit by hand
#> % Please edit documentation in ./<text>
#> \name{foo}
#> \alias{foo}
#> \title{Title}
#> \usage{
#> foo()
#> }
#> \description{
#> Title
#> }
#> \examples{
#> paths <- list(".\\aaa\\zzz\\\",
#>  "foobar")
#> }

Created on 2019-11-14 by the reprex package (v0.3.0)

Inline fails as well, slightly differently, because roxygen checks for well-formed rd:

library(roxygen2)

roc_proc_text(rd_roclet(), "
  #' Title
  #'
  #' @examples
  #' paths <- list(\".\\aaa\\zzz\\\\\",
  #'               \"foobar\")
  foo <- function() NULL
")
#> Warning: [<text>:4] @examples mismatched braces or quotes
#> $foo.Rd
#> % Generated by roxygen2: do not edit by hand
#> % Please edit documentation in ./<text>
#> \name{foo}
#> \alias{foo}
#> \title{Title}
#> \usage{
#> foo()
#> }
#> \description{
#> Title
#> }

Created on 2019-11-14 by the reprex package (v0.3.0)

@hadley hadley added this to the v7.0.1 milestone Nov 20, 2019
@hadley

This comment has been minimized.

Copy link
Member

@hadley hadley commented Nov 20, 2019

Slightly more minimal reprex:

library(roxygen2)

text <- "
  #' Title
  #'
  #' @examples
  #' x <- c('\\\\', 'foobar')
  foo <- function() NULL
"
cat(text)
#> 
#>   #' Title
#>   #'
#>   #' @examples
#>   #' x <- c('\\', 'foobar')
#>   foo <- function() NULL
roc_proc_text(rd_roclet(), text)[[1]]$get_section("examples")
#> Warning: [<text>:4] @examples mismatched braces or quotes
#> NULL

Created on 2019-11-20 by the reprex package (v0.3.0)

@gaborcsardi

This comment has been minimized.

Copy link
Member

@gaborcsardi gaborcsardi commented Nov 21, 2019

The problem is that we first escape the backslashes here:

x1 <- gsub("\\", "\\\\", x, fixed = TRUE, useBytes = TRUE)

and then try to un-escape the ones within strings here:

roxygen2/R/rd-examples.R

Lines 58 to 59 in f6b46a8

x <- gsub("\\\\'", "\\'", x, fixed = TRUE)
x <- gsub('\\\\"', '\\"', x, fixed = TRUE)

However the un-escaping does not know if the backslash of \\' is actually part of an escaped backslash, like int the reprex.

Maybe it would be better not to touch strings at all when we escape the examples.

(Actually, I think the ideal solution is not to escape the examples at all, but that ship has sailed.)

hadley added a commit that referenced this issue Nov 21, 2019
Fixes #967
@hadley hadley closed this in #986 Nov 21, 2019
hadley added a commit that referenced this issue Nov 21, 2019
Fixes #967
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.