treeline 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +14 -0
- data/LICENSE.md +158 -0
- data/README.md +91 -0
- data/Rakefile +41 -0
- data/lib/treeline/parser.rb +54 -0
- data/lib/treeline/version.rb +3 -0
- data/test/01_parser_test.rb +140 -0
- data/treeline.gemspec +24 -0
- metadata +64 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
/pkg/
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
The Don't Be a Dick License
|
2
|
+
===========================
|
3
|
+
_version 0.1_
|
4
|
+
|
5
|
+
**Project:** [Treeline](http://github.com/CraigCottingham/treeline) v0.1
|
6
|
+
**Author:** Craig S. Cottingham (<craig.cottingham@gmail.com>)
|
7
|
+
|
8
|
+
The purpose of this license is to permit the broadest feasible scope for reuse and modification of creative work,
|
9
|
+
restricted only by the requirement that one is not a dick about it.
|
10
|
+
|
11
|
+
1. Legal Parameters
|
12
|
+
-------------------
|
13
|
+
For legal purposes, the DBAD license is a superset of the [Apache License, Version 2.0][1] and incorporates all
|
14
|
+
terms, conditions, privileges and limitations therein. The following text is a binding part of this license for
|
15
|
+
this project:
|
16
|
+
|
17
|
+
> Copyright 2011 Craig S. Cottingham
|
18
|
+
|
19
|
+
> Licensed under the Apache License, Version 2.0 (the "License");
|
20
|
+
you may not use this file except in compliance with the License.
|
21
|
+
You may obtain a copy of the License at
|
22
|
+
|
23
|
+
> <http://www.apache.org/licenses/LICENSE-2.0>
|
24
|
+
|
25
|
+
> Unless required by applicable law or agreed to in writing, software
|
26
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
27
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
28
|
+
See the License for the specific language governing permissions and
|
29
|
+
limitations under the License.
|
30
|
+
|
31
|
+
Nothing in the following text should be construed to inhibit, contradict, or override any part of the Apache
|
32
|
+
License, Version 2.0.
|
33
|
+
|
34
|
+
2. Definitions
|
35
|
+
--------------
|
36
|
+
The following terms and definitions shall be in effect for the rest of this document.
|
37
|
+
|
38
|
+
> **NOTE:** Singular nouns and pronouns are used throughout this License for
|
39
|
+
grammatical convenience. However, any of the terms below _may_ refer to a
|
40
|
+
collective work or group of people. If this pegs your punctiliousness, you
|
41
|
+
are directed to mentally substitute "Person _or persons_," "Dick _or
|
42
|
+
dicks,_" etc., throughout this license. Just don't tell us about it.
|
43
|
+
|
44
|
+
### A. Project
|
45
|
+
|
46
|
+
A creative work of (software | writing | visual art | music) into which significant time and energy have been
|
47
|
+
invested by people who _are not you,_ and which has been released into the world for the benefit of the general
|
48
|
+
public (_including you._)
|
49
|
+
|
50
|
+
The **Project** may include, incorporate, derive from, or be inspired by other works. The Author, being a
|
51
|
+
Reasonable Person, has made use of such source materials only as permitted by their own licenses or applicable
|
52
|
+
law. The License you are reading applies only to those portions of the Project which are original and distinct to
|
53
|
+
it. Source materials may be covered by their own licenses or conditions, and should not be assumed to have
|
54
|
+
coverage under this License. (However, you are strongly encouraged not to be a dick about them either.)
|
55
|
+
|
56
|
+
### B. Author
|
57
|
+
|
58
|
+
A person who has invested significant time and energy into the Project licensed herein. Given the Author's
|
59
|
+
release of the Project to the world under a liberal license, the Author is declared a Reasonable Person (at least
|
60
|
+
within this context) and inherits all attributes, freedoms, and responsibilities thereof. No other assumptions
|
61
|
+
are made about the Author, nor should you make any.
|
62
|
+
|
63
|
+
### C. Reasonable Person
|
64
|
+
|
65
|
+
A person who respects the time and energy that have been invested in the Project licensed herein, and acts
|
66
|
+
accordingly. A Reasonable Person is broadly characterized as one who exercises his or her privilege to use,
|
67
|
+
_not_ use, redistribute, modify, improve, worsen, review, report issues upon, participate in the community of,
|
68
|
+
or ignore the work _without_ placing undue demands upon the Author. I.e., a Reasonable Person is a constituent
|
69
|
+
of the majority of open source users and the population at large who are not Dicks.
|
70
|
+
|
71
|
+
### D. Dick
|
72
|
+
|
73
|
+
A person who _does not_ respect the time and energy that have been invested in the Project, and acts to punish
|
74
|
+
such effort by giving others associated with the Project -- including, but not limited to, the Author -- a hard
|
75
|
+
time. A Dick is nearly always selfish, but not necessarily with deliberate intent; some Dicks are merely
|
76
|
+
thoughtless. The distinguishing characteristic of a Dick is that he or she places burdens upon Reasonable People,
|
77
|
+
reducing their motivation to engage in open source activities. This damping effect is a significant detriment to
|
78
|
+
the Project, to open source in general, to the production of new intellectual value in the world -- and,
|
79
|
+
ultimately, to the Dick himself or herself.
|
80
|
+
|
81
|
+
> **NOTE:** Despite its original gender association, the word "Dick" is used herein in a _cultural_ context
|
82
|
+
and not a _genital_ context. This License has chosen to adopt the term for its linguistic force and psychological
|
83
|
+
impact, and sincerely regrets any inference of sexism. For purposes of the terms and conditions contained herein,
|
84
|
+
it is understood that both men and women are equally capable of being Dicks.
|
85
|
+
|
86
|
+
> (But they shouldn't be.)
|
87
|
+
|
88
|
+
3. Permissions
|
89
|
+
--------------
|
90
|
+
|
91
|
+
The following privileges are granted explicitly and exclusively to Reasonable People. Although the Author
|
92
|
+
acknowledges the practical unfeasibility of barring Dicks from enjoying the same privileges, they are nevertheless
|
93
|
+
asked to refrain from any activity related to the Project _and/or_ to reconsider their behavior and stop
|
94
|
+
being Dicks.
|
95
|
+
|
96
|
+
1. You are permitted to use the Project or any component of the Project.
|
97
|
+
|
98
|
+
2. You are permitted to redistribute the Project or any component of the Project, by itself or as part of a
|
99
|
+
different work, provided that you give fair and reasonable credit back to the Author.
|
100
|
+
|
101
|
+
3. You are permitted to change the Project for your own needs or anyone else's. You may keep your changes to
|
102
|
+
yourself or submit them back to the Author or the community, as you see fit, provided you are not a Dick about it.
|
103
|
+
|
104
|
+
4. You are permitted and encouraged to participate in any community related to the Project, or to create new
|
105
|
+
communities.
|
106
|
+
|
107
|
+
5. You are permitted to report issues or problems with the Project, and to request that they be addressed,
|
108
|
+
so long as the request is made in a reasonable fashion. (This privilege does _not_ oblige the Author to respond.)
|
109
|
+
|
110
|
+
6. You are permitted to make money from the Project. No recompense is owed to the Author unless by separate
|
111
|
+
agreement, although sharing opportunities for mutual benefit is by no means discouraged.
|
112
|
+
|
113
|
+
7. You are permitted to discuss the Project in any medium, in any positive or negative spirit, so long as
|
114
|
+
criticism is not libelous nor _ad hominem._ (I.e., don't lie, and keep it about the _work_ and not the _people._)
|
115
|
+
|
116
|
+
8. You are permitted to ignore the Project completely and make no use of it whatsoever. This right is
|
117
|
+
irrevocable and absolute, and extended to Dicks and Reasonable People alike.
|
118
|
+
|
119
|
+
4. Limitations
|
120
|
+
--------------
|
121
|
+
|
122
|
+
The following restrictions are imposed explicitly and exclusively upon Dicks. These limitations are the inverse
|
123
|
+
of the above privileges and are also tautological, as the prohibited actions are those _definitive_ of Dickhood.
|
124
|
+
|
125
|
+
1. You may not impede Reasonable People from exercising their privilege to use, redistribute, change, participate
|
126
|
+
in, profit from, discuss, or ignore the Project.
|
127
|
+
|
128
|
+
2. You may not withhold the Author's credit for the Project, nor otherwise present the work of anyone else as
|
129
|
+
your own.
|
130
|
+
|
131
|
+
3. You may not hold the Author responsible for any use or abuse of the Project by you or anyone else.
|
132
|
+
|
133
|
+
4. You may not troll, flame, nor dumb down any community associated with the Project.
|
134
|
+
|
135
|
+
5. Barring separate agreements, you may not _demand_ any time or attention on the part of the Author nor anyone
|
136
|
+
else in the community. You may not hold the Author personally accountable for any issues you discover nor
|
137
|
+
otherwise spread your own problems to other people.
|
138
|
+
|
139
|
+
6. You may not attempt to _compel_ time nor money from the Author nor any other community member by any means,
|
140
|
+
including but not limited to legal action, intimidation, or annoyance.
|
141
|
+
|
142
|
+
7. You may not engage in _ad hominem_ (i.e. personal) attacks or criticism of the Author in the course of
|
143
|
+
criticizing the Project.
|
144
|
+
|
145
|
+
8. You may not impede the absolute and irrevocable privilege of the Author and other members of the community
|
146
|
+
to ignore you.
|
147
|
+
|
148
|
+
5. Contact
|
149
|
+
----------
|
150
|
+
For more information about this Project, contact the Author at:
|
151
|
+
|
152
|
+
* Craig S. Cottingham - <craig.cottingham@gmail.com>
|
153
|
+
|
154
|
+
For more information about the DBAD License, contact the Author, or the originator of the License at:
|
155
|
+
|
156
|
+
* Stephen Eley - <sfeley@gmail.com>
|
157
|
+
|
158
|
+
[1]: http://apache.org/licenses/LICENSE-2.0
|
data/README.md
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
# Treeline
|
2
|
+
|
3
|
+
Treeline turns indented-line input into a tree structure.
|
4
|
+
|
5
|
+
Given a sequence of lines with varying levels of indentation, like this:
|
6
|
+
|
7
|
+
line 1
|
8
|
+
line 2
|
9
|
+
line 3
|
10
|
+
line 4
|
11
|
+
line 5
|
12
|
+
|
13
|
+
Treeline will produce a hash like this:
|
14
|
+
|
15
|
+
{
|
16
|
+
"line 1" => {
|
17
|
+
"line 2" => {},
|
18
|
+
"line 3" => {
|
19
|
+
"line 4" => {},
|
20
|
+
},
|
21
|
+
"line 5" => {},
|
22
|
+
},
|
23
|
+
}
|
24
|
+
|
25
|
+
## Installation
|
26
|
+
|
27
|
+
$ gem install treeline
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
The `parse` method on `Treeline::Parser` does the heavy lifting.
|
32
|
+
|
33
|
+
parser = Treeline::Parser.new
|
34
|
+
tree = parser.parse lines
|
35
|
+
|
36
|
+
The parser is bone-headed simple. The first line of input is taken to be the root of a new tree.
|
37
|
+
For each subsequent line, the amount of indentation is compared to the amount in the previous line, and
|
38
|
+
|
39
|
+
* if the indentation is the same, the new line is added as a sibling of the previous;
|
40
|
+
* if the indentation is greater, the new line is added as a child of the previous; or
|
41
|
+
* if the indentation is less, the parser climbs back towards the root until one of the previous
|
42
|
+
two rules applies.
|
43
|
+
|
44
|
+
`parse` optionally takes a block. Each line of the input will be passed to the block, which should
|
45
|
+
return the line modified as desired. For instance, to force all of the text to lowercase:
|
46
|
+
|
47
|
+
parser = Treeline::Parser.new
|
48
|
+
tree = parser.parse(lines) do | line |
|
49
|
+
line.downcase
|
50
|
+
end
|
51
|
+
|
52
|
+
The block is called *before* the amount of indentation is determined, so you can change the indentation
|
53
|
+
if you want to.
|
54
|
+
|
55
|
+
## Dependencies
|
56
|
+
|
57
|
+
None at the moment.
|
58
|
+
|
59
|
+
## Support
|
60
|
+
|
61
|
+
Wiki: <https://github.com/CraigCottingham/treeline/wiki>
|
62
|
+
|
63
|
+
## To do
|
64
|
+
|
65
|
+
Some things I'm considering adding:
|
66
|
+
|
67
|
+
* Allow the first line to have leading whitespace, and strip that amount of whitespace from each
|
68
|
+
subsequent line
|
69
|
+
|
70
|
+
## Contributing
|
71
|
+
|
72
|
+
Treeline has been written the particular need I have *right now* in mind. I'm trying hard not to bulk it up
|
73
|
+
with stuff that I or someone else might want someday. That being said, if you have a particular need that
|
74
|
+
Treeline doesn't quite satisfy in its current state, I'm happy to consider requests or (better yet)
|
75
|
+
contributions.
|
76
|
+
|
77
|
+
Here’s the most direct way to get your work merged into the project:
|
78
|
+
|
79
|
+
1. Fork the project.
|
80
|
+
2. Clone down your fork ( git clone git://github.com/<username>/treeline.git ).
|
81
|
+
3. Create a topic branch to contain your change ( git checkout -b my_awesome_feature ).
|
82
|
+
4. Hack away, add tests. Not necessarily in that order.
|
83
|
+
5. Make sure everything still passes by running `rake test`.
|
84
|
+
6. If necessary, rebase your commits into logical chunks, without errors.
|
85
|
+
7. Push the branch up ( git push origin my_awesome_feature ).
|
86
|
+
8. Send a pull request.
|
87
|
+
|
88
|
+
## License
|
89
|
+
|
90
|
+
Copyright © 2011 Craig S. Cottingham.
|
91
|
+
It is free software, and may be redistributed under the terms specified in the LICENSE file.
|
data/Rakefile
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require File.expand_path('../lib/treeline/version', __FILE__)
|
5
|
+
|
6
|
+
Bundler::GemHelper.install_tasks
|
7
|
+
|
8
|
+
Rake::TestTask.new(:test) do |test|
|
9
|
+
test.libs << 'lib' << 'test'
|
10
|
+
test.pattern = 'test/**/*_test.rb'
|
11
|
+
end
|
12
|
+
|
13
|
+
# namespace :test do
|
14
|
+
# Rake::TestTask.new(:lint) do |test|
|
15
|
+
# test.libs << 'lib' << 'test'
|
16
|
+
# test.pattern = 'test/test_active_model_lint.rb'
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# task :all => ['test', 'test:lint']
|
20
|
+
# end
|
21
|
+
|
22
|
+
# task :default => 'test:all'
|
23
|
+
task :default => 'test'
|
24
|
+
|
25
|
+
desc 'Builds the gem'
|
26
|
+
task :build do
|
27
|
+
sh "gem build treeline.gemspec"
|
28
|
+
end
|
29
|
+
|
30
|
+
desc 'Builds and installs the gem'
|
31
|
+
task :install => :build do
|
32
|
+
sh "gem install pkg/treeline-#{Treeline::VERSION}.gem"
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'Tags version, pushes to remote, and pushes gem'
|
36
|
+
task :release => :build do
|
37
|
+
sh "git tag v#{Treeline::VERSION}"
|
38
|
+
sh "git push origin master"
|
39
|
+
sh "git push origin v#{Treeline::VERSION}"
|
40
|
+
sh "gem push treeline-#{Treeline::VERSION}.gem"
|
41
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/usr/bin/env ruby -wKU
|
2
|
+
|
3
|
+
module Treeline
|
4
|
+
class Parser
|
5
|
+
|
6
|
+
def parse(lines)
|
7
|
+
tree = {}
|
8
|
+
@path = []
|
9
|
+
|
10
|
+
lines.each do | line |
|
11
|
+
# line.chomp!
|
12
|
+
line.rstrip!
|
13
|
+
line = yield(line) if block_given?
|
14
|
+
|
15
|
+
# first, catch root elements (with no indent)
|
16
|
+
if (line =~ /^\S/)
|
17
|
+
@path = [ [ line, 0 ] ]
|
18
|
+
else
|
19
|
+
# next, catch indented elements
|
20
|
+
matched = /^(\s+)/.match(line)
|
21
|
+
unless (matched.nil?)
|
22
|
+
indent = matched[1].length
|
23
|
+
while (indent <= @path[0][1])
|
24
|
+
@path.shift
|
25
|
+
end
|
26
|
+
line.lstrip!
|
27
|
+
@path.unshift [ line, indent ]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# puts self.to_s
|
32
|
+
make_path_to_node(tree, @path.reverse)
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
tree
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
def make_path_to_node(tree, path)
|
42
|
+
make_path_to_node(tree[path[0][0]], path[1..-1]) if (path.count > 1)
|
43
|
+
tree[path[0][0]] = {} if (path.count == 1)
|
44
|
+
tree
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def to_s
|
50
|
+
@path.reverse.map { | item | item[0] }.join(" > ")
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
#!/usr/bin/env ruby -wKU
|
2
|
+
|
3
|
+
require "test/unit"
|
4
|
+
require File.expand_path('lib/treeline/parser')
|
5
|
+
|
6
|
+
class ParserTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def test_parser
|
9
|
+
lines = []
|
10
|
+
lines << "A"
|
11
|
+
lines << " A::B1"
|
12
|
+
lines << " A::B2"
|
13
|
+
lines << " A::B2::C"
|
14
|
+
lines << " A::B3"
|
15
|
+
lines << " A::B3::D1"
|
16
|
+
lines << " A::B3::D2"
|
17
|
+
|
18
|
+
parser = Treeline::Parser.new
|
19
|
+
|
20
|
+
tree = parser.parse lines
|
21
|
+
assert_not_nil tree
|
22
|
+
assert_equal 1, tree.keys.count
|
23
|
+
assert_has_key tree, 'A'
|
24
|
+
|
25
|
+
subtree = tree['A']
|
26
|
+
assert_not_nil subtree
|
27
|
+
assert_equal 3, subtree.keys.count
|
28
|
+
assert_has_key subtree, 'A::B1'
|
29
|
+
assert_has_key subtree, 'A::B2'
|
30
|
+
assert_has_key subtree, 'A::B3'
|
31
|
+
|
32
|
+
subsubtree = subtree['A::B1']
|
33
|
+
assert_not_nil subsubtree
|
34
|
+
assert_equal 0, subsubtree.keys.count
|
35
|
+
|
36
|
+
subsubtree = subtree['A::B2']
|
37
|
+
assert_not_nil subsubtree
|
38
|
+
assert_equal 1, subsubtree.keys.count
|
39
|
+
assert_has_key subsubtree, 'A::B2::C'
|
40
|
+
|
41
|
+
subsubtree = subtree['A::B3']
|
42
|
+
assert_not_nil subsubtree
|
43
|
+
assert_equal 2, subsubtree.keys.count
|
44
|
+
assert_has_key subsubtree, 'A::B3::D1'
|
45
|
+
assert_has_key subsubtree, 'A::B3::D2'
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_parser_with_block
|
49
|
+
lines = []
|
50
|
+
lines << "A"
|
51
|
+
lines << " A::B1"
|
52
|
+
lines << " A::B2"
|
53
|
+
lines << " A::B2::C"
|
54
|
+
lines << " A::B3"
|
55
|
+
lines << " A::B3::D1"
|
56
|
+
lines << " A::B3::D2"
|
57
|
+
|
58
|
+
parser = Treeline::Parser.new
|
59
|
+
|
60
|
+
tree = parser.parse(lines) do | item |
|
61
|
+
item.downcase
|
62
|
+
end
|
63
|
+
assert_not_nil tree
|
64
|
+
assert_equal 1, tree.keys.count
|
65
|
+
assert_has_key tree, 'a'
|
66
|
+
|
67
|
+
subtree = tree['a']
|
68
|
+
assert_not_nil subtree
|
69
|
+
assert_equal 3, subtree.keys.count
|
70
|
+
assert_has_key subtree, 'a::b1'
|
71
|
+
assert_has_key subtree, 'a::b2'
|
72
|
+
assert_has_key subtree, 'a::b3'
|
73
|
+
|
74
|
+
subsubtree = subtree['a::b1']
|
75
|
+
assert_not_nil subsubtree
|
76
|
+
assert_equal 0, subsubtree.keys.count
|
77
|
+
|
78
|
+
subsubtree = subtree['a::b2']
|
79
|
+
assert_not_nil subsubtree
|
80
|
+
assert_equal 1, subsubtree.keys.count
|
81
|
+
assert_has_key subsubtree, 'a::b2::c'
|
82
|
+
|
83
|
+
subsubtree = subtree['a::b3']
|
84
|
+
assert_not_nil subsubtree
|
85
|
+
assert_equal 2, subsubtree.keys.count
|
86
|
+
assert_has_key subsubtree, 'a::b3::d1'
|
87
|
+
assert_has_key subsubtree, 'a::b3::d2'
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_block_changing_indentation
|
91
|
+
lines = []
|
92
|
+
lines << "0 A"
|
93
|
+
lines << "1 A::B1"
|
94
|
+
lines << "1 A::B2"
|
95
|
+
lines << "2 A::B2::C"
|
96
|
+
lines << "1 A::B3"
|
97
|
+
lines << "2 A::B3::D1"
|
98
|
+
lines << "2 A::B3::D2"
|
99
|
+
|
100
|
+
parser = Treeline::Parser.new
|
101
|
+
|
102
|
+
tree = parser.parse(lines) do | item |
|
103
|
+
matched = /^(\d+)\s+(.*)$/.match(item)
|
104
|
+
(" " * matched[1].to_i) + matched[2]
|
105
|
+
end
|
106
|
+
assert_not_nil tree
|
107
|
+
assert_equal 1, tree.keys.count
|
108
|
+
assert_has_key tree, 'A'
|
109
|
+
|
110
|
+
subtree = tree['A']
|
111
|
+
assert_not_nil subtree
|
112
|
+
assert_equal 3, subtree.keys.count
|
113
|
+
assert_has_key subtree, 'A::B1'
|
114
|
+
assert_has_key subtree, 'A::B2'
|
115
|
+
assert_has_key subtree, 'A::B3'
|
116
|
+
|
117
|
+
subsubtree = subtree['A::B1']
|
118
|
+
assert_not_nil subsubtree
|
119
|
+
assert_equal 0, subsubtree.keys.count
|
120
|
+
|
121
|
+
subsubtree = subtree['A::B2']
|
122
|
+
assert_not_nil subsubtree
|
123
|
+
assert_equal 1, subsubtree.keys.count
|
124
|
+
assert_has_key subsubtree, 'A::B2::C'
|
125
|
+
|
126
|
+
subsubtree = subtree['A::B3']
|
127
|
+
assert_not_nil subsubtree
|
128
|
+
assert_equal 2, subsubtree.keys.count
|
129
|
+
assert_has_key subsubtree, 'A::B3::D1'
|
130
|
+
assert_has_key subsubtree, 'A::B3::D2'
|
131
|
+
end
|
132
|
+
|
133
|
+
protected
|
134
|
+
|
135
|
+
def assert_has_key(tree, key, msg=nil)
|
136
|
+
msg = "Key '#{key}' not found" if msg.nil?
|
137
|
+
flunk msg unless tree.has_key?(key)
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
data/treeline.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# treeline.gemspec
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
$:.push File.expand_path("../lib", __FILE__)
|
4
|
+
require "treeline/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "treeline"
|
8
|
+
s.version = Treeline::VERSION
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ["Craig S. Cottingham"]
|
11
|
+
s.email = ["craig.cottingham@gmail.com"]
|
12
|
+
s.homepage = "https://github.com/CraigCottingham/treeline"
|
13
|
+
s.summary = %q{Turns indented-line input into a tree structure.}
|
14
|
+
s.description = %q{Turns indented-line input into a tree structure.}
|
15
|
+
|
16
|
+
# s.add_development_dependency "rspec"
|
17
|
+
|
18
|
+
# s.rubyforge_project = ""
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
|
+
s.require_paths = ["lib"]
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: treeline
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Craig S. Cottingham
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-05-13 00:00:00 Z
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Turns indented-line input into a tree structure.
|
17
|
+
email:
|
18
|
+
- craig.cottingham@gmail.com
|
19
|
+
executables: []
|
20
|
+
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files: []
|
24
|
+
|
25
|
+
files:
|
26
|
+
- .gitignore
|
27
|
+
- Gemfile
|
28
|
+
- Gemfile.lock
|
29
|
+
- LICENSE.md
|
30
|
+
- README.md
|
31
|
+
- Rakefile
|
32
|
+
- lib/treeline/parser.rb
|
33
|
+
- lib/treeline/version.rb
|
34
|
+
- test/01_parser_test.rb
|
35
|
+
- treeline.gemspec
|
36
|
+
homepage: https://github.com/CraigCottingham/treeline
|
37
|
+
licenses: []
|
38
|
+
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
requirements: []
|
57
|
+
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 1.8.2
|
60
|
+
signing_key:
|
61
|
+
specification_version: 3
|
62
|
+
summary: Turns indented-line input into a tree structure.
|
63
|
+
test_files:
|
64
|
+
- test/01_parser_test.rb
|