nodaire 0.4.0 → 0.5.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 +4 -4
- data/README.md +21 -28
- data/lib/nodaire/base.rb +4 -2
- data/lib/nodaire/errors.rb +2 -0
- data/lib/nodaire/indental/indental.rb +85 -26
- data/lib/nodaire/tablatal/tablatal.rb +99 -25
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '088490e1cd30efae42ca1f6ac32639378df03eb8fe5e65782744280dcd050ada'
|
4
|
+
data.tar.gz: b0dafd1457ab1db55e2200037fc834f54b5d3fbec5a408d4de93fc788bd97ece
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf2d5f24bc4a8f60b8328cae06945e1f2978d7b488112e15152d1fadefc9d2130192e8ab918c64398366e279f5120f4590760235d18a6aca9abcf35b601cc931
|
7
|
+
data.tar.gz: 7ddeca02582654ebaf4237cf57602e757920a93ff681faf8ecda89dec76daa8e7a1066b26c797d7e9e749f81039316bc3d2ad26532dc09de9ed3604b28ea255d
|
data/README.md
CHANGED
@@ -8,10 +8,12 @@ Expect breaking API changes before v1.0.0 is released.
|
|
8
8
|
|
9
9
|
## File formats
|
10
10
|
|
11
|
-
Nodaire
|
11
|
+
Nodaire supports the following text file formats:
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
| File format | Documentation and examples | Origin |
|
14
|
+
|---|---|---|
|
15
|
+
| __Indental__ | [`Nodaire::Indental`](https://slisne.github.io/nodaire/Nodaire/Indental.html) | https://wiki.xxiivv.com/#indental |
|
16
|
+
| __Tablatal__ | [`Nodaire::Tablatal`](https://slisne.github.io/nodaire/Nodaire/Tablatal.html) | https://wiki.xxiivv.com/#tablatal |
|
15
17
|
|
16
18
|
## Install
|
17
19
|
|
@@ -27,14 +29,12 @@ gem install nodaire
|
|
27
29
|
|
28
30
|
Keep reading below for examples of how to use Nodaire.
|
29
31
|
|
30
|
-
## Usage
|
31
|
-
|
32
|
-
### Indental
|
32
|
+
## Usage example
|
33
33
|
|
34
34
|
```ruby
|
35
35
|
require 'nodaire/indental'
|
36
36
|
|
37
|
-
|
37
|
+
source = <<~NDTL
|
38
38
|
NAME
|
39
39
|
KEY : VALUE
|
40
40
|
LIST
|
@@ -42,29 +42,22 @@ doc = Nodaire::Indental.parse! <<~NDTL
|
|
42
42
|
ITEM2
|
43
43
|
NDTL
|
44
44
|
|
45
|
-
doc.
|
46
|
-
doc.categories # ["NAME"]
|
47
|
-
doc.to_h # {"NAME"=>{"KEY"=>"VALUE", "LIST"=>["ITEM1", "ITEM2"]}}
|
48
|
-
doc.to_json # '{"NAME":{"KEY":"VALUE","LIST":["ITEM1","ITEM2"]}}'
|
49
|
-
```
|
45
|
+
doc = Nodaire::Indental.parse(source)
|
50
46
|
|
51
|
-
|
47
|
+
doc.valid?
|
48
|
+
#=> true
|
52
49
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
doc
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
doc.valid? # true
|
65
|
-
doc.keys # ["NAME", "AGE", "COLOR"]
|
66
|
-
doc.to_a.last # {"NAME"=>"Ruca", "AGE"=>"45", "COLOR"=>"Grey"}
|
67
|
-
doc.to_csv # "NAME,AGE,COLOR\nErica,12,Opal\nAlex,23,..."
|
50
|
+
doc.categories
|
51
|
+
#=> ["NAME"]
|
52
|
+
|
53
|
+
doc['NAME']['KEY']
|
54
|
+
#=> "VALUE"
|
55
|
+
|
56
|
+
doc.to_h
|
57
|
+
#=> {"NAME" => {"KEY"=>"VALUE", "LIST"=>["ITEM1", "ITEM2"]}}
|
58
|
+
|
59
|
+
doc.to_json
|
60
|
+
#=> '{"NAME":{"KEY":"VALUE","LIST":["ITEM1","ITEM2"]}}'
|
68
61
|
```
|
69
62
|
|
70
63
|
## Development
|
data/lib/nodaire/base.rb
CHANGED
@@ -3,9 +3,11 @@
|
|
3
3
|
##
|
4
4
|
# Nodaire is a collection of text file parsers.
|
5
5
|
#
|
6
|
+
# @author Liam Cooke
|
7
|
+
#
|
6
8
|
module Nodaire
|
7
9
|
# The version number.
|
8
|
-
VERSION = '0.
|
10
|
+
VERSION = '0.5.0'
|
9
11
|
# The date when this version was released.
|
10
|
-
DATE = '2019-08-
|
12
|
+
DATE = '2019-08-26'
|
11
13
|
end
|
data/lib/nodaire/errors.rb
CHANGED
@@ -5,14 +5,16 @@ require 'json'
|
|
5
5
|
require_relative 'parser'
|
6
6
|
|
7
7
|
##
|
8
|
-
# Interface for documents in
|
8
|
+
# Interface for documents in Indental format.
|
9
9
|
#
|
10
|
-
#
|
11
|
-
#
|
10
|
+
# Indental is a text file format which represents a 'dictionary-type database'.
|
11
|
+
# This format was created by Devine Lu Linvega --
|
12
|
+
# see https://wiki.xxiivv.com/#indental for more information.
|
12
13
|
#
|
14
|
+
# @example
|
13
15
|
# require 'nodaire/indental'
|
14
16
|
#
|
15
|
-
#
|
17
|
+
# source = <<~NDTL
|
16
18
|
# NAME
|
17
19
|
# KEY : VALUE
|
18
20
|
# LIST
|
@@ -20,34 +22,58 @@ require_relative 'parser'
|
|
20
22
|
# ITEM2
|
21
23
|
# NDTL
|
22
24
|
#
|
23
|
-
# doc.
|
24
|
-
#
|
25
|
-
# doc.
|
26
|
-
#
|
25
|
+
# doc = Nodaire::Indental.parse(source)
|
26
|
+
#
|
27
|
+
# doc.valid?
|
28
|
+
# #=> true
|
29
|
+
#
|
30
|
+
# doc.categories
|
31
|
+
# #=> ["NAME"]
|
32
|
+
#
|
33
|
+
# doc['NAME']['KEY']
|
34
|
+
# #=> "VALUE"
|
35
|
+
#
|
36
|
+
# doc.to_h
|
37
|
+
# #=> {"NAME" => {"KEY"=>"VALUE", "LIST"=>["ITEM1", "ITEM2"]}}
|
38
|
+
#
|
39
|
+
# doc.to_json
|
40
|
+
# #=> '{"NAME":{"KEY":"VALUE","LIST":["ITEM1","ITEM2"]}}'
|
27
41
|
#
|
28
42
|
# @since 0.2.0
|
29
43
|
#
|
30
44
|
class Nodaire::Indental
|
31
|
-
|
45
|
+
include Enumerable
|
46
|
+
|
47
|
+
# @deprecated This will be removed in a future release. Use {#to_h} instead.
|
32
48
|
# @return [Hash]
|
33
49
|
attr_reader :data
|
34
|
-
#
|
50
|
+
# @return [Array<String>] the category names.
|
35
51
|
# @since 0.3.0
|
36
|
-
# @return [Array<String>]
|
37
52
|
attr_reader :categories
|
38
|
-
#
|
39
|
-
# @
|
53
|
+
# @return [Array<String>] an array of zero or more error message strings.
|
54
|
+
# @see #valid?
|
40
55
|
attr_reader :errors
|
41
56
|
|
42
|
-
alias_method :to_h, :data
|
43
|
-
|
44
57
|
##
|
45
58
|
# Parse the document +source+.
|
46
59
|
#
|
60
|
+
# @example Read an Indental file
|
61
|
+
# source = File.read('example.ndtl')
|
62
|
+
#
|
63
|
+
# doc = Nodaire::Indental.parse(source)
|
64
|
+
# puts doc['MY CATEGORY']
|
65
|
+
#
|
66
|
+
# @example Read an Indental file and symbolize names
|
67
|
+
# source = File.read('example.ndtl')
|
68
|
+
#
|
69
|
+
# doc = Nodaire::Indental.parse(source, symbolize_names: true)
|
70
|
+
# puts doc[:my_category]
|
71
|
+
#
|
47
72
|
# @param [String] source The document source to parse.
|
48
73
|
# @param [Boolean] symbolize_names
|
49
|
-
# If true
|
74
|
+
# If +true+, normalize category and key names and convert them to
|
50
75
|
# lowercase symbols.
|
76
|
+
# If +false+, convert category and key names to uppercase strings.
|
51
77
|
#
|
52
78
|
# @return [Indental]
|
53
79
|
#
|
@@ -60,13 +86,18 @@ class Nodaire::Indental
|
|
60
86
|
##
|
61
87
|
# Parse the document +source+, raising an exception if a parser error occurs.
|
62
88
|
#
|
63
|
-
# @
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
89
|
+
# @example Error handling
|
90
|
+
# begin
|
91
|
+
# doc = Nodaire::Indental.parse(source)
|
92
|
+
# puts doc['EXAMPLE']
|
93
|
+
# rescue Nodaire::ParserError => error
|
94
|
+
# puts error
|
95
|
+
# end
|
96
|
+
#
|
97
|
+
# @param (see .parse)
|
67
98
|
#
|
68
|
-
# @raise [ParserError]
|
69
99
|
# @return [Indental]
|
100
|
+
# @raise [ParserError]
|
70
101
|
#
|
71
102
|
def self.parse!(source, symbolize_names: false)
|
72
103
|
parser = Parser.new(source, true, symbolize_names: symbolize_names)
|
@@ -75,21 +106,49 @@ class Nodaire::Indental
|
|
75
106
|
end
|
76
107
|
|
77
108
|
##
|
78
|
-
#
|
79
|
-
#
|
80
|
-
# @return [Boolean]
|
109
|
+
# @return [Boolean] whether the source was parsed without errors.
|
110
|
+
# @see #errors
|
81
111
|
#
|
82
112
|
def valid?
|
83
113
|
@errors.empty?
|
84
114
|
end
|
85
115
|
|
116
|
+
##
|
117
|
+
# Returns the data for a given +category+.
|
118
|
+
#
|
119
|
+
# @example
|
120
|
+
# doc = Nodaire::Indental.parse(source)
|
121
|
+
# puts doc['CATEGORY']
|
122
|
+
#
|
123
|
+
# @return [Hash] the data for +category+. If not found, returns +nil+.
|
124
|
+
# @since 0.5.0
|
125
|
+
#
|
126
|
+
def [](category)
|
127
|
+
@data[category]
|
128
|
+
end
|
129
|
+
|
130
|
+
##
|
131
|
+
# Convert the document to a hash.
|
132
|
+
#
|
133
|
+
# @return [Hash]
|
134
|
+
#
|
135
|
+
def to_h(*args)
|
136
|
+
@data.to_h(*args)
|
137
|
+
end
|
138
|
+
|
86
139
|
##
|
87
140
|
# Convert the document to JSON.
|
88
141
|
#
|
89
142
|
# @return [String]
|
90
143
|
#
|
91
|
-
def to_json(*
|
92
|
-
|
144
|
+
def to_json(*args)
|
145
|
+
@data.to_json(*args)
|
146
|
+
end
|
147
|
+
|
148
|
+
# Enumerable
|
149
|
+
# @private
|
150
|
+
def each(&block)
|
151
|
+
@data.each(&block)
|
93
152
|
end
|
94
153
|
|
95
154
|
private
|
@@ -5,14 +5,16 @@ require 'csv'
|
|
5
5
|
require_relative 'parser'
|
6
6
|
|
7
7
|
##
|
8
|
-
# Interface for documents in
|
8
|
+
# Interface for documents in Tablatal format.
|
9
9
|
#
|
10
|
-
#
|
11
|
-
#
|
10
|
+
# Tablatal is a text file format which represents a 'list-type database'.
|
11
|
+
# This format was created by Devine Lu Linvega --
|
12
|
+
# see https://wiki.xxiivv.com/#tablatal for more information.
|
12
13
|
#
|
14
|
+
# @example
|
13
15
|
# require 'nodaire/tablatal'
|
14
16
|
#
|
15
|
-
#
|
17
|
+
# source = <<~TBTL
|
16
18
|
# NAME AGE COLOR
|
17
19
|
# Erica 12 Opal
|
18
20
|
# Alex 23 Cyan
|
@@ -20,36 +22,63 @@ require_relative 'parser'
|
|
20
22
|
# Ruca 45 Grey
|
21
23
|
# TBTL
|
22
24
|
#
|
23
|
-
# doc.
|
24
|
-
#
|
25
|
-
# doc.
|
26
|
-
#
|
25
|
+
# doc = Nodaire::Tablatal.parse(source)
|
26
|
+
#
|
27
|
+
# doc.valid?
|
28
|
+
# #=> true
|
29
|
+
#
|
30
|
+
# doc.keys
|
31
|
+
# #=> ["NAME", "AGE", "COLOR"]
|
32
|
+
#
|
33
|
+
# doc[0]['NAME']
|
34
|
+
# #=> "Erica"
|
35
|
+
#
|
36
|
+
# doc.to_a
|
37
|
+
# #=> [{"NAME"=>"Erica", "AGE"=>"12", "COLOR"=>"Opal"}, ...]
|
38
|
+
#
|
39
|
+
# doc.to_json
|
40
|
+
# #=> '[{"NAME":"Erica","AGE":"12","COLOR":"Opal"},...]'
|
41
|
+
#
|
42
|
+
# doc.to_csv
|
43
|
+
# #=> "NAME,AGE,COLOR\nErica,12,Opal\nAlex,23,Cyan\n..."
|
27
44
|
#
|
28
45
|
# @since 0.1.0
|
29
46
|
#
|
30
47
|
class Nodaire::Tablatal
|
31
|
-
|
48
|
+
include Enumerable
|
49
|
+
|
50
|
+
# @deprecated This will be removed in a future release. Use {#to_a} instead.
|
32
51
|
# @return [Array<Hash>]
|
33
52
|
attr_reader :data
|
34
|
-
#
|
35
|
-
# @return [Array]
|
53
|
+
# @return [Array] the keys from the first line of the source.
|
36
54
|
attr_reader :keys
|
37
|
-
#
|
55
|
+
# @return [Array<String>] an array of zero or more error message strings.
|
56
|
+
# @see #valid?
|
38
57
|
# @since 0.2.0
|
39
|
-
# @return [Array<String>]
|
40
58
|
attr_reader :errors
|
41
59
|
|
42
|
-
alias_method :to_a, :data
|
43
|
-
|
44
60
|
##
|
45
61
|
# Parse the document +source+.
|
46
62
|
#
|
63
|
+
# @example Read a Tablatal file
|
64
|
+
# source = File.read('example.tbtl')
|
65
|
+
#
|
66
|
+
# doc = Nodaire::Tablatal.parse(source)
|
67
|
+
# puts doc.first['NAME']
|
68
|
+
#
|
69
|
+
# @example Read a Tablatal file and symbolize names
|
70
|
+
# source = File.read('example.tbtl')
|
71
|
+
#
|
72
|
+
# doc = Nodaire::Tablatal.parse(source, symbolize_names: true)
|
73
|
+
# puts doc.first[:name]
|
74
|
+
#
|
47
75
|
# @param [String] source The document source to parse.
|
48
76
|
# @param [Boolean] symbolize_names
|
49
|
-
# If true
|
77
|
+
# If +true+, normalize key names and convert them to lowercase symbols.
|
78
|
+
# If +false+, convert keys to uppercase strings.
|
50
79
|
#
|
51
|
-
# @since 0.2.0
|
52
80
|
# @return [Tablatal]
|
81
|
+
# @since 0.2.0
|
53
82
|
#
|
54
83
|
def self.parse(source, symbolize_names: false)
|
55
84
|
parser = Parser.new(source, false, symbolize_names: symbolize_names)
|
@@ -60,13 +89,19 @@ class Nodaire::Tablatal
|
|
60
89
|
##
|
61
90
|
# Parse the document +source+, raising an exception if a parser error occurs.
|
62
91
|
#
|
63
|
-
# @
|
64
|
-
#
|
65
|
-
#
|
92
|
+
# @example Error handling
|
93
|
+
# begin
|
94
|
+
# doc = Nodaire::Tablatal.parse(source)
|
95
|
+
# puts doc.first
|
96
|
+
# rescue Nodaire::ParserError => error
|
97
|
+
# puts error
|
98
|
+
# end
|
99
|
+
#
|
100
|
+
# @param (see .parse)
|
66
101
|
#
|
67
|
-
# @since 0.2.0
|
68
|
-
# @raise [ParserError]
|
69
102
|
# @return [Tablatal]
|
103
|
+
# @raise [ParserError]
|
104
|
+
# @since 0.2.0
|
70
105
|
#
|
71
106
|
def self.parse!(source, symbolize_names: false)
|
72
107
|
parser = Parser.new(source, true, symbolize_names: symbolize_names)
|
@@ -75,15 +110,48 @@ class Nodaire::Tablatal
|
|
75
110
|
end
|
76
111
|
|
77
112
|
##
|
78
|
-
#
|
79
|
-
#
|
113
|
+
# @return [Boolean] whether the source was parsed without errors.
|
114
|
+
# @see #errors
|
80
115
|
# @since 0.2.0
|
81
|
-
# @return [Boolean]
|
82
116
|
#
|
83
117
|
def valid?
|
84
118
|
@errors.empty?
|
85
119
|
end
|
86
120
|
|
121
|
+
##
|
122
|
+
# Returns the data for a given row +index+.
|
123
|
+
#
|
124
|
+
# @example
|
125
|
+
# doc = Nodaire::Tablatal.parse(source)
|
126
|
+
# puts doc[0]
|
127
|
+
#
|
128
|
+
# @return [Hash] the data for the given row +index+.
|
129
|
+
# If not found, returns +nil+.
|
130
|
+
# @since 0.5.0
|
131
|
+
#
|
132
|
+
def [](index)
|
133
|
+
@data[index]
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# Convert the document to an array of hashes.
|
138
|
+
#
|
139
|
+
# @return [Array<Hash>]
|
140
|
+
#
|
141
|
+
def to_a(*args)
|
142
|
+
@data.to_a(*args)
|
143
|
+
end
|
144
|
+
|
145
|
+
##
|
146
|
+
# Convert the document to JSON.
|
147
|
+
#
|
148
|
+
# @return [String]
|
149
|
+
# @since 0.5.0
|
150
|
+
#
|
151
|
+
def to_json(*args)
|
152
|
+
@data.to_json(*args)
|
153
|
+
end
|
154
|
+
|
87
155
|
##
|
88
156
|
# Convert the document to CSV.
|
89
157
|
#
|
@@ -98,6 +166,12 @@ class Nodaire::Tablatal
|
|
98
166
|
end
|
99
167
|
end
|
100
168
|
|
169
|
+
# Enumerable
|
170
|
+
# @private
|
171
|
+
def each(&block)
|
172
|
+
@data.each(&block)
|
173
|
+
end
|
174
|
+
|
101
175
|
private
|
102
176
|
|
103
177
|
def initialize(parser)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nodaire
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Liam Cooke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-08-
|
11
|
+
date: 2019-08-26 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Nodaire is a collection of text file parsers.
|
14
14
|
email: nodaire@liamcooke.com
|