spacetree 1.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 +7 -0
- data/Changelog +2 -0
- data/LICENSE +20 -0
- data/README.md +39 -0
- data/Rakefile +13 -0
- data/lib/spacetree.rb +22 -0
- data/lib/spacetree/node.rb +59 -0
- data/lib/spacetree/parser.rb +44 -0
- data/test/helper.rb +13 -0
- data/test/test_node.rb +58 -0
- data/test/test_parser.rb +78 -0
- metadata +68 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: e1ec12ace1a11f7639558f401ffb4c2169978ae0
|
|
4
|
+
data.tar.gz: 0281ff038ee6bed1dd0f1e6349aa196905d8b71d
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 34f9c9a26e16ca0113c6069968af7ef1373bc1c6d2e7154fe1374a4b652a30551c5f519428f1dd081602ed1f59fb96e631f4a646cc262341d07b2f4cddeb163c
|
|
7
|
+
data.tar.gz: a795c3716be4b02facd945fcee59c7802cf4aa09ebf1a6f6379649554429eac4c3b56a3b3bf71108c4472fbab63d97515896ced02a389066a46b5a36fd082e78
|
data/Changelog
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2016 Jan Friedrich
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
|
11
|
+
all copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
THE SOFTWARE.
|
|
20
|
+
|
data/README.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
spacetree
|
|
2
|
+
=========
|
|
3
|
+
|
|
4
|
+
A Ruby library to generate a tree structure from a text file indented by spaces.
|
|
5
|
+
|
|
6
|
+
Example
|
|
7
|
+
-------
|
|
8
|
+
|
|
9
|
+
Given a text file tree.txt
|
|
10
|
+
|
|
11
|
+
foo
|
|
12
|
+
bar
|
|
13
|
+
baz
|
|
14
|
+
|
|
15
|
+
Parsing it:
|
|
16
|
+
|
|
17
|
+
require 'spacetree'
|
|
18
|
+
parser = Spacetree::Parser.new
|
|
19
|
+
tree = parser.parse File.read('tree.txt')
|
|
20
|
+
p tree.value # => "foo"
|
|
21
|
+
p tree.map(&:value) # => ["bar", "baz"]
|
|
22
|
+
|
|
23
|
+
Emitting a tree as indented text:
|
|
24
|
+
|
|
25
|
+
puts tree.emit
|
|
26
|
+
|
|
27
|
+
or simple
|
|
28
|
+
|
|
29
|
+
puts tree
|
|
30
|
+
|
|
31
|
+
Author
|
|
32
|
+
------
|
|
33
|
+
|
|
34
|
+
Jan Friedrich <janfri26@gmail.com>
|
|
35
|
+
|
|
36
|
+
License
|
|
37
|
+
-------
|
|
38
|
+
|
|
39
|
+
MIT license see file LICENSE.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'rim/tire'
|
|
2
|
+
require 'rim/version'
|
|
3
|
+
require_relative 'lib/spacetree'
|
|
4
|
+
|
|
5
|
+
Rim.setup do
|
|
6
|
+
name 'spacetree'
|
|
7
|
+
authors 'Jan Friedrich'
|
|
8
|
+
email 'janfri26@gmail.com'
|
|
9
|
+
license 'MIT'
|
|
10
|
+
summary 'Generate a tree structure from a text file indented by spaces.'
|
|
11
|
+
version Spacetree::VERSION
|
|
12
|
+
end
|
|
13
|
+
|
data/lib/spacetree.rb
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# -- encoding: utf-8 --
|
|
2
|
+
# Generate a tree structure from a text file indented by spaces.
|
|
3
|
+
module Spacetree
|
|
4
|
+
|
|
5
|
+
VERSION = '1.0.0'
|
|
6
|
+
|
|
7
|
+
autoload :Node, 'spacetree/node'
|
|
8
|
+
autoload :Parser, 'spacetree/parser'
|
|
9
|
+
|
|
10
|
+
# Do parsing @see Parser#parse
|
|
11
|
+
def self.parse s, &blk
|
|
12
|
+
Parser.new.parse s, &blk
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Generate a formatted string representation of a node and its children
|
|
16
|
+
# recursively
|
|
17
|
+
# @see Node#emit
|
|
18
|
+
def self.emit node
|
|
19
|
+
node.emit
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# -- encoding: utf-8 --
|
|
2
|
+
module Spacetree
|
|
3
|
+
|
|
4
|
+
# Represent a node respectively a tree
|
|
5
|
+
class Node
|
|
6
|
+
|
|
7
|
+
include Enumerable
|
|
8
|
+
|
|
9
|
+
attr_accessor :value, :children
|
|
10
|
+
|
|
11
|
+
# @param value value of the node
|
|
12
|
+
# @children array of nodes wich represent the children of this node
|
|
13
|
+
def initialize value=nil, *children
|
|
14
|
+
@value = value
|
|
15
|
+
@children = children
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def == o
|
|
19
|
+
return false unless o.kind_of? Node
|
|
20
|
+
[self.value, self.children] == [o.value, o.children]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def each *args, &blk
|
|
24
|
+
enum = Enumerator.new do |y|
|
|
25
|
+
y << self
|
|
26
|
+
children.each do |c|
|
|
27
|
+
c.each *args, &blk
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
if block_given?
|
|
31
|
+
enum.each *args, &blk
|
|
32
|
+
else
|
|
33
|
+
enum
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Generate a formatted string representation of a node and its children
|
|
38
|
+
# recursively
|
|
39
|
+
# @param indent Count of spaces to indent a level deeper
|
|
40
|
+
# @param level level of indentation
|
|
41
|
+
def emit indent: 2, level: 0
|
|
42
|
+
res = []
|
|
43
|
+
if value.nil?
|
|
44
|
+
children.each {|c| res << c.emit(indent: indent, level: level)}
|
|
45
|
+
else
|
|
46
|
+
spaces = ' ' * indent * level
|
|
47
|
+
res << (spaces << value.to_s)
|
|
48
|
+
children.each {|c| res << c.emit(indent: indent, level: level+1)}
|
|
49
|
+
end
|
|
50
|
+
res.join("\n")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def to_s
|
|
54
|
+
emit
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# -- encoding: utf-8 --
|
|
2
|
+
module Spacetree
|
|
3
|
+
|
|
4
|
+
# Parser to parse a text file indented by spaces to a tree structure
|
|
5
|
+
class Parser
|
|
6
|
+
|
|
7
|
+
# Do parsing
|
|
8
|
+
# @s String to parse
|
|
9
|
+
# @blk if block given each line without the starting spaces is yielded
|
|
10
|
+
def parse s, &blk
|
|
11
|
+
root = Node.new
|
|
12
|
+
@indent_map = {-1 => root}
|
|
13
|
+
s.chomp.split(/\n/).each do |line|
|
|
14
|
+
generate_node line, &blk
|
|
15
|
+
end
|
|
16
|
+
root
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
protected
|
|
20
|
+
|
|
21
|
+
def generate_node line
|
|
22
|
+
if line =~ /(^ *)([^ ].*)$/
|
|
23
|
+
indent = $1.size
|
|
24
|
+
line = $2
|
|
25
|
+
line = yield line if block_given?
|
|
26
|
+
parent = search_parent_node indent
|
|
27
|
+
new_node = Node.new line
|
|
28
|
+
@indent_map[indent] = new_node
|
|
29
|
+
parent.children << new_node
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def search_parent_node indent
|
|
34
|
+
fail ArgumentError if indent < 0
|
|
35
|
+
(indent - 1).downto(-1).each do |i|
|
|
36
|
+
res = @indent_map[i]
|
|
37
|
+
return res if res
|
|
38
|
+
end
|
|
39
|
+
fail ArgumentError
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
data/test/helper.rb
ADDED
data/test/test_node.rb
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# -- encoding: utf-8 --
|
|
2
|
+
require_relative 'helper'
|
|
3
|
+
|
|
4
|
+
class TestNode < Minitest::Test
|
|
5
|
+
|
|
6
|
+
include Helper
|
|
7
|
+
|
|
8
|
+
FOO_BAR_BAZ_TREE_STRING = <<~END.chomp
|
|
9
|
+
foo1
|
|
10
|
+
foo2
|
|
11
|
+
foo3
|
|
12
|
+
bar1
|
|
13
|
+
bar2
|
|
14
|
+
bar3
|
|
15
|
+
baz1
|
|
16
|
+
baz2
|
|
17
|
+
baz3
|
|
18
|
+
END
|
|
19
|
+
|
|
20
|
+
def test_enumerable
|
|
21
|
+
arr = [nil, 'foo1', 'foo2', 'foo3', 'bar1', 'bar2', 'bar3', 'baz1', 'baz2', 'baz3']
|
|
22
|
+
res = foo_bar_baz_tree.map &:value
|
|
23
|
+
assert_equal arr, res
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_emit_one_node
|
|
27
|
+
assert_equal '', n(nil).emit
|
|
28
|
+
assert_equal 'foo', n('foo').emit
|
|
29
|
+
assert_equal ' foo', n('foo').emit(level: 1)
|
|
30
|
+
assert_equal ' foo', n('foo').emit(level: 2)
|
|
31
|
+
assert_equal ' foo', n('foo').emit(indent: 3, level: 1)
|
|
32
|
+
assert_equal ' foo', n('foo').emit(indent: 3, level: 2)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def test_complex_emit
|
|
36
|
+
assert_equal FOO_BAR_BAZ_TREE_STRING, foo_bar_baz_tree.emit
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def test_emit_argumenterror_for_negative_arguments
|
|
40
|
+
assert_raises ArgumentError do
|
|
41
|
+
n('foo').emit(indent: -1)
|
|
42
|
+
end
|
|
43
|
+
assert_raises ArgumentError do
|
|
44
|
+
n('foo').emit(level: -1)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def test_to_s
|
|
49
|
+
assert_equal FOO_BAR_BAZ_TREE_STRING, foo_bar_baz_tree.emit
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
protected
|
|
53
|
+
|
|
54
|
+
def foo_bar_baz_tree
|
|
55
|
+
n(nil, n('foo1', n('foo2', n('foo3'))), n('bar1', n('bar2', n('bar3'))), n('baz1', n('baz2', n('baz3'))))
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
data/test/test_parser.rb
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# -- encoding: utf-8 --
|
|
2
|
+
require_relative 'helper'
|
|
3
|
+
|
|
4
|
+
class TestParser < Minitest::Test
|
|
5
|
+
|
|
6
|
+
include Helper
|
|
7
|
+
include Spacetree
|
|
8
|
+
|
|
9
|
+
def setup
|
|
10
|
+
@parser = Parser.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_empty_string
|
|
14
|
+
assert_equal n, @parser.parse('')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_one_node
|
|
18
|
+
assert_equal n(nil, n('foo')), @parser.parse('foo')
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def test_more_nodes
|
|
22
|
+
tree = n(nil, n('foo'), n('bar'), n('baz'))
|
|
23
|
+
s = <<~END
|
|
24
|
+
foo
|
|
25
|
+
bar
|
|
26
|
+
baz
|
|
27
|
+
END
|
|
28
|
+
assert_equal tree, @parser.parse(s)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_simple_indentation
|
|
32
|
+
tree = n(nil, n('foo', n('bar')))
|
|
33
|
+
s = <<~END
|
|
34
|
+
foo
|
|
35
|
+
bar
|
|
36
|
+
END
|
|
37
|
+
assert_equal tree, @parser.parse(s)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_usual_indentation
|
|
41
|
+
tree = n(nil, n('foo1', n('foo2', n('foo3'))), n('bar1', n('bar2', n('bar3'))), n('baz1', n('baz2', n('baz3'))))
|
|
42
|
+
s = <<~END
|
|
43
|
+
foo1
|
|
44
|
+
foo2
|
|
45
|
+
foo3
|
|
46
|
+
bar1
|
|
47
|
+
bar2
|
|
48
|
+
bar3
|
|
49
|
+
baz1
|
|
50
|
+
baz2
|
|
51
|
+
baz3
|
|
52
|
+
END
|
|
53
|
+
assert_equal tree, @parser.parse(s)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def test_spaces_in_line
|
|
57
|
+
tree = n(nil, n('foo and bar', n('bar and baz', n('baz and foo'))))
|
|
58
|
+
s = <<~END
|
|
59
|
+
foo and bar
|
|
60
|
+
bar and baz
|
|
61
|
+
baz and foo
|
|
62
|
+
END
|
|
63
|
+
assert_equal tree, @parser.parse(s)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def test_converting_line
|
|
67
|
+
tree = n(nil, n(%i(foo bar)), n(%i(bar baz)))
|
|
68
|
+
s = <<~END
|
|
69
|
+
foo bar
|
|
70
|
+
bar baz
|
|
71
|
+
END
|
|
72
|
+
res = @parser.parse(s) do |line|
|
|
73
|
+
line.split.map &:to_sym
|
|
74
|
+
end
|
|
75
|
+
assert_equal tree, res
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: spacetree
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Jan Friedrich
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2016-05-27 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rim
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '2.6'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '2.6'
|
|
27
|
+
description: ''
|
|
28
|
+
email: janfri26@gmail.com
|
|
29
|
+
executables: []
|
|
30
|
+
extensions: []
|
|
31
|
+
extra_rdoc_files: []
|
|
32
|
+
files:
|
|
33
|
+
- Changelog
|
|
34
|
+
- LICENSE
|
|
35
|
+
- README.md
|
|
36
|
+
- Rakefile
|
|
37
|
+
- lib/spacetree.rb
|
|
38
|
+
- lib/spacetree/node.rb
|
|
39
|
+
- lib/spacetree/parser.rb
|
|
40
|
+
- test/helper.rb
|
|
41
|
+
- test/test_node.rb
|
|
42
|
+
- test/test_parser.rb
|
|
43
|
+
homepage:
|
|
44
|
+
licenses:
|
|
45
|
+
- MIT
|
|
46
|
+
metadata: {}
|
|
47
|
+
post_install_message:
|
|
48
|
+
rdoc_options: []
|
|
49
|
+
require_paths:
|
|
50
|
+
- lib
|
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
52
|
+
requirements:
|
|
53
|
+
- - ">="
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: '0'
|
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
requirements: []
|
|
62
|
+
rubyforge_project:
|
|
63
|
+
rubygems_version: 2.6.4
|
|
64
|
+
signing_key:
|
|
65
|
+
specification_version: 4
|
|
66
|
+
summary: Generate a tree structure from a text file indented by spaces.
|
|
67
|
+
test_files: []
|
|
68
|
+
has_rdoc:
|