RbYAML 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/LICENSE +19 -0
  2. data/README +31 -0
  3. data/lib/rbyaml.rb +378 -0
  4. data/lib/rbyaml/composer.rb +189 -0
  5. data/lib/rbyaml/constructor.rb +374 -0
  6. data/lib/rbyaml/detector.rb +44 -0
  7. data/lib/rbyaml/dumper.rb +40 -0
  8. data/lib/rbyaml/emitter.rb +1116 -0
  9. data/lib/rbyaml/error.rb +81 -0
  10. data/lib/rbyaml/events.rb +92 -0
  11. data/lib/rbyaml/loader.rb +49 -0
  12. data/lib/rbyaml/nodes.rb +69 -0
  13. data/lib/rbyaml/parser.rb +488 -0
  14. data/lib/rbyaml/reader.rb +127 -0
  15. data/lib/rbyaml/representer.rb +183 -0
  16. data/lib/rbyaml/scanner.rb +1258 -0
  17. data/lib/rbyaml/serializer.rb +120 -0
  18. data/lib/rbyaml/test.rb +56 -0
  19. data/lib/rbyaml/tokens.rb +163 -0
  20. data/lib/rbyaml/yaml.rb +143 -0
  21. data/test/test_rbyaml.rb +18 -0
  22. data/test/yaml/gems.yml +130951 -0
  23. data/test/yaml/gems2.yml +113 -0
  24. data/test/yaml/test1.yml +3 -0
  25. data/test/yaml/test10.yml +8 -0
  26. data/test/yaml/test12.yml +8 -0
  27. data/test/yaml/test13.yml +4 -0
  28. data/test/yaml/test14.yml +4 -0
  29. data/test/yaml/test15.yml +8 -0
  30. data/test/yaml/test16.yml +7 -0
  31. data/test/yaml/test18.yml +6 -0
  32. data/test/yaml/test19.yml +5 -0
  33. data/test/yaml/test2.yml +3 -0
  34. data/test/yaml/test20.yml +6 -0
  35. data/test/yaml/test21.yml +4 -0
  36. data/test/yaml/test22.yml +4 -0
  37. data/test/yaml/test23.yml +13 -0
  38. data/test/yaml/test24.yml +14 -0
  39. data/test/yaml/test25.yml +7 -0
  40. data/test/yaml/test26.yml +7 -0
  41. data/test/yaml/test27.yml +29 -0
  42. data/test/yaml/test28.yml +26 -0
  43. data/test/yaml/test29.yml +13 -0
  44. data/test/yaml/test3.yml +8 -0
  45. data/test/yaml/test30.yml +7 -0
  46. data/test/yaml/test31.yml +2 -0
  47. data/test/yaml/test32.yml +13 -0
  48. data/test/yaml/test33.yml +2 -0
  49. data/test/yaml/test34.yml +8 -0
  50. data/test/yaml/test35.yml +4 -0
  51. data/test/yaml/test36.yml +8 -0
  52. data/test/yaml/test37.yml +2 -0
  53. data/test/yaml/test38.yml +8 -0
  54. data/test/yaml/test39.yml +2 -0
  55. data/test/yaml/test4.yml +8 -0
  56. data/test/yaml/test40.yml +3 -0
  57. data/test/yaml/test41.yml +5 -0
  58. data/test/yaml/test42.yml +12 -0
  59. data/test/yaml/test43.yml +15 -0
  60. data/test/yaml/test44.yml +23 -0
  61. data/test/yaml/test5.yml +3 -0
  62. data/test/yaml/test6.yml +5 -0
  63. data/test/yaml/test7.yml +10 -0
  64. data/test/yaml/test8.yml +10 -0
  65. data/test/yaml/test9.yml +8 -0
  66. metadata +111 -0
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2006 Ola Bini
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/README ADDED
@@ -0,0 +1,31 @@
1
+ = RbYAML - A pure Ruby YAML 1.1 loader and dumper
2
+
3
+ Project Contact: Ola Bini <ola@ologix.com>
4
+
5
+ The code is based mostly on the Python code written by Kirill Simonov <xi@resolvent.net> for PyYAML3000.
6
+
7
+ RbYAML is a project originating in the JRuby project (http://jruby.sourceforge.net), to create a pure Ruby
8
+ YAML parser for use in JRuby and SYCK cannot be used in this case.
9
+ Since the effort of writing a new one from scratch seemed like a major undertaking it seemed easier to
10
+ port an existing one.
11
+
12
+ The current functionality is more or less 1.1-compliant. What's missing is the Unicode-support. The idea
13
+ is to have the interface resemble SYCK as much as possible, but this is still work in progress, since some
14
+ of the major architectural choices are quite different.
15
+
16
+ == Use
17
+
18
+ Just require 'rbyaml' and use it as you would use YAML, but in module RbYAML instead:
19
+
20
+ require 'rbyaml'
21
+
22
+ RbYAML.load("--- \n- A\n- b\n- c\n") ----> ["A","b","c"]
23
+ "foo".to_yaml ----> "foo\n"
24
+
25
+ == More information
26
+
27
+ Visit http://rbyaml.ologix.com for more information and updated versions
28
+
29
+ == License
30
+
31
+ RbYAML is distributed with a MIT license, which can be found in the file LICENSE.
@@ -0,0 +1,378 @@
1
+
2
+ require 'rbyaml/yaml'
3
+
4
+ module RbYAML
5
+ def self.dump(obj, io = nil)
6
+ _dump(obj,io)
7
+ end
8
+
9
+ def self.load( io )
10
+ _load(io)
11
+ end
12
+
13
+ def self.load_file( filepath )
14
+ File.open( filepath ) do |f|
15
+ load( f )
16
+ end
17
+ end
18
+
19
+ # this operation does not make sense in RbYAML (right now)
20
+ def self.parse( io )
21
+ # yp = @@parser.new( :Model => :Generic ).load( io )
22
+ end
23
+
24
+ # this operation does not make sense in RbYAML (right now)
25
+ def self.parse_file( filepath )
26
+ # File.open( filepath ) do |f|
27
+ # parse( f )
28
+ # end
29
+ end
30
+
31
+ def self.each_document( io, &block )
32
+ _load_all(io,&block)
33
+ end
34
+
35
+ def self.load_documents( io, &doc_proc )
36
+ each_document( io, &doc_proc )
37
+ end
38
+
39
+ # this operation does not make sense in RbYAML (right now)
40
+ def self.each_node( io, &doc_proc )
41
+ # yp = @@parser.new( :Model => :Generic ).load_documents( io, &doc_proc )
42
+ end
43
+
44
+ # this operation does not make sense in RbYAML (right now)
45
+ def self.parse_documents( io, &doc_proc )
46
+ # YAML.each_node( io, &doc_proc )
47
+ end
48
+
49
+ def self.load_stream( io )
50
+ d = nil
51
+ load_documents(io) { |doc|
52
+ d = Stream.new( nil ) if not d
53
+ d.add( doc )
54
+ }
55
+ d
56
+ end
57
+
58
+ def self.dump_stream( *objs )
59
+ d = RbYAML::Stream.new
60
+ objs.each do |doc|
61
+ d.add( doc )
62
+ end
63
+ d.emit
64
+ end
65
+
66
+ # this operation does not make sense in RbYAML (right now)
67
+ def self.add_domain_type( domain, type_re, &transfer_proc )
68
+ # @@loader.add_domain_type( domain, type_re, &transfer_proc )
69
+ end
70
+
71
+ # this operation does not make sense in RbYAML (right now)
72
+ def self.add_builtin_type( type_re, &transfer_proc )
73
+ # @@loader.add_builtin_type( type_re, &transfer_proc )
74
+ end
75
+
76
+ # this operation does not make sense in RbYAML (right now)
77
+ def self.add_ruby_type( type_tag, &transfer_proc )
78
+ # @@loader.add_ruby_type( type, &transfer_proc )
79
+ end
80
+
81
+ # this operation does not make sense in RbYAML (right now)
82
+ def self.add_private_type( type_re, &transfer_proc )
83
+ # @@loader.add_private_type( type_re, &transfer_proc )
84
+ end
85
+
86
+ def self.detect_implicit( val )
87
+ SimpleDetector.detect(val)
88
+ end
89
+
90
+ # this operation does not make sense in RbYAML (right now)
91
+ def self.transfer( type_id, obj )
92
+ # @@loader.transfer( type_id, obj )
93
+ end
94
+
95
+ # this operation does not make sense in RbYAML (right now)
96
+ def self.try_implicit( obj )
97
+ # YAML.transfer( YAML.detect_implicit( obj ), obj )
98
+ end
99
+
100
+ def self.read_type_class( type, obj_class )
101
+ scheme, domain, type, tclass = type.split( ':', 4 )
102
+ tclass.split( "::" ).each { |c| obj_class = obj_class.const_get( c ) } if tclass
103
+ return [ type, obj_class ]
104
+ end
105
+
106
+ def self.object_maker( obj_class, val )
107
+ if Hash === val
108
+ o = obj_class.allocate
109
+ val.each_pair { |k,v|
110
+ o.instance_variable_set("@#{k}", v)
111
+ }
112
+ o
113
+ else
114
+ raise YAMLError, "Invalid object explicitly tagged !ruby/Object: " + val.inspect
115
+ end
116
+ end
117
+
118
+ # this operation does not make sense in RbYAML (right now)
119
+ def self.quick_emit( oid, opts = {}, &e )
120
+ end
121
+
122
+ # A dictionary of taguris which map to
123
+ # Ruby classes.
124
+ @@tagged_classes = {}
125
+
126
+ #
127
+ # Associates a taguri _tag_ with a Ruby class _cls_. The taguri is used to give types
128
+ # to classes when loading YAML. Taguris are of the form:
129
+ #
130
+ # tag:authorityName,date:specific
131
+ #
132
+ # The +authorityName+ is a domain name or email address. The +date+ is the date the type
133
+ # was issued in YYYY or YYYY-MM or YYYY-MM-DD format. The +specific+ is a name for
134
+ # the type being added.
135
+ #
136
+ # For example, built-in YAML types have 'yaml.org' as the +authorityName+ and '2002' as the
137
+ # +date+. The +specific+ is simply the name of the type:
138
+ #
139
+ # tag:yaml.org,2002:int
140
+ # tag:yaml.org,2002:float
141
+ # tag:yaml.org,2002:timestamp
142
+ #
143
+ # The domain must be owned by you on the +date+ declared. If you don't own any domains on the
144
+ # date you declare the type, you can simply use an e-mail address.
145
+ #
146
+ # tag:why@ruby-lang.org,2004:notes/personal
147
+ #
148
+ def self.tag_class( tag, cls )
149
+ if @@tagged_classes.has_key? tag
150
+ warn "class #{ @@tagged_classes[tag] } held ownership of the #{ tag } tag"
151
+ end
152
+ @@tagged_classes[tag] = cls
153
+ end
154
+
155
+ # Returns the complete dictionary of taguris, paired with classes. The key for
156
+ # the dictionary is the full taguri. The value for each key is the class constant
157
+ # associated to that taguri.
158
+ #
159
+ # YAML.tagged_classes["tag:yaml.org,2002:int"] => Integer
160
+ #
161
+ def self.tagged_classes
162
+ @@tagged_classes
163
+ end
164
+
165
+ #
166
+ # RbYAML::Stream -- for emitting many documents
167
+ #
168
+ class Stream
169
+ include Enumerable
170
+
171
+ attr_accessor :documents, :options
172
+ def initialize(opts = {})
173
+ @options = opts
174
+ @documents = []
175
+ end
176
+
177
+ def [](i)
178
+ @documents[ i ]
179
+ end
180
+
181
+ def add(doc)
182
+ @documents << doc
183
+ end
184
+
185
+ def edit(doc_num,doc)
186
+ @documents[ doc_num ] = doc
187
+ end
188
+
189
+ def each(&block)
190
+ @documents.each(&block)
191
+ end
192
+
193
+ def emit
194
+ # TODO: implement
195
+
196
+ opts = @options.dup
197
+ opts[:UseHeader] = true if @documents.length > 1
198
+ ct = 0
199
+ out = Emitter.new( opts )
200
+ @documents.each { |v|
201
+ if ct > 0
202
+ out << "\n--- "
203
+ end
204
+ v.to_yaml( :Emitter => out )
205
+ ct += 1
206
+ }
207
+ out.end_object
208
+ end
209
+ end
210
+ end
211
+
212
+ if !Object.method_defined?(:to_yaml)
213
+ class Module # :nodoc: all
214
+ def yaml_as( tag, sc = true )
215
+ class_eval <<-"end;", __FILE__, __LINE__+1
216
+ attr_writer :taguri
217
+ def taguri
218
+ return @taguri if defined?(@taguri) and @taguri
219
+ tag = #{ tag.dump }
220
+ if self.class.yaml_tag_subclasses? and self.class != RbYAML::tagged_classes[tag]
221
+ tag = "\#{ tag }:\#{ self.class.yaml_tag_class_name }"
222
+ end
223
+ tag
224
+ end
225
+ def self.yaml_tag_subclasses?; #{ sc ? 'true' : 'false' }; end
226
+ end;
227
+ RbYAML::tag_class tag, self
228
+ end
229
+ # Transforms the subclass name into a name suitable for display
230
+ # in a subclassed tag.
231
+ def yaml_tag_class_name
232
+ self.name
233
+ end
234
+ # Transforms the subclass name found in the tag into a Ruby
235
+ # constant name.
236
+ def yaml_tag_read_class( name )
237
+ name
238
+ end
239
+ end
240
+
241
+ require 'date'
242
+
243
+ class Class
244
+ def to_yaml( opts = {} )
245
+ raise RbYAML::TypeError, "can't dump anonymous class %s" % self.class
246
+ end
247
+ end
248
+
249
+ class Object
250
+ yaml_as "tag:ruby.yaml.org,2002:object"
251
+ def is_complex_yaml?; true; end
252
+ def to_yaml_style; end
253
+ def to_yaml_properties; instance_variables.sort; end
254
+ def to_yaml( opts = {} )
255
+ RbYAML::_dump_ruby_object(self)
256
+ end
257
+ end
258
+
259
+ class Hash
260
+ yaml_as "tag:ruby.yaml.org,2002:hash"
261
+ yaml_as "tag:yaml.org,2002:map"
262
+ def is_complex_yaml?; true; end
263
+ def yaml_initialize( tag, val )
264
+ if Array === val
265
+ update Hash.[]( *val ) # Convert the map to a sequence
266
+ elsif Hash === val
267
+ update val
268
+ else
269
+ raise RbYAML::TypeError, "Invalid map explicitly tagged #{ tag }: " + val.inspect
270
+ end
271
+ end
272
+ end
273
+
274
+ class Array
275
+ yaml_as "tag:ruby.yaml.org,2002:array"
276
+ yaml_as "tag:yaml.org,2002:seq"
277
+ def is_complex_yaml?; true; end
278
+ def yaml_initialize( tag, val ); concat( val.to_a ); end
279
+ end
280
+
281
+ class Exception
282
+ yaml_as "tag:ruby.yaml.org,2002:exception"
283
+ def Exception.yaml_new( klass, tag, val )
284
+ o = RbYAML.object_maker( klass, { 'mesg' => val.delete( 'message' ) } )
285
+ val.each_pair do |k,v|
286
+ o.instance_variable_set("@#{k}", v)
287
+ end
288
+ o
289
+ end
290
+ end
291
+
292
+ class String
293
+ yaml_as "tag:ruby.yaml.org,2002:string"
294
+ yaml_as "tag:yaml.org,2002:binary"
295
+ yaml_as "tag:yaml.org,2002:str"
296
+ def is_complex_yaml?
297
+ to_yaml_style or not to_yaml_properties.empty? or self =~ /\n.+/
298
+ end
299
+ def is_binary_data?
300
+ ( self.count( "^ -~", "^\r\n" ) / self.size > 0.3 || self.count( "\x00" ) > 0 ) unless empty?
301
+ end
302
+ def String.yaml_new( klass, tag, val )
303
+ val = val.unpack("m")[0] if tag == "tag:yaml.org,2002:binary"
304
+ val = { 'str' => val } if String === val
305
+ if Hash === val
306
+ s = klass.allocate
307
+ # Thank you, NaHi
308
+ String.instance_method(:initialize).
309
+ bind(s).
310
+ call( val.delete( 'str' ) )
311
+ val.each { |k,v| s.instance_variable_set( k, v ) }
312
+ s
313
+ else
314
+ raise RbYAML::TypeError, "Invalid String: " + val.inspect
315
+ end
316
+ end
317
+ end
318
+
319
+ class Symbol
320
+ yaml_as "tag:ruby.yaml.org,2002:symbol"
321
+ yaml_as "tag:ruby.yaml.org,2002:sym"
322
+ def is_complex_yaml?; false; end
323
+ def Symbol.yaml_new( klass, tag, val )
324
+ if String === val
325
+ val.intern
326
+ else
327
+ raise RbYAML::TypeError, "Invalid Symbol: " + val.inspect
328
+ end
329
+ end
330
+ end
331
+
332
+ class Time
333
+ yaml_as "tag:ruby.yaml.org,2002:time"
334
+ yaml_as "tag:yaml.org,2002:timestamp"
335
+ def is_complex_yaml?; false; end
336
+ def Time.yaml_new( klass, tag, val )
337
+ if Hash === val
338
+ t = val.delete( 'at' )
339
+ val.each { |k,v| t.instance_variable_set( k, v ) }
340
+ t
341
+ else
342
+ raise RbYAML::TypeError, "Invalid Time: " + val.inspect
343
+ end
344
+ end
345
+ end
346
+
347
+ class Date
348
+ yaml_as "tag:yaml.org,2002:timestamp#ymd"
349
+ def is_complex_yaml?; false; end
350
+ end
351
+
352
+ class Numeric
353
+ def is_complex_yaml?; false; end
354
+ end
355
+
356
+ class Fixnum
357
+ yaml_as "tag:yaml.org,2002:int"
358
+ end
359
+
360
+ class Float
361
+ yaml_as "tag:yaml.org,2002:float"
362
+ end
363
+
364
+ class TrueClass
365
+ yaml_as "tag:yaml.org,2002:bool#yes"
366
+ def is_complex_yaml?; false; end
367
+ end
368
+
369
+ class FalseClass
370
+ yaml_as "tag:yaml.org,2002:bool#no"
371
+ def is_complex_yaml?; false; end
372
+ end
373
+
374
+ class NilClass
375
+ yaml_as "tag:yaml.org,2002:null"
376
+ def is_complex_yaml?; false; end
377
+ end
378
+ end
@@ -0,0 +1,189 @@
1
+ require 'rbyaml/error'
2
+ require 'rbyaml/events'
3
+ require 'rbyaml/nodes'
4
+
5
+ module RbYAML
6
+ class ComposerError < MarkedYAMLError
7
+ end
8
+
9
+ module BaseComposer
10
+ @@yaml_resolvers = {}
11
+
12
+ def initialize_composer
13
+ @all_anchors = {}
14
+ @complete_anchors = {}
15
+ @resolver_tags = []
16
+ @resolver_paths = []
17
+ end
18
+
19
+ def check_node
20
+ !check_event(StreamEndEvent)
21
+ end
22
+
23
+ def get_node
24
+ compose_document if check_node
25
+ end
26
+
27
+ def each_node
28
+ yield compose_document while check_node
29
+ end
30
+
31
+ def compose_document
32
+ # Drop the STREAM-START event.
33
+ get_event if check_event(StreamStartEvent)
34
+ get_event
35
+ # Compose the root node.
36
+ node = compose_node([])
37
+ # Drop the DOCUMENT-END event.
38
+ get_event
39
+ @all_anchors = {}
40
+ @complete_anchors = {}
41
+ @resolver_tags = []
42
+ @resolver_paths = []
43
+ node
44
+ end
45
+
46
+ def increase_resolver_depth(path)
47
+ depth = path.length
48
+ tag = []
49
+ paths = []
50
+ if depth == 0
51
+ for resolver_path in @@yaml_resolvers.keys
52
+ if resolver_path
53
+ paths += resolver_path
54
+ else
55
+ tag = @@yaml_resolvers[resolver_path]
56
+ end
57
+ end
58
+ else
59
+ base, index = path[-1]
60
+ if ScalarNode === index && index.tag == DEFAULT_SCALAR_TAG
61
+ index = index.value
62
+ elsif Node === index
63
+ index = nil
64
+ end
65
+ if @resolver_paths[-1]
66
+ for resolver_path in @resolver_paths[-1]
67
+ resolver_index = resolver_path[depth-1]
68
+ if resolver_index.nil? || resolver_index == index
69
+ if resolver_index.length > depth
70
+ paths += resolver_path
71
+ else
72
+ tag = @@yaml_resolvers[resolver_path]
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ @resolver_tags += tag
80
+ @resolver_paths += paths
81
+ end
82
+
83
+ def decrease_resolver_depth
84
+ @resolver_tags.pop
85
+ @resolver_paths.pop
86
+ end
87
+
88
+ def compose_node(path)
89
+ if check_event(AliasEvent)
90
+ event = get_event
91
+ anchor = event.anchor
92
+ raise ComposerError.new(nil, nil, "found undefined alias #{anchor}", event.start_mark) if !@all_anchors.include?(anchor)
93
+ if !@complete_anchors.include?(anchor)
94
+ collection_event = @all_anchors[anchor]
95
+ raise ComposerError.new("while composing a collection",collection_event.start_mark,"found recursive anchor #{anchor}",event.start_mark)
96
+ end
97
+ return @complete_anchors[anchor]
98
+ end
99
+ increase_resolver_depth(path)
100
+ event = peek_event
101
+ anchor = event.anchor
102
+ if !anchor.nil?
103
+ if @all_anchors.include?(anchor)
104
+ raise ComposerError.new("found duplicate anchor #{anchor}; first occurence", @all_anchors[anchor].start_mark,"second occurence", event.start_mark)
105
+ end
106
+ @all_anchors[anchor] = event
107
+ end
108
+ if check_event(ScalarEvent)
109
+ node = compose_scalar_node(path)
110
+ elsif check_event(SequenceStartEvent)
111
+ node = compose_sequence_node(path)
112
+ elsif check_event(MappingStartEvent)
113
+ node = compose_mapping_node(path)
114
+ end
115
+
116
+ if !anchor.nil?
117
+ @complete_anchors[anchor] = node
118
+ end
119
+ decrease_resolver_depth
120
+ node
121
+ end
122
+
123
+ def compose_scalar_node(path)
124
+ event = get_event
125
+ tag = resolve_scalar(path, event.tag, event.implicit, event.value)
126
+ ScalarNode.new(tag, event.value,event.start_mark, event.end_mark, style=event.style)
127
+ end
128
+
129
+ def compose_sequence_node(path)
130
+ start_event = get_event
131
+ tag = resolve_sequence(path, start_event.tag)
132
+ node = SequenceNode.new(tag, [],start_event.start_mark, nil,flow_style=start_event.flow_style)
133
+ index = 0
134
+ while !check_event(SequenceEndEvent)
135
+ node.value << compose_node(path+[[node, index]])
136
+ index += 1
137
+ end
138
+
139
+ end_event = get_event
140
+ node.end_mark = end_event.end_mark
141
+ node
142
+ end
143
+
144
+ def compose_mapping_node(path)
145
+ start_event = get_event
146
+ tag = resolve_mapping(path, start_event.tag)
147
+ node = MappingNode.new(tag, {},start_event.start_mark, nil,flow_style=start_event.flow_style)
148
+ while !check_event(MappingEndEvent)
149
+ key_event = peek_event
150
+ item_key = compose_node(path+[[node, nil]])
151
+ item_value = compose_node(path+[[node, item_key]])
152
+ if node.value.include?(item_key)
153
+ raise ComposerError.new("while composing a mapping", start_event.start_mark,"found duplicate key", key_event.start_mark)
154
+ end
155
+ node.value[item_key] = item_value
156
+ end
157
+ end_event = get_event
158
+ node.end_mark = end_event.end_mark
159
+ node
160
+ end
161
+
162
+ def resolve_scalar(path, tag, implicit, value)
163
+ tag = detect(value) if implicit
164
+ tag = resolver_tags[-1] if (tag.nil? || tag == []) && @resolver_tags[-1]
165
+ tag = DEFAULT_SCALAR_TAG if tag.nil? || tag == [] || tag == "!"
166
+ tag
167
+ end
168
+
169
+ def resolve_sequence(path, tag)
170
+ tag = resolver_tags[-1] if tag.nil? && @resolver_tags[-1]
171
+ tag = DEFAULT_SEQUENCE_TAG if tag.nil? || tag == "!"
172
+ tag
173
+ end
174
+
175
+ def resolve_mapping(path, tag)
176
+ tag = resolver_tags[-1] if tag.nil? && @resolver_tags[-1]
177
+ tag = DEFAULT_MAPPING_TAG if tag.nil? || tag == "!"
178
+ tag
179
+ end
180
+
181
+ def self.add_resolver(tag, path)
182
+ @@yaml_resolvers[path] = tag
183
+ end
184
+ end
185
+
186
+ module Composer
187
+ include BaseComposer
188
+ end
189
+ end