toml-rb 0.1.6 → 0.2.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/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
|
+
[](http://badge.fury.io/rb/toml-rb)
|
5
|
+
[](https://travis-ci.org/emancu/toml-rb)
|
6
|
+
[](https://codeclimate.com/github/emancu/toml-rb)
|
7
|
+
[](https://gemnasium.com/emancu/toml-rb)
|
5
8
|
|
6
|
-
[
|
7
|
-
|
8
|
-
|
9
|
-
[](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
|