ccls-common_lib 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.rdoc +116 -0
- data/lib/ccls-common_lib.rb +1 -0
- data/lib/common_lib.rb +37 -0
- data/lib/common_lib/action_controller_extension.rb +8 -0
- data/lib/common_lib/action_controller_extension/accessible_via_protocol.rb +405 -0
- data/lib/common_lib/action_controller_extension/accessible_via_user.rb +605 -0
- data/lib/common_lib/action_controller_extension/routing.rb +20 -0
- data/lib/common_lib/action_controller_extension/test_case.rb +22 -0
- data/lib/common_lib/action_view_extension.rb +3 -0
- data/lib/common_lib/action_view_extension/base.rb +310 -0
- data/lib/common_lib/action_view_extension/form_builder.rb +197 -0
- data/lib/common_lib/active_model.rb +4 -0
- data/lib/common_lib/active_model/errors.rb +16 -0
- data/lib/common_lib/active_model/validations/absence.rb +78 -0
- data/lib/common_lib/active_model/validations/complete_date.rb +138 -0
- data/lib/common_lib/active_model/validations/past_date.rb +121 -0
- data/lib/common_lib/active_record.rb +1 -0
- data/lib/common_lib/active_record/base.rb +129 -0
- data/lib/common_lib/active_support_extension.rb +12 -0
- data/lib/common_lib/active_support_extension/assertions.rb +108 -0
- data/lib/common_lib/active_support_extension/associations.rb +154 -0
- data/lib/common_lib/active_support_extension/attributes.rb +296 -0
- data/lib/common_lib/active_support_extension/pending.rb +115 -0
- data/lib/common_lib/active_support_extension/test_case.rb +203 -0
- data/lib/common_lib/railtie.rb +48 -0
- data/lib/common_lib/ruby.rb +8 -0
- data/lib/common_lib/ruby/array.rb +128 -0
- data/lib/common_lib/ruby/fixnum.rb +5 -0
- data/lib/common_lib/ruby/hash.rb +51 -0
- data/lib/common_lib/ruby/integer.rb +11 -0
- data/lib/common_lib/ruby/nil_class.rb +13 -0
- data/lib/common_lib/ruby/numeric.rb +0 -0
- data/lib/common_lib/ruby/object.rb +53 -0
- data/lib/common_lib/ruby/string.rb +20 -0
- data/lib/common_lib/translation_table.rb +129 -0
- data/lib/tasks/common_lib.rake +10 -0
- data/lib/tasks/csv.rake +0 -0
- data/lib/tasks/database.rake +229 -0
- data/lib/tasks/rcov.rake +52 -0
- data/vendor/assets/javascripts/common_lib.js +77 -0
- data/vendor/assets/stylesheets/common_lib.css +71 -0
- metadata +84 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
module CommonLib::Hash # :nodoc:
|
2
|
+
|
3
|
+
# delete all keys matching the given regex
|
4
|
+
# and return the new hash
|
5
|
+
def delete_keys_matching!(regex)
|
6
|
+
self.keys.each do |k|
|
7
|
+
if k.to_s =~ Regexp.new(regex)
|
8
|
+
self.delete(k)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
# delete all keys in the given array
|
15
|
+
# and return the new hash
|
16
|
+
def delete_keys!(*keys)
|
17
|
+
keys.each do |k|
|
18
|
+
self.delete(k)
|
19
|
+
end
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
# params.dig('study_events',se.id.to_s,'eligible')
|
24
|
+
def dig(*args)
|
25
|
+
if args.length > 0 && self.keys.include?(args.first)
|
26
|
+
key = args.shift
|
27
|
+
if args.length > 0
|
28
|
+
if self[key].is_a?(Hash)
|
29
|
+
self[key].dig(*args)
|
30
|
+
else
|
31
|
+
nil # This shouldn't ever happen
|
32
|
+
end
|
33
|
+
else
|
34
|
+
self[key]
|
35
|
+
end
|
36
|
+
else
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# from http://iain.nl/writing-yaml-files
|
42
|
+
def deep_stringify_keys
|
43
|
+
new_hash = {}
|
44
|
+
self.each do |key, value|
|
45
|
+
new_hash.merge!(key.to_s => ( value.is_a?(Hash) ? value.deep_stringify_keys : value ))
|
46
|
+
end
|
47
|
+
new_hash # originally didn't return new_hash, which didn't work for me. returned self apparently.
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
Hash.send( :include, CommonLib::Hash )
|
File without changes
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module CommonLib::Object # :nodoc:
|
2
|
+
#
|
3
|
+
# # originally from ActiveSupport::Callbacks::Callback
|
4
|
+
## needs modified to actually work the way I'd like
|
5
|
+
## needs tests
|
6
|
+
## x(:some_method)
|
7
|
+
## x(Proc.new(....))
|
8
|
+
## x(lambda{...})
|
9
|
+
# # def evaluate_method(method, *args, &block)
|
10
|
+
# def evaluate_method(method, *args, &block)
|
11
|
+
# case method
|
12
|
+
# when Symbol
|
13
|
+
## I don't quite understand the shift (it fails)
|
14
|
+
## object = args.shift
|
15
|
+
## object.send(method, *args, &block)
|
16
|
+
# send(method, *args, &block)
|
17
|
+
# when String
|
18
|
+
# eval(method, args.first.instance_eval { binding })
|
19
|
+
# when Proc, Method
|
20
|
+
## fails
|
21
|
+
# method.call(*args, &block)
|
22
|
+
# else
|
23
|
+
# if method.respond_to?(kind)
|
24
|
+
# method.send(kind, *args, &block)
|
25
|
+
# else
|
26
|
+
# raise ArgumentError,
|
27
|
+
# "Callbacks must be a symbol denoting the method to call, a string to be evaluated, " +
|
28
|
+
# "a block to be invoked, or an object responding to the callback method."
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
# alias_method :x, :evaluate_method
|
33
|
+
#
|
34
|
+
def to_boolean
|
35
|
+
# return [true, 'true', 1, '1', 't'].include?(
|
36
|
+
return ![nil, false, 'false', 0, '0', 'f'].include?(
|
37
|
+
( self.is_a?(String) ) ? self.downcase : self )
|
38
|
+
end
|
39
|
+
|
40
|
+
# looking for an explicit true
|
41
|
+
def true?
|
42
|
+
return [true, 'true', 1, '1', 't'].include?(
|
43
|
+
( self.is_a?(String) ) ? self.downcase : self )
|
44
|
+
end
|
45
|
+
|
46
|
+
# looking for an explicit false (not nil)
|
47
|
+
def false?
|
48
|
+
return [false, 'false', 0, '0', 'f'].include?(
|
49
|
+
( self.is_a?(String) ) ? self.downcase : self )
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
Object.send(:include, CommonLib::Object )
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module CommonLib::String # :nodoc:
|
2
|
+
|
3
|
+
# Convert a query string like that in a URL
|
4
|
+
# to a Hash
|
5
|
+
def to_params_hash
|
6
|
+
h = HashWithIndifferentAccess.new
|
7
|
+
self.split('&').each do |p|
|
8
|
+
(k,v) = p.split('=',2)
|
9
|
+
h[k] = URI.decode(v)
|
10
|
+
end
|
11
|
+
return h
|
12
|
+
end
|
13
|
+
|
14
|
+
# Return self
|
15
|
+
def uniq
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
String.send( :include, CommonLib::String )
|
@@ -0,0 +1,129 @@
|
|
1
|
+
class CommonLib::TranslationTable
|
2
|
+
|
3
|
+
def self.[](key=nil)
|
4
|
+
short(key) || short(key.to_s.downcase) || value(key) || nil
|
5
|
+
end
|
6
|
+
|
7
|
+
# DO NOT MEMORIZE HERE. IT ENDS UP IN ALL SUBCLASSES
|
8
|
+
# Doesn't really seem necessary. It isn't that complicated.
|
9
|
+
|
10
|
+
# [1,2,999]
|
11
|
+
def self.valid_values
|
12
|
+
# @@valid_values ||= table.collect{ |x| x[:value] }
|
13
|
+
table.collect{ |x| x[:value] }
|
14
|
+
end
|
15
|
+
|
16
|
+
# [['Yes',1],['No',2],["Don't Know",999]]
|
17
|
+
def self.selector_options
|
18
|
+
# @@selector_options ||= table.collect{|x| [x[:long],x[:value]] }
|
19
|
+
table.collect{|x| [x[:long],x[:value]] }
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
def self.short(key)
|
25
|
+
index = table.find_index{|x| x[:short] == key.to_s }
|
26
|
+
( index.nil? ) ? nil : table[index][:value]
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.value(key)
|
30
|
+
# used in testing and breaks in ruby 1.9.3 so next line is NEEDED!
|
31
|
+
return nil if key == :nil
|
32
|
+
index = table.find_index{|x| x[:value] == key.to_i }
|
33
|
+
( index.nil? ) ? nil : table[index][:long]
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.table
|
37
|
+
[]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
class YNDK < CommonLib::TranslationTable
|
43
|
+
# unique translation table
|
44
|
+
def self.table
|
45
|
+
@@table ||= [
|
46
|
+
{ :value => 1, :short => 'yes', :long => "Yes" },
|
47
|
+
{ :value => 2, :short => 'no', :long => "No" },
|
48
|
+
{ :value => 999, :short => 'dk', :long => "Don't Know" }
|
49
|
+
]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
#
|
53
|
+
# YNDK[1] => 'Yes'
|
54
|
+
# YNDK['1'] => 'Yes'
|
55
|
+
# YNDK['yes'] => 1
|
56
|
+
# YNDK[:yes] => 1
|
57
|
+
# YNDK[:asdf] => nil
|
58
|
+
#
|
59
|
+
# YNDK[:Yes] => 1
|
60
|
+
# YNDK[:YES] => 1
|
61
|
+
#
|
62
|
+
# YNDK[:nil] => ???? # worked in ruby 1.8.7, errors in 1.9.3
|
63
|
+
# :nil.to_i => NoMethodError: undefined method `to_i' for :nil:Symbol
|
64
|
+
# what did it do? was that correct?
|
65
|
+
#
|
66
|
+
# in jruby
|
67
|
+
# jruby-1.5.1 :003 > :nil.to_i
|
68
|
+
# => 610
|
69
|
+
# which, in hind site, makes some sort of sense, but is NOT what is wanted
|
70
|
+
# same in ruby 1.8.7 (basically object id)
|
71
|
+
#
|
72
|
+
class YNODK < CommonLib::TranslationTable
|
73
|
+
def self.table
|
74
|
+
@@table ||= [
|
75
|
+
{ :value => 1, :short => 'yes', :long => "Yes" },
|
76
|
+
{ :value => 2, :short => 'no', :long => "No" },
|
77
|
+
{ :value => 3, :short => 'other', :long => "Other" },
|
78
|
+
{ :value => 999, :short => 'dk', :long => "Don't Know" }
|
79
|
+
]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
class YNRDK < CommonLib::TranslationTable
|
83
|
+
def self.table
|
84
|
+
@@table ||= [
|
85
|
+
{ :value => 1, :short => 'yes', :long => "Yes" },
|
86
|
+
{ :value => 2, :short => 'no', :long => "No" },
|
87
|
+
{ :value => 999, :short => 'dk', :long => "Don't Know" },
|
88
|
+
{ :value => 888, :short => 'refused', :long => "Refused" }
|
89
|
+
]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
class YNORDK < CommonLib::TranslationTable
|
93
|
+
def self.table
|
94
|
+
@@table ||= [
|
95
|
+
{ :value => 1, :short => 'yes', :long => "Yes" },
|
96
|
+
{ :value => 2, :short => 'no', :long => "No" },
|
97
|
+
{ :value => 3, :short => 'other', :long => "Other" },
|
98
|
+
{ :value => 999, :short => 'dk', :long => "Don't Know" },
|
99
|
+
{ :value => 888, :short => 'refused', :long => "Refused" }
|
100
|
+
]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
class ADNA < CommonLib::TranslationTable
|
104
|
+
def self.table
|
105
|
+
@@table ||= [
|
106
|
+
{ :value => 1, :short => 'agree', :long => "Agree" },
|
107
|
+
{ :value => 2, :short => 'disagree', :long => "Do Not Agree" },
|
108
|
+
{ :value => 555, :short => 'na', :long => "N/A" },
|
109
|
+
{ :value => 999, :short => 'dk', :long => "Don't Know" }
|
110
|
+
]
|
111
|
+
end
|
112
|
+
end
|
113
|
+
class PADK < CommonLib::TranslationTable
|
114
|
+
def self.table
|
115
|
+
@@table ||= [
|
116
|
+
{ :value => 1, :short => 'present', :long => "Present" },
|
117
|
+
{ :value => 2, :short => 'absent', :long => "Absent" },
|
118
|
+
{ :value => 999, :short => 'dk', :long => "Don't Know" }
|
119
|
+
]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
class POSNEG < CommonLib::TranslationTable
|
123
|
+
def self.table
|
124
|
+
@@table ||= [
|
125
|
+
{ :value => 1, :short => 'pos', :long => "Positive" },
|
126
|
+
{ :value => 2, :short => 'neg', :long => "Negative" }
|
127
|
+
]
|
128
|
+
end
|
129
|
+
end
|
data/lib/tasks/csv.rake
ADDED
File without changes
|
@@ -0,0 +1,229 @@
|
|
1
|
+
class Hash
|
2
|
+
# From http://snippets.dzone.com/posts/show/5811
|
3
|
+
# Renaming and replacing the to_yaml function so it'll serialize hashes sorted (by their keys)
|
4
|
+
# Original function is in /usr/lib/ruby/1.8/yaml/rubytypes.rb
|
5
|
+
def to_ordered_yaml( opts = {} )
|
6
|
+
YAML::quick_emit( object_id, opts ) do |out|
|
7
|
+
out.map( taguri, to_yaml_style ) do |map|
|
8
|
+
sort.each do |k, v| # <-- here's my addition (the 'sort')
|
9
|
+
# The above sort, sorts the main yaml 'keys' or fixture labels.
|
10
|
+
# k is a fixture label here, eg. "pages_001"
|
11
|
+
# v is the attributes hash
|
12
|
+
# The hash attributes are NOT sorted, unfortunately.
|
13
|
+
# Still working on that one.
|
14
|
+
map.add( k, v )
|
15
|
+
|
16
|
+
|
17
|
+
#pages_001:
|
18
|
+
# position: 1
|
19
|
+
# menu_en: CCLS
|
20
|
+
# body_es:
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
namespace :app do
|
28
|
+
namespace :db do
|
29
|
+
|
30
|
+
desc "Create yml fixtures for given model in database\n" <<
|
31
|
+
"rake app:db:extract_fixtures_from pages"
|
32
|
+
task :extract_fixtures_from => :environment do
|
33
|
+
me = $*.shift
|
34
|
+
while( table_name = $*.shift )
|
35
|
+
# File.open("#{RAILS_ROOT}/db/#{table_name}.yml", 'w') do |file|
|
36
|
+
File.open("#{Rails.root}/db/#{table_name}.yml", 'w') do |file|
|
37
|
+
# data = table_name.singularize.capitalize.constantize.find(
|
38
|
+
# data = table_name.singularize.classify.constantize.find(
|
39
|
+
# :all).collect(&:attributes)
|
40
|
+
# Added unscoped to break any default scope and sort by id to add some order.
|
41
|
+
# Doesn't seem to actually work though. Still not sorted properly.
|
42
|
+
# Cause the result is an unordered hash. Bummer
|
43
|
+
# Still use unscoped, just in case there is a default scope with a limit.
|
44
|
+
#
|
45
|
+
data = table_name.singularize.classify.constantize.unscoped.order(
|
46
|
+
'id asc').collect(&:attributes)
|
47
|
+
|
48
|
+
# file.write data.inject({}) { |hash, record|
|
49
|
+
# record.delete('created_at')
|
50
|
+
# record.delete('updated_at')
|
51
|
+
# # so that it is really string sortable, add leading zeros
|
52
|
+
# hash["#{table_name}_#{sprintf('%03d',record['id'])}"] = record
|
53
|
+
# hash
|
54
|
+
# }.to_ordered_yaml
|
55
|
+
|
56
|
+
|
57
|
+
file.write recursive_hash_to_yml_string(
|
58
|
+
data.inject({}) { |hash, record|
|
59
|
+
record.delete('created_at')
|
60
|
+
record.delete('updated_at')
|
61
|
+
# so that it is really string sortable, add leading zeros
|
62
|
+
hash["#{table_name}_#{sprintf('%03d',record['id'])}"] = record
|
63
|
+
hash
|
64
|
+
}
|
65
|
+
)
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
exit # REQUIRED OR WILL ATTEMPT TO PROCESS ARGUMENTS AS RAKE TASK
|
70
|
+
end
|
71
|
+
|
72
|
+
desc "Dump MYSQL table descriptions."
|
73
|
+
task :describe => :environment do
|
74
|
+
puts
|
75
|
+
puts "FYI: This task ONLY works on MYSQL databases."
|
76
|
+
puts
|
77
|
+
config = ActiveRecord::Base.connection.instance_variable_get(:@config)
|
78
|
+
#=> {:adapter=>"mysql", :host=>"localhost", :password=>nil, :username=>"root", :database=>"my_development", :encoding=>"utf8"}
|
79
|
+
|
80
|
+
# tables = ActiveRecord::Base.connection.execute('show tables;')
|
81
|
+
# while( table = tables.fetch_row ) do
|
82
|
+
# changes for MySQL2
|
83
|
+
tables = ActiveRecord::Base.connection.execute('show tables;').to_a.flatten.sort
|
84
|
+
while( table = tables.shift ) do
|
85
|
+
puts "Table: #{table}"
|
86
|
+
|
87
|
+
# may have to include host and port
|
88
|
+
system("mysql --table=true " <<
|
89
|
+
"--user=#{config[:username]} " <<
|
90
|
+
"--password='#{config[:password]}' " <<
|
91
|
+
"--execute='describe #{table}' " <<
|
92
|
+
config[:database]);
|
93
|
+
|
94
|
+
#
|
95
|
+
# mysql formats the table well so doing it by hand is something that
|
96
|
+
# will have to wait until I feel like wasting my time
|
97
|
+
#
|
98
|
+
# columns = ActiveRecord::Base.connection.execute("describe #{table};")
|
99
|
+
# while( column = columns.fetch_hash ) do
|
100
|
+
# puts column.keys Extra Default Null Type Field Key
|
101
|
+
# end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
desc "Calculate row size"
|
108
|
+
task :row_sizes => :environment do
|
109
|
+
puts
|
110
|
+
puts "FYI: This task ONLY works on MYSQL databases."
|
111
|
+
puts
|
112
|
+
config = ActiveRecord::Base.connection.instance_variable_get(:@config)
|
113
|
+
#=> {:adapter=>"mysql", :host=>"localhost", :password=>nil,
|
114
|
+
# :username=>"root", :database=>"my_development", :encoding=>"utf8"}
|
115
|
+
|
116
|
+
tables = ActiveRecord::Base.connection.execute('show tables;').to_a.flatten.sort
|
117
|
+
require 'nokogiri'
|
118
|
+
|
119
|
+
while( table = tables.shift ) do
|
120
|
+
# begin
|
121
|
+
# table = tables.first
|
122
|
+
puts "Table: #{table}"
|
123
|
+
|
124
|
+
# may have to include host and port
|
125
|
+
command = "mysql -X " <<
|
126
|
+
"--user=#{config[:username]} " <<
|
127
|
+
"--password='#{config[:password]}' " <<
|
128
|
+
"--execute='describe #{table}' " <<
|
129
|
+
config[:database]
|
130
|
+
|
131
|
+
# puts command
|
132
|
+
xml_doc = Nokogiri::XML(`#{command}`)
|
133
|
+
|
134
|
+
# <row>
|
135
|
+
# <field name="Field">id</field>
|
136
|
+
# <field name="Type">int(11)</field>
|
137
|
+
# <field name="Null">NO</field>
|
138
|
+
# <field name="Key">PRI</field>
|
139
|
+
# <field name="Default" xsi:nil="true" />
|
140
|
+
# <field name="Extra">auto_increment</field>
|
141
|
+
# </row>
|
142
|
+
table_size = 0
|
143
|
+
# http://www.w3schools.com/xpath/xpath_syntax.asp
|
144
|
+
xml_doc.xpath("//row/field[@name='Type']").each do |field|
|
145
|
+
field_size = case field.text
|
146
|
+
when /tinyint/ then 1
|
147
|
+
when /smallint/ then 2
|
148
|
+
when /mediumint/ then 3
|
149
|
+
when /bigint/ then 8
|
150
|
+
when /int/ then 4 # or integer (match last as would match above)
|
151
|
+
when /double/ then 4
|
152
|
+
when /float/ then 4
|
153
|
+
when /datetime/ then 8
|
154
|
+
when /timestamp/ then 4
|
155
|
+
when /year/ then 1
|
156
|
+
when /date/ then 3
|
157
|
+
when /time/ then 3
|
158
|
+
when /varchar\(\d+\)/ then field.text.scan(/varchar\((\d+)\)/).first.first.to_i
|
159
|
+
else 100 # just a guess
|
160
|
+
# puts field
|
161
|
+
end
|
162
|
+
# puts "#{field.name} - #{field.text} - #{field_size}"
|
163
|
+
table_size += field_size
|
164
|
+
end
|
165
|
+
puts table_size
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
end # namespace :db do
|
171
|
+
end # namespace :app do
|
172
|
+
|
173
|
+
|
174
|
+
|
175
|
+
|
176
|
+
|
177
|
+
# Would have to be very careful here as to not break anything.
|
178
|
+
# I don't know when to quote, add a | or a |- (or what the diff is)
|
179
|
+
|
180
|
+
|
181
|
+
#Possible yaml sort. Doesn't use the yaml library
|
182
|
+
|
183
|
+
#http://stackoverflow.com/questions/7275952/how-can-i-sort-yaml-files
|
184
|
+
# (modified)
|
185
|
+
|
186
|
+
|
187
|
+
# This WILL NOT WORK when the hash contains values that contains multi-line
|
188
|
+
# strings (like a text area). Somehow things need quoted or | or |- added.
|
189
|
+
|
190
|
+
# needed for escape
|
191
|
+
require 'yaml'
|
192
|
+
|
193
|
+
# doesn't exist in ruby 1.9.3,
|
194
|
+
# but seems ok with it being commented out.
|
195
|
+
# probably included in yaml.rb
|
196
|
+
#require 'yaml/encoding'
|
197
|
+
|
198
|
+
def recursive_hash_to_yml_string(hash, depth=0)
|
199
|
+
yml_string = ''
|
200
|
+
spacer = ""
|
201
|
+
depth.times { spacer += " "}
|
202
|
+
hash.keys.sort.each do |sorted_key|
|
203
|
+
yml_string += spacer + sorted_key + ": "
|
204
|
+
if hash[sorted_key].is_a?(Hash)
|
205
|
+
yml_string += "\n"
|
206
|
+
yml_string += recursive_hash_to_yml_string(hash[sorted_key], depth+1)
|
207
|
+
else
|
208
|
+
s = hash[sorted_key].to_s
|
209
|
+
if s.match("\n")
|
210
|
+
yml_string += "|-\n"
|
211
|
+
s.split(/\n/).each do |line|
|
212
|
+
yml_string += "#{spacer} #{line}\n"
|
213
|
+
end
|
214
|
+
else
|
215
|
+
# YAML.escape doesn't actually seem to escape as I would expect
|
216
|
+
# yml_string += "#{s.gsub(/([:>])/,"\\1")}\n"
|
217
|
+
# yml_string += "\"#{s}\"\n"
|
218
|
+
|
219
|
+
if s.match(/:/)
|
220
|
+
yml_string += "\"#{s}\"\n"
|
221
|
+
else
|
222
|
+
yml_string += "#{s}\n"
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
yml_string
|
228
|
+
end
|
229
|
+
|