felixSchl/neodoc

Failed to parse formal usage specification?

fidian opened this issue · 5 comments

I'm trying to find a good parser for JavaScript and I am struggling. docopt (npm module) really doesn't like my syntax even though the website's Python parser thinks this is splendid. neodoc also chokes. Is there something I can do to fix this?

Here's my code:

#!/usr/bin/env node
"use strict";

var syntax;

syntax = `Usage: animal.js [options]

    --cow    Pretend to be a cow.
`;

require("neodoc").run(syntax);

And here's the message.

Failed to parse the formal usage specification:
Expected End of usage section

This is an error with the program itself and not your fault.
Please bring this to the program author's attention.

I admit the error message could be better, but it's a simple fix: simply add the "options" title, that indicates to neodoc/docopt to start parsing options:

#!/usr/bin/env node
"use strict";

var syntax;

syntax = `\
Usage: animal.js [options]
options:
    --cow    Pretend to be a cow.
`;

require("neodoc").run(syntax);

Checkout testcases.docopt to see what else is possible :)

Edit: remember you can also quickly try things out here: https://felixschl.github.io/neodoc

Incidentally, I removed the spaces before --cow and tried to run it...

$ ./options.js --cow
animal.js: unknown option --cow
Usage: animal.js [options]
See animal.js --help for more information

I was about to append this to my issue here, but your reply was first.

I will add the options heading to simply make this work, but that seems contrary to what docopt documents on their website:

Usage: my_program [options] <path>

--all             List everything.
--long            Long output.
--human-readable  Display in human-readable format.

Further, it appears that they only require leading hyphens on a line.

Words starting with one or two dashes (with exception of "-", "--" by themselves) are interpreted as short (one-letter) or long options, respectively.

Why is it required to have the "options:" header? Is this parser not compliant with docopt's style?

Yes, there is a difference in behavior currently, but I certainly see the appeal
of a nameless [option] section and want to adopt it. It really just comes down
to writing a scanner that breaks the document apart into parse-able chunks w/o
relying on tokenization/parsing.

Some other differences that might interest you:

  1. empty lines in usage section:

    usage:
    
    prog <path>
    

    The above will only accept the empty input (yield {}) and complain with
    Usage: otherwise. But we might be otherwise able to use it. The

    neodoc, on the otherhand deals with these cases fine:

    usage:
    
      prog foo
    
      prog bar
    
  2. confusing option-argument binding

    usage: prog [options]
    
    options:
      -f, --foo -b qux
    

    The above will bind an argument "-b" to --foo, even though it visually does
    not look like an argument. Neodoc will only bind <arg> (name in angles) and ARG (all uppercase name) as they these are less likely to occur and are visually more distinct (the 2 spaces are
    easily missed)

  3. too eager options acquisition

    usage: prog [options]
    
    options:
    
    --foo this is foo, and it is similar to some-command's
              --bar in that it does qux.
    

    Here, the author is mentioning --bar which is part of some other command.
    Docopt will take the bar and consider it it's own. Neodoc won't (based on
    indentation), making it less likely to accidentally introduce options.

  4. multi-line option aliases

    usage: prog [options]
    
    options:
      -f,
      --foo this is foo [default: 100]
    

    Here, docopt ends up with two options, whereas the author likely ment one
    option.

I have been toying with the idea to make the scanning phase extensible, to allow
e.g. #58 and see if contributors show up that write a better scanner than what
neodoc comes with, so it could be adopted. The hardest part here really is not
implementation but coming up w/ a document structure that is both lenient for
the author but understandable by neodoc.

On a related note, there are plans to expand options by their section name #57,
so this nameless option section would be equivalent to [options] (i.e. the
"global" options section).

Ok. Well, since this is a known deviation from the spec, I suppose that I should close this issue. It would be nice to get some of these documented in the README so others don't have the same issues as I had. I really appreciate the thoroughness in your answer.

I will update the README accordingly, thank you for reporting this issue.