help_parser 7.0.200907 → 8.1.221206

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7df1feedeed249286efe5cd5f1e2cc187a91d348eab654d5a6f110292d0c3476
4
- data.tar.gz: a3f142a3d2cf4c6bf038b25e3552dfc3f56bfbb3469749386994b0763ccaea4c
3
+ metadata.gz: 157ae793a16a5b92ca1633306080465fcd2e9671aaed67dc01fb47cb318f0824
4
+ data.tar.gz: cc72ed9f03c94ef2f5455897807a49ba69e79786ceae5daa3d158d3265e9a931
5
5
  SHA512:
6
- metadata.gz: c3df75b2ae4640bc268e86774facbc7f60e74fda4d58c3262022e3a571cb3d716af2be92e7d1652e2ffa5469a1852da4a412e582141f155fe849f37e62d4e4dc
7
- data.tar.gz: 447dfb4939662fec618c4c315f104785e1923a6a625b82ed028981a9ff98c35c9049b23586501c8bd06e244f21de8da4cec2c491bf815a17d3c2d38f93495e4e
6
+ metadata.gz: aea35622e25f8fd0cf84cc3115ce15b524440e698f516ebbd89188fa56d30c098dcc8711d61cee4b07aa7b77f935091222c2b0ff71465480d0e9cf76530810f5
7
+ data.tar.gz: 88a2613d9487be0b11e0da90bef805abc5fc1a7ca0012a97b32d5aa62540f382cc91e38b6714e4279bdba319475b323126625b4cf092e037742f30ba1c4ee22a
data/README.md CHANGED
@@ -1,25 +1,30 @@
1
- # Help Parser VII: Deader
1
+ # Help Parser VIII: Helpland
2
2
 
