term_utils 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/COPYING +3 -3
- data/README.md +7 -1
- data/doc/TermUtils/AP/Article.html +991 -0
- data/doc/TermUtils/AP/Element.html +1025 -0
- data/doc/TermUtils/AP/Flag.html +539 -0
- data/doc/TermUtils/AP/Level.html +638 -0
- data/doc/TermUtils/AP/NoSuchValueError.html +217 -0
- data/doc/TermUtils/AP/Parameter.html +804 -0
- data/doc/TermUtils/AP/ParseError.html +217 -0
- data/doc/TermUtils/AP/Parser.html +572 -0
- data/doc/TermUtils/AP/Result.html +1029 -0
- data/doc/TermUtils/AP/ResultView.html +597 -0
- data/doc/TermUtils/AP/Syntax.html +1051 -0
- data/doc/TermUtils/AP/SyntaxError.html +217 -0
- data/doc/TermUtils/AP.html +505 -0
- data/doc/TermUtils/FF/Config.html +1 -1
- data/doc/TermUtils/FF/Cursor/Context.html +1 -1
- data/doc/TermUtils/FF/Cursor.html +1 -1
- data/doc/TermUtils/FF/Query.html +1 -1
- data/doc/TermUtils/FF.html +1 -1
- data/doc/TermUtils/PropertyTreeNode.html +1999 -0
- data/doc/TermUtils/Tab/Column.html +1 -1
- data/doc/TermUtils/Tab/Holder.html +1 -1
- data/doc/TermUtils/Tab/Printer.html +1 -1
- data/doc/TermUtils/Tab/Table.html +1 -1
- data/doc/TermUtils/Tab.html +1 -1
- data/doc/TermUtils.html +5 -3
- data/doc/_index.html +143 -1
- data/doc/class_list.html +1 -1
- data/doc/file.README.html +8 -2
- data/doc/index.html +8 -2
- data/doc/method_list.html +638 -22
- data/doc/top-level-namespace.html +1 -1
- data/lib/term_utils/ap/article.rb +68 -0
- data/lib/term_utils/ap/element.rb +78 -0
- data/lib/term_utils/ap/flag.rb +48 -0
- data/lib/term_utils/ap/level.rb +57 -0
- data/lib/term_utils/ap/no_such_value_error.rb +27 -0
- data/lib/term_utils/ap/parameter.rb +75 -0
- data/lib/term_utils/ap/parse_error.rb +27 -0
- data/lib/term_utils/ap/parser.rb +185 -0
- data/lib/term_utils/ap/result.rb +175 -0
- data/lib/term_utils/ap/syntax.rb +112 -0
- data/lib/term_utils/ap/syntax_error.rb +27 -0
- data/lib/term_utils/ap.rb +59 -0
- data/lib/term_utils/property_tree_node.rb +200 -0
- data/lib/term_utils.rb +1 -0
- data/term_utils.gemspec +2 -2
- metadata +29 -2
@@ -0,0 +1,175 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
#
|
3
|
+
# Copyright (C) 2019 Thomas Baron
|
4
|
+
#
|
5
|
+
# This file is part of term_utils.
|
6
|
+
#
|
7
|
+
# term_utils is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation, version 3 of the License.
|
10
|
+
#
|
11
|
+
# term_utils is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with term_utils. If not, see <https://www.gnu.org/licenses/>.
|
18
|
+
module TermUtils
|
19
|
+
module AP
|
20
|
+
# Represents an argument parsing Result.
|
21
|
+
class Result
|
22
|
+
# @return [TermUtils::PropertyTreeNode]
|
23
|
+
attr_accessor :value
|
24
|
+
# Constructs a new Result.
|
25
|
+
# @param syntax [Darn::AP::Syntax] Syntax.
|
26
|
+
# @param element [Darn::AP::Element] Optional Element.
|
27
|
+
# @param value [Darn::PropertyTreeNode] Optional value.
|
28
|
+
def initialize(syntax, element = nil, value = nil)
|
29
|
+
@syntax = syntax.dup
|
30
|
+
@element = element ? element.dup : nil
|
31
|
+
if value
|
32
|
+
@value = value.dup
|
33
|
+
@value.key = nil
|
34
|
+
else
|
35
|
+
@value = TermUtils::PropertyTreeNode.new
|
36
|
+
end
|
37
|
+
end
|
38
|
+
# Tests whether a given level/parameter/article is present in the result value.
|
39
|
+
# @param id [Symbol, Array<Symbol>]
|
40
|
+
# @return [Boolean]
|
41
|
+
def present?(id)
|
42
|
+
if id.is_a? Symbol
|
43
|
+
!!@value.child_node(id)
|
44
|
+
elsif id.is_a? Array
|
45
|
+
@value.node_exists?(id)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
# Evaluates the number of occurrences of a given level, parameter or article.
|
49
|
+
# @param id [Symbol, Array<Symbol>]
|
50
|
+
# @return [Integer]
|
51
|
+
def eval_occurs(id)
|
52
|
+
id = [id] if id.is_a? Symbol
|
53
|
+
obj = fetch_syntax_object(id)
|
54
|
+
raise TermUtils::AP::NoSuchValueError, "no such syntax object" unless obj
|
55
|
+
node = @value.find_node(id)
|
56
|
+
return 0 unless node
|
57
|
+
return 1 if obj.occur_bounded? && (obj.max_occurs == 1)
|
58
|
+
# Parameter is multiple.
|
59
|
+
node.child_nodes ? node.child_nodes.length : 0
|
60
|
+
end
|
61
|
+
# Fetches a value.
|
62
|
+
# @param id [Symbol, Array<Symbol>, nil]
|
63
|
+
# @param opts [Hash] `:index`, `:multi`.
|
64
|
+
# @option opts [Integer] :index The index of a multiple-occurrence level/parameter/article.
|
65
|
+
# @option opts [Boolean] :multi Whether an array of values shall be returned instead of a single value.
|
66
|
+
# @return [Object]
|
67
|
+
# @raise [TermUtils::AP::NoSuchValueError]
|
68
|
+
def fetch_value(id, opts = {})
|
69
|
+
index = opts.fetch(:index, nil)
|
70
|
+
multi = opts.fetch(:multi, false)
|
71
|
+
unless id
|
72
|
+
node = @value
|
73
|
+
if node && node.child_nodes && index
|
74
|
+
node = node.child_node(index)
|
75
|
+
end
|
76
|
+
raise TermUtils::AP::NoSuchValueError, "no such value" unless node
|
77
|
+
vals = node.collect_values
|
78
|
+
raise TermUtils::AP::NoSuchValueError, "no such value" if vals.empty?
|
79
|
+
return multi ? vals : vals.first
|
80
|
+
end
|
81
|
+
id = [id] if id.is_a? Symbol
|
82
|
+
obj = fetch_syntax_object(id)
|
83
|
+
raise TermUtils::AP::NoSuchValueError, "no such syntax object" unless obj
|
84
|
+
node = @value.find_node(id)
|
85
|
+
if node && node.child_nodes && index
|
86
|
+
node = node.child_node(index)
|
87
|
+
end
|
88
|
+
raise TermUtils::AP::NoSuchValueError, "no such value" unless node
|
89
|
+
catch :value do
|
90
|
+
if obj.is_a? TermUtils::AP::Parameter
|
91
|
+
raise TermUtils::AP::NoSuchValueError, "parameter has no article" if obj.articles.empty?
|
92
|
+
raise TermUtils::AP::NoSuchValueError, "no such value" if node.leaf?
|
93
|
+
vals = node.collect_values
|
94
|
+
raise TermUtils::AP::NoSuchValueError, "no such value" if vals.empty?
|
95
|
+
if multi
|
96
|
+
throw :value, vals
|
97
|
+
else
|
98
|
+
throw :value, vals.first
|
99
|
+
end
|
100
|
+
elsif obj.is_a? TermUtils::AP::Article
|
101
|
+
# raise TermUtils::AP::NoSuchValueError, "no such value" if node.leaf?
|
102
|
+
vals = node.collect_values
|
103
|
+
raise TermUtils::AP::NoSuchValueError, "no such value" if vals.empty?
|
104
|
+
if multi
|
105
|
+
throw :value, vals
|
106
|
+
else
|
107
|
+
throw :value, vals.first
|
108
|
+
end
|
109
|
+
end
|
110
|
+
raise TermUtils::AP::NoSuchValueError, "wrong id"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
# Shifts this one.
|
114
|
+
# @param id [Symbol, Array<Symbol>]
|
115
|
+
# @param opts [Hash] `:index`, `:multi`.
|
116
|
+
# @option opts [Integer] :index The index of a multiple-occurrence level/parameter/article.
|
117
|
+
# @return [TermUtils::AP::Result]
|
118
|
+
# @raise [TermUtils::AP::NoSuchValueError]
|
119
|
+
def shift(id, opts = {})
|
120
|
+
index = opts.fetch(:index, nil)
|
121
|
+
id = [id] if id.is_a? Symbol
|
122
|
+
obj = fetch_syntax_object(id)
|
123
|
+
raise TermUtils::AP::NoSuchValueError, "no such syntax object" unless obj
|
124
|
+
node = @value.find_node(id)
|
125
|
+
if node && node.child_nodes && index
|
126
|
+
node = node.child_node(index)
|
127
|
+
end
|
128
|
+
raise TermUtils::AP::NoSuchValueError, "no such value" unless node
|
129
|
+
catch :value do
|
130
|
+
if obj.is_a? TermUtils::AP::Level
|
131
|
+
throw :value, TermUtils::AP::Result.new(obj.syntax, nil, node)
|
132
|
+
elsif obj.is_a? TermUtils::AP::Parameter
|
133
|
+
throw :value, TermUtils::AP::Result.new(@syntax, obj, node)
|
134
|
+
elsif obj.is_a? TermUtils::AP::Article
|
135
|
+
throw :value, TermUtils::AP::Result.new(@syntax, obj, node)
|
136
|
+
end
|
137
|
+
raise TermUtils::AP::NoSuchValueError, "wrong id"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
private
|
141
|
+
# Fetches a given syntax object.
|
142
|
+
# @param id_path [Array<Symbol>]
|
143
|
+
# @return [TermUtils::AP::Level, TermUtils::AP::Parameter, TermUtils::AP::Article, nil]
|
144
|
+
def fetch_syntax_object(id_path)
|
145
|
+
id = id_path.dup
|
146
|
+
id = [@element.id].concat(id) if @element
|
147
|
+
catch :done do
|
148
|
+
fetch_syntax_object0(@syntax, id)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
# Fetches a given syntax object.
|
152
|
+
# @param syntax [TermUtils::AP::Syntax]
|
153
|
+
# @param id_path [Array<Symbol>]
|
154
|
+
# @return [TermUtils::AP::Level, TermUtils::AP::Parameter, TermUtils::AP::Article, nil]
|
155
|
+
def fetch_syntax_object0(syntax, id_path)
|
156
|
+
id = id_path.shift
|
157
|
+
syntax.elements.each do |e|
|
158
|
+
next unless e.id == id
|
159
|
+
throw :done, e if id_path.empty?
|
160
|
+
if e.is_a? TermUtils::AP::Level
|
161
|
+
fetch_syntax_object0(e.syntax, id_path)
|
162
|
+
elsif e.is_a? TermUtils::AP::Parameter
|
163
|
+
throw :done if id_path.empty?
|
164
|
+
id = id_path.shift
|
165
|
+
throw :done unless id_path.empty?
|
166
|
+
e.articles.each do |a|
|
167
|
+
throw :done, a if a.id = id
|
168
|
+
end
|
169
|
+
throw :done
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
#
|
3
|
+
# Copyright (C) 2019 Thomas Baron
|
4
|
+
#
|
5
|
+
# This file is part of term_utils.
|
6
|
+
#
|
7
|
+
# term_utils is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation, version 3 of the License.
|
10
|
+
#
|
11
|
+
# term_utils is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with term_utils. If not, see <https://www.gnu.org/licenses/>.
|
18
|
+
module TermUtils
|
19
|
+
module AP
|
20
|
+
# Represents the argument list syntax. It holds a list of parameters and
|
21
|
+
# levels.
|
22
|
+
class Syntax
|
23
|
+
# @return [Array<TermUtils::AP::Element>]
|
24
|
+
attr_accessor :elements
|
25
|
+
# Constructs a new Syntax.
|
26
|
+
def initialize
|
27
|
+
@elements = []
|
28
|
+
end
|
29
|
+
# For dup method.
|
30
|
+
def initialize_dup(other)
|
31
|
+
if other.elements
|
32
|
+
@elements = []
|
33
|
+
other.elements.each do |e|
|
34
|
+
@elements << e.dup
|
35
|
+
end
|
36
|
+
end
|
37
|
+
super
|
38
|
+
end
|
39
|
+
# Finalizes this one. Internal use.
|
40
|
+
# @return [nil]
|
41
|
+
def finalize!(opts = {})
|
42
|
+
opts[:anonymous] = 0 unless opts.has_key? :anonymous
|
43
|
+
@elements.each { |e| e.finalize!(opts) }
|
44
|
+
end
|
45
|
+
# Creates and adds a new Parameter.
|
46
|
+
# @param opts [Hash]
|
47
|
+
# @option opts [Symbol] :id
|
48
|
+
# @option opts [Integer] :min_occurs Default value is `0`.
|
49
|
+
# @option opts [Integer] :max_occurs Default value is `1`.
|
50
|
+
# @return [TermUtils::AP::Parameter]
|
51
|
+
def define_parameter(opts = {}, &block)
|
52
|
+
new_parameter = TermUtils::AP::Parameter.new(opts)
|
53
|
+
@elements << new_parameter
|
54
|
+
block.call(new_parameter) if block
|
55
|
+
new_parameter
|
56
|
+
end
|
57
|
+
# Creates and adds a new Level.
|
58
|
+
# @param opts [Hash]
|
59
|
+
# @option opts [Symbol] :id
|
60
|
+
# @option opts [Integer] :min_occurs Default value is `0`.
|
61
|
+
# @option opts [Integer] :max_occurs Default value is `1`.
|
62
|
+
# @return [TermUtils::AP::Level]
|
63
|
+
def define_level(opts = {}, &block)
|
64
|
+
new_level = TermUtils::AP::Level.new(opts)
|
65
|
+
@elements << new_level
|
66
|
+
block.call(new_level) if block
|
67
|
+
new_level
|
68
|
+
end
|
69
|
+
# Fetches all direct flagged parameters and levels.
|
70
|
+
# @return [Array]
|
71
|
+
# @see TermUtils::AP::Syntax#fetch_flagged_elements
|
72
|
+
# @see TermUtils::AP::Syntax#fetch_unflagged_parameters
|
73
|
+
def fetch_elements
|
74
|
+
flagged_elems = {}
|
75
|
+
unflagged_params = []
|
76
|
+
@elements.each do |e|
|
77
|
+
if e.flags.empty?
|
78
|
+
# Parameter
|
79
|
+
unflagged_params << e
|
80
|
+
else
|
81
|
+
# Parameter or Level
|
82
|
+
e.flags.each do |f|
|
83
|
+
flagged_elems[f.to_s] = e
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
[flagged_elems, unflagged_params]
|
88
|
+
end
|
89
|
+
# Fetches all direct flagged parameters and levels.
|
90
|
+
# @return [Hash<String, TermUtils::AP::Element>]
|
91
|
+
def fetch_flagged_elements
|
92
|
+
elems = {}
|
93
|
+
@elements.each do |e|
|
94
|
+
e.flags.each do |f|
|
95
|
+
elems[f.to_s] = e
|
96
|
+
end
|
97
|
+
end
|
98
|
+
elems
|
99
|
+
end
|
100
|
+
# Fetches all direct unflagged.
|
101
|
+
# @return [Array<TermUtils::AP::Parameter>]
|
102
|
+
def fetch_unflagged_parameters
|
103
|
+
params = []
|
104
|
+
@elements.each do |e|
|
105
|
+
next unless e.is_a? TermUtils::AP::Parameter
|
106
|
+
params << e if e.flags.empty?
|
107
|
+
end
|
108
|
+
params
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
#
|
3
|
+
# Copyright (C) 2019 Thomas Baron
|
4
|
+
#
|
5
|
+
# This file is part of term_utils.
|
6
|
+
#
|
7
|
+
# term_utils is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation, version 3 of the License.
|
10
|
+
#
|
11
|
+
# term_utils is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with term_utils. If not, see <https://www.gnu.org/licenses/>.
|
18
|
+
module TermUtils
|
19
|
+
module AP
|
20
|
+
# Syntax error.
|
21
|
+
class SyntaxError < StandardError
|
22
|
+
def initialize(msg)
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# Copyright (C) 2019 Thomas Baron
|
2
|
+
#
|
3
|
+
# This file is part of term_utils.
|
4
|
+
#
|
5
|
+
# term_utils is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, version 3 of the License.
|
8
|
+
#
|
9
|
+
# term_utils is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with term_utils. If not, see <https://www.gnu.org/licenses/>.
|
16
|
+
require 'term_utils/property_tree_node'
|
17
|
+
require 'term_utils/ap/no_such_value_error'
|
18
|
+
require 'term_utils/ap/parse_error'
|
19
|
+
require 'term_utils/ap/syntax_error'
|
20
|
+
require 'term_utils/ap/article'
|
21
|
+
require 'term_utils/ap/flag'
|
22
|
+
require 'term_utils/ap/element'
|
23
|
+
require 'term_utils/ap/level'
|
24
|
+
require 'term_utils/ap/parameter'
|
25
|
+
require 'term_utils/ap/syntax'
|
26
|
+
require 'term_utils/ap/result'
|
27
|
+
require 'term_utils/ap/parser'
|
28
|
+
module TermUtils
|
29
|
+
# The Argument Parser module provides a way to parse command arguments.
|
30
|
+
module AP
|
31
|
+
# Creates a new Syntax.
|
32
|
+
# @return [TermUtils::AP::Syntax]
|
33
|
+
def self.create_syntax(&block)
|
34
|
+
new_syntax = TermUtils::AP::Syntax.new
|
35
|
+
block.call(new_syntax) if block
|
36
|
+
new_syntax
|
37
|
+
end
|
38
|
+
# Parses a given command.
|
39
|
+
# @param syntax [TermUtils::AP::Syntax]
|
40
|
+
# @param command [String]
|
41
|
+
# @param opts [Hash]
|
42
|
+
# @return [TermUtils::AP::Result]
|
43
|
+
# @raise [TermUtils::AP::ParseError]
|
44
|
+
# @raise [TermUtils::AP::SyntaxError]
|
45
|
+
def self.parse_command(syntax, command, opts = {})
|
46
|
+
TermUtils::AP::Parser.new.parse_command(syntax, command, opts)
|
47
|
+
end
|
48
|
+
# Parses a given list of arguments.
|
49
|
+
# @param syntax [TermUtils::AP::Syntax]
|
50
|
+
# @param arguments [Array<String>]
|
51
|
+
# @param opts [Hash]
|
52
|
+
# @return [TermUtils::AP::Result]
|
53
|
+
# @raise [TermUtils::AP::ParseError]
|
54
|
+
# @raise [TermUtils::AP::SyntaxError]
|
55
|
+
def self.parse_arguments(syntax, arguments, opts = {})
|
56
|
+
TermUtils::AP::Parser.new.parse_arguments(syntax, arguments, opts)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
# Copyright (C) 2019 Thomas Baron
|
2
|
+
#
|
3
|
+
# This file is part of term_utils.
|
4
|
+
#
|
5
|
+
# term_utils is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, version 3 of the License.
|
8
|
+
#
|
9
|
+
# term_utils is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with term_utils. If not, see <https://www.gnu.org/licenses/>.
|
16
|
+
module TermUtils
|
17
|
+
# Represents a general-purpose tree node that holds a key-value pair.
|
18
|
+
class PropertyTreeNode
|
19
|
+
# @return [TermUtils::PropertyTreeNode]
|
20
|
+
attr_accessor :parent_node
|
21
|
+
# @return [Array<TermUtils::PropertyTreeNode>]
|
22
|
+
attr_accessor :child_nodes
|
23
|
+
# @return [Object]
|
24
|
+
attr_accessor :key
|
25
|
+
# @return [Object]
|
26
|
+
attr_accessor :value
|
27
|
+
# Creates a new node.
|
28
|
+
# @param opts [Hash<Symbol, Object>]
|
29
|
+
# option opts [Object] :key
|
30
|
+
# option opts [Object] :value
|
31
|
+
def initialize(opts = {}, &block)
|
32
|
+
@parent_node = nil
|
33
|
+
@child_nodes = nil
|
34
|
+
@key = opts.fetch(:key, nil)
|
35
|
+
@value = opts.fetch(:value, nil)
|
36
|
+
block.call(self) if block
|
37
|
+
end
|
38
|
+
# For dup method.
|
39
|
+
def initialize_dup(other)
|
40
|
+
@parent_node = nil
|
41
|
+
if other.child_nodes
|
42
|
+
@child_nodes = []
|
43
|
+
other.child_nodes.each do |n|
|
44
|
+
new_node = n.dup
|
45
|
+
new_node.parent_node = self
|
46
|
+
@child_nodes << new_node
|
47
|
+
end
|
48
|
+
end
|
49
|
+
super
|
50
|
+
end
|
51
|
+
# Tests whether this one is the head of the tree (i.e. has no parent).
|
52
|
+
# @return [Boolean]
|
53
|
+
def head?
|
54
|
+
@parent_node == nil
|
55
|
+
end
|
56
|
+
# Tests whether this one is a leaf of the tree (i.e. has no child).
|
57
|
+
# @return [Boolean]
|
58
|
+
def leaf?
|
59
|
+
@child_nodes == nil
|
60
|
+
end
|
61
|
+
# Returns the child node identified by a given key.
|
62
|
+
# @param key [Object]
|
63
|
+
# @return [TermUtils::PropertyTreeNode, nil]
|
64
|
+
def child_node(key)
|
65
|
+
if @child_nodes
|
66
|
+
@child_nodes.find { |n| n.key == key }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
# Creates a new node and adds it as a child.
|
70
|
+
# @param opts [Hash<Symbol,Object>] key value
|
71
|
+
# @return [TermUtils::PropertyTreeNode]
|
72
|
+
def define_node(opts = {}, &block)
|
73
|
+
new_node = TermUtils::PropertyTreeNode.new(opts)
|
74
|
+
new_node.parent_node = self
|
75
|
+
@child_nodes = [] unless @child_nodes
|
76
|
+
@child_nodes << new_node
|
77
|
+
block.call(new_node) if block
|
78
|
+
new_node
|
79
|
+
end
|
80
|
+
# Builds the path of keys.
|
81
|
+
# @return [Array<Object>]
|
82
|
+
def path
|
83
|
+
p = @parent_node ? @parent_node.path : []
|
84
|
+
p << @key if @key
|
85
|
+
p
|
86
|
+
end
|
87
|
+
# Iterates over every node.
|
88
|
+
# @param opts [Hash<Symbol,Object>] `:path`, `:leaf_only`
|
89
|
+
# @return [nil]
|
90
|
+
def each_node(opts = {}, &block)
|
91
|
+
rpath = nil
|
92
|
+
if opts.has_key? :path
|
93
|
+
rpath = opts[:path].dup
|
94
|
+
end
|
95
|
+
dive = true
|
96
|
+
if @key
|
97
|
+
hide = false
|
98
|
+
if rpath
|
99
|
+
if rpath.shift == @key
|
100
|
+
unless rpath.empty?
|
101
|
+
hide = true
|
102
|
+
end
|
103
|
+
else
|
104
|
+
dive = false
|
105
|
+
hide = true
|
106
|
+
end
|
107
|
+
end
|
108
|
+
unless hide or (opts[:leaf_only] and @child_nodes)
|
109
|
+
if opts.has_key? :block
|
110
|
+
opts[:block].call(self)
|
111
|
+
elsif block
|
112
|
+
block.call(self)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end # if @key
|
116
|
+
if dive and @child_nodes
|
117
|
+
ropts = opts.dup
|
118
|
+
if rpath
|
119
|
+
if rpath.empty?
|
120
|
+
ropts.delete :path
|
121
|
+
else
|
122
|
+
ropts[:path] = rpath
|
123
|
+
end
|
124
|
+
end
|
125
|
+
if block
|
126
|
+
ropts[:block] = block
|
127
|
+
end
|
128
|
+
@child_nodes.each do |n|
|
129
|
+
n.each_node(ropts)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
nil
|
133
|
+
end
|
134
|
+
# Collects nodes.
|
135
|
+
# @param opts [Hash<Symbol,Object>] `:path`, `:leaf_only`
|
136
|
+
# @return [Array<TermUtils::PropertyTreeNode>]
|
137
|
+
def collect_nodes(opts = {})
|
138
|
+
nodes = []
|
139
|
+
each_node(opts) do |n|
|
140
|
+
nodes << n
|
141
|
+
end
|
142
|
+
nodes
|
143
|
+
end
|
144
|
+
# Collects node paths.
|
145
|
+
# @param opts [Hash<Symbol,Object>] `:path`, `:leaf_only`
|
146
|
+
# @return [Array<Array<Object>>]
|
147
|
+
def collect_paths(opts = {})
|
148
|
+
paths = []
|
149
|
+
each_node(opts) do |n|
|
150
|
+
paths << n.path
|
151
|
+
end
|
152
|
+
paths
|
153
|
+
end
|
154
|
+
# Collect node values.
|
155
|
+
# @param opts [Hash<Symbol,Object>] `:path`, `:leaf_only`
|
156
|
+
# @return [Array<Object>]
|
157
|
+
def collect_values(opts = {})
|
158
|
+
vals = []
|
159
|
+
each_node(opts) do |n|
|
160
|
+
vals << n.value if n.value
|
161
|
+
end
|
162
|
+
vals
|
163
|
+
end
|
164
|
+
# Finds the node identified by a given path of keys.
|
165
|
+
# @param path [Array<Object>]
|
166
|
+
# @return [TermUtils::PropertyTreeNode]
|
167
|
+
def find_node(path)
|
168
|
+
catch :found do
|
169
|
+
each_node(:path => path) do |n|
|
170
|
+
throw :found, n
|
171
|
+
end
|
172
|
+
nil
|
173
|
+
end
|
174
|
+
end
|
175
|
+
# Tests whether the node identified by a given path of keys exists.
|
176
|
+
# @param path [Array<Object>]
|
177
|
+
# @return [Boolean]
|
178
|
+
def node_exists?(path)
|
179
|
+
find_node(path) != nil
|
180
|
+
end
|
181
|
+
# Evaluates the total number of nodes in the tree represented by this one.
|
182
|
+
# @param path [Array<Object>]
|
183
|
+
# @return [Integer]
|
184
|
+
def eval_child_count(path)
|
185
|
+
node = find_node(path)
|
186
|
+
if node
|
187
|
+
node.child_nodes ? node.child_nodes.length : 0
|
188
|
+
end
|
189
|
+
end
|
190
|
+
# Finds the node identified by a given path of keys and returns its value.
|
191
|
+
# @param path [Array<Object>]
|
192
|
+
# @return [Object]
|
193
|
+
def find_node_value(path)
|
194
|
+
node = find_node(path)
|
195
|
+
if node
|
196
|
+
node.value
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
data/lib/term_utils.rb
CHANGED
data/term_utils.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: term_utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Baron
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-10
|
11
|
+
date: 2019-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: 'Provides terminal utilities like table formatting.
|
14
14
|
|
@@ -24,11 +24,25 @@ files:
|
|
24
24
|
- README.md
|
25
25
|
- Rakefile
|
26
26
|
- doc/TermUtils.html
|
27
|
+
- doc/TermUtils/AP.html
|
28
|
+
- doc/TermUtils/AP/Article.html
|
29
|
+
- doc/TermUtils/AP/Element.html
|
30
|
+
- doc/TermUtils/AP/Flag.html
|
31
|
+
- doc/TermUtils/AP/Level.html
|
32
|
+
- doc/TermUtils/AP/NoSuchValueError.html
|
33
|
+
- doc/TermUtils/AP/Parameter.html
|
34
|
+
- doc/TermUtils/AP/ParseError.html
|
35
|
+
- doc/TermUtils/AP/Parser.html
|
36
|
+
- doc/TermUtils/AP/Result.html
|
37
|
+
- doc/TermUtils/AP/ResultView.html
|
38
|
+
- doc/TermUtils/AP/Syntax.html
|
39
|
+
- doc/TermUtils/AP/SyntaxError.html
|
27
40
|
- doc/TermUtils/FF.html
|
28
41
|
- doc/TermUtils/FF/Config.html
|
29
42
|
- doc/TermUtils/FF/Cursor.html
|
30
43
|
- doc/TermUtils/FF/Cursor/Context.html
|
31
44
|
- doc/TermUtils/FF/Query.html
|
45
|
+
- doc/TermUtils/PropertyTreeNode.html
|
32
46
|
- doc/TermUtils/Tab.html
|
33
47
|
- doc/TermUtils/Tab/Column.html
|
34
48
|
- doc/TermUtils/Tab/Holder.html
|
@@ -49,10 +63,23 @@ files:
|
|
49
63
|
- doc/method_list.html
|
50
64
|
- doc/top-level-namespace.html
|
51
65
|
- lib/term_utils.rb
|
66
|
+
- lib/term_utils/ap.rb
|
67
|
+
- lib/term_utils/ap/article.rb
|
68
|
+
- lib/term_utils/ap/element.rb
|
69
|
+
- lib/term_utils/ap/flag.rb
|
70
|
+
- lib/term_utils/ap/level.rb
|
71
|
+
- lib/term_utils/ap/no_such_value_error.rb
|
72
|
+
- lib/term_utils/ap/parameter.rb
|
73
|
+
- lib/term_utils/ap/parse_error.rb
|
74
|
+
- lib/term_utils/ap/parser.rb
|
75
|
+
- lib/term_utils/ap/result.rb
|
76
|
+
- lib/term_utils/ap/syntax.rb
|
77
|
+
- lib/term_utils/ap/syntax_error.rb
|
52
78
|
- lib/term_utils/ff.rb
|
53
79
|
- lib/term_utils/ff/config.rb
|
54
80
|
- lib/term_utils/ff/cursor.rb
|
55
81
|
- lib/term_utils/ff/query.rb
|
82
|
+
- lib/term_utils/property_tree_node.rb
|
56
83
|
- lib/term_utils/tab.rb
|
57
84
|
- term_utils.gemspec
|
58
85
|
homepage: https://git.yellowcube.net/tvb/term_utils
|