In Files

Parent

Namespace

Included Modules

Files

Class Index [+]

Quicksearch

Ya2YAML

$Id: ya2yaml.rb,v 0.29 2009/02/09 09:01:30 funai Exp funai $

Author

Akira FUNAI

Copyright

Copyright © 2006 Akira FUNAI

License

MIT License

Public Class Methods

new(opts = {}) click to toggle source
    # File lib/ya2yaml.rb, line 11
11:         def initialize(opts = {})
12:                 options = opts.dup
13:                 options[:indent_size] = 2          if options[:indent_size].to_i <= 0
14:                 options[:minimum_block_length] = 0 if options[:minimum_block_length].to_i <= 0
15:                 options.update(
16:                         {
17:                                 :printable_with_syck  => true,
18:                                 :escape_b_specific    => true,
19:                                 :escape_as_utf8       => true,
20:                         }
21:                 ) if options[:syck_compatible]
22: 
23:                 @options = options
24:         end

Public Instance Methods

_ya2yaml(obj) click to toggle source
    # File lib/ya2yaml.rb, line 26
26:         def _ya2yaml(obj)
27:                 throw 'set $KCODE to "UTF8".' if (RUBY_VERSION < '1.9.0') && ($KCODE != 'UTF8')
28:                 '--- ' + emit(obj,1) + "\n"
29:         end

Private Instance Methods

