ptolemy 0.0.1 → 0.0.2
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.
- data/README.md +55 -2
- data/lib/ptolemy.rb +13 -0
- data/lib/ptolemy/exceptions.rb +7 -0
- data/lib/ptolemy/nodes.rb +65 -2
- data/lib/ptolemy/parser.rb +9 -0
- data/lib/ptolemy/version.rb +1 -1
- metadata +3 -3
data/README.md
CHANGED
@@ -1,5 +1,58 @@
|
|
1
1
|

|
2
|
+
|
2
3
|
[](https://travis-ci.org/natansh/ptolemy)
|
3
|
-
|
4
|
+
[](http://badge.fury.io/rb/ptolemy)
|
5
|
+
|
6
|
+
===
|
7
|
+
Ptolemy is a simple TOML parser for Ruby, based on Treetop. It is useful for parsing the [TOML Format](https://github.com/mojombo/toml).
|
8
|
+
|
9
|
+
Ptolemy currently supports version [0.1.0](https://github.com/mojombo/toml/blob/master/versions/toml-v0.1.0.md) of TOML.
|
10
|
+
|
11
|
+
Installation
|
12
|
+
---
|
13
|
+
|
14
|
+
# Bundler
|
15
|
+
Add this to your `Gemfile`
|
16
|
+
|
17
|
+
gem 'ptolemy', '~> 0.0.2'
|
18
|
+
|
19
|
+
And then run
|
20
|
+
|
21
|
+
bundle install
|
22
|
+
|
23
|
+
# Manual
|
24
|
+
You can install it manually using
|
25
|
+
|
26
|
+
gem install ptolemy
|
27
|
+
|
28
|
+
Usage
|
29
|
+
---
|
30
|
+
* `Ptolemy.parse` can parse a string in TOML format.
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
data = <<END
|
34
|
+
# This is an example TOML input
|
35
|
+
[group]
|
36
|
+
string = "hello"
|
37
|
+
integer = 0
|
38
|
+
END
|
39
|
+
|
40
|
+
Ptolemy.parse(data)
|
41
|
+
|
42
|
+
# => {"group"=>{"string"=>"hello", "integer"=>0}}
|
43
|
+
|
44
|
+
```
|
45
|
+
* `Ptolemy.parse_file` can read from a UTF-8 encoded file directly.
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
filename = 'example.toml'
|
49
|
+
Ptolemy.parse_file(filename)
|
50
|
+
```
|
51
|
+
|
52
|
+
Test Suite
|
53
|
+
---
|
54
|
+
Ptolemy has a fairly exhaustive test suite built on `rspec` and can
|
55
|
+
successfully parse the specification file and hard example given
|
56
|
+
in the TOML specification.
|
4
57
|
|
5
|
-
|
58
|
+
You can run the test suite by running `rake`.
|
data/lib/ptolemy.rb
CHANGED
@@ -5,10 +5,23 @@ require "ptolemy/parser"
|
|
5
5
|
|
6
6
|
module Ptolemy
|
7
7
|
|
8
|
+
# Parses TOML string input
|
9
|
+
#
|
10
|
+
# Ptolemy.parse 'key = "value"'
|
11
|
+
#
|
12
|
+
# @param data [String] the input string
|
13
|
+
# @return [Hash] the input parsed into a ruby hash
|
8
14
|
def self.parse data
|
9
15
|
Parser.parse data
|
10
16
|
end
|
11
17
|
|
18
|
+
# Parses data from a file containing TOML.
|
19
|
+
# The file should be UTF-8 encoded.
|
20
|
+
#
|
21
|
+
# Ptolemy.parse_file 'example.toml'
|
22
|
+
#
|
23
|
+
# @param filename [String] full path of the file
|
24
|
+
# @return [Hash] the input parsed into a ruby hash
|
12
25
|
def self.parse_file filename
|
13
26
|
File.open filename, 'r:utf-8' do |file|
|
14
27
|
# TODO: Should the check for valid UTF-8 be done over here?
|
data/lib/ptolemy/exceptions.rb
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
|
3
3
|
module Ptolemy
|
4
4
|
|
5
|
+
# Represents the error that occurs while parsing a TOML
|
6
|
+
# input.
|
7
|
+
#
|
8
|
+
# Possible sources of error are
|
9
|
+
# * Encoding issues
|
10
|
+
# * Issues while parsing into AST
|
11
|
+
# * Duplication issues
|
5
12
|
class ParseError < StandardError; end
|
6
13
|
|
7
14
|
end
|
data/lib/ptolemy/nodes.rb
CHANGED
@@ -7,7 +7,16 @@ require 'ptolemy/exceptions'
|
|
7
7
|
module Ptolemy
|
8
8
|
module TOML
|
9
9
|
|
10
|
+
# Represents the top level node of TOML AST
|
10
11
|
class Toml < Treetop:: Runtime::SyntaxNode
|
12
|
+
|
13
|
+
# Evaluate the individual subtrees of the AST
|
14
|
+
# and then combine them to form the complete hash.
|
15
|
+
#
|
16
|
+
# @return [Hash] a (possibly nested) hash containing all
|
17
|
+
# key value pairs.
|
18
|
+
# @raise [ParseError] if there are duplications in
|
19
|
+
# key groups or key value pairs.
|
11
20
|
def to_value
|
12
21
|
result = {}
|
13
22
|
# Keep track of location under which all the key value pairs must be
|
@@ -47,7 +56,12 @@ module TOML
|
|
47
56
|
end
|
48
57
|
end
|
49
58
|
|
59
|
+
# Represents an element of the form [x.y.z.w]
|
50
60
|
class KeyGroup < Treetop::Runtime::SyntaxNode
|
61
|
+
|
62
|
+
# Evaluate an array of keys split by the '.'
|
63
|
+
#
|
64
|
+
# @return [Array] the array of nested keys represented by the key group
|
51
65
|
def to_value
|
52
66
|
result = [keys.key.to_value]
|
53
67
|
keys.remaining_keys.elements.each do |elem|
|
@@ -57,23 +71,43 @@ module TOML
|
|
57
71
|
end
|
58
72
|
end
|
59
73
|
|
74
|
+
# Represents an element of the form key = value
|
60
75
|
class KeyValue < Treetop::Runtime::SyntaxNode
|
76
|
+
|
77
|
+
# Evaluate both key and value and return as a 2 element array
|
78
|
+
#
|
79
|
+
# @return [Array] Two-element array containing key and value
|
61
80
|
def to_value
|
62
81
|
[key.to_value, value.to_value]
|
63
82
|
end
|
64
83
|
end
|
65
84
|
|
85
|
+
# Represents a valid key
|
66
86
|
class Key < Treetop::Runtime::SyntaxNode
|
87
|
+
|
88
|
+
# Evaluates the key which is just the text_value of the node
|
67
89
|
def to_value
|
68
90
|
text_value
|
69
91
|
end
|
70
92
|
end
|
71
93
|
|
94
|
+
# Represents a Comment
|
72
95
|
class Comment < Treetop::Runtime::SyntaxNode
|
73
96
|
end
|
74
97
|
|
98
|
+
# Represents a homogeneous array. Mixing of types is not allowed
|
99
|
+
# for elements of an array.
|
100
|
+
#
|
101
|
+
# * [1, 2, 3, 4]
|
102
|
+
# * ["Hello", "World"]
|
103
|
+
# * [ ["Alpha", "Beta"], [1, 2]] <-- This is fine
|
75
104
|
class ArrayLiteral < Treetop::Runtime::SyntaxNode
|
76
|
-
|
105
|
+
|
106
|
+
# Evaluate the array by mapping the individual elements
|
107
|
+
# of the array to their evaluated selves.
|
108
|
+
#
|
109
|
+
# @return [Array] evaluated array
|
110
|
+
def to_value
|
77
111
|
result = list.elements.map do|elem|
|
78
112
|
elem.item.to_value
|
79
113
|
end
|
@@ -84,24 +118,44 @@ module TOML
|
|
84
118
|
end
|
85
119
|
end
|
86
120
|
|
121
|
+
# Represents an integer. Ruby doesn't have overflow issues
|
122
|
+
# so any big integer is going to be fine.
|
87
123
|
class IntegerLiteral < Treetop::Runtime::SyntaxNode
|
88
|
-
|
124
|
+
|
125
|
+
# Evaluate an integer by converting the text_value to
|
126
|
+
# integer directly.
|
127
|
+
#
|
128
|
+
# @return [Integer] evaluated integer
|
129
|
+
def to_value
|
89
130
|
text_value.to_i
|
90
131
|
end
|
91
132
|
end
|
92
133
|
|
134
|
+
# Represents a Float
|
93
135
|
class FloatLiteral < Treetop::Runtime::SyntaxNode
|
136
|
+
|
137
|
+
# Evaluate a float by converting the text_value to a
|
138
|
+
# float directly
|
139
|
+
#
|
140
|
+
# @return [Float] evaluated float
|
94
141
|
def to_value
|
95
142
|
text_value.to_f
|
96
143
|
end
|
97
144
|
end
|
98
145
|
|
146
|
+
# Represents a Boolean
|
99
147
|
class BooleanLiteral < Treetop::Runtime::SyntaxNode
|
148
|
+
|
149
|
+
# Evaluate a boolean by checking whether its
|
150
|
+
# text value matches true
|
151
|
+
#
|
152
|
+
# @return [true, false] evaluated boolean
|
100
153
|
def to_value
|
101
154
|
text_value == 'true'
|
102
155
|
end
|
103
156
|
end
|
104
157
|
|
158
|
+
# Represents a UTF-8 encoded string
|
105
159
|
class StringLiteral < Treetop::Runtime::SyntaxNode
|
106
160
|
|
107
161
|
private
|
@@ -119,6 +173,10 @@ module TOML
|
|
119
173
|
|
120
174
|
public
|
121
175
|
|
176
|
+
# Evaluate a string by unescaping the escaped characters and
|
177
|
+
# unicode characters written in the form \uXXXX
|
178
|
+
#
|
179
|
+
# @return [String] evaluated string
|
122
180
|
def to_value
|
123
181
|
elem = string.text_value
|
124
182
|
# Unescape unicode characters of the form \uXXXX
|
@@ -132,6 +190,11 @@ module TOML
|
|
132
190
|
end
|
133
191
|
|
134
192
|
class DateLiteral < Treetop::Runtime::SyntaxNode
|
193
|
+
|
194
|
+
# Evaluate the date by extracting individual elements such as year, month etc.
|
195
|
+
# from the parsed date and using that to construct a {DateTime} object.
|
196
|
+
#
|
197
|
+
# @return [DateTime] the evaluated date represented by the elements
|
135
198
|
def to_value
|
136
199
|
args = [year, month, day, hour, min, sec].map(&:text_value).map(&:to_i)
|
137
200
|
DateTime.new(*args)
|
data/lib/ptolemy/parser.rb
CHANGED
@@ -7,6 +7,8 @@ require 'ptolemy/exceptions'
|
|
7
7
|
|
8
8
|
module Ptolemy
|
9
9
|
|
10
|
+
# The main class that encapsulates all the parsing functionality.
|
11
|
+
# It includes the parser generated by the treetop grammar.
|
10
12
|
class Parser
|
11
13
|
|
12
14
|
# Load TOML grammar into Treetop
|
@@ -16,6 +18,13 @@ module Ptolemy
|
|
16
18
|
# Treetop would've generated a parser for TOML based on the grammar
|
17
19
|
@@parser = TOMLParser.new
|
18
20
|
|
21
|
+
# Verifies that the data is encoded in UTF-8 and that
|
22
|
+
# the encoding is valid.
|
23
|
+
# Parses the data using the {TOMLParser} generated by Treetop
|
24
|
+
#
|
25
|
+
# @param data [String] input to be parsed
|
26
|
+
# @return [Hash] the input parsed into a ruby hash
|
27
|
+
# @raise [ParseError] if there are encoding issues or parsing issues.
|
19
28
|
def self.parse data
|
20
29
|
# Data should be a valid UTF-8 encoded string.
|
21
30
|
if data.encoding != Encoding::UTF_8
|
data/lib/ptolemy/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ptolemy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-09-
|
12
|
+
date: 2013-09-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: treetop
|
@@ -137,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
137
|
version: '0'
|
138
138
|
segments:
|
139
139
|
- 0
|
140
|
-
hash: -
|
140
|
+
hash: -1910015093891202054
|
141
141
|
requirements: []
|
142
142
|
rubyforge_project:
|
143
143
|
rubygems_version: 1.8.24
|