3
- * [VERSION 7.0.200907](https://github.com/carlosjhr64/Ruby-HelpParser/releases)
4
- * [github](https://www.github.com/carlosjhr64/Ruby-HelpParser)
3
+ * [VERSION 8.1.221206](https://github.com/carlosjhr64/help_parser/releases)
4
+ * [github](https://www.github.com/carlosjhr64/help_parser)
5
5
  * [rubygems](https://rubygems.org/gems/help_parser)
6
6
 
7
7
  ## DESCRIPTION:
8
8
 
9
- Can't help YOU???
10
- You're not the first to say that...
9
+ Welcome to Help Parser!
10
+ Do you have your help text?
11
+ Let's parse!
11
12
 
12
- I will parse your help!
13
+ ## INSTALL:
14
+
15
+ ```console
16
+ $ gem install help_parser
17
+ ```
13
18
 
14
19
  ## SYNOPSIS:
15
20
  <!-- The following PREVIEW has been approved for ALL PROGRAMMERS by CarlosJHR64.
16
21
  For the README validator that checks against me lying....
17
22
  ```ruby
18
- unless File.basename($PROGRAM_NAME) == 'deader'
23
+ unless File.basename($PROGRAM_NAME) == 'party'
19
24
  # For example's sake say
20
- $PROGRAM_NAME = 'deader'
25
+ $PROGRAM_NAME = 'party'
21
26
  # and ARGV is
22
- ARGV.concat ["-\-age", "-\-date=2020-09-07", 'invoke', 'the', 'command']
27
+ ARGV.concat ["-\-age", "-\-date=2020-09-07", 'touch', 'that']
23
28
  # and proceed as if run as:
24
29
  # awesome -\-name=Doe -\-value a b c
25
30
  end
@@ -28,34 +33,35 @@ The following gem has been rated
28
33
  | M | Mature |
29
34
  -->
30
35
 
31
- > Who ever you are, you were meant to find me today...
32
- > there is no turning back!
33
- > Above all, don't invoke the command!
34
-
35
36
  ```ruby
36
37
  require "help_parser"
37
38
 
38
39
  HELP = <<-HELP
39
40
  # <= Hash here, parser skips
40
- # HelpParser: Deader command example #
41
+ # HelpParser: Party command example #
41
42
  Usage:
42
- deader :options+ [<args>+]
43
- deader [:alternate] <arg=FLOAT>
44
- deader literal <arg1=WORD> <arg2=WORD> <arg3=WORD>
43
+ party :options+ [<args>+]
44
+ party [:alternate] <arg=FLOAT>
45
+ party literal <arg1=WORD> <arg2=WORD>
45
46
  Options:
46
47
  -v --version \t Give version and quit
47
48
  -h --help \t Give help and quit
48
49
  -s --long \t Short long synonyms
49
- --command invoke \t Defaulted
50
+ --touch that \t Defaulted
50
51
  --date=DATE \t Typed
51
52
  --age=INTEGER 80 \t Typed and Defaulted
52
53
  -a --all=YN y \t Short, long, typed, and defaulted
53
54
  --to_be
54
55
  --not_to_be
56
+ --rain
57
+ --water
58
+ --wet
55
59
  Exclusive:
56
60
  to_be not_to_be \t Tells parser these are mutually exclusive keys
57
61
  Inclusive:
58
62
  date age \t Tells parser any of these must include all of these
63
+ Conditional:
64
+ rain water wet \t Tells parser if first then all
59
65
  Alternate:
60
66
  --invoke
61
67
  --wut
@@ -67,7 +73,7 @@ Types:
67
73
  YN /^[YNyn]$/
68
74
  # <= Hash here, parser breaks out
69
75
  # Notes #
70
- Don't invoke the command.
76
+ I wouldn't touch that!
71
77
  HELP
72
78
 
73
79
  VERSION = "1.2.3"
@@ -82,30 +88,27 @@ HelpParser.string(:arg1, :arg2, :arg3) # for OPTIONS.arg1, etc : String
82
88
  #=> [:arg1, :arg2, :arg3]
83
89
 
84
90
  ## If run as:
85
- ## deader --age --date=2020-09-07 invoke the command
86
- OPTIONS.age #=> 80
87
- OPTIONS.args #=> ["invoke", "the", "command"]
91
+ ## party --age --date=2020-09-07 touch that
92
+ OPTIONS.age? #=> 80
93
+ OPTIONS.age?.class #=> Integer
94
+ OPTIONS.args? #=> ["touch", "that"]
95
+ OPTIONS.args?.class #=> Array
88
96
  OPTIONS.arg? and OPTIONS.arg #=> false
97
+ OPTIONS.arg?.class #=> FalseClass
89
98
  ```
90
99
 
91
- YOU HAVE INVOKED THE COMMAND...
92
- YOUR HELP BELONGS TO ME!!!
93
-
94
100
  ## Features
95
101
 
96
- * $DEBUG=true on --debug
97
- * $VERBOSE=true on --verbose
102
+ * `$DEBUG=true` on --debug
103
+ * `$VERBOSE=true` on --verbose
98
104
  * -h and --help simultaneously will check help string for errors
99
-
100
- ## INSTALL:
101
-
102
- $ sudo gem install help_parser
105
+ * `HelpParser::REDTTY[msg]` will red color output `msg` to `$stderr`.
103
106
 
104
107
  ## LICENSE:
105
108
 
106
109
  (The MIT License)
107
110
 
108
- Copyright (c) 2020 CarlosJHR64
111
+ Copyright (c) 2022 CarlosJHR64
109
112
 
110
113
  Permission is hereby granted, free of charge, to any person obtaining
111
114
  a copy of this software and associated documentation files (the
@@ -28,9 +28,14 @@ module HelpParser
28
28
  # Diagnose user's usage.
29
29
  def diagnose
30
30
  dict = {}
31
- @specs.each do |k,v|
32
- next if RESERVED[k]
33
- v.flatten.map{|_|_.scan(/\w+/).first}.each{|_|dict[_]=true}
31
+ @specs.each do |section,list|
32
+ next if RESERVED.include? section
33
+ list.flatten.select{_1[0]=='-'}.each do |key_type|
34
+ key_type.scan(/\w+/) do |key|
35
+ dict[key]=true
36
+ break
37
+ end
38
+ end
34
39
  end
35
40
  typos = @hash.keys.select{|k|k.is_a? String and not dict[k]}
36
41
  raise UsageError, MSG[UNRECOGNIZED, typos] unless typos.empty?
@@ -46,10 +51,15 @@ module HelpParser
46
51
  regex = t2r[type]
47
52
  case value
48
53
  when String
49
- raise UsageError, "--#{key}=#{value} !~ #{type}=#{regex.inspect}" unless value=~regex
54
+ unless value=~regex
55
+ raise UsageError, "--#{key}=#{value} !~ #{type}=#{regex.inspect}"
56
+ end
50
57
  when Array
51
58
  value.each do |string|
52
- raise UsageError, "--#{key}=#{string} !~ #{type}=#{regex.inspect}" unless string=~regex
59
+ unless string=~regex
60
+ raise UsageError,
61
+ "--#{key}=#{string} !~ #{type}=#{regex.inspect}"
62
+ end
53
63
  end
54
64
  else
55
65
  raise UsageError, "--#{key} !~ #{type}=#{regex.inspect}"
@@ -61,7 +71,7 @@ module HelpParser
61
71
  def pad
62
72
  # Synonyms and defaults:
63
73
  @specs.each do |section,options|
64
- next if section==USAGE || section==TYPES
74
+ next if RESERVED.any?{section==_1}
65
75
  options.each do |words|
66
76
  next unless words.size>1
67
77
  first,second,default = words[0],words[1],words[2]
@@ -90,6 +100,8 @@ module HelpParser
90
100
  @hash[long] = default
91
101
  end
92
102
  end
103
+ else
104
+ raise SoftwareError, MSG[UNEXPECTED, words]
93
105
  end
94
106
  end
95
107
  end
@@ -106,22 +118,22 @@ module HelpParser
106
118
  end
107
119
  next
108
120
  elsif m=FLAG_GROUP.match(token)
109
- group,plus = m['k'],m['p']
121
+ group,plus = m[:k],m[:p]
110
122
  key = keys[i]
111
- raise NoMatch if key.nil? || key.is_a?(Integer)
123
+ raise NoMatch unless key.is_a? String
112
124
  list = @specs[group].flatten.select{|f|f[0]=='-'}.map{|f| F2K[f]}
113
125
  raise NoMatch unless list.include?(key)
114
126
  unless plus.nil?
115
127
  loop do
116
128
  key = keys[i+1]
117
- break if key.nil? || key.is_a?(Integer) || !list.include?(key)
129
+ break unless key.is_a?(String) and list.include?(key)
118
130
  i+=1
119
131
  end
120
132
  end
121
133
  elsif m=VARIABLE.match(token)
122
134
  key = keys[i]
123
135
  raise NoMatch unless key.is_a?(Integer)
124
- variable,plus = m['k'],m['p']
136
+ variable,plus = m[:k],m[:p]
125
137
  if plus.nil?
126
138
  @cache[variable] = @hash[key]
127
139
  else
@@ -1,8 +1,19 @@
1
1
  module HelpParser
2
+ VSN = ['v','version']
3
+ HLP = ['h','help']
4
+ VRBS,DBG = 'verbose','debug'
5
+
6
+ # reserved name
2
7
  USAGE = 'usage'
3
8
  TYPES = 'types'
4
9
  EXCLUSIVE = 'exclusive'
5
10
  INCLUSIVE = 'inclusive'
11
+ CONDITIONAL = 'conditional'
12
+ FLAG_CLUMPS = [EXCLUSIVE,INCLUSIVE,CONDITIONAL]
13
+ RESERVED = [USAGE,TYPES,EXCLUSIVE,INCLUSIVE,CONDITIONAL]
14
+
15
+ # sections
16
+ SECTION_NAME = /^(?<name>[A-Z]\w+):$/
6
17
 
7
18
  # usage
8
19
  FLAG = /^[-][-]?(?<k>\w+)$/
@@ -16,7 +27,8 @@ module HelpParser
16
27
 
17
28
  # spec -w,? --w+
18
29
  SHORT_LONG = /^[-](?<s>\w),?\s+[-][-](?<k>\w+)$/
19
- SHORT_LONG_DEFAULT = /^[-](?<s>\w),?\s+[-][-](?<k>\w+)(=(?<t>[A-Z]+))?,?\s+(?<d>[^-\s]\S*)$/
30
+ SHORT_LONG_DEFAULT =
31
+ /^[-](?<s>\w),?\s+[-][-](?<k>\w+)(=(?<t>[A-Z]+))?,?\s+(?<d>\S*)$/
20
32
 
21
33
  # spec W+ /~/
22
34
  TYPE_DEF = /^(?<t>[A-Z]+),?\s+\/(?<r>\S+)\/$/
@@ -43,6 +55,7 @@ module HelpParser
43
55
  REDUNDANT = 'Redundant'
44
56
  EXCLUSIVE_KEYS = 'Exclusive keys'
45
57
  INCLUSIVE_KEYS = 'Inclusive keys'
58
+ CONDITIONAL_KEYS = 'Conditional keys'
46
59
  UNBALANCED = 'Unbalanced brackets'
47
60
  UNRECOGNIZED_TOKEN = 'Unrecognized usage token'
48
61
  UNRECOGNIZED_TYPE = 'Unrecognized type spec'
@@ -68,6 +81,7 @@ module HelpParser
68
81
  # lambda utilities
69
82
  MSG = lambda{|msg,*keys| "#{msg}: #{keys.join(' ')}"}
70
83
  F2K = lambda{|f| f[1]=='-' ? f[2..((f.index('=')||0)-1)] : f[1]}
71
- RESERVED = lambda{|k| [USAGE,TYPES,EXCLUSIVE,INCLUSIVE].include?(k)} # reserved
72
- REDTTY = lambda{|msg,out=$stderr| out.tty? ? out.puts("\033[0;31m#{msg}\033[0m"): out.puts(msg)}
84
+ REDTTY = lambda{|msg,out=$stderr|
85
+ out.tty? ? out.puts("\033[0;31m#{msg}\033[0m"): out.puts(msg)
86
+ }
73
87
  end
@@ -1,10 +1,14 @@
1
1
  module HelpParser
2
+ # k2t is an acronym for the "key to type" mapping
2
3
  def self.k2t(specs)
3
4
  k2t = NoDupHash.new
4
- tokens = specs.select{|k,v| !(k==TYPES)}.values.flatten.select{|v|v.include?('=')}
5
+ # If specs section is not a RESERVED section, it's an options list.
6
+ tokens = specs.select{|k,v| k==USAGE or not RESERVED.include?(k)}
7
+ # Tokens associating a key to a type.
8
+ .values.flatten.select{|v|v.include?('=')}
5
9
  tokens.each do |token|
6
10
  if match = VARIABLE.match(token) || LONG.match(token)
7
- name, type = match['k'], match['t']
11
+ name, type = match[:k], match[:t]
8
12
  if _=k2t[name]
9
13
  raise HelpError, MSG[INCONSISTENT,name,type,_] unless type==_
10
14
  else
@@ -18,6 +22,7 @@ module HelpParser
18
22
  return k2t
19
23
  end
20
24
 
25
+ # t2r is an acronym for "type to regexp"
21
26
  def self.t2r(specs)
22
27
  if types = specs[TYPES]
23
28
  t2r = NoDupHash.new
@@ -20,7 +20,8 @@ module HelpParser
20
20
  class Options
21
21
  def #{name}?
22
22
  s = @hash['#{name}']
23
- raise UsageError, MSG[NOT_STRING,'#{name}'] unless s.nil? || s.is_a?(String)
23
+ raise UsageError, MSG[NOT_STRING,'#{name}'] unless s.nil? ||
24
+ s.is_a?(String)
24
25
  return s
25
26
  end
26
27
  end
@@ -50,7 +51,8 @@ module HelpParser
50
51
  class Options
51
52
  def #{name}?
52
53
  a = @hash['#{name}']
53
- raise UsageError, MSG[NOT_STRINGS,'#{name}'] unless a.nil? || a.is_a?(Array)
54
+ raise UsageError, MSG[NOT_STRINGS,'#{name}'] unless a.nil? ||
55
+ a.is_a?(Array)
54
56
  return a
55
57
  end
56
58
  end
@@ -64,9 +66,7 @@ module HelpParser
64
66
  code = <<-CODE
65
67
  class Options
66
68
  def #{name}
67
- f = @hash['#{name}']
68
- raise if f.nil?
69
- f.to_f
69
+ @hash['#{name}']&.to_f or raise
70
70
  rescue
71
71
  raise UsageError, MSG[NOT_FLOAT,'#{name}']
72
72
  end
@@ -81,9 +81,7 @@ module HelpParser
81
81
  code = <<-CODE
82
82
  class Options
83
83
  def #{name}?
84
- f = @hash['#{name}']
85
- f = f.to_f if f
86
- return f
84
+ @hash['#{name}']&.to_f
87
85
  rescue
88
86
  raise UsageError, MSG[NOT_FLOAT,'#{name}']
89
87
  end
@@ -98,9 +96,7 @@ module HelpParser
98
96
  code = <<-CODE
99
97
  class Options
100
98
  def #{name}
101
- f = @hash['#{name}']
102
- raise unless f.is_a?(Array)
103
- f.map{|_|_.to_f}
99
+ @hash['#{name}'].map{_1.to_f}
104
100
  rescue
105
101
  raise UsageError, MSG[#{NOT_FLOATS},'#{name}']
106
102
  end
@@ -115,10 +111,7 @@ module HelpParser
115
111
  code = <<-CODE
116
112
  class Options
117
113
  def #{name}?
118
- f = @hash['#{name}']
119
- return nil unless f
120
- raise unless f.is_a?(Array)
121
- f.map{|_|_.to_f}
114
+ @hash['#{name}']&.map{_1.to_f}
122
115
  rescue
123
116
  raise UsageError, MSG[NOT_FLOATS,'#{name}']
124
117
  end
@@ -133,9 +126,7 @@ module HelpParser
133
126
  code = <<-CODE
134
127
  class Options
135
128
  def #{name}
136
- f = @hash['#{name}']
137
- raise if f.nil?
138
- f.to_i
129
+ @hash['#{name}']&.to_i or raise
139
130
  rescue
140
131
  raise UsageError, MSG[NOT_INTEGER,'#{name}']
141
132
  end
@@ -150,9 +141,7 @@ module HelpParser
150
141
  code = <<-CODE
151
142
  class Options
152
143
  def #{name}?
153
- f = @hash['#{name}']
154
- f = f.to_i if f
155
- return f
144
+ @hash['#{name}']&.to_i
156
145
  rescue
157
146
  raise UsageError, MSG[NOT_INTEGER,'#{name}']
158
147
  end
@@ -167,9 +156,7 @@ module HelpParser
167
156
  code = <<-CODE
168
157
  class Options
169
158
  def #{name}
170
- f = @hash['#{name}']
171
- raise unless f.is_a?(Array)
172
- f.map{|_|_.to_i}
159
+ @hash['#{name}'].map{_1.to_i}
173
160
  rescue
174
161
  raise UsageError, MSG[NOT_INTEGERS,'#{name}']
175
162
  end
@@ -184,10 +171,7 @@ module HelpParser
184
171
  code = <<-CODE
185
172
  class Options
186
173
  def #{name}?
187
- f = @hash['#{name}']
188
- return nil unless f
189
- raise unless f.is_a?(Array)
190
- f.map{|_|_.to_i}
174
+ @hash['#{name}']&.map{_1.to_i}
191
175
  rescue
192
176
  raise UsageError, MSG[NOT_INTEGERS,'#{name}']
193
177
  end
@@ -2,36 +2,44 @@ module HelpParser
2
2
  class Options
3
3
  def initialize(version, help, argv)
4
4
  @hash = HelpParser.parsea(argv)
5
- if version && (@hash.has_key?('v') || @hash.has_key?('version'))
5
+ if version && VSN.any?{@hash.has_key? _1}
6
6
  # -v or --version
7
7
  raise VersionException, version
8
8
  end
9
9
  if help
10
- h = ['h', 'help']
11
- if h.any?{|_|@hash.key?_}
12
- HelpParser.parseh(help, validate: true) if h.all?{|_|@hash.key?_}
10
+ if HLP.any?{@hash.key? _1}
11
+ HelpParser.parseh(help, validate: true) if HLP.all?{@hash.key? _1}
13
12
  raise HelpException, help
14
13
  end
15
14
  specs = HelpParser.parseh(help)
16
15
  Completion.new(@hash, specs)
17
16
  if exclusive=specs[EXCLUSIVE]
18
17
  exclusive.each do |x|
19
- count = @hash.keys.count{|k|x.include?(k)}
18
+ count = x.count{@hash.key? _1}
20
19
  raise HelpParser::UsageError, MSG[EXCLUSIVE_KEYS,*x] if count > 1
21
20
  end
22
21
  end
23
22
  if inclusive=specs[INCLUSIVE]
24
23
  inclusive.each do |i|
25
- count = @hash.keys.count{|k|i.include?(k)}
26
- raise HelpParser::UsageError, MSG[INCLUSIVE_KEYS,*i] unless count==0 or count==i.length
24
+ count = i.count{@hash.key? _1}
25
+ unless count==0 or count==i.length
26
+ raise HelpParser::UsageError, MSG[INCLUSIVE_KEYS,*i]
27
+ end
28
+ end
29
+ end
30
+ if conditional=specs[CONDITIONAL]
31
+ conditional.each do |c|
32
+ if @hash.key? c[0] and not c.all?{@hash.key? _1}
33
+ raise HelpParser::UsageError, MSG[CONDITIONAL_KEYS,*c]
34
+ end
27
35
  end
28
36
  end
29
37
  end
30
- $VERBOSE = true if @hash['verbose']==true
31
- $DEBUG = true if @hash['debug']==true
38
+ $VERBOSE = true if @hash[VRBS]==true
39
+ $DEBUG = true if @hash[DBG]==true
32
40
  end
33
41
 
34
- def _hash
42
+ def to_h
35
43
  @hash
36
44
  end
37
45
 
@@ -4,8 +4,8 @@ module HelpParser
4
4
  help.each_line do |line|
5
5
  line.chomp!
6
6
  next if line==''
7
- if line=~/^[A-Z]\w+:$/
8
- name = line[0..-2].downcase
7
+ if md = SECTION_NAME.match(line)
8
+ name = md[:name].downcase
9
9
  specs[name] = []
10
10
  else
11
11
  next if name==''
@@ -15,29 +15,32 @@ module HelpParser
15
15
  raise HelpError, EXTRANEOUS_SPACES if validate and spec==''
16
16
  case name
17
17
  when USAGE
18
- HelpParser.validate_line_chars(spec.chars) if validate
18
+ Validate.balanced_brackets(spec.chars) if validate
19
19
  tokens = HelpParser.parseu(spec.chars)
20
- HelpParser.validate_usage_tokens(tokens) if validate
20
+ Validate.usage_tokens(tokens) if validate
21
21
  specs[USAGE].push tokens
22
22
  when TYPES
23
- raise HelpError, MSG[UNRECOGNIZED_TYPE,spec] if validate and not spec=~TYPE_DEF
23
+ if validate and not spec=~TYPE_DEF
24
+ raise HelpError, MSG[UNRECOGNIZED_TYPE,spec]
25
+ end
24
26
  specs[TYPES].push spec.split(CSV)
25
- when EXCLUSIVE,INCLUSIVE
26
- raise HelpError, MSG[UNRECOGNIZED_X,spec] if validate and not spec=~X_DEF
27
+ when *FLAG_CLUMPS # EXCLUSIVE,INCLUSIVE,CONDITIONAL,...
28
+ if validate and not spec=~X_DEF
29
+ raise HelpError, MSG[UNRECOGNIZED_X,spec]
30
+ end
27
31
  specs[name].push spec.split(CSV)
28
32
  else
29
- if validate and not [SHORT, LONG, SHORT_LONG, SHORT_LONG_DEFAULT].any?{|_|_=~spec}
30
- raise HelpError, MSG[UNRECOGNIZED_OPTION,spec]
31
- end
33
+ raise HelpError, MSG[UNRECOGNIZED_OPTION,spec] if validate and
34
+ not [SHORT, LONG, SHORT_LONG, SHORT_LONG_DEFAULT].any?{_1=~spec}
32
35
  specs[name].push spec.split(CSV)
33
36
  end
34
37
  end
35
38
  end
36
39
  if validate
37
- HelpParser.validate_usage_specs(specs)
40
+ Validate.usage_specs(specs)
38
41
  if t2r = HelpParser.t2r(specs)
39
42
  k2t = HelpParser.k2t(specs)
40
- HelpParser.validate_k2t2r(specs, k2t, t2r)
43
+ Validate.k2t2r(specs, k2t, t2r)
41
44
  end
42
45
  end
43
46
  return specs
@@ -1,4 +1,8 @@
1
1
  module HelpParser
2
+ # Chars := String.split(/\t/,2).first.strip.chars
3
+ # Token := String=~/^[^ \[\]]$/
4
+ # Note that emergent Token is String=~/^[^\s\[\]]$/
5
+ # Tokens := Array(Token|Tokens)
2
6
  def self.parseu(chars)
3
7
  tokens,token = [],''
4
8
  while c = chars.shift
@@ -1,5 +1,6 @@
1
1
  module HelpParser
2
- def self.validate_line_chars(chars)
2
+ module Validate
3
+ def self.balanced_brackets(chars)
3
4
  count = 0
4
5
  chars.each do |c|
5
6
  if c=='['
@@ -12,30 +13,29 @@ module HelpParser
12
13
  raise HelpError, MSG[UNBALANCED,chars.join] unless count==0
13
14
  end
14
15
 
15
- def self.validate_usage_tokens(tokens)
16
+ def self.usage_tokens(tokens)
16
17
  words = []
17
18
  tokens.flatten.each do |token|
18
- match = token.match(FLAG) ||
19
- token.match(LITERAL) ||
20
- token.match(VARIABLE) ||
21
- token.match(FLAG_GROUP)
22
- raise HelpError, MSG[UNRECOGNIZED_TOKEN,token] unless match
23
- words.push match['k'] # key
19
+ raise HelpError, MSG[UNRECOGNIZED_TOKEN,token] unless
20
+ [FLAG,LITERAL,VARIABLE,FLAG_GROUP]
21
+ .detect{_=token.match(_1) and words.push(_[:k])}
24
22
  end
25
23
  words.each_with_index do |word,i|
26
24
  raise HelpError, MSG[DUP_WORD,word] unless i==words.rindex(word)
27
25
  end
28
26
  end
29
27
 
30
- def self.validate_usage_specs(specs)
31
- option_specs = specs.select{|a,b| !RESERVED[a]}
32
- flags = option_specs.values.flatten.select{|f|f[0]=='-'}.map{|f| F2K[f]}
33
- [EXCLUSIVE,INCLUSIVE].each do |k|
28
+ def self.usage_specs(specs)
29
+ flags = specs.select{|a,b| not RESERVED.include? a}.values.flatten
30
+ .select{|f|f[0]=='-'}.map{|f| F2K[f]}
31
+ FLAG_CLUMPS.each do |k|
34
32
  if a=specs[k]
35
33
  seen = {}
36
34
  a.each do |xs|
37
35
  k = xs.sort.join(' ').to_sym
38
- raise HelpError, MSG[DUP_X,k] if seen[k] or not xs.length==xs.uniq.length
36
+ if seen[k] or not xs.length==xs.uniq.length
37
+ raise HelpError, MSG[DUP_X,k]
38
+ end
39
39
  seen[k] = true
40
40
  xs.each do |x|
41
41
  raise HelpError, MSG[UNSEEN_FLAG, x] unless flags.include?(x)
@@ -51,7 +51,7 @@ module HelpParser
51
51
  unless specs_usage.nil?
52
52
  specs_usage.flatten.each do |token|
53
53
  if match = token.match(FLAG_GROUP)
54
- key = match['k']
54
+ key = match[:k]
55
55
  raise HelpError, MSG[UNDEFINED_SECTION,key] unless specs[key]
56
56
  group.push(key)
57
57
  end
@@ -59,19 +59,19 @@ module HelpParser
59
59
  end
60
60
  specs.each do |key,tokens|
61
61
  raise HelpError, MSG[MISSING_CASES,key] unless tokens.size>0
62
- next if specs_usage.nil? or RESERVED[key]
62
+ next if specs_usage.nil? or RESERVED.include? key
63
63
  raise HelpError, MSG[MISSING_USAGE,key] unless group.include?(key)
64
64
  end
65
65
  end
66
66
 
67
- def self.validate_k2t2r(specs, k2t, t2r)
67
+ def self.k2t2r(specs, k2t, t2r)
68
68
  a,b = k2t.values.uniq.sort,t2r.keys.sort
69
69
  unless a==b
70
70
  c = (a+b).uniq.select{|x|!(a.include?(x) && b.include?(x))}
71
71
  raise HelpError, MSG[UNCOMPLETED_TYPES,c.join(',')]
72
72
  end
73
73
  specs.each do |section,tokens|
74
- next if section==USAGE || section==TYPES
74
+ next if RESERVED.include? section
75
75
  tokens.each do |words|
76
76
  next if words.size<2
77
77
  default = words[-1]
@@ -82,8 +82,11 @@ module HelpParser
82
82
  long = long_type[2..(i-1)]
83
83
  type = long_type[(i+1)..-1]
84
84
  regex = t2r[type]
85
- raise HelpError, MSG[BAD_DEFAULT,long,default,type,regex.inspect] unless regex=~default
85
+ unless regex=~default
86
+ raise HelpError, MSG[BAD_DEFAULT,long,default,type,regex.inspect]
87
+ end
86
88
  end
87
89
  end
88
90
  end
89
91
  end
92
+ end
data/lib/help_parser.rb CHANGED
@@ -1,17 +1,17 @@
1
- require_relative './help_parser/constants'
2
- require_relative './help_parser/exceptions'
3
- require_relative './help_parser/aliases'
4
- require_relative './help_parser/parsea'
5
- require_relative './help_parser/validations'
6
- require_relative './help_parser/parseu'
7
- require_relative './help_parser/parseh'
8
- require_relative './help_parser/k2t2r'
9
- require_relative './help_parser/completion'
10
- require_relative './help_parser/options'
11
- require_relative './help_parser/macros'
1
+ require_relative 'help_parser/constants'
2
+ require_relative 'help_parser/exceptions'
3
+ require_relative 'help_parser/aliases'
4
+ require_relative 'help_parser/parsea'
5
+ require_relative 'help_parser/parseu'
6
+ require_relative 'help_parser/parseh'
7
+ require_relative 'help_parser/k2t2r'
8
+ require_relative 'help_parser/completion'
9
+ require_relative 'help_parser/options'
10
+ require_relative 'help_parser/macros'
12
11
 
13
12
  module HelpParser
14
- VERSION = '7.0.200907'
13
+ VERSION = '8.1.221206'
14
+ autoload :Validate, 'help_parser/validate'
15
15
 
16
16
  def self.[](
17
17
  version = nil,
@@ -21,16 +21,6 @@ module HelpParser
21
21
  rescue HelpParserException => exception
22
22
  exception.exit
23
23
  end
24
-
25
- def self.run(
26
- version = nil,
27
- help = nil,
28
- argv = [File.basename($0)]+ARGV)
29
- options = Options.new(version, help, argv)
30
- yield options
31
- rescue HelpParserException => exception
32
- exception.exit
33
- end
34
24
  end
35
25
 
36
26
  # Requires:
metadata CHANGED
@@ -1,20 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: help_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.0.200907
4
+ version: 8.1.221206
5
5
  platform: ruby
6
6
  authors:
7
- - carlosjhr64
7
+ - CarlosJHR64
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-07 00:00:00.000000000 Z
11
+ date: 2022-12-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: |
14
- Can't help YOU???
15
- You're not the first to say that...
16
-
17
- I will parse your help!
13
+ description: "Welcome to Help Parser! \nDo you have your help text? \nLet's parse!\n"
18
14
  email: carlosjhr64@gmail.com
19
15
  executables: []
20
16
  extensions: []
@@ -33,8 +29,8 @@ files:
33
29
  - lib/help_parser/parsea.rb
34
30
  - lib/help_parser/parseh.rb
35
31
  - lib/help_parser/parseu.rb
36
- - lib/help_parser/validations.rb
37
- homepage: https://github.com/carlosjhr64/Ruby-HelpParser
32
+ - lib/help_parser/validate.rb
33
+ homepage: https://github.com/carlosjhr64/help_parser
38
34
  licenses:
39
35
  - MIT
40
36
  metadata: {}
@@ -53,9 +49,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
53
49
  - !ruby/object:Gem::Version
54
50
  version: '0'
55
51
  requirements:
56
- - 'ruby: ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]'
57
- rubygems_version: 3.1.2
52
+ - 'ruby: ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [aarch64-linux]'
53
+ rubygems_version: 3.3.7
58
54
  signing_key:
59
55
  specification_version: 4
60
- summary: Can't help YOU??? You're not the first to say that...
56
+ summary: Welcome to Help Parser! Do you have your help text? Let's parse!
61
57
  test_files: []