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.
@@ -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
@@ -0,0 +1,2 @@
1
+ 1.0.0
2
+ First release.
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
+
@@ -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.
@@ -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
+
@@ -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
@@ -0,0 +1,13 @@
1
+ # -- encoding: utf-8 --
2
+ require 'minitest/autorun'
3
+ require 'spacetree'
4
+
5
+ module Helper
6
+
7
+ protected
8
+
9
+ def n *args
10
+ Spacetree::Node.new *args
11
+ end
12
+
13
+ end
@@ -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
@@ -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: