yamlr 2.0.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.
@@ -0,0 +1,116 @@
1
+ module Yamlr
2
+ module Reader
3
+ module Format
4
+ # format datatypes in the parsed hash
5
+ #
6
+ def self.format(phs)
7
+ self.adjust_options(phs)
8
+ self.stripper(phs)
9
+ self.key_to_int(phs)
10
+ self.val_to_int(phs)
11
+ self.key_to_sym(phs)
12
+ self.val_to_sym(phs)
13
+ self.key_to_true(phs)
14
+ self.val_to_true(phs)
15
+ phs
16
+ end
17
+
18
+ # strips keys and values
19
+ #
20
+ def self.stripper(phs)
21
+ psp = phs[:opt][:strip]
22
+ psk = phs[:opt][:strip_keys]
23
+ psv = phs[:opt][:strip_vals]
24
+ phs[:key] = phs[:key].to_s.strip if psp or psk
25
+ phs[:val] = phs[:val].to_s.strip if psp or psv
26
+ end
27
+
28
+ # adjusts options
29
+ #
30
+ def self.adjust_options(phs)
31
+ if phs[:opt][:auto_sym]
32
+ phs[:opt][:auto_sym_keys] = true
33
+ phs[:opt][:auto_sym_vals] = true
34
+ end
35
+ end
36
+
37
+ # true key
38
+ #
39
+ def self.key_to_true(phs)
40
+ x = []
41
+ x << phs[:opt][:auto_true].is_a?(TrueClass)
42
+ x << phs[:opt][:auto_true_keys].is_a?(TrueClass)
43
+ if x.any?
44
+ case
45
+ when (phs[:key].to_s.strip == "true") then phs[:key] = true
46
+ when (phs[:key].to_s.strip == "false") then phs[:key] = false
47
+ end
48
+ end
49
+ end
50
+
51
+ # true val
52
+ #
53
+ def self.val_to_true(phs)
54
+ x = []
55
+ x << phs[:opt][:auto_true].is_a?(TrueClass)
56
+ x << phs[:opt][:auto_true_vals].is_a?(TrueClass)
57
+ if x.any?
58
+ case
59
+ when (phs[:val].to_s.strip == "true") then phs[:val] = true
60
+ when (phs[:val].to_s.strip == "false") then phs[:val] = false
61
+ end
62
+ end
63
+ end
64
+
65
+ # symbolize key
66
+ #
67
+ def self.key_to_sym(phs)
68
+ is_str = !phs[:key].is_a?(Integer)
69
+ x = []
70
+ x << (phs[:opt][:sym_str] && is_str).is_a?(TrueClass)
71
+ x << (phs[:opt][:sym_str_keys] && is_str).is_a?(TrueClass)
72
+ x << phs[:opt][:symbolize].is_a?(TrueClass)
73
+ x << (phs[:ask] && phs[:opt][:auto_sym_keys] && is_str).is_a?(TrueClass)
74
+ x << phs[:opt][:symbolize_keys].is_a?(TrueClass)
75
+ phs[:key] = phs[:key].to_s.to_sym if x.any?
76
+ end
77
+
78
+ # symbolize val
79
+ #
80
+ def self.val_to_sym(phs)
81
+ is_str = !phs[:val].is_a?(Integer)
82
+ x = []
83
+ x << (phs[:opt][:sym_str] && is_str).is_a?(TrueClass)
84
+ x << (phs[:opt][:sym_str_vals] && is_str).is_a?(TrueClass)
85
+ x << phs[:opt][:symbolize].is_a?(TrueClass)
86
+ x << (phs[:asv] && phs[:opt][:auto_sym_vals] && is_str).is_a?(TrueClass)
87
+ x << phs[:opt][:symbolize_vals].is_a?(TrueClass)
88
+ phs[:val] = phs[:val].to_s.to_sym if (x.any? && !phs[:val].to_s.strip.empty?)
89
+ end
90
+
91
+ # key is parsed as string, so try to_i
92
+ #
93
+ def self.key_to_int(phs)
94
+ x = []
95
+ x << phs[:opt][:int].is_a?(TrueClass)
96
+ x << phs[:opt][:int_keys].is_a?(TrueClass)
97
+ phs[:key] = self.string_to_int(phs[:key]) if x.any?
98
+ end
99
+
100
+ # val is parsed as string, so try to_i
101
+ #
102
+ def self.val_to_int(phs)
103
+ x = []
104
+ x << phs[:opt][:int].is_a?(TrueClass)
105
+ x << phs[:opt][:int_vals].is_a?(TrueClass)
106
+ phs[:val] = self.string_to_int(phs[:val]) if x.any?
107
+ end
108
+
109
+ # returns int if string is convertable
110
+ #
111
+ def self.string_to_int(string)
112
+ string.to_s.strip =~ /^\d+$/ ? string.to_s.to_i : string
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,53 @@
1
+ module Yamlr
2
+ module Reader
3
+ module Node
4
+ # hashpair
5
+ #
6
+ def self.hashpair(hsh, sym, spc)
7
+ /^(#{spc}*)(\S*)#{hsh}#{spc}*(.*)#{spc}*$/
8
+ end
9
+
10
+ # hashpair, both key and val are symbol
11
+ #
12
+ def self.hashpair_sym_all(hsh, sym, spc)
13
+ /^(#{spc}*)(#{sym}\S*)#{hsh}#{spc}*(#{sym}.*)#{spc}*$/
14
+ end
15
+
16
+ # hashpair, key is symbol
17
+ #
18
+ def self.hashpair_sym_key(hsh, sym, spc)
19
+ /^(#{spc}*)(#{sym}\S*)#{hsh}#{spc}*(.*)#{spc}*$/
20
+ end
21
+
22
+ # hashpair, value is symbol
23
+ #
24
+ def self.hashpair_sym_val(hsh, sym, spc)
25
+ /^(#{spc}*)(\S*)#{hsh}#{spc}*(#{sym}.*)#{spc}*$/
26
+ end
27
+
28
+ # hashkey is symbol
29
+ #
30
+ def self.hashkey_sym(hsh, sym, spc)
31
+ /^(#{spc}*)(#{sym}\S*)#{hsh}#{spc}*$/
32
+ end
33
+
34
+ # hashkey is awesome
35
+ #
36
+ def self.hashkey(hsh, spc)
37
+ /^(#{spc}*)(\S*)#{hsh}#{spc}*$/
38
+ end
39
+
40
+ # docstart and docterm
41
+ #
42
+ def self.document(idc, spc)
43
+ /^#{spc}*#{idc}#{spc}*$/
44
+ end
45
+
46
+ # comments and arrays
47
+ #
48
+ def self.left_match(idc, spc)
49
+ /^(#{spc}*)#{idc}(#{spc}*)(.*)#{spc}*$/
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,68 @@
1
+ module Yamlr
2
+ module Reader
3
+ module Parser
4
+ class IndentError < StandardError; end
5
+
6
+ def self.parse(line, opts, num)
7
+ results = self.parse_line(line, opts)
8
+ phs = self.results_to_hash(results, opts)
9
+ self.check_indent(line, phs[:spc], opts[:indent], num)
10
+ phs
11
+ end
12
+
13
+ # invalid number of spaces, line num and truncated line for context
14
+ #
15
+ def self.check_indent(line, spc, idt, num)
16
+ raise IndentError, "#{num} #{line[1..50]}" if spc % idt != 0
17
+ end
18
+
19
+ # parses line, returns array, dependent on Node module
20
+ #
21
+ def self.parse_line(line, opts)
22
+ nod = Yamlr::Reader::Node
23
+ spc = opts[:space]
24
+ hsh = opts[:hash]
25
+ sym = opts[:symbol]
26
+ dcs = opts[:doc_start]
27
+ dct = opts[:doc_term]
28
+ arr = opts[:array]
29
+ com = opts[:comment]
30
+
31
+ begin
32
+ case line
33
+ when nod.left_match(arr, spc) then [:arr, Regexp.last_match.captures]
34
+ when nod.left_match(com, spc) then [:com, Regexp.last_match.captures]
35
+ when nod.hashkey_sym(hsh, sym, spc) then [:hky, Regexp.last_match.captures, nil, true]
36
+ when nod.hashkey(hsh, spc) then [:hky, Regexp.last_match.captures]
37
+ when nod.hashpair_sym_all(hsh, sym, spc) then [:hpr, Regexp.last_match.captures, true, true]
38
+ when nod.hashpair_sym_key(hsh, sym, spc) then [:hpr, Regexp.last_match.captures, true]
39
+ when nod.hashpair_sym_val(hsh, sym, spc) then [:hpr, Regexp.last_match.captures, nil, true]
40
+ when nod.hashpair(hsh, sym, spc) then [:hpr, Regexp.last_match.captures]
41
+ when /^\s*$/ then [:bla]
42
+ when nod.document(dcs, spc) then [:dcs]
43
+ when nod.document(dct, spc) then [:dct]
44
+ else
45
+ raise 'MALFORMED'
46
+ end
47
+ rescue => e
48
+ # log or whatever
49
+ [:mal, '', nil, line.strip]
50
+ end
51
+ end
52
+
53
+ # creates hash with array vals, includes options
54
+ #
55
+ def self.results_to_hash(results, opt)
56
+ #raise results.flatten.to_s + " results.class => #{results.class}"
57
+ msg, spc, key, val, ask, asv = results.flatten
58
+ { :msg => msg,
59
+ :spc => (spc.nil? ? 0 : spc.length),
60
+ :key => key.to_s.sub(/^:/, ''),
61
+ :val => val.to_s.sub(/^:/, ''),
62
+ :ask => ask,
63
+ :asv => asv,
64
+ :opt => opt}
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,3 @@
1
+ module Yamlr
2
+ VERSION = '2.0.0'
3
+ end
@@ -0,0 +1,47 @@
1
+ require 'yamlr/writer/builder'
2
+
3
+ module Yamlr
4
+ module Writer
5
+ class EmptyFilenameError < StandardError; end
6
+ class EmptyInputError < StandardError; end
7
+ class InvalidInputError < StandardError; end
8
+ class InvalidFilenameError < StandardError; end
9
+
10
+ # array, hash, or string to array of lines of .yml file
11
+ #
12
+ def self.build(object, options)
13
+ raise Yamlr::Writer::EmptyInputError if object.is_a?(String) && object.strip.empty?
14
+ raise Yamlr::Writer::InvalidInputError unless object.is_a?(String) or object.is_a?(Array) or object.is_a?(Hash)
15
+ Yamlr::Writer::Builder.build([], object, options)
16
+ end
17
+
18
+ # array, hash, or string to file
19
+ #
20
+ def self.write(object, filename, options)
21
+ filename = "#{ENV['HOME']}/#{File.basename(filename.to_s)}" if (filename =~ /^~/)
22
+ raise Yamlr::Writer::EmptyInputError if (object.is_a?(String) && object.strip.empty?)
23
+ raise Yamlr::Writer::InvalidInputError unless (object.is_a?(String) or object.is_a?(Array) or object.is_a?(Hash))
24
+ raise Yamlr::Writer::EmptyFilenameError if File.basename(filename.to_s).strip.empty?
25
+ raise Yamlr::Writer::InvalidFilenameError unless File.exists?(File.dirname(filename))
26
+ File.open(filename, "w") do |file|
27
+ self.build(object, options).each {|line|
28
+ file.print("#{line}\n")
29
+ }
30
+ end
31
+ filename
32
+ end
33
+
34
+ # write a yamlr dotfile to home dir
35
+ #
36
+ def self.dotfile(options, home)
37
+ filename = "#{home.chomp("/")}/.yamlrc"
38
+ new_name = nil
39
+ if File.exists?(filename)
40
+ new_name = "#{filename}.#{Time.now.strftime("%Y%m%d%H%M%S")}"
41
+ File.rename(filename, new_name)
42
+ end
43
+ self.write(options, filename, Yamlr::Indicators.options)
44
+ new_name ? new_name : filename
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,93 @@
1
+ module Yamlr
2
+ module Writer
3
+ module Builder
4
+ def self.build(arr, inp, opt)
5
+ spc = (opt[:space] * opt[:indent])
6
+ case
7
+ when inp.is_a?(Hash) then self.hash_to_array(arr, inp, opt, spc)
8
+ when inp.is_a?(Array) then self.array_to_lines(arr, inp, opt, spc)
9
+ when inp.is_a?(String) then self.string_to_array(arr, inp, opt, spc)
10
+ end
11
+ arr
12
+ end
13
+
14
+ def self.sym_to_str(x, y = nil)
15
+ a = x.is_a?(Symbol) ? ":#{x}" : x
16
+ b = y.is_a?(Symbol) ? ":#{y}" : y
17
+ [a, b]
18
+ end
19
+
20
+ def self.string_to_array(arr, inp, opt, spc)
21
+ self.array_to_lines(arr, inp.split(opt[:line_end]), opt, spc)
22
+ end
23
+
24
+ def self.hash_to_array(arr, inp, opt, spc)
25
+ inp.each do |key,val|
26
+ case
27
+ when val.is_a?(Hash)
28
+ key = self.sym_to_str(key)
29
+ arr << opt[:doc_start] if opt[:docs]
30
+ arr << "#{key.join}#{opt[:hash]}" unless opt[:docs]
31
+ self.hash_to_lines(arr, val, val.keys, opt, spc, (opt[:docs] ? 0 : 1))
32
+ when val.is_a?(Array)
33
+ arr << opt[:doc_start] if opt[:docs]
34
+ self.array_to_lines(arr, val, opt)
35
+ else
36
+ key, val = self.sym_to_str(key, val)
37
+ arr << "#{key}#{opt[:hash]} #{val}"
38
+ end
39
+ end
40
+ end
41
+
42
+ # line is array, push each indice to array, assumes every indice is a string
43
+ #
44
+ def self.array_to_lines(arr, val, opt, spc, idt = nil)
45
+ idt = 0 if idt.nil?
46
+ ist = spc * idt
47
+ ind = opt[:array]
48
+ until val.empty? do
49
+ x = val.shift
50
+ case
51
+ when x.is_a?(Hash)
52
+ arr << "#{ist}#{ind}"
53
+ self.hash_to_lines(arr, x, x.keys, opt, spc, (idt + 1))
54
+ when x.is_a?(Array)
55
+ i = idt
56
+ arr << "#{ist}#{ind}" if opt[:yaml]
57
+ i += 1
58
+ self.array_to_lines(arr, x, opt, spc, i)
59
+ else
60
+ x = self.sym_to_str(x)
61
+ arr << "#{ist}#{ind} #{x.join}"
62
+ end
63
+ end
64
+ end
65
+
66
+ # recursively add lines to array
67
+ #
68
+ def self.hash_to_lines(arr, hsh, kys, opt, spc, idt = nil)
69
+ idt = 0 if idt.nil?
70
+ while !kys.empty?
71
+ ist = spc * idt
72
+ key = kys.shift
73
+ val = hsh[key]
74
+ ind = opt[:hash]
75
+ case
76
+ when val.is_a?(Hash)
77
+ # push key into lines_array
78
+ arr << "#{ist}#{key}#{ind}"
79
+ # step indent
80
+ # call this again (the recursive part)
81
+ self.hash_to_lines(arr, val, val.keys, opt, spc, (idt + 1))
82
+ when val.is_a?(Array)
83
+ arr << "#{ist}#{key}#{ind}"
84
+ self.array_to_lines(arr, val, opt, spc, (idt + 1))
85
+ else
86
+ # if not Writer or Array, it must be String
87
+ arr << "#{ist}#{key}#{ind} #{val}"
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,3 @@
1
+ content:
2
+ 01: 200901.yml
3
+ 02: 200902.yml
@@ -0,0 +1,15 @@
1
+ -
2
+ - 1
3
+ - 2
4
+ -
5
+ -
6
+ -
7
+ - awesome
8
+ - awesome
9
+ - 4
10
+ - 5
11
+ - 6
12
+ - 7
13
+ - 8
14
+ - dude
15
+ -
File without changes
@@ -0,0 +1,17 @@
1
+ # dude
2
+ 1: 1
3
+ # awesome
4
+ 2: 2
5
+ #
6
+ # camaro
7
+ #
8
+ 3: 3
9
+ ##
10
+ # nice
11
+ # one
12
+ # bro!
13
+ #
14
+ 4:
15
+ - 1
16
+ - 2
17
+ - 3
@@ -0,0 +1,26 @@
1
+ grocery_list:
2
+ beer:
3
+ 1:
4
+ model: 24 pack - Coors Lite
5
+ count: 1
6
+ meatsez:
7
+ 1:
8
+ model: Spam
9
+ count: 5
10
+ 2:
11
+ model: Log of ground beef
12
+ count: 1
13
+ cigarettes:
14
+ 1:
15
+ model: Carton - Basic Ultra Menthol Box 100
16
+ count: 2
17
+ other:
18
+ 1:
19
+ model: Economy-Size Pork & Beans
20
+ count: 2
21
+ 2:
22
+ model: Jumbo Miracle Whip
23
+ count: 1
24
+ 3:
25
+ model: White Wonder Bread
26
+ count: 2