lib/tap/support/parser.rb in bahuvrihi-tap-0.10.7 vs lib/tap/support/parser.rb in bahuvrihi-tap-0.10.8
- old
+ new
@@ -2,10 +2,12 @@
autoload(:Shellwords, 'shellwords')
module Tap
module Support
+ # == Syntax
+ #
# ==== Round Assignment
# Tasks can be defined and set to a round using the following:
#
# break assigns task(s) to round
# -- next 0
@@ -21,11 +23,11 @@
# schema.rounds(true) # => [[0,1,3],[2], nil, [4]]
#
# ==== Workflow Assignment
# All simple workflow patterns except switch can be specified within
# the parse syntax (switch is the exception because there is no good
- # way to define a block from an array).
+ # way to define the switch block).
#
# break pattern source(s) target(s)
# --: sequence last next
# --[] fork last next
# --{} merge next last
@@ -38,11 +40,11 @@
# --[] last.fork(next)
# --1{2,3,4} 1.merge(2,3,4)
# --(2,3,4) last.sync_merge(2,3,4)
#
# Note how all of the bracketed styles behave similarly; they are
- # parsed with essentially the same code, only reversing the source
+ # parsed with essentially the same code, but reverse the source
# and target in the case of merges.
#
# Here a and b are sequenced inline. Task c is assigned to no
# workflow until the final argument which sequenced b and c.
#
@@ -244,10 +246,59 @@
options[Join::FLAGS[index]] = true
end
options
end
+
+ # Parses an arg hash into a schema argv. An arg hash is a hash
+ # using numeric keys to specify the [row][col] in a two-dimensional
+ # array where a set of values should go. Breaks are added between
+ # rows (if necessary) and the array is collapsed to yield the
+ # argv:
+ #
+ # argh = {
+ # 0 => {
+ # 0 => 'a',
+ # 1 => ['b', 'c']},
+ # 1 => 'z'
+ # }
+ # parse_argh(argh) # => ['--', 'a', 'b', 'c', '--', 'z']
+ #
+ # Non-numeric keys are converted to integers using to_i and
+ # existing breaks (such as workflow breaks) occuring at the
+ # start of a row are preseved.
+ #
+ # argh = {
+ # '0' => {
+ # '0' => 'a',
+ # '1' => ['b', 'c']},
+ # '1' => ['--:', 'z']
+ # }
+ # parse_argh(argh) # => ['--', 'a', 'b', 'c', '--:', 'z']
+ #
+ def parse_argh(argh)
+ rows = []
+ argh.each_pair do |row, values|
+ if values.kind_of?(Hash)
+ arry = []
+ values.each_pair {|col, value| arry[col.to_i] = value }
+ values = arry
+ end
+
+ rows[row.to_i] = values
+ end
+
+ argv = []
+ rows.each do |row|
+ row = [row].flatten.compact
+ if row.empty? || row[0] !~ BREAK
+ argv << '--'
+ end
+ argv.concat row
+ end
+ argv
+ end
end
include Utils
# The schema into which nodes are parsed
@@ -264,19 +315,25 @@
# workflow break lines. Rounds and workflows are dynamically parsed;
# tasks may be reassigned to different rounds or workflows by later
# arguments.
#
# Parse is non-destructive to argv. If a string argv is provided, parse
- # splits it into an array using Shellwords.
+ # splits it into an array using Shellwords; if a hash argv is provided,
+ # parse converts it to an array using Parser::Utils#parse_argh.
#
def parse(argv)
parse!(argv.kind_of?(String) ? argv : argv.dup)
end
# Same as parse, but removes parsed args from argv.
def parse!(argv)
- argv = Shellwords.shellwords(argv) if argv.kind_of?(String)
+ argv = case argv
+ when Array then argv
+ when String then Shellwords.shellwords(argv)
+ when Hash then parse_argh(argv)
+ else argv
+ end
argv.unshift('--')
escape = false
current_argv = schema[current_index].argv
@@ -344,13 +401,13 @@
end
protected
# The index of the node currently being parsed.
- attr_accessor :current_index
+ attr_accessor :current_index # :nodoc:
# Returns current_index-1, or raises an error if current_index < 1.
- def previous_index
+ def previous_index # :nodoc:
raise ArgumentError, 'there is no previous index' if current_index < 1
current_index - 1
end
# determines the type of break and modifies self appropriately
\ No newline at end of file