diff options
Diffstat (limited to 'lib/yaml/emitter.rb')
-rw-r--r-- | lib/yaml/emitter.rb | 245 |
1 files changed, 9 insertions, 236 deletions
diff --git a/lib/yaml/emitter.rb b/lib/yaml/emitter.rb index 0255cc7d02..a6be4a6733 100644 --- a/lib/yaml/emitter.rb +++ b/lib/yaml/emitter.rb @@ -2,9 +2,8 @@ # Output classes and methods # -require 'yaml/constants' +require 'yaml/baseemitter' require 'yaml/encoding' -require 'yaml/error' module YAML @@ -13,7 +12,11 @@ module YAML # class Emitter + + include BaseEmitter + attr_accessor :options + def initialize( opts ) opts = {} if opts.class != Hash @options = YAML::DEFAULTS.dup.update( opts ) @@ -30,6 +33,10 @@ module YAML @buffer = [] end + def level + @level + end + # # Version string # @@ -48,201 +55,6 @@ module YAML end end - # - # Emit binary data - # - def binary_base64( value ) - self << "!binary " - self.node_text( [value].pack("m"), '|' ) - end - - # - # Emit plain, normal flowing text - # - def node_text( value, block = '>' ) - @seq_map = false - valx = value.dup - if @options[:UseBlock] - block = '|' - elsif not @options[:UseFold] and valx =~ /\n[ \t]/ and not valx =~ /#{YAML::ESCAPE_CHAR}/ - block = '|' - end - str = block.dup - if valx =~ /\n\Z\n/ - str << "+" - elsif valx =~ /\Z\n/ - else - str << "-" - end - if valx =~ /#{YAML::ESCAPE_CHAR}/ - valx = YAML::escape( valx ) - end - if valx =~ /\A[ \t#]/ - str << @options[:Indent].to_s - end - if block == '>' - valx = fold( valx ) - end - self << str + indent_text( valx ) + "\n" - end - - # - # Emit a simple, unqouted string - # - def simple( value ) - @seq_map = false - self << value.to_s - end - - # - # Emit double-quoted string - # - def double( value ) - "\"#{YAML.escape( value )}\"" - end - - # - # Emit single-quoted string - # - def single( value ) - "'#{value}'" - end - - # - # Write a text block with the current indent - # - def indent_text( text ) - return "" if text.to_s.empty? - spacing = " " * ( @level * @options[:Indent] ) - return "\n" + text.gsub( /^([^\n])/, "#{spacing}\\1" ) - end - - # - # Write a current indent - # - def indent - #p [ self.id, @level, :INDENT ] - return " " * ( @level * @options[:Indent] ) - end - - # - # Add indent to the buffer - # - def indent! - self << indent - end - - # - # Folding paragraphs within a column - # - def fold( value ) - value.gsub!( /\A\n+/, '' ) - folded = $&.to_s - width = (0..@options[:BestWidth]) - while not value.empty? - last = value.index( /(\n+)/ ) - chop_s = false - if width.include?( last ) - last += $1.length - 1 - elsif width.include?( value.length ) - last = value.length - else - last = value.rindex( /[ \t]/, @options[:BestWidth] ) - chop_s = true - end - folded += value.slice!( 0, width.include?( last ) ? last + 1 : @options[:BestWidth] ) - folded.chop! if chop_s - folded += "\n" unless value.empty? - end - folded - end - - # - # Quick mapping - # - def map( type, &e ) - val = Mapping.new - e.call( val ) - self << "#{type} " if type.length.nonzero? - - # - # Empty hashes - # - if val.length.zero? - self << "{}" - @seq_map = false - else - if @buffer.length == 1 and @options[:UseHeader] == false and type.length.zero? - @headless = 1 - end - - defkey = @options.delete( :DefaultKey ) - if defkey - seq_map_shortcut - self << "= : " - defkey.to_yaml( :Emitter => self ) - end - - # - # Emit the key and value - # - val.each { |v| - seq_map_shortcut - if v[0].is_complex_yaml? - self << "? " - end - v[0].to_yaml( :Emitter => self ) - if v[0].is_complex_yaml? - self << "\n" - indent! - end - self << ": " - v[1].to_yaml( :Emitter => self ) - } - end - end - - def seq_map_shortcut - if @seq_map - @anchor_extras[@buffer.length - 1] = "\n" + indent - @seq_map = false - else - self << "\n" - indent! - end - end - - # - # Quick sequence - # - def seq( type, &e ) - @seq_map = false - val = Sequence.new - e.call( val ) - self << "#{type} " if type.length.nonzero? - - # - # Empty arrays - # - if val.length.zero? - self << "[]" - else - if @buffer.length == 1 and @options[:UseHeader] == false and type.length.zero? - @headless = 1 - end - # - # Emit the key and value - # - val.each { |v| - self << "\n" - indent! - self << "- " - @seq_map = true if v.class == Hash - v.to_yaml( :Emitter => self ) - } - end - end - # # Concatenate to the buffer # @@ -291,44 +103,5 @@ module YAML end end - # - # Emitter helper classes - # - class Mapping < Array - def add( k, v ) - push [k, v] - end - end - - class Sequence < Array - def add( v ) - push v - end - end - - # - # Allocate an Emitter if needed - # - def YAML.quick_emit( oid, opts = {}, &e ) - old_opt = nil - if opts[:Emitter].is_a? YAML::Emitter - out = opts.delete( :Emitter ) - old_opt = out.options.dup - out.options.update( opts ) - else - out = YAML::Emitter.new( opts ) - end - aidx = out.start_object( oid ) - if aidx - out.simple( "*#{out.options[:AnchorFormat]} " % [ aidx ] ) - else - e.call( out ) - end - if old_opt.is_a? Hash - out.options = old_opt - end - out.end_object - end - end |