PageRenderTime 28ms CodeModel.GetById 2ms app.highlight 23ms RepoModel.GetById 1ms app.codeStats 0ms

/IronPython_Main/External.LCA_RESTRICTED/Languages/Ruby/redist-libs/ruby/1.9.1/syck/baseemitter.rb

#
Ruby | 242 lines | 161 code | 21 blank | 60 comment | 20 complexity | b4ca8cede890dde02a556ab9a09579ab MD5 | raw file
  1#
  2# BaseEmitter
  3#
  4
  5require 'syck/constants'
  6require 'syck/encoding'
  7require 'syck/error'
  8
  9module Syck
 10  module BaseEmitter
 11    def options( opt = nil )
 12      if opt
 13        @options[opt] || DEFAULTS[opt]
 14      else
 15        @options
 16      end
 17    end
 18
 19    def options=( opt )
 20      @options = opt
 21    end
 22
 23    #
 24    # Emit binary data
 25    #
 26    def binary_base64( value )
 27      self << "!binary "
 28      self.node_text( [value].pack("m"), '|' )
 29    end
 30
 31    #
 32    # Emit plain, normal flowing text
 33    #
 34    def node_text( value, block = nil )
 35      @seq_map = false
 36      valx = value.dup
 37      unless block
 38        block =
 39          if options(:UseBlock)
 40            '|'
 41          elsif not options(:UseFold) and valx =~ /\n[ \t]/ and not valx =~ /#{ESCAPE_CHAR}/
 42            '|'
 43          else
 44            '>'
 45          end
 46        indt = $&.to_i if block =~ /\d+/
 47        if valx =~ /(\A\n*[ \t#]|^---\s+)/
 48          indt = options(:Indent) unless indt.to_i > 0
 49          block += indt.to_s
 50        end
 51
 52        block +=
 53          if valx =~ /\n\Z\n/
 54            "+"
 55          elsif valx =~ /\Z\n/
 56            ""
 57          else
 58            "-"
 59          end
 60      end
 61      block += "\n"
 62      if block[0] == ?"
 63        esc_skip = ( "\t\n" unless valx =~ /^[ \t]/ ) || ""
 64        valx = fold( Syck.escape( valx, esc_skip ) + "\"" ).chomp
 65        self << '"' + indent_text( valx, indt, false )
 66      else
 67        if block[0] == ?>
 68          valx = fold( valx )
 69        end
 70        #p [block, indt]
 71        self << block + indent_text( valx, indt )
 72      end
 73    end
 74
 75    #
 76    # Emit a simple, unqouted string
 77    #
 78    def simple( value )
 79      @seq_map = false
 80      self << value.to_s
 81    end
 82
 83    #
 84    # Emit double-quoted string
 85    #
 86    def double( value )
 87      "\"#{Syck.escape( value )}\""
 88    end
 89
 90    #
 91    # Emit single-quoted string
 92    #
 93    def single( value )
 94      "'#{value}'"
 95    end
 96
 97    #
 98    # Write a text block with the current indent
 99    #
100    def indent_text( text, mod, first_line = true )
101      return "" if text.to_s.empty?
102      spacing = indent( mod )
103      text = text.gsub( /\A([^\n])/, "#{ spacing }\\1" ) if first_line
104      return text.gsub( /\n^([^\n])/, "\n#{spacing}\\1" )
105    end
106
107    #
108    # Write a current indent
109    #
110    def indent( mod = nil )
111      #p [ self.id, level, mod, :INDENT ]
112      if level <= 0
113        mod ||= 0
114      else
115        mod ||= options(:Indent)
116        mod += ( level - 1 ) * options(:Indent)
117      end
118      return " " * mod
119    end
120
121    #
122    # Add indent to the buffer
123    #
124    def indent!
125      self << indent
126    end
127
128    #
129    # Folding paragraphs within a column
130    #
131    def fold( value )
132      value.gsub( /(^[ \t]+.*$)|(\S.{0,#{options(:BestWidth) - 1}})(?:[ \t]+|(\n+(?=[ \t]|\Z))|$)/ ) do
133        $1 || $2 + ( $3 || "\n" )
134      end
135    end
136
137    #
138    # Quick mapping
139    #
140    def map( type, &e )
141      val = Mapping.new
142      e.call( val )
143      self << "#{type} " if type.length.nonzero?
144
145      #
146      # Empty hashes
147      #
148      if val.length.zero?
149        self << "{}"
150        @seq_map = false
151      else
152        # FIXME
153        # if @buffer.length == 1 and options(:UseHeader) == false and type.length.zero?
154        #     @headless = 1
155        # end
156
157        defkey = @options.delete( :DefaultKey )
158        if defkey
159          seq_map_shortcut
160          self << "= : "
161          defkey.to_yaml( :Emitter => self )
162        end
163
164        #
165        # Emit the key and value
166        #
167        val.each { |v|
168          seq_map_shortcut
169          if v[0].is_complex_yaml?
170            self << "? "
171          end
172          v[0].to_yaml( :Emitter => self )
173          if v[0].is_complex_yaml?
174            self << "\n"
175            indent!
176          end
177          self << ": "
178          v[1].to_yaml( :Emitter => self )
179        }
180      end
181    end
182
183    def seq_map_shortcut
184      # FIXME: seq_map needs to work with the new anchoring system
185      # if @seq_map
186      #     @anchor_extras[@buffer.length - 1] = "\n" + indent
187      #     @seq_map = false
188      # else
189      self << "\n"
190      indent!
191      # end
192    end
193
194    #
195    # Quick sequence
196    #
197    def seq( type, &e )
198      @seq_map = false
199      val = Sequence.new
200      e.call( val )
201      self << "#{type} " if type.length.nonzero?
202
203      #
204      # Empty arrays
205      #
206      if val.length.zero?
207        self << "[]"
208      else
209        # FIXME
210        # if @buffer.length == 1 and options(:UseHeader) == false and type.length.zero?
211        #     @headless = 1
212        # end
213
214        #
215        # Emit the key and value
216        #
217        val.each { |v|
218          self << "\n"
219          indent!
220          self << "- "
221          @seq_map = true if v.class == Hash
222          v.to_yaml( :Emitter => self )
223        }
224      end
225    end
226  end
227
228  #
229  # Emitter helper classes
230  #
231  class Mapping < Array
232    def add( k, v )
233      push [k, v]
234    end
235  end
236
237  class Sequence < Array
238    def add( v )
239      push v
240    end
241  end
242end