toml-rb 0.1.6 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +7 -5
- data/Rakefile +2 -3
- data/init.rb +1 -1
- data/lib/toml.rb +0 -2
- data/lib/toml/dumper.rb +49 -8
- data/lib/toml/grammars/array.citrus +7 -7
- data/lib/toml/grammars/document.citrus +6 -2
- data/lib/toml/grammars/primitive.citrus +72 -10
- data/lib/toml/keygroup.rb +4 -3
- data/lib/toml/keyvalue.rb +1 -1
- data/lib/toml/parser.rb +4 -0
- data/lib/toml/string.rb +39 -23
- data/lib/toml/table_array.rb +29 -0
- data/test/dumper_test.rb +20 -11
- data/test/errors_test.rb +10 -12
- data/test/example-v0.3.1.toml +180 -0
- data/test/grammar_test.rb +56 -6
- data/test/hard_example.toml +5 -2
- data/test/toml_examples.rb +171 -0
- data/test/toml_test.rb +22 -55
- data/toml-rb.gemspec +13 -13
- metadata +22 -23
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 97909cd5d9ac3403acf5fba07cfb3177fb343458
|
4
|
+
data.tar.gz: ee82bae7cb2a1ec814b269390899ccd47781dabd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ef153da7a2aa9623a2554825b1604f460dfad351bfee4ed4078f2a45b3902992d4ecc2fae2d32b39ed37ef29182d9c4948b389584264e4b499b6f3acad261fd9
|
7
|
+
data.tar.gz: 2869e5f5d5b5c946940d3d38cda21440378ba4162cf73c4218aac9c2904630b95e9b075151db1f2fe6449209641f4d65470307b4ac1b4ded510a44e8c0905fdc
|
data/README.md
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
toml-rb
|
2
2
|
=======
|
3
3
|
|
4
|
-
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/toml-rb.svg)](http://badge.fury.io/rb/toml-rb)
|
5
|
+
[![Build Status](https://travis-ci.org/emancu/toml-rb.svg)](https://travis-ci.org/emancu/toml-rb)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/emancu/toml-rb/badges/gpa.svg)](https://codeclimate.com/github/emancu/toml-rb)
|
7
|
+
[![Dependency Status](https://gemnasium.com/emancu/toml-rb.svg)](https://gemnasium.com/emancu/toml-rb)
|
5
8
|
|
6
|
-
[
|
7
|
-
|
8
|
-
|
9
|
-
[![Dependency Status](https://gemnasium.com/emancu/toml-rb.png)](https://gemnasium.com/emancu/toml-rb)
|
9
|
+
A [TOML](https://github.com/mojombo/toml) parser using [Citrus](http://mjackson.github.io/citrus) library.
|
10
|
+
|
11
|
+
TOML specs supported: `0.3.1`
|
10
12
|
|
11
13
|
Installation
|
12
14
|
------------
|
data/Rakefile
CHANGED
data/init.rb
CHANGED
@@ -3,6 +3,7 @@ require 'citrus'
|
|
3
3
|
ROOT = File.dirname(File.expand_path(__FILE__))
|
4
4
|
|
5
5
|
require "#{ROOT}/lib/toml/string"
|
6
|
+
require "#{ROOT}/lib/toml/table_array"
|
6
7
|
require "#{ROOT}/lib/toml/keyvalue"
|
7
8
|
require "#{ROOT}/lib/toml/keygroup"
|
8
9
|
require "#{ROOT}/lib/toml/parser"
|
@@ -12,4 +13,3 @@ Citrus.load "#{ROOT}/lib/toml/grammars/helper.citrus"
|
|
12
13
|
Citrus.load "#{ROOT}/lib/toml/grammars/primitive.citrus"
|
13
14
|
Citrus.load "#{ROOT}/lib/toml/grammars/array.citrus"
|
14
15
|
Citrus.load "#{ROOT}/lib/toml/grammars/document.citrus"
|
15
|
-
|
data/lib/toml.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require_relative '../init'
|
2
2
|
|
3
3
|
module TOML
|
4
|
-
|
5
4
|
# Public: Returns a hash from *TOML* content.
|
6
5
|
#
|
7
6
|
# content - TOML string to be parsed.
|
@@ -56,7 +55,6 @@ module TOML
|
|
56
55
|
TOML.parse(File.read(path), options)
|
57
56
|
end
|
58
57
|
|
59
|
-
|
60
58
|
# Public: Returns a *TOML* string from a Ruby Hash.
|
61
59
|
#
|
62
60
|
# hash - Ruby Hash to be dumped into *TOML*
|
data/lib/toml/dumper.rb
CHANGED
@@ -5,39 +5,80 @@ module TOML
|
|
5
5
|
def initialize(hash)
|
6
6
|
@toml_str = ''
|
7
7
|
|
8
|
-
visit(hash,
|
8
|
+
visit(hash, [])
|
9
9
|
end
|
10
10
|
|
11
11
|
private
|
12
12
|
|
13
|
-
def visit(hash, prefix)
|
13
|
+
def visit(hash, prefix, extra_brackets = false)
|
14
14
|
nested_pairs = []
|
15
15
|
simple_pairs = []
|
16
|
+
table_array_pairs = []
|
16
17
|
|
17
18
|
hash.keys.sort.each do |key|
|
18
19
|
val = hash[key]
|
19
|
-
|
20
|
+
element = [key, val]
|
21
|
+
|
22
|
+
if val.is_a? Hash
|
23
|
+
nested_pairs << element
|
24
|
+
elsif val.is_a?(Array) && val.first.is_a?(Hash)
|
25
|
+
table_array_pairs << element
|
26
|
+
else
|
27
|
+
simple_pairs << element
|
28
|
+
end
|
20
29
|
end
|
21
30
|
|
22
|
-
|
31
|
+
unless prefix.empty? || simple_pairs.empty?
|
32
|
+
print_prefix prefix, extra_brackets
|
33
|
+
end
|
23
34
|
|
24
35
|
# First add simple pairs, under the prefix
|
25
36
|
simple_pairs.each do |key, val|
|
26
|
-
|
37
|
+
key = quote_key(key) unless bare_key? key
|
38
|
+
@toml_str << "#{key} = #{to_toml(val)}\n"
|
27
39
|
end
|
28
40
|
|
29
41
|
nested_pairs.each do |key, val|
|
30
|
-
|
42
|
+
key = quote_key(key) unless bare_key? key
|
43
|
+
|
44
|
+
visit val, prefix + [key], false
|
45
|
+
end
|
46
|
+
|
47
|
+
table_array_pairs.each do |key, val|
|
48
|
+
key = quote_key(key) unless bare_key? key
|
49
|
+
aux_prefix = prefix + [key]
|
50
|
+
|
51
|
+
val.each do |child|
|
52
|
+
if child.empty?
|
53
|
+
print_prefix aux_prefix, true
|
54
|
+
else
|
55
|
+
visit child, aux_prefix, true
|
56
|
+
end
|
57
|
+
end
|
31
58
|
end
|
32
59
|
end
|
33
60
|
|
61
|
+
def print_prefix(prefix, extra_brackets = false)
|
62
|
+
new_prefix = prefix.join('.')
|
63
|
+
new_prefix = '[' + new_prefix + ']' if extra_brackets
|
64
|
+
|
65
|
+
@toml_str += "[" + new_prefix + "]\n"
|
66
|
+
end
|
67
|
+
|
34
68
|
def to_toml(obj)
|
35
|
-
|
36
|
-
when obj.is_a?(Time)
|
69
|
+
if obj.is_a? Time
|
37
70
|
obj.strftime('%Y-%m-%dT%H:%M:%SZ')
|
38
71
|
else
|
39
72
|
obj.inspect
|
40
73
|
end
|
41
74
|
end
|
75
|
+
|
76
|
+
def bare_key?(key)
|
77
|
+
!!key.to_s.match(/^[a-zA-Z0-9_-]*$/)
|
78
|
+
end
|
79
|
+
|
80
|
+
def quote_key(key)
|
81
|
+
'"' + key.gsub('"', '\\"') + '"'
|
82
|
+
end
|
42
83
|
end
|
43
84
|
end
|
@@ -6,30 +6,30 @@ grammar TomlArray
|
|
6
6
|
end
|
7
7
|
|
8
8
|
rule elements
|
9
|
-
float_array | string_array | array_array | integer_array | datetime_array | bool_array
|
9
|
+
comment | float_array | string_array | array_array | integer_array | datetime_array | bool_array
|
10
10
|
end
|
11
11
|
|
12
12
|
rule float_array
|
13
|
-
(float ("," indent? float)*)
|
13
|
+
(float ("," indent? (float | comment))*)
|
14
14
|
end
|
15
15
|
|
16
16
|
rule string_array
|
17
|
-
(string ("," indent? string)*)
|
17
|
+
(string ("," indent? (string | comment))*)
|
18
18
|
end
|
19
19
|
|
20
20
|
rule array_array
|
21
|
-
(array ("," indent? array)*)
|
21
|
+
(array ("," indent? (array | comment))*)
|
22
22
|
end
|
23
23
|
|
24
24
|
rule integer_array
|
25
|
-
(integer ("," indent? integer)*)
|
25
|
+
(integer ("," indent? (integer | comment))*)
|
26
26
|
end
|
27
27
|
|
28
28
|
rule datetime_array
|
29
|
-
(datetime ("," indent? datetime)*)
|
29
|
+
(datetime ("," indent? (datetime | comment))*)
|
30
30
|
end
|
31
31
|
|
32
32
|
rule bool_array
|
33
|
-
(bool ("," indent? bool)*)
|
33
|
+
(bool ("," indent? (bool | comment))*)
|
34
34
|
end
|
35
35
|
end
|
@@ -3,11 +3,15 @@ grammar Document
|
|
3
3
|
include TomlArray
|
4
4
|
|
5
5
|
rule document
|
6
|
-
(comment | keygroup | keyvalue | line_break)*
|
6
|
+
(comment | table_array | keygroup | keyvalue | line_break)*
|
7
|
+
end
|
8
|
+
|
9
|
+
rule table_array
|
10
|
+
(space? '[[' (space? key space? "."?)+ ']]' space? comment?) <TableArray>
|
7
11
|
end
|
8
12
|
|
9
13
|
rule keygroup
|
10
|
-
(space? '['
|
14
|
+
(space? '[' (space? key space? "."?)+ ']' space? comment?) <Keygroup>
|
11
15
|
end
|
12
16
|
|
13
17
|
rule keyvalue
|
@@ -5,30 +5,72 @@ grammar Primitive
|
|
5
5
|
string | bool | datetime | number
|
6
6
|
end
|
7
7
|
|
8
|
+
##
|
9
|
+
# String rules
|
10
|
+
##
|
11
|
+
|
8
12
|
rule string
|
9
|
-
|
13
|
+
multiline_string | multiline_literal | basic_string | literal_string
|
10
14
|
end
|
11
15
|
|
12
|
-
rule
|
13
|
-
|
16
|
+
rule basic_string
|
17
|
+
(/(["])(?:\\?.)*?\1/ space) <TomlBasicString>
|
18
|
+
end
|
19
|
+
|
20
|
+
rule literal_string
|
21
|
+
(/(['])(?:\\?.)*?\1/ space) <TomlLiteralString>
|
22
|
+
end
|
23
|
+
|
24
|
+
rule multiline_string
|
25
|
+
('"""' line_break* text:~'"""' '"""' space) <TomlMultilineString>
|
26
|
+
end
|
27
|
+
|
28
|
+
rule multiline_literal
|
29
|
+
("'''" line_break* text:~"'''" "'''" space) <TomlMultilineLiteral>
|
14
30
|
end
|
15
31
|
|
16
|
-
|
32
|
+
##
|
33
|
+
# Date time rules
|
34
|
+
##
|
35
|
+
|
17
36
|
rule datetime
|
18
|
-
(
|
19
|
-
|
20
|
-
|
37
|
+
(date_skeleton ("Z" | date_offset | [,\.] frac:(/\d/1*6) date_offset)) {
|
38
|
+
skeleton = captures[:date_skeleton].first
|
39
|
+
y,m,d,h,mi,s = skeleton.value
|
40
|
+
offset = captures[:date_offset].first || "+00:00"
|
41
|
+
sec_frac = captures[:frac].first || 0
|
42
|
+
s = "#{s}.#{sec_frac}".to_f
|
43
|
+
|
44
|
+
Time.new(*[y,m,d,h,mi,s,offset.to_s])
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
rule date_skeleton
|
49
|
+
(y:/\d\d\d\d/ "-" m:/\d\d/ "-" d:/\d\d/ "T" h:/\d\d/ ":" mi:/\d\d/ ":" s:/\d\d/) {
|
50
|
+
[:y,:m,:d,:h,:mi,:s].map{ |s| capture(s).value }
|
21
51
|
}
|
22
52
|
end
|
23
53
|
|
54
|
+
rule date_offset
|
55
|
+
offset:(sign /\d\d/ ":" /\d\d/)
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Number rules
|
60
|
+
##
|
61
|
+
|
24
62
|
rule number
|
25
|
-
|
63
|
+
exponent | float | integer
|
26
64
|
end
|
27
65
|
|
28
66
|
rule float
|
29
67
|
(integer '.' integer) { to_str.to_f }
|
30
68
|
end
|
31
69
|
|
70
|
+
rule exponent
|
71
|
+
( (float | integer) [eE] integer) { to_str.to_f }
|
72
|
+
end
|
73
|
+
|
32
74
|
rule integer
|
33
75
|
(sign? [0-9]+) { to_str.to_i }
|
34
76
|
end
|
@@ -37,8 +79,12 @@ grammar Primitive
|
|
37
79
|
'+' | '-'
|
38
80
|
end
|
39
81
|
|
40
|
-
|
41
|
-
|
82
|
+
##
|
83
|
+
# Boolean rules
|
84
|
+
##
|
85
|
+
|
86
|
+
rule bool
|
87
|
+
true | false
|
42
88
|
end
|
43
89
|
|
44
90
|
rule true
|
@@ -48,4 +94,20 @@ grammar Primitive
|
|
48
94
|
rule false
|
49
95
|
'false' { false }
|
50
96
|
end
|
97
|
+
|
98
|
+
##
|
99
|
+
# Key rules
|
100
|
+
##
|
101
|
+
|
102
|
+
rule key
|
103
|
+
quoted_key | bare_key
|
104
|
+
end
|
105
|
+
|
106
|
+
rule bare_key
|
107
|
+
[a-zA-Z_] [a-zA-Z_0-9_-]*
|
108
|
+
end
|
109
|
+
|
110
|
+
rule quoted_key
|
111
|
+
string
|
112
|
+
end
|
51
113
|
end
|
data/lib/toml/keygroup.rb
CHANGED
@@ -8,14 +8,15 @@ module TOML
|
|
8
8
|
@nested_keys.each do |key|
|
9
9
|
key = symbolize_keys ? key.to_sym : key
|
10
10
|
hash[key] = {} unless hash[key]
|
11
|
-
|
11
|
+
element = hash[key]
|
12
|
+
hash = element.is_a?(Array) ? element.last : element
|
12
13
|
end
|
13
14
|
|
14
15
|
hash
|
15
16
|
end
|
16
17
|
|
17
18
|
def accept_visitor(parser)
|
18
|
-
parser.visit_keygroup
|
19
|
+
parser.visit_keygroup self
|
19
20
|
end
|
20
21
|
end
|
21
22
|
end
|
@@ -23,6 +24,6 @@ end
|
|
23
24
|
# Used in document.citrus
|
24
25
|
module Keygroup
|
25
26
|
def value
|
26
|
-
TOML::Keygroup.new(
|
27
|
+
TOML::Keygroup.new(captures[:key].map(&:value))
|
27
28
|
end
|
28
29
|
end
|
data/lib/toml/keyvalue.rb
CHANGED
data/lib/toml/parser.rb
CHANGED
@@ -19,6 +19,10 @@ module TOML
|
|
19
19
|
|
20
20
|
# Read about the Visitor pattern
|
21
21
|
# http://en.wikipedia.org/wiki/Visitor_pattern
|
22
|
+
def visit_table_array(table_array)
|
23
|
+
@current = table_array.navigate_keys @hash, @symbolize_keys
|
24
|
+
end
|
25
|
+
|
22
26
|
def visit_keygroup(keygroup)
|
23
27
|
@current = keygroup.navigate_keys(@hash, @symbolize_keys)
|
24
28
|
end
|
data/lib/toml/string.rb
CHANGED
@@ -1,27 +1,43 @@
|
|
1
1
|
# Used in primitive.citrus
|
2
|
-
module
|
2
|
+
module TomlBasicString
|
3
3
|
def value
|
4
|
-
aux = first.value
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
4
|
+
aux = TomlBasicString.transform_escaped_chars first.value
|
5
|
+
|
6
|
+
aux[1...-1]
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.transform_escaped_chars(str)
|
10
|
+
str
|
11
|
+
.gsub(/\\0/, "\0")
|
12
|
+
.gsub(/\\t/, "\t")
|
13
|
+
.gsub(/\\n/, "\n")
|
14
|
+
.gsub(/\\\"/, '"')
|
15
|
+
.gsub(/\\r/, "\r")
|
16
|
+
.gsub(/\\\\/, '\\')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module TomlLiteralString
|
21
|
+
def value
|
22
|
+
first.value[1...-1]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module TomlMultilineString
|
27
|
+
def value
|
28
|
+
aux = captures[:text].first.value
|
29
|
+
|
30
|
+
# Remove spaces on multilined Singleline strings
|
31
|
+
aux.gsub!(/\\\r?\n[\n\t\r ]*/, '')
|
32
|
+
|
33
|
+
TomlBasicString.transform_escaped_chars aux
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module TomlMultilineLiteral
|
38
|
+
def value
|
39
|
+
aux = captures[:text].first.value
|
40
|
+
|
41
|
+
aux.gsub(/\\\r?\n[\n\t\r ]*/, '')
|
26
42
|
end
|
27
43
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module TOML
|
2
|
+
class TableArray
|
3
|
+
def initialize(nested_keys)
|
4
|
+
@nested_keys = nested_keys
|
5
|
+
end
|
6
|
+
|
7
|
+
def navigate_keys(hash, symbolize_keys = false)
|
8
|
+
@nested_keys.each do |key|
|
9
|
+
key = symbolize_keys ? key.to_sym : key
|
10
|
+
hash[key] = [] unless hash[key]
|
11
|
+
hash[key] << {} if @nested_keys.last == key.to_s || hash[key].empty?
|
12
|
+
hash = hash[key].last
|
13
|
+
end
|
14
|
+
|
15
|
+
hash
|
16
|
+
end
|
17
|
+
|
18
|
+
def accept_visitor(parser)
|
19
|
+
parser.visit_table_array self
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Used in document.citrus
|
25
|
+
module TableArray
|
26
|
+
def value
|
27
|
+
TOML::TableArray.new(captures[:key].map(&:value))
|
28
|
+
end
|
29
|
+
end
|