Skip to content

Commit

Permalink
Add support for docopt's [options] shortcut (closes issue docopt#22)
Browse files Browse the repository at this point in the history
When the [options] shortcut is detected on the usage section, we use the
contents of the options section to get the full list of options, rather
than
just getting those options that are explicitly mentioned on the usage
section.
  • Loading branch information
AngelEzquerra committed Feb 14, 2014
1 parent 08c5236 commit 1d925db
Showing 1 changed file with 17 additions and 10 deletions.
27 changes: 17 additions & 10 deletions docopt_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,25 +98,32 @@ def c_if_option(o):
c_name(o.long or o.short))


def parse_leafs(pattern):
def parse_leafs(pattern, all_options):
options_shortcut = False
leafs = []
queue = [(0, pattern)]
while queue:
level, node = queue.pop(-1) # depth-first search
if hasattr(node, 'children'):
if not options_shortcut and type(node) == docopt.OptionsShortcut:
options_shortcut = True
elif hasattr(node, 'children'):
children = [((level + 1), child) for child in node.children]
children.reverse()
queue.extend(children)
else:
if node not in leafs:
leafs.append(node)
leafs.sort(key=lambda e: e.name)
sort_by_name = lambda e: e.name
leafs.sort(key=sort_by_name)
commands = [leaf for leaf in leafs if type(leaf) == docopt.Command]
arguments = [leaf for leaf in leafs if type(leaf) == docopt.Argument]
flags = [leaf for leaf in leafs
if type(leaf) == docopt.Option and leaf.argcount == 0]
options = [leaf for leaf in leafs
if type(leaf) == docopt.Option and leaf.argcount > 0]
if options_shortcut:
option_leafs = all_options
option_leafs.sort(key=sort_by_name)
else:
option_leafs = [leaf for leaf in leafs if type(leaf) == docopt.Option]
flags = [leaf for leaf in option_leafs if leaf.argcount == 0]
options = [leaf for leaf in option_leafs if leaf.argcount > 0]
leafs = [i for sl in [commands, arguments, flags, options] for i in sl]
return leafs, commands, arguments, flags, options

Expand Down Expand Up @@ -148,9 +155,9 @@ def parse_leafs(pattern):
if isinstance(usage, list):
raise docopt.DocoptLanguageError(''.join(usage))

options = docopt.parse_defaults(doc)
pattern = docopt.parse_pattern(docopt.formal_usage(usage), options)
leafs, commands, arguments, flags, options = parse_leafs(pattern)
all_options = docopt.parse_defaults(doc)
pattern = docopt.parse_pattern(docopt.formal_usage(usage), all_options)
leafs, commands, arguments, flags, options = parse_leafs(pattern, all_options)

t_commands = ';\n '.join('int %s' % c_name(cmd.name)
for cmd in commands)
Expand Down

2 comments on commit 1d925db

@AngelEzquerra
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was my first commit using GitHub's Git client. I made sure that the commit message lines were wrapped at 80 chars but it seems that GigHub itself automatically wraps them 73 characters, which made the actual commit message look a bit weird.

@kblomqvist
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your efforts. I'll take a look at this.

Please sign in to comment.