ascii_tree 1.0.3 → 2.0.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/README.md +5 -3
- data/lib/ascii_tree/comment_stripper.rb +0 -2
- data/lib/ascii_tree/coordinate.rb +12 -11
- data/lib/ascii_tree/edge.rb +15 -15
- data/lib/ascii_tree/edge_parser.rb +0 -2
- data/lib/ascii_tree/node.rb +4 -6
- data/lib/ascii_tree/node_builder.rb +2 -8
- data/lib/ascii_tree/parenthesis_toggle.rb +2 -3
- data/lib/ascii_tree/relationship.rb +0 -2
- data/lib/ascii_tree/relationships_builder.rb +17 -19
- data/lib/ascii_tree/scanner.rb +0 -2
- data/lib/ascii_tree/word.rb +4 -6
- data/lib/ascii_tree/word_parser.rb +7 -11
- metadata +30 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 727377cc812889ffd5a12fe02510d31fd8c60046
|
4
|
+
data.tar.gz: 51e1abce380f5c8a587be253e0494d973faecb76
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b7032761679fa3c2c9f63647da68e1d284e5b576b99c88539509f715061c012157ff3ed677b02948bd6bbf7e2f3e00a451ebd4cb8cd855d708c97a1d581bd17
|
7
|
+
data.tar.gz: 9d19f645ed89eaa27ad43ad89c7ba550211c2de2cf4da9d561c547620f996af5bd9039bd5b84bbd35af971045b9ce2cdaacf00e8cb3316ea3541fcd390a15b22
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
## Ascii Tree
|
2
2
|
|
3
|
+
[](https://travis-ci.org/tuzz/ascii_tree)
|
4
|
+
|
3
5
|
Parses a usable tree from ASCII art.
|
4
6
|
|
5
7
|
Ascii Tree turns something humans understand into something computers
|
@@ -24,14 +26,14 @@ root = AsciiTree.parse('
|
|
24
26
|
|
25
27
|
')
|
26
28
|
|
27
|
-
root.
|
29
|
+
root.identity
|
28
30
|
#=> "chestnuts"
|
29
31
|
|
30
32
|
root.parent
|
31
33
|
#=> nil
|
32
34
|
|
33
35
|
root.children
|
34
|
-
#=> [#<AsciiTree::Node @
|
36
|
+
#=> [#<AsciiTree::Node @identity="roasting">, ...]
|
35
37
|
```
|
36
38
|
|
37
39
|
## Multiple words
|
@@ -47,7 +49,7 @@ root = AsciiTree.parse('
|
|
47
49
|
|
48
50
|
')
|
49
51
|
|
50
|
-
root.
|
52
|
+
root.identity
|
51
53
|
#=> "single node"
|
52
54
|
```
|
53
55
|
|
@@ -1,13 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module AsciiTree
|
2
|
+
class Coordinate
|
3
|
+
attr_reader :x, :y
|
4
|
+
|
5
|
+
def initialize(x:, y:)
|
6
|
+
@x = x
|
7
|
+
@y = y
|
8
|
+
end
|
9
|
+
|
10
|
+
def ==(other)
|
11
|
+
x == other.x && y == other.y
|
12
|
+
end
|
7
13
|
end
|
8
|
-
|
9
|
-
def ==(other)
|
10
|
-
x == other.x && y == other.y
|
11
|
-
end
|
12
|
-
|
13
14
|
end
|
data/lib/ascii_tree/edge.rb
CHANGED
@@ -1,19 +1,19 @@
|
|
1
|
-
|
1
|
+
module AsciiTree
|
2
|
+
class Edge
|
3
|
+
attr_reader :character, :coordinate, :parent_coordinate, :child_coordinate
|
2
4
|
|
3
|
-
|
5
|
+
def initialize(character:, coordinate:, parent_coordinate:, child_coordinate:)
|
6
|
+
@character = character
|
7
|
+
@coordinate = coordinate
|
8
|
+
@parent_coordinate = parent_coordinate
|
9
|
+
@child_coordinate = child_coordinate
|
10
|
+
end
|
4
11
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
12
|
+
def ==(other)
|
13
|
+
character == other.character &&
|
14
|
+
coordinate == other.coordinate &&
|
15
|
+
parent_coordinate == other.parent_coordinate &&
|
16
|
+
child_coordinate == other.child_coordinate
|
17
|
+
end
|
10
18
|
end
|
11
|
-
|
12
|
-
def ==(other)
|
13
|
-
character == other.character &&
|
14
|
-
coordinate == other.coordinate &&
|
15
|
-
parent_coordinate == other.parent_coordinate &&
|
16
|
-
child_coordinate == other.child_coordinate
|
17
|
-
end
|
18
|
-
|
19
19
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module AsciiTree
|
2
2
|
module EdgeParser
|
3
3
|
class << self
|
4
|
-
|
5
4
|
def parse(string)
|
6
5
|
edge_chars_with_coordinates(string).map do |char, coordinate|
|
7
6
|
offsets = edge_offsets[char]
|
@@ -36,7 +35,6 @@ module AsciiTree
|
|
36
35
|
edge_offsets.keys.include?(char)
|
37
36
|
end
|
38
37
|
end
|
39
|
-
|
40
38
|
end
|
41
39
|
end
|
42
40
|
end
|
data/lib/ascii_tree/node.rb
CHANGED
@@ -1,21 +1,19 @@
|
|
1
1
|
module AsciiTree
|
2
2
|
class Node
|
3
|
+
attr_reader :identity, :value, :parent, :children
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
def initialize(id:, value:, parent:, children:)
|
7
|
-
@id = id
|
5
|
+
def initialize(identity:, value:, parent:, children:)
|
6
|
+
@identity = identity
|
8
7
|
@value = value
|
9
8
|
@parent = parent
|
10
9
|
@children = children
|
11
10
|
end
|
12
11
|
|
13
12
|
def ==(other)
|
14
|
-
|
13
|
+
identity == other.identity &&
|
15
14
|
value == other.value &&
|
16
15
|
parent == other.parent &&
|
17
16
|
children == other.children
|
18
17
|
end
|
19
|
-
|
20
18
|
end
|
21
19
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module AsciiTree
|
2
2
|
class NodeBuilder
|
3
|
-
|
4
3
|
def self.build(*args)
|
5
4
|
new(*args).build
|
6
5
|
end
|
@@ -10,11 +9,7 @@ module AsciiTree
|
|
10
9
|
end
|
11
10
|
|
12
11
|
def build
|
13
|
-
if relationships.any?
|
14
|
-
build_for(root_word, nil)
|
15
|
-
else
|
16
|
-
nil
|
17
|
-
end
|
12
|
+
build_for(root_word, nil) if relationships.any?
|
18
13
|
end
|
19
14
|
|
20
15
|
private
|
@@ -31,7 +26,7 @@ module AsciiTree
|
|
31
26
|
|
32
27
|
def build_for(word, parent)
|
33
28
|
node = Node.new(
|
34
|
-
|
29
|
+
identity: word.identity,
|
35
30
|
value: word.value,
|
36
31
|
parent: parent,
|
37
32
|
children: []
|
@@ -53,6 +48,5 @@ module AsciiTree
|
|
53
48
|
build_for(r.child_word, parent)
|
54
49
|
end
|
55
50
|
end
|
56
|
-
|
57
51
|
end
|
58
52
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module AsciiTree
|
2
2
|
class Relationship
|
3
|
-
|
4
3
|
attr_reader :parent_word, :edge, :child_word
|
5
4
|
|
6
5
|
def initialize(parent_word:, edge:, child_word:)
|
@@ -14,6 +13,5 @@ module AsciiTree
|
|
14
13
|
edge == other.edge &&
|
15
14
|
child_word == other.child_word
|
16
15
|
end
|
17
|
-
|
18
16
|
end
|
19
17
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module AsciiTree
|
2
2
|
module RelationshipsBuilder
|
3
3
|
class << self
|
4
|
-
|
5
4
|
def build(words, edges)
|
6
5
|
relationships = []
|
7
6
|
|
@@ -24,27 +23,26 @@ module AsciiTree
|
|
24
23
|
private
|
25
24
|
|
26
25
|
def root_relationship(words)
|
27
|
-
|
26
|
+
return unless words.any?
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
end
|
28
|
+
root_word = words.first
|
29
|
+
Relationship.new(parent_word: nil, edge: nil, child_word: root_word)
|
32
30
|
end
|
33
31
|
|
34
32
|
def validate_presence(parent, child, edge)
|
35
33
|
if parent.nil? && child.nil?
|
36
34
|
error = "No parent or child"
|
37
35
|
elsif parent.nil?
|
38
|
-
error = "No parent for child '#{child.
|
36
|
+
error = "No parent for child '#{child.identity}'"
|
39
37
|
elsif child.nil?
|
40
|
-
error = "No child for parent '#{parent.
|
38
|
+
error = "No child for parent '#{parent.identity}'"
|
41
39
|
end
|
42
40
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
41
|
+
return unless error
|
42
|
+
|
43
|
+
c = edge.coordinate
|
44
|
+
error += " for edge '#{edge.character}' at line #{c.y}, column #{c.x}"
|
45
|
+
fail ::AsciiTree::RelationshipError, error
|
48
46
|
end
|
49
47
|
|
50
48
|
def validate_one_parent(relationships)
|
@@ -56,11 +54,11 @@ module AsciiTree
|
|
56
54
|
count > 1
|
57
55
|
end
|
58
56
|
|
59
|
-
groups = multiple_parents.group_by
|
57
|
+
groups = multiple_parents.group_by(&:child_word)
|
60
58
|
|
61
|
-
maps = groups.map do |child_word,
|
62
|
-
parent_words =
|
63
|
-
[child_word.
|
59
|
+
maps = groups.map do |child_word, rels|
|
60
|
+
parent_words = rels.map(&:parent_word)
|
61
|
+
[child_word.identity, parent_words.map(&:identity)]
|
64
62
|
end
|
65
63
|
|
66
64
|
if maps.any?
|
@@ -72,10 +70,10 @@ module AsciiTree
|
|
72
70
|
end
|
73
71
|
end
|
74
72
|
|
75
|
-
|
73
|
+
fail ::AsciiTree::RelationshipError, error if error
|
76
74
|
end
|
77
|
-
|
78
|
-
class ::AsciiTree::RelationshipError < StandardError; end
|
79
75
|
end
|
80
76
|
end
|
77
|
+
|
78
|
+
class RelationshipError < StandardError; end
|
81
79
|
end
|
data/lib/ascii_tree/scanner.rb
CHANGED
data/lib/ascii_tree/word.rb
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
module AsciiTree
|
2
2
|
class Word
|
3
|
+
attr_reader :identity, :value, :start_coordinate, :end_coordinate
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
def initialize(id:, value:, start_coordinate:, end_coordinate:)
|
7
|
-
@id = id
|
5
|
+
def initialize(identity:, value:, start_coordinate:, end_coordinate:)
|
6
|
+
@identity = identity
|
8
7
|
@value = value
|
9
8
|
@start_coordinate = start_coordinate
|
10
9
|
@end_coordinate = end_coordinate
|
11
10
|
end
|
12
11
|
|
13
12
|
def ==(other)
|
14
|
-
|
13
|
+
identity == other.identity &&
|
15
14
|
value == other.value &&
|
16
15
|
start_coordinate == other.start_coordinate &&
|
17
16
|
end_coordinate == other.end_coordinate
|
@@ -30,6 +29,5 @@ module AsciiTree
|
|
30
29
|
def inside?(x)
|
31
30
|
(start_coordinate.x..end_coordinate.x).include?(x)
|
32
31
|
end
|
33
|
-
|
34
32
|
end
|
35
33
|
end
|
@@ -1,14 +1,13 @@
|
|
1
1
|
module AsciiTree
|
2
2
|
module WordParser
|
3
3
|
class << self
|
4
|
-
|
5
4
|
def parse(string)
|
6
5
|
chars = word_chars_with_coordinates(string)
|
7
6
|
group_contiguous(chars).map do |word_with_coords|
|
8
|
-
|
7
|
+
identity, value = identity_value(word_with_coords)
|
9
8
|
|
10
9
|
Word.new(
|
11
|
-
|
10
|
+
identity: identity.strip,
|
12
11
|
value: value,
|
13
12
|
start_coordinate: word_with_coords.first.last,
|
14
13
|
end_coordinate: word_with_coords.last.last
|
@@ -21,7 +20,7 @@ module AsciiTree
|
|
21
20
|
def word_chars_with_coordinates(string)
|
22
21
|
toggle = ParenthesisToggle.new
|
23
22
|
|
24
|
-
Scanner.scan(string).reject do |char,
|
23
|
+
Scanner.scan(string).reject do |char, _coordinate|
|
25
24
|
toggle.read(char)
|
26
25
|
toggle.off? && (edge?(char) || whitespace?(char))
|
27
26
|
end
|
@@ -35,7 +34,7 @@ module AsciiTree
|
|
35
34
|
char.match(/\s/)
|
36
35
|
end
|
37
36
|
|
38
|
-
def
|
37
|
+
def identity_value(word_with_coords)
|
39
38
|
chars = word_with_coords.map(&:first)
|
40
39
|
chars = remove_parentheses(chars)
|
41
40
|
|
@@ -43,10 +42,10 @@ module AsciiTree
|
|
43
42
|
word.strip!
|
44
43
|
|
45
44
|
if word.end_with?("}")
|
46
|
-
|
45
|
+
identity, tail = word.split("{", 2)
|
47
46
|
expression = tail[0..-2]
|
48
47
|
value = eval(expression)
|
49
|
-
[
|
48
|
+
[identity, value]
|
50
49
|
else
|
51
50
|
[word, nil]
|
52
51
|
end
|
@@ -61,7 +60,7 @@ module AsciiTree
|
|
61
60
|
end
|
62
61
|
|
63
62
|
def group_contiguous(chars)
|
64
|
-
chars.
|
63
|
+
chars.each_with_object([]) do |(char, coord), array|
|
65
64
|
prev = previous_coordinate(array)
|
66
65
|
|
67
66
|
if contigous?(prev, coord)
|
@@ -69,8 +68,6 @@ module AsciiTree
|
|
69
68
|
else
|
70
69
|
array << [[char, coord]]
|
71
70
|
end
|
72
|
-
|
73
|
-
array
|
74
71
|
end
|
75
72
|
end
|
76
73
|
|
@@ -85,7 +82,6 @@ module AsciiTree
|
|
85
82
|
previous_coordinate.y == coordinate.y &&
|
86
83
|
previous_coordinate.x == coordinate.x - 1
|
87
84
|
end
|
88
|
-
|
89
85
|
end
|
90
86
|
end
|
91
87
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ascii_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Patuzzo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -24,6 +24,34 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.4'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rubocop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.31'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.31'
|
27
55
|
description: Parses a usable tree from ASCII art.
|
28
56
|
email: chris@patuzzo.co.uk
|
29
57
|
executables: []
|