yamlr 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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