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

Cannot parse quoted arguments #4

Closed
aniketschneider opened this issue Aug 18, 2014 · 11 comments
Closed

Cannot parse quoted arguments #4

aniketschneider opened this issue Aug 18, 2014 · 11 comments

Comments

@aniketschneider
Copy link

I have been unable to get this to parse a quoted argument with a space as a single argument. For example:

library(docopt)
library(methods)

doc <- '
Usage:
  exampleScript <arg1>
'
docopt(doc, commandArgs(trailingOnly=TRUE))
$ Rscript exampleScript.R 'multi-word arg'
Error in docopt(doc, commandArgs(trailingOnly = TRUE)) : 
  usage: exampleScript <arg1>
Execution halted
@edwindj
Copy link
Member

edwindj commented Aug 19, 2014

Thanks for reporting: I will look into it this week.

@edwindj
Copy link
Member

edwindj commented Aug 19, 2014

I added supportfor quoted arguments in the github repo.

However note that:

  • docopt (the python version) has no support for quoted arguments
  • this solution does not support nested quotes.

Could you please check if this is solving your problem, so I can close the issue?

Best,

@aniketschneider
Copy link
Author

Thanks for looking into this!

Using http://try.docopt.org/ , quoted arguments do seem to work fine. I looked a little further and found a related issue on the docopt repo: docopt/docopt#129

I think the core issue here is not quoting specifically (which in R is handled just fine by commandArgs()), but rather that docopt accepts a list argument, but docopt.R doesn't respect the separation of items in a list when they have spaces in them. That is, if there is a list of two items - "a", "b c" - docopt.R treats this as two arguments:

> doc <- 'Usage:
   exampleScript <arg1> <arg2>'
> docopt(doc, c("a", "b c"))
Error in docopt(doc, c("a", "b c")) : usage: exampleScript <arg1> <arg2>
> docopt(doc, c("a", "b"))
$`<arg1>`
[1] "a"

$`<arg2>`
[1] "b"

Whereas the python docopt treats this as two arguments:

>>> from docopt import docopt
>>> doc = """Usage:
... exampleScript <arg1> <arg2>"""
>>> docopt(doc, ["a", "b c"])
{'<arg1>': 'a',
 '<arg2>': 'b c'}

@edwindj
Copy link
Member

edwindj commented Aug 20, 2014

I'm not sure what you mean with that quoted arguments seem to work find in http://try.docopt.org

For example (at http://try.docopt.org)
ship Guardian move 1 2 works as expected, but
ship "Guardian II" move 1 2, does not work.

The latest version of docopt:

devtools::install_github("edwindj/docopt.R")

will parse

doc <- 'Usage:
   exampleScript <arg1> <arg2>'
docopt(doc, 'a "b c"')

as

$`<arg1>`
[1] "a"

$`<arg2>`
[1] "b c"

Is this your intended behavior?

@aniketschneider
Copy link
Author

I don't know what I thought I saw on http://try.docopt.org/, you're clearly right about that.

The behavior for quoted arguments in the current github version is what I originally wanted, but as you pointed out it is not consistent with the docopt reference implementation in python. I think the best solution here should maintain consistency with the reference implementation.

The python implementation accepts two types of inputs: a string or a list. When presented with a string, it treats the string as a whitespace-delimited sequence of tokens (irrespective of quotation marks). When presented with a list, it treats each element in the list as a single token, even if the element has spaces in it.

It is that last behavior that is not consistent between docopt.R and the reference implementation. When passed a list (or other sequence), docopt.R still splits the individual list elements into multiple tokens at whitespace boundaries.

Specifically, the following example works in the python implementation, and is what I would like to work in this one:

> doc <- 'Usage:
   exampleScript <arg1> <arg2>'
> docopt(doc, c("a", "b c"))
Error in docopt(doc, c("a", "b c")) : usage: exampleScript <arg1> <arg2>

@holgerbrandl
Copy link

Hi,
I'm using the latest version including the quoted_args option. However, it seems to be not really robust against what's in the quotes. E.g. try

> doc <- 'Usage: do_something.R [-S] <dirname> [<other>...]'
> docopt(doc, "some_directory '--quoted test'", quoted_args=T)
$`-S`
[1] FALSE

$`--quoted test`
[1] TRUE

$`<dirname>`
[1] "some_directory"

$`<other>`
list()

$S
[1] FALSE

$`quoted test`
[1] TRUE

$dirname
[1] "some_directory"

$other
list()

I would expect '--quoted test' to show up as it is in other but somehow it does not work that way (yet?).

@edwindj
Copy link
Member

edwindj commented Nov 26, 2014

Thanks for reporting! I will look into it later this week and get back to you. I'm not sure what the golden docopt.py standard is in this matter.

Best,

Edwin

@holgerbrandl
Copy link

docopt.R deviated from the reference already by supporting quotes (which is great and very useful).

Some users seem to want quote support also for the reference, see
docopt/try.docopt.org#3
docopt/docopt#207

Quote handling is just not really consistent at the moment in docopt.R.

@edwindj
Copy link
Member

edwindj commented Dec 19, 2014

@holgerbrandl
Again thanks for reporting. Your reported issue has itself an issue: you are using "--" inside optional arguments, which is againt the docopt spec.

Let me illustrate it with two examples:

doc <- 'Usage: do.R <dirname> [<other>...]'
# omit the double --
docopt(doc, "some_directory 'quoted test'", quoted_args=T)
$`<dirname>`
[1] "some_directory"

$`<other>`
[1] "quoted test"

$dirname
[1] "some_directory"

$other
[1] "quoted test"

which is what you are expecting (and which is parsed by docopt.R, but not by docopt.py)

The other example is using an unquoted optional argument:

doc <- 'Usage: do.R <dirname> [<other>...]'
docopt(doc, "some_directory --notquoted")

which generates an error. This is conform docopt.py (test it on try.docopt.org).

I see quotation as a means to have white spaces in parameters and arguments, and this seems to work right now.

@edwindj
Copy link
Member

edwindj commented Dec 19, 2014

After a little thought I implemented your wish anyway: should work now.
@holgerbrandl
If not you can reopen the issue.

Best!

@edwindj edwindj closed this as completed Dec 19, 2014
@holgerbrandl
Copy link

@edwindj Awesome, thanks a lot for this christmas fix/present. I've tried it already, and it works like a charm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants