docopt.nim-0.7.1/0000775000175000017510000000000014502143666013131 5ustar nileshnileshdocopt.nim-0.7.1/test/0000775000175000017510000000000014502143666014110 5ustar nileshnileshdocopt.nim-0.7.1/test/testcases.docopt0000664000175000017510000002405214502143666017323 0ustar nileshnileshr"""Usage: prog """ $ prog {} $ prog --xxx "user-error" r"""Usage: prog [options] -a All. """ $ prog {"-a": false} $ prog -a {"-a": true} $ prog -x "user-error" r"""Usage: prog [options] --all All. """ $ prog {"--all": false} $ prog --all {"--all": true} $ prog --xxx "user-error" r"""Usage: prog [options] -v, --verbose Verbose. """ $ prog --verbose {"--verbose": true} $ prog --ver {"--verbose": true} $ prog -v {"--verbose": true} r"""Usage: prog [options] -p PATH """ $ prog -p home/ {"-p": "home/"} $ prog -phome/ {"-p": "home/"} $ prog -p "user-error" r"""Usage: prog [options] --path """ $ prog --path home/ {"--path": "home/"} $ prog --path=home/ {"--path": "home/"} $ prog --pa home/ {"--path": "home/"} $ prog --pa=home/ {"--path": "home/"} $ prog --path "user-error" r"""Usage: prog [options] -p PATH, --path= Path to files. """ $ prog -proot {"--path": "root"} r"""Usage: prog [options] -p --path PATH Path to files. """ $ prog -p root {"--path": "root"} $ prog --path root {"--path": "root"} r"""Usage: prog [options] -p PATH Path to files [default: ./] """ $ prog {"-p": "./"} $ prog -phome {"-p": "home"} r"""UsAgE: prog [options] --path= Path to files [dEfAuLt: /root] """ $ prog {"--path": "/root"} $ prog --path=home {"--path": "home"} r"""usage: prog [options] -a Add -r Remote -m Message """ $ prog -a -r -m Hello {"-a": true, "-r": true, "-m": "Hello"} $ prog -armyourass {"-a": true, "-r": true, "-m": "yourass"} $ prog -a -r {"-a": true, "-r": true, "-m": null} r"""Usage: prog [options] --version --verbose """ $ prog --version {"--version": true, "--verbose": false} $ prog --verbose {"--version": false, "--verbose": true} $ prog --ver "user-error" $ prog --verb {"--version": false, "--verbose": true} r"""usage: prog [-a -r -m ] -a Add -r Remote -m Message """ $ prog -armyourass {"-a": true, "-r": true, "-m": "yourass"} r"""usage: prog [-armmsg] -a Add -r Remote -m Message """ $ prog -a -r -m Hello {"-a": true, "-r": true, "-m": "Hello"} r"""usage: prog -a -b -a -b """ $ prog -a -b {"-a": true, "-b": true} $ prog -b -a {"-a": true, "-b": true} $ prog -a "user-error" $ prog "user-error" r"""usage: prog (-a -b) -a -b """ $ prog -a -b {"-a": true, "-b": true} $ prog -b -a {"-a": true, "-b": true} $ prog -a "user-error" $ prog "user-error" r"""usage: prog [-a] -b -a -b """ $ prog -a -b {"-a": true, "-b": true} $ prog -b -a {"-a": true, "-b": true} $ prog -a "user-error" $ prog -b {"-a": false, "-b": true} $ prog "user-error" r"""usage: prog [(-a -b)] -a -b """ $ prog -a -b {"-a": true, "-b": true} $ prog -b -a {"-a": true, "-b": true} $ prog -a "user-error" $ prog -b "user-error" $ prog {"-a": false, "-b": false} r"""usage: prog (-a|-b) -a -b """ $ prog -a -b "user-error" $ prog "user-error" $ prog -a {"-a": true, "-b": false} $ prog -b {"-a": false, "-b": true} r"""usage: prog [ -a | -b ] -a -b """ $ prog -a -b "user-error" $ prog {"-a": false, "-b": false} $ prog -a {"-a": true, "-b": false} $ prog -b {"-a": false, "-b": true} r"""usage: prog """ $ prog 10 {"": "10"} $ prog 10 20 "user-error" $ prog "user-error" r"""usage: prog [] """ $ prog 10 {"": "10"} $ prog 10 20 "user-error" $ prog {"": null} r"""usage: prog """ $ prog 10 20 40 {"": "10", "": "20", "": "40"} $ prog 10 20 "user-error" $ prog "user-error" r"""usage: prog [ ] """ $ prog 10 20 40 {"": "10", "": "20", "": "40"} $ prog 10 20 {"": "10", "": "20", "": null} $ prog "user-error" r"""usage: prog [ | ] """ $ prog 10 20 40 "user-error" $ prog 20 40 {"": null, "": "20", "": "40"} $ prog {"": null, "": null, "": null} r"""usage: prog ( --all | ) --all """ $ prog 10 --all {"": "10", "--all": true, "": null} $ prog 10 {"": null, "--all": false, "": "10"} $ prog "user-error" r"""usage: prog [ ] """ $ prog 10 20 {"": ["10", "20"]} $ prog 10 {"": ["10"]} $ prog {"": []} r"""usage: prog [( )] """ $ prog 10 20 {"": ["10", "20"]} $ prog 10 "user-error" $ prog {"": []} r"""usage: prog NAME... """ $ prog 10 20 {"NAME": ["10", "20"]} $ prog 10 {"NAME": ["10"]} $ prog "user-error" r"""usage: prog [NAME]... """ $ prog 10 20 {"NAME": ["10", "20"]} $ prog 10 {"NAME": ["10"]} $ prog {"NAME": []} r"""usage: prog [NAME...] """ $ prog 10 20 {"NAME": ["10", "20"]} $ prog 10 {"NAME": ["10"]} $ prog {"NAME": []} r"""usage: prog [NAME [NAME ...]] """ $ prog 10 20 {"NAME": ["10", "20"]} $ prog 10 {"NAME": ["10"]} $ prog {"NAME": []} r"""usage: prog (NAME | --foo NAME) --foo """ $ prog 10 {"NAME": "10", "--foo": false} $ prog --foo 10 {"NAME": "10", "--foo": true} $ prog --foo=10 "user-error" r"""usage: prog (NAME | --foo) [--bar | NAME] --foo --bar """ $ prog 10 {"NAME": ["10"], "--foo": false, "--bar": false} $ prog 10 20 {"NAME": ["10", "20"], "--foo": false, "--bar": false} $ prog --foo --bar {"NAME": [], "--foo": true, "--bar": true} r"""Naval Fate. Usage: prog ship new ... prog ship [] move [--speed=] prog ship shoot prog mine (set|remove) [--moored|--drifting] prog -h | --help prog --version Options: -h --help Show this screen. --version Show version. --speed= Speed in knots [default: 10]. --moored Mored (anchored) mine. --drifting Drifting mine. """ $ prog ship Guardian move 150 300 --speed=20 {"--drifting": false, "--help": false, "--moored": false, "--speed": "20", "--version": false, "": ["Guardian"], "": "150", "": "300", "mine": false, "move": true, "new": false, "remove": false, "set": false, "ship": true, "shoot": false} r"""usage: prog --hello """ $ prog --hello {"--hello": true} r"""usage: prog [--hello=] """ $ prog {"--hello": null} $ prog --hello wrld {"--hello": "wrld"} r"""usage: prog [-o] """ $ prog {"-o": false} $ prog -o {"-o": true} r"""usage: prog [-opr] """ $ prog -op {"-o": true, "-p": true, "-r": false} r"""usage: prog --aabb | --aa """ $ prog --aa {"--aabb": false, "--aa": true} $ prog --a "user-error" # not a unique prefix # # Counting number of flags # r"""Usage: prog -v """ $ prog -v {"-v": true} r"""Usage: prog [-v -v] """ $ prog {"-v": 0} $ prog -v {"-v": 1} $ prog -vv {"-v": 2} r"""Usage: prog -v ... """ $ prog "user-error" $ prog -v {"-v": 1} $ prog -vv {"-v": 2} $ prog -vvvvvv {"-v": 6} r"""Usage: prog [-v | -vv | -vvv] This one is probably most readable user-friednly variant. """ $ prog {"-v": 0} $ prog -v {"-v": 1} $ prog -vv {"-v": 2} $ prog -vvvv "user-error" r"""usage: prog [--ver --ver] """ $ prog --ver --ver {"--ver": 2} # # Counting commands # r"""usage: prog [go] """ $ prog go {"go": true} r"""usage: prog [go go] """ $ prog {"go": 0} $ prog go {"go": 1} $ prog go go {"go": 2} $ prog go go go "user-error" r"""usage: prog go... """ $ prog go go go go go {"go": 5} # # Test [options] shourtcut # r"""Usage: prog [options] A -q Be quiet -v Be verbose. """ $ prog arg {"A": "arg", "-v": false, "-q": false} $ prog -v arg {"A": "arg", "-v": true, "-q": false} $ prog -q arg {"A": "arg", "-v": false, "-q": true} # # Test single dash # r"""usage: prog [-]""" $ prog - {"-": true} $ prog {"-": false} # # If argument is repeated, its value should always be a list # r"""usage: prog [NAME [NAME ...]]""" $ prog a b {"NAME": ["a", "b"]} $ prog {"NAME": []} # # Option's argument defaults to null/None # r"""usage: prog [options] -a Add -m Message """ $ prog -a {"-m": null, "-a": true} # # Test options without description # r"""usage: prog --hello""" $ prog --hello {"--hello": true} r"""usage: prog [--hello=]""" $ prog {"--hello": null} $ prog --hello wrld {"--hello": "wrld"} r"""usage: prog [-o]""" $ prog {"-o": false} $ prog -o {"-o": true} r"""usage: prog [-opr]""" $ prog -op {"-o": true, "-p": true, "-r": false} r"""usage: git [-v | --verbose]""" $ prog -v {"-v": true, "--verbose": false} r"""usage: git remote [-v | --verbose]""" $ prog remote -v {"remote": true, "-v": true, "--verbose": false} # # Test empty usage pattern # r"""usage: prog""" $ prog {} r"""usage: prog prog """ $ prog 1 2 {"": "1", "": "2"} $ prog {"": null, "": null} r"""usage: prog prog """ $ prog {"": null, "": null} # # Option's argument should not capture default value from usage pattern # r"""usage: prog [--file=]""" $ prog {"--file": null} r"""usage: prog [--file=] --file """ $ prog {"--file": null} r"""Usage: prog [-a ] -a, --address TCP address [default: localhost:6283]. """ $ prog {"--address": "localhost:6283"} # # If option with argument could be repeated, # its arguments should be accumulated into a list # r"""usage: prog --long= ...""" $ prog --long one {"--long": ["one"]} $ prog --long one --long two {"--long": ["one", "two"]} # # Test multiple elements repeated at once # r"""usage: prog (go --speed=)...""" $ prog go left --speed=5 go right --speed=9 {"go": 2, "": ["left", "right"], "--speed": ["5", "9"]} # # Required options should work with option shortcut # r"""usage: prog [options] -a -a """ $ prog -a {"-a": true} # # If option could be repeated its defaults should be split into a list # r"""usage: prog [-o ]... -o [default: x] """ $ prog -o this -o that {"-o": ["this", "that"]} $ prog {"-o": ["x"]} r"""usage: prog [-o ]... -o [default: x y] """ $ prog -o this {"-o": ["this"]} $ prog {"-o": ["x", "y"]} # # Test stacked option's argument # r"""usage: prog -pPATH -p PATH """ $ prog -pHOME {"-p": "HOME"} # # Issue 56: Repeated mutually exclusive args give nested lists sometimes # r"""Usage: foo (--xx=x|--yy=y)...""" $ prog --xx=1 --yy=2 {"--xx": ["1"], "--yy": ["2"]} docopt.nim-0.7.1/test/test.nim0000664000175000017510000000412414502143666015575 0ustar nileshnileshimport std/[json, strutils, tables, options] include docopt proc test(doc, args, expected_s: string): bool = var expected_json = parse_json(expected_s) var error = "" try: try: var output = docopt(doc, args.split_whitespace(), quit = false) var expected = init_table[string, Value]() for k, v in expected_json: expected[k] = case v.kind of JNull: val() of JString: val(v.str) of JInt: val(int(v.num)) of JBool: val(v.bval) of JArray: val(v.elems.map_it(string, it.str)) else: val() error = "!= " & $output assert expected == output except DocoptExit: error = "DocoptExit on valid input" assert expected_json.kind == JString and expected_json.str == "user-error" return true except AssertionDefect: echo "-------- TEST NOT PASSED --------" echo doc echo "$ prog ", args, " " echo expected_s echo error echo "---------------------------------" return false var args, expected: options.Option[string] var doc: string var in_doc = false var total, passed = 0 const tests = static_read("testcases.docopt") for each_line in (tests & "\n\n").split_lines(): var line = each_line.partition("#").left if not in_doc and line.starts_with("r\"\"\""): in_doc = true doc = "" line = line.substr(4) if in_doc: doc &= line if line.ends_with("\"\"\""): doc = doc[0 .. doc.len-4] in_doc = false doc &= "\n" elif line.starts_with("$ prog"): assert args.is_none and expected.is_none args = some(line.substr(7)) elif line.starts_with("{") or line.starts_with("\""): assert args.is_some and expected.is_none expected = some(line) elif line.len > 0: assert expected.is_some expected = some(expected.get & "\n" & line) if line.len == 0 and args.is_some and expected.is_some: total += 1 if test(doc, args.get, expected.get): passed += 1 stdout.write("\rTests passed: $#/$#\r".format(passed, total)) args = none(string) expected = none(string) echo() quit(if passed == total: 0 else: 1) docopt.nim-0.7.1/test/nim.cfg0000664000175000017510000000015414502143666015354 0ustar nileshnileshpath = "$project_path/../src" hints = off linedir = on debuginfo stacktrace = on linetrace = on threads = ondocopt.nim-0.7.1/src/0000775000175000017510000000000014502143666013720 5ustar nileshnileshdocopt.nim-0.7.1/src/docopt/0000775000175000017510000000000014502143666015210 5ustar nileshnileshdocopt.nim-0.7.1/src/docopt/value.nim0000664000175000017510000000556614502143666017045 0ustar nileshnilesh# Copyright (C) 2015 Oleh Prypin # Licensed under terms of MIT license (see LICENSE) import std/strutils import util type ValueKind* = enum vkNone, ## No value vkBool, ## A boolean vkInt, ## An integer vkStr, ## A string vkList ## A list of strings Value* = object ## docopt variant type case kind*: ValueKind of vkNone: nil of vkBool: bool_v: bool of vkInt: int_v: int of vkStr: str_v: string of vkList: list_v: seq[string] converter to_bool*(v: Value): bool = ## Convert a Value to bool, depending on its kind: ## - vkNone: false ## - vkBool: boolean value itself ## - vkInt: true if integer is not zero ## - vkStr: true if string is not empty ## - vkList: true if sequence is not empty case v.kind of vkNone: false of vkBool: v.bool_v of vkInt: v.int_v != 0 of vkStr: v.str_v.len > 0 of vkList: v.list_v.len > 0 proc len*(v: Value): int = ## Return the integer of a vkInt Value ## or the length of the seq of a vkList value. ## It is an error to use it on other kinds of Values. if v.kind == vkInt: v.int_v else: v.list_v.len proc `@`*(v: Value): seq[string] = ## Return the seq of a vkList Value. ## It is an error to use it on other kinds of Values. v.list_v proc `[]`*(v: Value, i: int): string = ## Return the i-th item of the seq of a vkList Value. ## It is an error to use it on other kinds of Values. v.list_v[i] iterator items*(v: Value): string = ## Iterate over the seq of a vkList Value. ## It is an error to use it on other kinds of Values. for val in v.list_v: yield val iterator pairs*(v: Value): tuple[key: int, val: string] = ## Iterate over the seq of a vkList Value, yielding ``(index, v[index])`` ## pairs. ## It is an error to use it on other kinds of Values. for key, val in v.list_v: yield (key: key, val: val) proc str(s: string): string = "\"" & s.replace("\"", "\\\"") & "\"" proc str[T](s: seq[T]): string = "[" & s.map_it(string, it.str).join(", ") & "]" proc str(v: Value): string = case v.kind of vkNone: "nil" of vkStr: v.str_v.str of vkInt: $v.int_v of vkBool: $v.bool_v of vkList: v.list_v.str proc `$`*(v: Value): string = ## Return the string of a vkStr Value, ## or the item of a vkList Value, if there is exactly one, ## or a string representation of any other kind of Value. if v.kind == vkStr: v.str_v elif v.kind == vkList and v.list_v.len == 1: v.list_v[0] else: v.str proc `==`*(a, b: Value): bool {.gcsafe.} = a.kind == b.kind and a.str == b.str proc val(): Value = Value(kind: vkNone) proc val(v: bool): Value = Value(kind: vkBool, bool_v: v) proc val(v: int): Value = Value(kind: vkInt, int_v: v) proc val(v: string): Value = Value(kind: vkStr, str_v: v) proc val(v: seq[string]): Value = Value(kind: vkList, list_v: v) docopt.nim-0.7.1/src/docopt/util.nim0000664000175000017510000000320314502143666016670 0ustar nileshnilesh# Copyright (C) 2015 Oleh Prypin # Licensed under terms of MIT license (see LICENSE) import std/[strutils, unicode, macros] template any_it*(lst: typed, pred: untyped): bool = ## Does `pred` return true for any of the `it`s of `lst`? var result {.gensym.} = false for it {.inject.} in lst: if pred: result = true break result template map_it*(lst, typ: typed, op: untyped): untyped = ## Returns `seq[typ]` that contains `op` applied to each `it` of `lst` var result {.gensym.}: seq[typ] = @[] for it {.inject.} in items(lst): result.add(op) result proc count*[T](s: openarray[T], it: T): int = ## How many times this item appears in an array result = 0 for x in s: if x == it: result += 1 proc partition*(s, sep: string): tuple[left, sep, right: string] = ## "a+b".partition("+") == ("a", "+", "b") ## "a+b".partition("-") == ("a+b", "", "") assert sep != "" let pos = s.find(sep) if pos < 0: (s, "", "") else: (s.substr(0, pos.pred), s.substr(pos, pos.pred+sep.len), s.substr(pos+sep.len)) proc is_upper*(s: string): bool = ## Is the string in uppercase (and there is at least one cased character)? let upper = unicode.to_upper(s) s == upper and upper != unicode.to_lower(s) macro gen_class*(body: untyped): untyped = ## When applied to a type block, this will generate methods ## that return each type's name as a string. for typ in body[0].children: var meth = "method class(self: $1): string" if $typ[2][0][1][0] == "RootObj": meth &= "{.base, gcsafe.}" meth &= "= \"$1\"" body.add(parse_stmt(meth.format(typ[0]))) body docopt.nim-0.7.1/src/docopt/dispatch.nim0000664000175000017510000001041014502143666017510 0ustar nileshnileshimport std/[macros, strutils, sequtils, typetraits] import docopt macro runUserImplemented(x: typed, fallback: untyped): untyped = ## This macro takes a type from a generic and checks if there exists a ## callable named `to`. If such a callable exists it will call it. ## Otherwise it will output an error saying that the type is invalid. let typ = x.getType if typ.kind == nnkBracketExpr and typ[0].kind == nnkSym and $typ[0] == "typeDesc": let call = newIdentNode("to" & $typ[1]) result = quote do: when declared(`call`): `call`(v) else: `fallback` else: # This shouldn't really ever happen when properly passed a type from a generic result = fallback proc to[T](v: Value): T = when T is SomeInteger: T(parseInt($v)) elif T is bool: v.toBool elif T is string: $v elif T is seq: @v else: runUserImplemented(T): {.error: "Invalid type \"" & $T & "\" in signature of dispatched procedure".} proc discardable(b: bool): bool {.discardable.} = ## Wrapper proc to allow the boolean result of `dispatchProc` to be discarded b proc deSym(x: NimNode): NimNode = ## Procedure to strip symbols from a tree, replacing them with idents. This ## is needed to be able to snip the arguments from a procedure implementation ## and place them as arguments in Nim 1.4.0 result = x for i in 0..', '-'}) == `nameStr`: `setArguments`[`i`] = true `name` = `args`[`argIt`].to[:`kind`]() call.add name inc i # Define the variable for set arguments in the var section argVariables.add nnkIdentDefs.newTree(setArguments, newEmptyNode(), setArgs) # Stitches everything together result = quote do: if `check`: `argVariables` for `argIt` in `args`.keys: `findArgs` if `setArguments`.allIt(it == true): `call` discardable true else: discardable false docopt.nim-0.7.1/src/docopt.nim0000664000175000017510000005332414502143666015724 0ustar nileshnilesh# Copyright (C) 2012-2014 Vladimir Keleshev # Copyright (C) 2015 Oleh Prypin # Licensed under terms of MIT license (see LICENSE) from std/sequtils import deduplicate, delete, filter_it import std/[options, os, tables] import regex import docopt/util export tables include docopt/value type DocoptLanguageError* = object of CatchableError ## Error in construction of usage-message by developer. DocoptExit* = object of CatchableError ## Exit in case user invoked program with incorrect arguments. usage*: string gen_class: type Pattern = ref object of RootObj m_name: string value: Value has_children: bool children: seq[Pattern] ChildPattern = ref object of Pattern ParentPattern = ref object of Pattern Argument = ref object of ChildPattern Command = ref object of Argument Option = ref object of ChildPattern short: string long: string argcount: int Required = ref object of ParentPattern Optional = ref object of ParentPattern AnyOptions = ref object of Optional ## Marker/placeholder for [options] shortcut. OneOrMore = ref object of ParentPattern Either = ref object of ParentPattern proc argument(name: string, value = val()): Argument = Argument(m_name: name, value: value) proc command(name: string, value = val(false)): Command = Command(m_name: name, value: value) proc option(short, long: string = "", argcount = 0, value = val(false)): Option = assert argcount in [0, 1] result = Option(short: short, long: long, argcount: argcount, value: value) if value.kind == vkBool and not value and argcount > 0: result.value = val() proc required(children: varargs[Pattern]): Required = Required(has_children: true, children: @children, value: val()) proc optional(children: varargs[Pattern]): Optional = Optional(has_children: true, children: @children, value: val()) proc any_options(children: varargs[Pattern]): AnyOptions = AnyOptions(has_children: true, children: @children, value: val()) proc one_or_more(children: varargs[Pattern]): OneOrMore = OneOrMore(has_children: true, children: @children, value: val()) proc either(children: varargs[Pattern]): Either = Either(has_children: true, children: @children, value: val()) type MatchResult = tuple[matched: bool; left, collected: seq[Pattern]] SingleMatchResult = tuple[pos: int, match: Pattern] {.warning[LockLevel]: off.} method str(self: Pattern): string {.base, gcsafe, nosideeffect.} = assert false method name(self: Pattern): string {.base, gcsafe.} = self.m_name method `name=`(self: Pattern, name: string) {.base, gcsafe.} = self.m_name = name proc `==`(self, other: Pattern): bool = if self.is_nil and other.is_nil: true elif not self.is_nil and not other.is_nil: self.str == other.str else: # Exactly one of the two is nil false method flat(self: Pattern, types: varargs[string]): seq[Pattern] {.base, gcsafe.} = assert false method match(self: Pattern, left: seq[Pattern], collected: seq[Pattern] = @[]): MatchResult {.base, gcsafe.} = assert false method fix_identities(self: Pattern, uniq: seq[Pattern]) {.base, gcsafe.} = ## Make pattern-tree tips point to same object if they are equal. for i, child in self.children: if not child.has_children: assert child in uniq self.children[i] = uniq[uniq.find(child)] else: child.fix_identities(uniq) method fix_identities(self: Pattern) {.base, gcsafe.} = self.fix_identities(self.flat().deduplicate()) method either(self: Pattern): Either {.base, gcsafe.} = ## Transform pattern into an equivalent, with only top-level Either. # Currently the pattern will not be equivalent, but more "narrow", # although good enough to reason about list arguments. var ret: seq[seq[Pattern]] = @[] var groups = @[@[self]] while groups.len > 0: var children = groups[0] groups.delete(0) let classes = children.map_it(string, it.class) const parents = "Required Optional AnyOptions Either OneOrMore".split() if parents.any_it(it in classes): var child: Pattern for i, c in children: if c.class in parents: child = c children.delete(i..i) break assert child != nil if child.class == "Either": for c in child.children: groups.add(@[c] & children) elif child.class == "OneOrMore": groups.add(child.children & child.children & children) else: groups.add(child.children & children) else: ret.add children either(ret.map_it(Pattern, required(it))) method fix_repeating_arguments(self: Pattern) {.base, gcsafe.} = ## Fix elements that should accumulate/increment values. var either: seq[seq[Pattern]] = @[] for child in self.either.children: either.add(@(child.children)) for cas in either: for e in cas: if cas.count(e) <= 1: continue if e.class == "Argument" or e.class == "Option" and Option(e).argcount > 0: if e.value.kind == vkNone: e.value = val(@[]) elif e.value.kind != vkList: e.value = val(($e.value).split_whitespace()) if e.class == "Command" or e.class == "Option" and Option(e).argcount == 0: e.value = val(0) method fix(self: Pattern) {.base, gcsafe.} = self.fix_identities() self.fix_repeating_arguments() method str(self: ChildPattern): string = "$#($#, $#)".format(self.class, self.name.str, self.value.str) method flat(self: ChildPattern, types: varargs[string]): seq[Pattern] = if types.len == 0 or self.class in types: @[Pattern(self)] else: @[] method single_match(self: ChildPattern, left: seq[Pattern]): SingleMatchResult {.base, gcsafe.} = assert false method match(self: ChildPattern, left: seq[Pattern], collected: seq[Pattern] = @[]): MatchResult = var m: SingleMatchResult try: m = self.single_match(left) except ValueError: return (false, left, collected) var (pos, match) = m let left2 = left[0.. 0: var m: RegexMatch if description.find(re"(?i)\[default:\ (.*)\]", m): let bounds = m.group(0)[0] value = val(description.substr(bounds.a, bounds.b)) else: value = val() constructor(short, long, argcount, value) method single_match(self: Option, left: seq[Pattern]): SingleMatchResult = for n, pattern in left: if self.name == pattern.name: return (n, pattern) raise new_exception(ValueError, "Not found") method name(self: Option): string = if self.long != "": self.long else: self.short method str(self: Option): string = "Option($#, $#, $#, $#)".format(self.short.str, self.long.str, self.argcount, self.value.str) method match(self: Required, left: seq[Pattern], collected: seq[Pattern] = @[]): MatchResult = result = (true, left, collected) for pattern in self.children: result = pattern.match(result.left, result.collected) if not result.matched: return (false, left, collected) method match(self: Optional, left: seq[Pattern], collected: seq[Pattern] = @[]): MatchResult = result = (true, left, collected) for pattern in self.children: result = pattern.match(result.left, result.collected) result.matched = true method match(self: OneOrMore, left: seq[Pattern], collected: seq[Pattern] = @[]): MatchResult = assert self.children.len == 1 result = (true, left, collected) var l2: seq[Pattern] var times = 0 while result.matched: # could it be that something didn't match but changed l or c? result = self.children[0].match(result.left, result.collected) if result.matched: times += 1 if l2 == result.left: break l2 = result.left if times >= 1: result.matched = true else: return (false, left, collected) method match(self: Either, left: seq[Pattern], collected: seq[Pattern] = @[]): MatchResult = var found = false for pattern in self.children: let outcome = pattern.match(left, collected) if outcome.matched: if not found or outcome.left.len < result.left.len: result = outcome found = true if not found: return (false, left, collected) type TokenStream = ref object tokens: seq[string] error: ref Exception proc `@`(tokens: TokenStream): var seq[string] = tokens.tokens proc token_stream(source: seq[string], error: ref Exception): TokenStream = TokenStream(tokens: source, error: error) proc token_stream(source: string, error: ref Exception): TokenStream = token_stream(source.split_whitespace(), error) proc current(self: TokenStream): string = if @self.len > 0: @self[0] else: "" proc move(self: TokenStream): string = result = self.current @self.delete(0) proc parse_long(tokens: TokenStream, options: var seq[Option]): seq[Pattern] = ## long ::= '--' chars [ ( ' ' | '=' ) chars ] ; let (long, eq, v) = tokens.move().partition("=") assert long.starts_with "--" var value = (if eq == "" and v == "": val() else: val(v)) var similar = options.filter_it(it.long == long) var o: Option if tokens.error of DocoptExit and similar.len == 0: # if no exact match similar = options.filter_it(it.long != "" and it.long.starts_with long) if similar.len > 1: # might be simply specified ambiguously 2+ times? tokens.error.msg = "$# is not a unique prefix: $#?".format( long, similar.map_it(string, it.long).join(", ")) raise tokens.error elif similar.len < 1: let argcount = (if eq == "=": 1 else: 0) o = option("", long, argcount) options.add o if tokens.error of DocoptExit: o = option("", long, argcount, if argcount > 0: value else: val(true)) else: o = option(similar[0].short, similar[0].long, similar[0].argcount, similar[0].value) if o.argcount == 0: if value.kind != vkNone: tokens.error.msg = "$# must not have an argument".format(o.long) raise tokens.error else: if value.kind == vkNone: if tokens.current == "": tokens.error.msg = "$# requires argument".format(o.long) raise tokens.error value = val(tokens.move()) if tokens.error of DocoptExit: o.value = (if value.kind != vkNone: value else: val(true)) @[Pattern(o)] proc parse_shorts(tokens: TokenStream, options: var seq[Option]): seq[Pattern] = ## shorts ::= '-' ( chars )* [ [ ' ' ] chars ] ; let token = tokens.move() assert token.starts_with("-") and not token.starts_with("--") var left = token.substr(1) result = @[] while left != "": let short = "-" & left[0] left = left.substr(1) let similar = options.filter_it(it.short == short) var o: Option if similar.len > 1: tokens.error.msg = "$# is specified ambiguously $# times".format( short, similar.len) raise tokens.error elif similar.len < 1: o = option(short, "", 0) options.add o if tokens.error of DocoptExit: o = option(short, "", 0, val(true)) else: # why copying is necessary here? o = option(short, similar[0].long, similar[0].argcount, similar[0].value) var value = val() if o.argcount != 0: if left == "": if tokens.current == "": tokens.error.msg = "$# requires argument".format(short) raise tokens.error value = val(tokens.move()) else: value = val(left) left = "" if tokens.error of DocoptExit: o.value = (if value.kind != vkNone: value else: val(true)) result.add o proc parse_expr(tokens: TokenStream, options: var seq[Option]): seq[ Pattern] {.gcsafe.} proc parse_pattern(source: string, options: var seq[Option]): Required = var tokens = token_stream( source.replace(re"([\[\]\(\)\|]|\.\.\.)", r" $1 "), new_exception(DocoptLanguageError, "") ) let ret = parse_expr(tokens, options) if tokens.current != "": tokens.error.msg = "unexpected ending: '$#'".format(@tokens.join(" ")) raise tokens.error required(ret) proc parse_seq(tokens: TokenStream, options: var seq[Option]): seq[ Pattern] {.gcsafe.} proc parse_expr(tokens: TokenStream, options: var seq[Option]): seq[Pattern] = ## expr ::= seq ( '|' seq )* ; var sequ = parse_seq(tokens, options) if tokens.current != "|": return sequ var res = (if sequ.len > 1: @[Pattern(required(sequ))] else: sequ) while tokens.current == "|": discard tokens.move() sequ = parse_seq(tokens, options) res.add(if sequ.len > 1: @[Pattern(required(sequ))] else: sequ) return (if res.len > 1: @[Pattern(either(res))] else: res) proc parse_atom(tokens: TokenStream, options: var seq[Option]): seq[ Pattern] {.gcsafe.} proc parse_seq(tokens: TokenStream, options: var seq[Option]): seq[Pattern] = ## seq ::= ( atom [ '...' ] )* ; result = @[] while tokens.current notin ["", "]", ")", "|"]: var atom = parse_atom(tokens, options) if tokens.current == "...": let oom = one_or_more(atom) atom = @[Pattern(oom)] discard tokens.move() result.add atom proc parse_atom(tokens: TokenStream, options: var seq[Option]): seq[Pattern] = ## atom ::= '(' expr ')' | '[' expr ']' | 'options' ## | long | shorts | argument | command ; var token = tokens.current if token in ["(", "["]: discard tokens.move() var matching: string var ret: Pattern case token of "(": matching = ")" ret = required(parse_expr(tokens, options)) of "[": matching = "]" ret = optional(parse_expr(tokens, options)) else: assert false if tokens.move() != matching: tokens.error.msg = "unmatched '$#'".format(token) raise tokens.error @[ret] elif token == "options": discard tokens.move() @[Pattern(any_options())] elif (token.starts_with "--") and token != "--": parse_long(tokens, options) elif (token.starts_with "-") and token notin ["-", "--"]: parse_shorts(tokens, options) elif (token.starts_with "<") and (token.ends_with ">") or util.is_upper(token): @[Pattern(argument(tokens.move()))] else: @[Pattern(command(tokens.move()))] proc parse_argv(tokens: TokenStream, options: var seq[Option], options_first = false): seq[Pattern] = ## Parse command-line argument vector. ## ## If options_first: ## argv ::= [ long | shorts ]* [ argument ]* [ '--' [ argument ]* ] ; ## else: ## argv ::= [ long | shorts | argument ]* [ '--' [ argument ]* ] ; result = @[] while tokens.current != "": if tokens.current == "--": return result & @tokens.map_it(Pattern, argument("", val(it))) elif tokens.current.starts_with "--": result.add parse_long(tokens, options) elif (tokens.current.starts_with "-") and tokens.current != "-": result.add parse_shorts(tokens, options) elif options_first: return result & @tokens.map_it(Pattern, argument("", val(it))) else: result.add argument("", val(tokens.move())) proc parse_defaults(doc: string): seq[Option] = var split = doc.split_incl(re"\n\ *(<\S+?>|-\S+?)") result = @[] for i in 1 .. split.len div 2: var s = split[i*2-1] & split[i*2] if s.starts_with "-": result.add option.option_parse(s) proc printable_usage(doc: string): string = var usage_split = doc.split_incl(re"(?i)(Usage:)") if usage_split.len < 3: raise new_exception(DocoptLanguageError, """"usage:" (case-insensitive) not found.""") if usage_split.len > 3: raise new_exception(DocoptLanguageError, """More than one "usage:" (case-insensitive).""") usage_split.delete(0) usage_split.join().split_incl(re"\n\s*\n")[0].strip() proc formal_usage(printable_usage: string): string = var pu = printable_usage.split_whitespace() pu.delete(0) var pu0 = pu[0] pu.delete(0) "( " & pu.map_it(string, if it == pu0: ") | (" else: it).join(" ") & " )" proc extras(help: bool, version: string, options: seq[Pattern], doc: string) = if help and options.any_it((it.name in ["-h", "--help"]) and it.value): echo(doc.strip()) quit() elif version != "" and options.any_it(it.name == "--version" and it.value): echo(version) quit() proc docopt_exc(doc: string, argv: seq[string], help: bool, version: string, options_first = false): Table[string, Value] {.gcsafe.} = var doc = doc.replace("\r\l", "\l") var docopt_exit = new_exception(DocoptExit, "") docopt_exit.usage = printable_usage(doc) var options = parse_defaults(doc) var pattern = parse_pattern(formal_usage(docopt_exit.usage), options) var argvt = parse_argv(token_stream(argv, docopt_exit), options, options_first) var pattern_options = pattern.flat("Option").deduplicate() for any_options in pattern.flat("AnyOptions"): var doc_options = parse_defaults(doc).deduplicate() any_options.children = doc_options.filter_it( it notin pattern_options).map_it(Pattern, Pattern(it)) extras(help, version, argvt, doc) pattern.fix() var (matched, left, collected) = pattern.match(argvt) if matched and left.len == 0: # better error message if left? result = init_table[string, Value]() for a in pattern.flat(): result[a.name] = a.value for a in collected: result[a.name] = a.value else: raise docopt_exit proc docopt*(doc: string, argv: seq[string] = command_line_params(), help = true, version: string = "", options_first = false, quit = true ): Table[string, Value] {.gcsafe.} = ## Parse `argv` based on command-line interface described in `doc`. ## ## `docopt` creates your command-line interface based on its ## description that you pass as `doc`. Such description can contain ## --options, , commands, which could be ## [optional], (required), (mutually | exclusive) or repeated... ## ## Parameters ## ---------- ## doc : str ## Description of your command-line interface. ## argv : seq[string], optional ## Argument vector to be parsed. sys.argv[1:] is used if not ## provided. ## help : bool (default: true) ## Set to false to disable automatic help on -h or --help ## options. ## version : string ## If passed, the string will be printed if --version is in ## `argv`. ## options_first : bool (default: false) ## Set to true to require options precede positional arguments, ## i.e. to forbid options and positional arguments intermix. ## quit : bool (default: true) ## Set to false to let this function raise DocoptExit instead ## of printing usage and quitting the application. ## ## Returns ## ------- ## args : Table[string, Value] ## A dictionary, where keys are names of command-line elements ## such as e.g. "--verbose" and "", and values are the ## parsed values of those elements. ## ## Example ## ------- ## import tables, docopt ## ## let doc = """ ## Usage: ## my_program tcp [--timeout=] ## my_program serial [--baud=] [--timeout=] ## my_program (-h | --help | --version) ## ## Options: ## -h, --help Show this screen and exit. ## --baud= Baudrate [default: 9600] ## """ ## let argv = @["tcp", "127.0.0.1", "80", "--timeout", "30"] ## echo docopt(doc, argv) ## ## # {serial: false, : "127.0.0.1", --help: false, --timeout: "30", ## # --baud: "9600", --version: false, tcp: true, : "80"} ## ## See also ## -------- ## Full documentation: http://docopt.org/ if not quit: return docopt_exc(doc, argv, help, version, options_first) try: return docopt_exc(doc, argv, help, version, options_first) except DocoptExit: stderr.write_line((ref DocoptExit)(get_current_exception()).usage) quit() docopt.nim-0.7.1/examples/0000775000175000017510000000000014502143666014747 5ustar nileshnileshdocopt.nim-0.7.1/examples/odd_even.nim0000664000175000017510000000037014502143666017237 0ustar nileshnileshlet doc = """ Usage: odd_even [-h | --help] (ODD EVEN)... Example, try: odd_even 1 2 3 4 Options: -h, --help """ import docopt let args = docopt(doc) echo args for i in 0 ..< args["ODD"].len: echo args["ODD"][i] & " " & args["EVEN"][i] docopt.nim-0.7.1/examples/nim.cfg0000664000175000017510000000003514502143666016211 0ustar nileshnileshpath: "$project_path/../src" docopt.nim-0.7.1/examples/dispatch.nim0000664000175000017510000000500714502143666017255 0ustar nileshnileshlet doc = """ Naval Fate. Usage: naval_fate ship new ... naval_fate ship move [--speed=] naval_fate ship shoot naval_fate mine (set|remove) [--moored | --drifting] naval_fate (-h | --help) naval_fate --version Options: -h --help Show this screen. --version Show version. --speed= Speed in knots [default: 10]. --moored Moored (anchored) mine. --drifting Drifting mine. """ import std/[strutils, sequtils] import docopt type CustomInt* = distinct int # You can name a proc `to` in order to have the dispatcher be able # to marshall your custom types. proc toCustomInt*(v: Value): CustomInt = CustomInt(parseInt($v)) import docopt/dispatch let args = docopt(doc, version = "Naval Fate 2.0") # Define procedures with parameters named the same as the arguments proc newShip(name: seq[string]) = for ship in name: echo "Creating ship $#" % ship proc moveShip(name: string, x, y: int, speed: int) = echo "Moving ship $# to ($#, $#) at $# kn".format( name, x, y, speed) proc shootShip(x, y: CustomInt) = # This works because we have `toCustomInt` defined above echo "Shooting ship at ($#, $#)".format(x.int, y.int) # These procedures are not used below, but could be used similar to those above proc setMine(x, y: int, moored, drifting: bool) = echo "Setting $# mine at ($#, $#)".format( (if moored: "moored" elif drifting: "drifting" else: ""), x, y) proc removeMine(x, y: int) = echo "Removing mine at ($#, $#)".format(x, y) # This procedure is named the same as an argument so it can be passed directly # to `dispatchProc` without supplying a list of arguments to match. When no # list is supplied it will simply check for an argument named the same as the # procedure. proc mine(x, y: int, moored, remove: bool) = if remove: echo "Removing mine at ($#, $#)".format(x, y) else: echo "Setting $# mine at ($#, $#)".format( (if moored: "moored" else: "drifting"), x, y) if args.dispatchProc(newShip, "ship", "new") or # Runs newShip when "ship" and "new" is set args.dispatchProc(moveShip, "ship", "move") or # Runs newShip when "ship" and "move" is set args.dispatchProc(shootShip, "ship", "shoot") or # Runs newShip when "ship" and "shoot" is set args.dispatchProc(mine): # Runs mine when "mine" is set echo "Ran something" else: echo doc # Instead of the `mine` dispatcher above these could be used instead #args.dispatchProc(setMine, "mine", "set") #args.dispatchProc(removeMine, "mine", "remove") docopt.nim-0.7.1/examples/cycle.nim0000664000175000017510000000132614502143666016555 0ustar nileshnileshlet doc = """ Repeatedly output the arguments. Usage: cycle [options] ... Options: -h --help show this help message and exit -n output all the arguments N times [default: infinite] --interval wait after every line of output """ import std/[strutils, os] import docopt let args = docopt(doc) echo args let infinite = ($args["-n"] == "infinite") var n: int if not infinite: n = parse_int($args["-n"]) var interval = 0 if args["--interval"]: interval = to_int(parse_float($args["--interval"])*1000) while true: for s in @(args[""]): echo s if interval > 0: sleep interval if not infinite: dec n if n <= 0: break docopt.nim-0.7.1/examples/counted.nim0000664000175000017510000000075414502143666017123 0ustar nileshnileshlet doc = """ Usage: counted --help counted -v... counted go [go] counted (--path=)... counted Try: counted -vvvvvvvvvv counted go go counted --path ./here --path ./there counted this.txt that.txt """ import std/[strutils, unicode] import docopt let args = docopt(doc) echo args if args["-v"]: echo unicode.capitalize(repeat("very ", args["-v"].len - 1) & "verbose") for path in @(args["--path"]): echo read_file(path) docopt.nim-0.7.1/docopt.nimble0000664000175000017510000000057014502143666015613 0ustar nileshnileshversion = "0.7.1" author = "Oleh Prypin" description = "Command line option parser that will make you smile" license = "MIT" srcDir = "src" requires "nim >= 0.20.0" requires "regex >= 0.11.1" task test, "Test": exec "nimble c --verbosity:0 -r -y test/test" for f in listFiles("examples"): if f[^4..^1] == ".nim": exec "nimble compile --verbosity:0 --hints:off " & f docopt.nim-0.7.1/README.md0000664000175000017510000002046714502143666014421 0ustar nileshnilesh[docopt][docopt.org] creates *beautiful* command-line interfaces ================================================================ **This is a port of [docopt][docopt.py] to [Nim][]. Visit [docopt.org][] for more information.** ```nim let doc = """ Naval Fate. Usage: naval_fate ship new ... naval_fate ship move [--speed=] naval_fate ship shoot naval_fate mine (set|remove) [--moored | --drifting] naval_fate (-h | --help) naval_fate --version Options: -h --help Show this screen. --version Show version. --speed= Speed in knots [default: 10]. --moored Moored (anchored) mine. --drifting Drifting mine. """ import strutils import docopt let args = docopt(doc, version = "Naval Fate 2.0") if args["move"]: echo "Moving ship $# to ($#, $#) at $# kn".format( args[""], args[""], args[""], args["--speed"]) ships[$args[""]].move( parseFloat($args[""]), parseFloat($args[""]), speed = parseFloat($args["--speed"])) if args["new"]: for name in @(args[""]): echo "Creating ship $#" % name ``` The option parser is generated based on the docstring above that is passed to `docopt` function. `docopt` parses the usage pattern (`"Usage: ..."`) and option descriptions (lines starting with dash "`-`") and ensures that the program invocation matches the usage pattern; it parses options, arguments and commands based on that. The basic idea is that *a good help message has all necessary information in it to make a parser*. Documentation ------------- ```nim proc docopt(doc: string, argv: seq[string] = nil, help = true, version: string = nil, optionsFirst = false, quit = true): Table[string, Value] ``` `docopt` takes 1 required and 5 optional arguments: - `doc` is a string that contains a **help message** that will be parsed to create the option parser. The simple rules of how to write such a help message are described at [docopt.org][]. Here is a quick example of such a string: Usage: my_program [-hso FILE] [--quiet | --verbose] [INPUT ...] -h --help show this -s --sorted sorted output -o FILE specify output file [default: ./test.txt] --quiet print less text --verbose print more text - `argv` is an optional argument vector; by default `docopt` uses the argument vector passed to your program (`commandLineParams()`). Alternatively you can supply a list of strings like `@["--verbose", "-o", "hai.txt"]`. - `help`, by default `true`, specifies whether the parser should automatically print the help message (supplied as `doc`) and terminate, in case `-h` or `--help` option is encountered (options should exist in usage pattern). If you want to handle `-h` or `--help` options manually (as other options), set `help = false`. - `version`, by default `nil`, is an optional argument that specifies the version of your program. If supplied, then, (assuming `--version` option is mentioned in usage pattern) when parser encounters the `--version` option, it will print the supplied version and terminate. `version` can be any string, e.g. `"2.1.0rc1"`. > Note, when `docopt` is set to automatically handle `-h`, `--help` and `--version` options, you still need to mention them in usage pattern for this to work. Also, for your users to know about them. - `optionsFirst`, by default `false`. If set to `true` will disallow mixing options and positional arguments. I.e. after first positional argument, all arguments will be interpreted as positional even if the look like options. This can be used for strict compatibility with POSIX, or if you want to dispatch your arguments to other programs. - `quit`, by default `true`, specifies whether [`quit()`][quit] should be called after encountering invalid arguments or printing the help message (see `help`). Setting this to `false` will allow `docopt` to raise a `DocoptExit` exception (with the `usage` member set) instead. If the `doc` string is invalid, `DocoptLanguageError` will be raised. The **return** value is a [`Table`][table] with options, arguments and commands as keys, spelled exactly like in your help message. Long versions of options are given priority. For example, if you invoke the top example as: naval_fate ship Guardian move 100 150 --speed=15 the result will be: ```nim {"--drifting": false, "mine": false, "--help": false, "move": true, "--moored": false, "new": false, "--speed": "15", "remove": false, "--version": false, "set": false, "": @["Guardian"], "ship": true, "": "100", "shoot": false, "": "150"} ``` Note that this is not how the values are actually stored, because a `Table` can hold values of only one type. For that reason, a variant `Value` type is needed. `Value`'s only accessible member is `kind: ValueKind` (which shouldn't be needed anyway, because it is known beforehand). `ValueKind` is one of: - `vkNone` (No value) This kind of `Value` appears when there is an option which hasn't been set and has no default. It is `false` when converted `toBool`. - `vkBool` (A boolean) This represents whether a boolean flag has been set or not. Just use it in a boolean context (conversion `toBool` is present). - `vkInt` (An integer) An integer represents how many times a flag has been repeated (if it is possible to supply it multiple times). Use `value.len` to obtain this `int`, or just use the value in a boolean context to find out whether this flag is present at least once. - `vkStr` (A string) Any option that has a user-supplied value will be represented as a `string` (conversion to integers, etc, does not happen). To obtain this string, use `$value`. - `vkList` (A list of strings) Any value that can be supplied multiple times will be represented by a `seq[string]`, even if the user provides just one. To obtain this `seq`, use `@value`. To obtain its length, use `value.len` or `@value.len`. To obtain the n-th value (0-indexed), both `value[i]` and `@value[i]` will work. If you are sure there is exactly one value, `$value` is the same as `value[0]`. Note that you can use any kind of value in a boolean context and convert any value to `string`. Look [in the source code](src/docopt/value.nim) to find out more about these conversions. As of version 0.7.0 docopt also includes a dispatch mechanism for automatically running procedures and converting arguments. This works by a simple macro that inspects the signature of the given procedure. The macro then returns code that will inspect the parsed arguments and if a list of supplied conditions are true the matched arguments from the signature will be extracted from the arguments and converted to the correct type before the procedure is called. A simple example would be something like this (a longer example can be found in the examples folder): ```nim let doc = """ Naval Fate Lite Usage: naval_fate ship new ... naval_fate ship move [--speed=] naval_fate (-h | --help) naval_fate --version Options: -h --help Show this screen. --version Show version. --speed= Speed in knots [default: 10]. """ import strutils import docopt import docopt/dispatch import sequtils let args = docopt(doc, version = "Naval Fate Lite") # Define procedures with parameters named the same as the arguments proc newShip(name: seq[string]) = for ship in name: echo "Creating ship $#" % ship proc moveShip(name: string, x, y: int, speed: int) = echo "Moving ship $# to ($#, $#) at $# kn".format( name, x, y, speed) if args.dispatchProc(newShip, "ship", "new") or # Runs newShip if "ship" and "new" is set args.dispatchProc(moveShip, "ship", "move"): # Runs newShip if "ship" and "move" is set echo "Ran something" else: echo doc ``` Examples -------- See [examples](examples) folder. For more examples of docopt language see [docopt.py examples][]. Installation ------------ nimble install docopt This library has no dependencies outside the standard library. An impure [`re`][re] library is used. [docopt.org]: http://docopt.org/ [docopt.py]: https://github.com/docopt/docopt [docopt.py examples]: https://github.com/docopt/docopt/tree/master/examples [nim]: http://nim-lang.org/ [re]: https://nim-lang.org/docs/re.html [table]: https://nim-lang.org/docs/tables.html [quit]: https://nim-lang.org/docs/system.html#quit%2Cint docopt.nim-0.7.1/LICENSE0000664000175000017510000000221614502143666014137 0ustar nileshnileshThe MIT License (MIT) Copyright (C) 2012-2014 Vladimir Keleshev Copyright (C) 2015 Oleh Prypin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. docopt.nim-0.7.1/.gitignore0000664000175000017510000000026014502143666015117 0ustar nileshnilesh* !.gitignore !*.nim /*.nim !*.nimble !*.docopt !*.md !nim.cfg !README* !LICENSE !/src !/src/docopt !/test !/examples !/.github/ !/.github/workflows/ !/.github/workflows/*.yml