mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/yaml.rb: reworking YAML::Stream to use the new
emitter. * lib/yaml/stream.rb: ditto. * lib/yaml/rubytypes.rb: added Object#yaml_new. * lib/yaml/tag.rb: the tag_subclasses? method now shows up in the class. allow taguri to be set using an accessor. continue support of Object#to_yaml_type. * ext/syck/rubyext.c: new emitter code. yaml_new and yaml_initialize get called, should they be present. consolidated all the diaspora of internal node types into the family below YAML::Syck::Node -- Map, Seq, Scalar -- all of whom are SyckNode structs pointing to Ruby data. moved Object#yaml_new into the node_import and made it the default behavior. the target_class is always called wih yaml_new, prepended a parameter, which is the klass. loaded nodes through GenericResolver show their style. new Resolver#tagurize converts type ids to taguris. * ext/syck/implicit.re: were 'y' and 'n' seriously omitted?? * ext/syck/emitter.c: renovated emitter, walks the tree in advance. consolidated redundant block_styles struct into the scalar_style struct. (this means loaded nodes can now be sent back to emitter and preserve at least its very basic formatting.) * ext/syck/gram.c: headless documents of any kind allowed. * ext/syck/node.c: new syck_replace_str methods and syck_empty_* methods for rewriting node contents, while keeping the ID and other setup info. added syck_seq_assign. * ext/syck/syck.h: reflect block_styles and new node functions. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9139 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
ef1ccbbc40
commit
9852657e86
3 changed files with 38 additions and 354 deletions
38
ChangeLog
38
ChangeLog
|
@ -1,3 +1,41 @@
|
||||||
|
Tue Sep 13 12:33:05 2005 <why@ruby-lang.org>
|
||||||
|
|
||||||
|
* lib/yaml.rb: reworking YAML::Stream to use the new
|
||||||
|
emitter.
|
||||||
|
|
||||||
|
* lib/yaml/stream.rb: ditto.
|
||||||
|
|
||||||
|
* lib/yaml/rubytypes.rb: added Object#yaml_new.
|
||||||
|
|
||||||
|
* lib/yaml/tag.rb: the tag_subclasses? method now
|
||||||
|
shows up in the class. allow taguri to be set using an accessor.
|
||||||
|
continue support of Object#to_yaml_type.
|
||||||
|
|
||||||
|
* ext/syck/rubyext.c: new emitter code. yaml_new and yaml_initialize
|
||||||
|
get called, should they be present. consolidated all the diaspora of internal
|
||||||
|
node types into the family below YAML::Syck::Node -- Map,
|
||||||
|
Seq, Scalar -- all of whom are SyckNode structs pointing to
|
||||||
|
Ruby data. moved Object#yaml_new into the node_import and made it the
|
||||||
|
default behavior. the target_class is always called wih yaml_new, prepended
|
||||||
|
a parameter, which is the klass. loaded nodes through GenericResolver show their style.
|
||||||
|
new Resolver#tagurize converts type ids to taguris.
|
||||||
|
|
||||||
|
* ext/syck/implicit.re: were 'y' and 'n' seriously omitted??
|
||||||
|
|
||||||
|
* ext/syck/emitter.c: renovated emitter, walks the tree in advance.
|
||||||
|
consolidated redundant block_styles struct into
|
||||||
|
the scalar_style struct. (this means loaded nodes can now
|
||||||
|
be sent back to emitter and preserve at least its very basic
|
||||||
|
formatting.)
|
||||||
|
|
||||||
|
* ext/syck/gram.c: headless documents of any kind allowed.
|
||||||
|
|
||||||
|
* ext/syck/node.c: new syck_replace_str methods and syck_empty_*
|
||||||
|
methods for rewriting node contents, while keeping the ID
|
||||||
|
and other setup info. added syck_seq_assign.
|
||||||
|
|
||||||
|
* ext/syck/syck.h: reflect block_styles and new node functions.
|
||||||
|
|
||||||
Tue Sep 13 08:09:18 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Tue Sep 13 08:09:18 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* lib/ostruct.rb (new_ostruct_member): Object#send no longer call
|
* lib/ostruct.rb (new_ostruct_member): Object#send no longer call
|
||||||
|
|
|
@ -1,247 +0,0 @@
|
||||||
#
|
|
||||||
# BaseEmitter
|
|
||||||
#
|
|
||||||
|
|
||||||
require 'yaml/constants'
|
|
||||||
require 'yaml/encoding'
|
|
||||||
require 'yaml/error'
|
|
||||||
|
|
||||||
module YAML
|
|
||||||
|
|
||||||
module BaseEmitter
|
|
||||||
|
|
||||||
def options( opt = nil )
|
|
||||||
if opt
|
|
||||||
@options[opt] || YAML::DEFAULTS[opt]
|
|
||||||
else
|
|
||||||
@options
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def options=( opt )
|
|
||||||
@options = opt
|
|
||||||
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 = nil )
|
|
||||||
@seq_map = false
|
|
||||||
valx = value.dup
|
|
||||||
unless block
|
|
||||||
block =
|
|
||||||
if options(:UseBlock)
|
|
||||||
'|'
|
|
||||||
elsif not options(:UseFold) and valx =~ /\n[ \t]/ and not valx =~ /#{YAML::ESCAPE_CHAR}/
|
|
||||||
'|'
|
|
||||||
else
|
|
||||||
'>'
|
|
||||||
end
|
|
||||||
|
|
||||||
indt = $&.to_i if block =~ /\d+/
|
|
||||||
if valx =~ /(\A\n*[ \t#]|^---\s+)/
|
|
||||||
indt = options(:Indent) unless indt.to_i > 0
|
|
||||||
block += indt.to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
block +=
|
|
||||||
if valx =~ /\n\Z\n/
|
|
||||||
"+"
|
|
||||||
elsif valx =~ /\Z\n/
|
|
||||||
""
|
|
||||||
else
|
|
||||||
"-"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
block += "\n"
|
|
||||||
if block[0] == ?"
|
|
||||||
esc_skip = ( "\t\n" unless valx =~ /^[ \t]/ ) || ""
|
|
||||||
valx = fold( YAML::escape( valx, esc_skip ) + "\"" ).chomp
|
|
||||||
self << '"' + indent_text( valx, indt, false )
|
|
||||||
else
|
|
||||||
if block[0] == ?>
|
|
||||||
valx = fold( valx )
|
|
||||||
end
|
|
||||||
#p [block, indt]
|
|
||||||
self << block + indent_text( valx, indt )
|
|
||||||
end
|
|
||||||
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, mod, first_line = true )
|
|
||||||
return "" if text.to_s.empty?
|
|
||||||
spacing = indent( mod )
|
|
||||||
text = text.gsub( /\A([^\n])/, "#{ spacing }\\1" ) if first_line
|
|
||||||
return text.gsub( /\n^([^\n])/, "\n#{spacing}\\1" )
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Write a current indent
|
|
||||||
#
|
|
||||||
def indent( mod = nil )
|
|
||||||
#p [ self.id, level, mod, :INDENT ]
|
|
||||||
if level <= 0
|
|
||||||
mod ||= 0
|
|
||||||
else
|
|
||||||
mod ||= options(:Indent)
|
|
||||||
mod += ( level - 1 ) * options(:Indent)
|
|
||||||
end
|
|
||||||
return " " * mod
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Add indent to the buffer
|
|
||||||
#
|
|
||||||
def indent!
|
|
||||||
self << indent
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Folding paragraphs within a column
|
|
||||||
#
|
|
||||||
def fold( value )
|
|
||||||
value.gsub( /(^[ \t]+.*$)|(\S.{0,#{options(:BestWidth) - 1}})(?:[ \t]+|(\n+(?=[ \t]|\Z))|$)/ ) do |s|
|
|
||||||
$1 || $2 + ( $3 || "\n" )
|
|
||||||
end
|
|
||||||
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
|
|
||||||
# FIXME
|
|
||||||
# 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
|
|
||||||
# FIXME: seq_map needs to work with the new anchoring system
|
|
||||||
# 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
|
|
||||||
# FIXME
|
|
||||||
# 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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,107 +0,0 @@
|
||||||
#
|
|
||||||
# Output classes and methods
|
|
||||||
#
|
|
||||||
|
|
||||||
require 'yaml/baseemitter'
|
|
||||||
require 'yaml/encoding'
|
|
||||||
|
|
||||||
module YAML
|
|
||||||
|
|
||||||
#
|
|
||||||
# Emit a set of values
|
|
||||||
#
|
|
||||||
|
|
||||||
class Emitter
|
|
||||||
|
|
||||||
include BaseEmitter
|
|
||||||
|
|
||||||
attr_accessor :options
|
|
||||||
|
|
||||||
def initialize( opts )
|
|
||||||
opts = {} if opts.class != Hash
|
|
||||||
@options = YAML::DEFAULTS.dup.update( opts )
|
|
||||||
@headless = 0
|
|
||||||
@seq_map = false
|
|
||||||
@anchors = {}
|
|
||||||
@anchor_extras = {}
|
|
||||||
@active_anchors = []
|
|
||||||
@level = -1
|
|
||||||
self.clear
|
|
||||||
end
|
|
||||||
|
|
||||||
def clear
|
|
||||||
@buffer = []
|
|
||||||
end
|
|
||||||
|
|
||||||
def level
|
|
||||||
@level
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Version string
|
|
||||||
#
|
|
||||||
def version_s
|
|
||||||
" %YAML:#{@options[:Version]}" if @options[:UseVersion]
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Header
|
|
||||||
#
|
|
||||||
def header
|
|
||||||
if @headless.nonzero?
|
|
||||||
""
|
|
||||||
else
|
|
||||||
"---#{version_s} "
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Concatenate to the buffer
|
|
||||||
#
|
|
||||||
def <<( str )
|
|
||||||
#p [ self.id, @level, str ]
|
|
||||||
@buffer.last << str
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Monitor objects and allow references
|
|
||||||
#
|
|
||||||
def start_object( oid )
|
|
||||||
@level += 1
|
|
||||||
@buffer.push( "" )
|
|
||||||
#p [ self.id, @level, :OPEN ]
|
|
||||||
idx = nil
|
|
||||||
if oid
|
|
||||||
if @anchors.has_key?( oid )
|
|
||||||
idx = @active_anchors.index( oid )
|
|
||||||
unless idx
|
|
||||||
idx = @active_anchors.length
|
|
||||||
af_str = "&#{@options[:AnchorFormat]} " % [ idx + 1 ]
|
|
||||||
af_str += @anchor_extras[ @anchors[ oid ] ].to_s
|
|
||||||
@buffer[ @anchors[ oid ] ][0,0] = af_str
|
|
||||||
@headless = 0 if @anchors[ oid ].zero?
|
|
||||||
end
|
|
||||||
idx += 1
|
|
||||||
@active_anchors.push( oid )
|
|
||||||
else
|
|
||||||
@anchors[ oid ] = @buffer.length - 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return idx
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Output method
|
|
||||||
#
|
|
||||||
def end_object
|
|
||||||
@level -= 1
|
|
||||||
@buffer.push( "" )
|
|
||||||
#p [ self.id, @level, :END ]
|
|
||||||
if @level < 0
|
|
||||||
header + @buffer.to_s[@headless..-1].to_s
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
Loading…
Reference in a new issue