$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 |
# 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
# 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
# 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
# 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
# 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
# File lib/ya2yaml.rb, line 136 136: def emit_simple_string(str,level) 137: str 138: end
# 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
# File lib/ya2yaml.rb, line 223 223: def is_one_line?(str) 224: str !~ /#{REX_ANY_LB}(?!\z)/ 225: end
# 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
# 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
# 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
# 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
# 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
# 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.
Generated with the Darkfish Rdoc Generator 1.1.6.