emit(obj,level) click to toggle source
     # File lib/ya2yaml.rb, line 33
 33:         def emit(obj,level)
 34:                 case obj
 35:                         when Array
 36:                                 if (obj.length == 0)
 37:                                         '[]'
 38:                                 else
 39:                                         indent = "\n" + s_indent(level - 1)
 40:                                         obj.collect {|o|
 41:                                                 indent + '- ' + emit(o,level + 1)
 42:                                         }.join('')
 43:                                 end
 44:                         when Hash
 45:                                 if (obj.length == 0)
 46:                                         '{}'
 47:                                 else
 48:                                         indent = "\n" + s_indent(level - 1)
 49:                                         hash_order = @options[:hash_order]
 50:                                         if (hash_order && level == 1)
 51:                                                 hash_keys = obj.keys.sort {|x,y|
 52:                                                         x_order = hash_order.index(x) ? hash_order.index(x) : Float::MAX
 53:                                                         y_order = hash_order.index(y) ? hash_order.index(y) : Float::MAX
 54:                                                         o = (x_order <=> y_order)
 55:                                                         (o != 0) ? o : (x.to_s <=> y.to_s)
 56:                                                 }
 57:                                         else
 58:                                                 hash_keys = obj.keys.sort {|x,y| x.to_s <=> y.to_s }
 59:                                         end
 60:                                         hash_keys.collect {|k|
 61:                                                 key = emit(k,level + 1)
 62:                                                 if (
 63:                                                         is_one_plain_line?(key) ||
 64:                                                         key =~ /\A(#{REX_BOOL}|#{REX_FLOAT}|#{REX_INT}|#{REX_NULL})\z/
 65:                                                 )
 66:                                                         indent + key + ': ' + emit(obj[k],level + 1)
 67:                                                 else
 68:                                                         indent + '? ' + key +
 69:                                                         indent + ': ' + emit(obj[k],level + 1)
 70:                                                 end
 71:                                         }.join('')
 72:                                 end
 73:                         when NilClass
 74:                                 '~'
 75:                         when String
 76:                                 emit_string(obj,level)
 77:                         when TrueClass,FalseClass
 78:                                 obj.to_s
 79:                         when Fixnum,Bignum,Float
 80:                                 obj.to_s
 81:                         when Date
 82:                                 obj.to_s
 83:                         when Time
 84:                                 offset = obj.gmtoff
 85:                                 off_hm = sprintf(
 86:                                         '%+.2d:%.2d',
 87:                                         (offset / 3600.0).to_i,
 88:                                         (offset % 3600.0) / 60
 89:                                 )
 90:                                 u_sec = (obj.usec != 0) ? sprintf(".%.6d",obj.usec) : ''
 91:                                 obj.strftime("%Y-%m-%d %H:%M:%S#{u_sec} #{off_hm}")
 92:                         when Symbol
 93:                                 '!ruby/symbol ' + emit_string(obj.to_s,level)
 94:                         when Range
 95:                                 '!ruby/range ' + obj.to_s
 96:                         when Regexp
 97:                                 '!ruby/regexp ' + obj.inspect
 98:                         else
 99:                                 case
100:                                         when obj.is_a?(Struct)
101:                                                 struct_members = {}
102:                                                 obj.each_pair{|k,v| struct_members[k.to_s] = v }
103:                                                 '!ruby/struct:' + obj.class.to_s.sub(/^(Struct::(.+)|.*)$/,'\2') + ' ' +
104:                                                 emit(struct_members,level + 1)
105:                                         else
106:                                                 # serialized as a generic object
107:                                                 object_members = {}
108:                                                 obj.instance_variables.each{|k,v|
109:                                                         object_members[k.to_s.sub(/^@/,'')] = obj.instance_variable_get(k)
110:                                                 }
111:                                                 '!ruby/object:' + obj.class.to_s + ' ' +
112:                                                 emit(object_members,level + 1)
113:                                 end
114:                 end
115:         end
emit_base64_binary(str,level) click to toggle source
     # File lib/ya2yaml.rb, line 180
180:         def emit_base64_binary(str,level)
181:                 indent = "\n" + s_indent(level)
182:                 base64 = [str].pack('m')
183:                 '!binary |' + indent + base64.gsub(/\n(?!\z)/,indent)
184:         end
emit_block_string(str,level) click to toggle source
     # File lib/ya2yaml.rb, line 140
140:         def emit_block_string(str,level)
141:                 str = normalize_line_break(str)
142: 
143:                 indent = s_indent(level)
144:                 indentation_indicator = (str =~ /\A /) ? indent.size.to_s : ''
145:                 str =~ /(#{REX_NORMAL_LB}*)\z/
146:                 chomping_indicator = case $1.length
147:                         when 0
148:                                 '-'
149:                         when 1
150:                                 ''
151:                         else
152:                                 '+'
153:                 end
154: 
155:                 str.chomp!
156:                 str.gsub!(/#{REX_NORMAL_LB}/) {
157:                         $1 + indent
158:                 }
159:                 '|' + indentation_indicator + chomping_indicator + "\n" + indent + str
160:         end
emit_quoted_string(str,level) click to toggle source
     # File lib/ya2yaml.rb, line 162
162:         def emit_quoted_string(str,level)
163:                 str = yaml_escape(normalize_line_break(str))
164:                 if (str.length < @options[:minimum_block_length])
165:                         str.gsub!(/#{REX_NORMAL_LB}/) { ESCAPE_SEQ_LB[$1] }
166:                 else
167:                         str.gsub!(/#{REX_NORMAL_LB}$/) { ESCAPE_SEQ_LB[$1] }
168:                         str.gsub!(/(#{REX_NORMAL_LB}+)(.)/) {
169:                                 trail_c = $3
170:                                 $1 + trail_c.sub(/([\t ])/) { ESCAPE_SEQ_WS[$1] }
171:                         }
172:                         indent = s_indent(level)
173:                         str.gsub!(/#{REX_NORMAL_LB}/) {
174:                                 ESCAPE_SEQ_LB[$1] + "\\\n" + indent
175:                         }
176:                 end
177:                 '"' + str + '"'
178:         end
emit_simple_string(str,level) click to toggle source
     # File lib/ya2yaml.rb, line 136
136:         def emit_simple_string(str,level)
137:                 str
138:         end
emit_string(str,level) click to toggle source
     # File lib/ya2yaml.rb, line 117
117:         def emit_string(str,level)
118:                 (is_string,is_printable,is_one_line,is_one_plain_line) = string_type(str)
119:                 if is_string
120:                         if is_printable
121:                                 if is_one_plain_line
122:                                         emit_simple_string(str,level)
123:                                 else
124:                                         (is_one_line || str.length < @options[:minimum_block_length]) ?
125:                                                 emit_quoted_string(str,level) :
126:                                                 emit_block_string(str,level)
127:                                 end
128:                         else
129:                                 emit_quoted_string(str,level)
130:                         end
131:                 else
132:                         emit_base64_binary(str,level)
133:                 end
134:         end
is_one_line?(str) click to toggle source
     # File lib/ya2yaml.rb, line 223
223:         def is_one_line?(str)
224:                 str !~ /#{REX_ANY_LB}(?!\z)/
225:         end
is_one_plain_line?(str) click to toggle source
     # File lib/ya2yaml.rb, line 227
227:         def is_one_plain_line?(str)
228:                 # YAML 1.1 / 4.6.11.
229:                 str !~ /^([\-\?:,\[\]\{\}\#&\*!\|>'"%@`\s]|---|\.\.\.)/    &&
230:                 str !~ /[:\#\s\[\]\{\},]/                                  &&
231:                 str !~ /#{REX_ANY_LB}/                                     &&
232:                 str !~ /^(#{REX_BOOL}|#{REX_FLOAT}|#{REX_INT}|#{REX_MERGE}
233:                         |#{REX_NULL}|#{REX_TIMESTAMP}|#{REX_VALUE})$/
234:         end
is_printable?(ucs_code) click to toggle source
     # File lib/ya2yaml.rb, line 207
207:         def is_printable?(ucs_code)
208:                 # YAML 1.1 / 4.1.1.
209:                 (
210:                         [0x09,0x0a,0x0d,0x85].include?(ucs_code)      ||
211:                         (ucs_code <=     0x7e && ucs_code >=    0x20) ||
212:                         (ucs_code <=   0xd7ff && ucs_code >=    0xa0) ||
213:                         (ucs_code <=   0xfffd && ucs_code >=  0xe000) ||
214:                         (ucs_code <= 0x10ffff && ucs_code >= 0x10000)
215:                 ) &&
216:                 !(
217:                         # treat LS/PS as non-printable characters
218:                         @options[:escape_b_specific] &&
219:                         (ucs_code == 0x2028 || ucs_code == 0x2029)
220:                 )
221:         end
normalize_line_break(str) click to toggle source
     # File lib/ya2yaml.rb, line 241
241:         def normalize_line_break(str)
242:                 # YAML 1.1 / 4.1.4.
243:                 str.gsub(/(#{REX_CRLF}|#{REX_CR}|#{REX_NEL})/,"\n")
244:         end
s_indent(level) click to toggle source
     # File lib/ya2yaml.rb, line 236
236:         def s_indent(level)
237:                 # YAML 1.1 / 4.2.2.
238:                 ' ' * (level * @options[:indent_size])
239:         end
string_type(str) click to toggle source
     # File lib/ya2yaml.rb, line 186
186:         def string_type(str)
187:                 if str.respond_to?(:valid_encoding?) && !str.valid_encoding?
188:                         return false,false,false,false
189:                 end
190:                 (ucs_codes = str.unpack('U*')) rescue (
191:                         # ArgumentError -> binary data
192:                         return false,false,false,false
193:                 )
194:                 if (
195:                         @options[:printable_with_syck] &&
196:                         str =~ /\A#{REX_ANY_LB}* | #{REX_ANY_LB}*\z|#{REX_ANY_LB}{2}\z/
197:                 )
198:                         # detour Syck bug
199:                         return true,false,nil,false
200:                 end
201:                 ucs_codes.each {|ucs_code|
202:                         return true,false,nil,false unless is_printable?(ucs_code)
203:                 }
204:                 return true,true,is_one_line?(str),is_one_plain_line?(str)
205:         end
yaml_escape(str) click to toggle source
     # File lib/ya2yaml.rb, line 246
246:         def yaml_escape(str)
247:                 # YAML 1.1 / 4.1.6.
248:                 str.gsub(/[^a-zA-Z0-9]/) {|c|
249:                         ucs_code, = (c.unpack('U') rescue [??])
250:                         case
251:                                 when ESCAPE_SEQ[c]
252:                                         ESCAPE_SEQ[c]
253:                                 when is_printable?(ucs_code)
254:                                         c
255:                                 when @options[:escape_as_utf8]
256:                                         c.respond_to?(:bytes) ?
257:                                                 c.bytes.collect {|b| '\x%.2x' % b }.join :
258:                                                 '\x' + c.unpack('H2' * c.size).join('\x')
259:                                 when ucs_code == 0x2028 || ucs_code == 0x2029
260:                                         ESCAPE_SEQ_LB[c]
261:                                 when ucs_code <= 0x7f
262:                                         sprintf('\x%.2x',ucs_code)
263:                                 when ucs_code <= 0xffff
264:                                         sprintf('\u%.4x',ucs_code)
265:                                 else
266:                                         sprintf('\U%.8x',ucs_code)
267:                         end
268:                 }
269:         end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.