--- %YAML:1.0 test: Sequence of scalars spec: 2.1 yaml: | - Mark McGwire - Sammy Sosa - Ken Griffey perl: | [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ] python: | [ ['Mark McGwire', 'Sammy Sosa', 'Ken Griffey'] ] ruby: | [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ] syck: | struct test_node seq[] = { { T_STR, 0, "Mark McGwire" }, { T_STR, 0, "Sammy Sosa" }, { T_STR, 0, "Ken Griffey" }, end_node }; struct test_node stream[] = { { T_SEQ, 0, 0, seq }, end_node }; --- test: Mapping of scalars to scalars spec: 2.2 yaml: | hr: 65 avg: 0.278 rbi: 147 perl: | { hr => 65, avg => 0.278, rbi => 147 } python: | [ {'hr': 65, 'avg': .278, 'rbi': 147} ] ruby: | { 'hr' => 65, 'avg' => 0.278, 'rbi' => 147 } syck: | struct test_node map[] = { { T_STR, 0, "hr" }, { T_STR, 0, "65" }, { T_STR, 0, "avg" }, { T_STR, 0, "0.278" }, { T_STR, 0, "rbi" }, { T_STR, 0, "147" }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Mapping of scalars to sequences spec: 2.3 yaml: | american: - Boston Red Sox - Detroit Tigers - New York Yankees national: - New York Mets - Chicago Cubs - Atlanta Braves perl: | { american => [ 'Boston Red Sox', 'Detroit Tigers', 'New York Yankees' ], national => [ 'New York Mets', 'Chicago Cubs', 'Atlanta Braves' ] } python: | [ { 'american': ['Boston Red Sox', 'Detroit Tigers', 'New York Yankees'], 'national': ['New York Mets', 'Chicago Cubs', 'Atlanta Braves'] } ] ruby: | { 'american' => [ 'Boston Red Sox', 'Detroit Tigers', 'New York Yankees' ], 'national' => [ 'New York Mets', 'Chicago Cubs', 'Atlanta Braves' ] } syck: | struct test_node seq1[] = { { T_STR, 0, "Boston Red Sox" }, { T_STR, 0, "Detroit Tigers" }, { T_STR, 0, "New York Yankees" }, end_node }; struct test_node seq2[] = { { T_STR, 0, "New York Mets" }, { T_STR, 0, "Chicago Cubs" }, { T_STR, 0, "Atlanta Braves" }, end_node }; struct test_node map[] = { { T_STR, 0, "american" }, { T_SEQ, 0, 0, seq1 }, { T_STR, 0, "national" }, { T_SEQ, 0, 0, seq2 }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Sequence of mappings spec: 2.4 yaml: | - name: Mark McGwire hr: 65 avg: 0.278 - name: Sammy Sosa hr: 63 avg: 0.288 perl: | [ {name => 'Mark McGwire', hr => 65, avg => 0.278}, {name => 'Sammy Sosa', hr => 63, avg => 0.288} ] python: | [[ { 'name': 'Mark McGwire', 'hr': 65, 'avg': 0.278 }, { 'name': 'Sammy Sosa', 'hr': 63, 'avg': 0.288 } ]] ruby: | [ {'name' => 'Mark McGwire', 'hr' => 65, 'avg' => 0.278}, {'name' => 'Sammy Sosa', 'hr' => 63, 'avg' => 0.288} ] syck: | struct test_node map1[] = { { T_STR, 0, "name" }, { T_STR, 0, "Mark McGwire" }, { T_STR, 0, "hr" }, { T_STR, 0, "65" }, { T_STR, 0, "avg" }, { T_STR, 0, "0.278" }, end_node }; struct test_node map2[] = { { T_STR, 0, "name" }, { T_STR, 0, "Sammy Sosa" }, { T_STR, 0, "hr" }, { T_STR, 0, "63" }, { T_STR, 0, "avg" }, { T_STR, 0, "0.288" }, end_node }; struct test_node seq[] = { { T_MAP, 0, 0, map1 }, { T_MAP, 0, 0, map2 }, end_node }; struct test_node stream[] = { { T_SEQ, 0, 0, seq }, end_node }; --- test: Legacy A5 spec: legacy_A5 yaml: | ? - New York Yankees - Atlanta Braves : - 2001-07-02 - 2001-08-12 - 2001-08-14 ? - Detroit Tigers - Chicago Cubs : - 2001-07-23 perl-busted: > YAML.pm will be able to emulate this behavior soon. In this regard it may be somewhat more correct than Python's native behaviour which can only use tuples as mapping keys. PyYAML will also need to figure out some clever way to roundtrip structured keys. python: | [ { ('New York Yankees', 'Atlanta Braves'): [yaml.timestamp('2001-07-02'), yaml.timestamp('2001-08-12'), yaml.timestamp('2001-08-14')], ('Detroit Tigers', 'Chicago Cubs'): [yaml.timestamp('2001-07-23')] } ] ruby: | { [ 'New York Yankees', 'Atlanta Braves' ] => [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ], [ 'Detroit Tigers', 'Chicago Cubs' ] => [ Date.new( 2001, 7, 23 ) ] } syck: | struct test_node seq1[] = { { T_STR, 0, "New York Yankees" }, { T_STR, 0, "Atlanta Braves" }, end_node }; struct test_node seq2[] = { { T_STR, 0, "2001-07-02" }, { T_STR, 0, "2001-08-12" }, { T_STR, 0, "2001-08-14" }, end_node }; struct test_node seq3[] = { { T_STR, 0, "Detroit Tigers" }, { T_STR, 0, "Chicago Cubs" }, end_node }; struct test_node seq4[] = { { T_STR, 0, "2001-07-23" }, end_node }; struct test_node map[] = { { T_SEQ, 0, 0, seq1 }, { T_SEQ, 0, 0, seq2 }, { T_SEQ, 0, 0, seq3 }, { T_SEQ, 0, 0, seq4 }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Sequence of sequences spec: 2.5 yaml: | - [ name , hr , avg ] - [ Mark McGwire , 65 , 0.278 ] - [ Sammy Sosa , 63 , 0.288 ] perl: | [ [ 'name', 'hr', 'avg' ], [ 'Mark McGwire', 65, 0.278 ], [ 'Sammy Sosa', 63, 0.288 ], ] python: | [[ [ 'name', 'hr', 'avg' ], [ 'Mark McGwire', 65, 0.278 ], [ 'Sammy Sosa', 63, 0.288 ] ]] ruby: | [ [ 'name', 'hr', 'avg' ], [ 'Mark McGwire', 65, 0.278 ], [ 'Sammy Sosa', 63, 0.288 ] ] syck: | struct test_node seq1[] = { { T_STR, 0, "name" }, { T_STR, 0, "hr" }, { T_STR, 0, "avg" }, end_node }; struct test_node seq2[] = { { T_STR, 0, "Mark McGwire" }, { T_STR, 0, "65" }, { T_STR, 0, "0.278" }, end_node }; struct test_node seq3[] = { { T_STR, 0, "Sammy Sosa" }, { T_STR, 0, "63" }, { T_STR, 0, "0.288" }, end_node }; struct test_node seq[] = { { T_SEQ, 0, 0, seq1 }, { T_SEQ, 0, 0, seq2 }, { T_SEQ, 0, 0, seq3 }, end_node }; struct test_node stream[] = { { T_SEQ, 0, 0, seq }, end_node }; --- test: Mapping of mappings spec: 2.6 yaml: | Mark McGwire: {hr: 65, avg: 0.278} Sammy Sosa: { hr: 63, avg: 0.288 } perl-xxx: | { 'Mark McGwire' => { 'hr' => 65, 'avg' => 0.278 }, 'Sammy Sosa' => { 'hr' => 63, 'avg' => 0.288 }, } not_yet_in_python: | [{ 'Mark McGwire': { 'hr': 65, 'avg': 0.278 }, 'Sammy Sosa': { 'hr': 63, 'avg': 0.288 } }] ruby: | { 'Mark McGwire' => { 'hr' => 65, 'avg' => 0.278 }, 'Sammy Sosa' => { 'hr' => 63, 'avg' => 0.288 } } syck: | struct test_node map1[] = { { T_STR, 0, "hr" }, { T_STR, 0, "65" }, { T_STR, 0, "avg" }, { T_STR, 0, "0.278" }, end_node }; struct test_node map2[] = { { T_STR, 0, "hr" }, { T_STR, 0, "63" }, { T_STR, 0, "avg" }, { T_STR, 0, "0.288" }, end_node }; struct test_node map[] = { { T_STR, 0, "Mark McGwire" }, { T_MAP, 0, 0, map1 }, { T_STR, 0, "Sammy Sosa" }, { T_MAP, 0, 0, map2 }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Two documents in a stream each with a leading comment spec: 2.7 yaml: | # Ranking of 1998 home runs --- - Mark McGwire - Sammy Sosa - Ken Griffey # Team ranking --- - Chicago Cubs - St Louis Cardinals perl: | { name => 'Mark McGwire', 'hr' => 65, 'avg' => 0.278 }, { name => 'Sammy Sosa', 'hr' => 63, 'avg' => 0.288 } python: | [ { 'name': 'Mark McGwire', 'hr': 65, 'avg': 0.278 }, { 'name': 'Sammy Sosa', 'hr': 63, 'avg': 0.288 } ] ruby: | y = YAML::Stream.new y.add( [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ] ) y.add( [ 'Chicago Cubs', 'St Louis Cardinals' ] ) syck: | struct test_node seq1[] = { { T_STR, 0, "Mark McGwire" }, { T_STR, 0, "Sammy Sosa" }, { T_STR, 0, "Ken Griffey" }, end_node }; struct test_node seq2[] = { { T_STR, 0, "Chicago Cubs" }, { T_STR, 0, "St Louis Cardinals" }, end_node }; struct test_node stream[] = { { T_SEQ, 0, 0, seq1 }, { T_SEQ, 0, 0, seq2 }, end_node }; documents: 2 --- test: Play by play feed from a game spec: 2.8 yaml: | --- time: 20:03:20 player: Sammy Sosa action: strike (miss) ... --- time: 20:03:47 player: Sammy Sosa action: grand slam ... perl: | [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ] python: | [[ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ]] ruby: | y = YAML::Stream.new y.add( {"player"=>"Sammy Sosa", "time"=>72200, "action"=>"strike (miss)"} ) y.add( {"player"=>"Sammy Sosa", "time"=>72227, "action"=>"grand slam"} ) syck: | struct test_node map1[] = { { T_STR, 0, "time" }, { T_STR, 0, "20:03:20" }, { T_STR, 0, "player" }, { T_STR, 0, "Sammy Sosa" }, { T_STR, 0, "action" }, { T_STR, 0, "strike (miss)" }, end_node }; struct test_node map2[] = { { T_STR, 0, "time" }, { T_STR, 0, "20:03:47" }, { T_STR, 0, "player" }, { T_STR, 0, "Sammy Sosa" }, { T_STR, 0, "action" }, { T_STR, 0, "grand slam" }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map1 }, { T_MAP, 0, 0, map2 }, end_node }; documents: 2 --- test: Single document with two comments spec: 2.9 yaml: | hr: # 1998 hr ranking - Mark McGwire - Sammy Sosa rbi: # 1998 rbi ranking - Sammy Sosa - Ken Griffey perl-xxx: | { 'hr' => [ 'Mark McGwire', 'Sammy Sosa' ], 'rbi' => [ 'Sammy Sosa', 'Ken Griffey' ] } python: | [{ 'hr': [ 'Mark McGwire', 'Sammy Sosa' ], 'rbi': [ 'Sammy Sosa', 'Ken Griffey' ] }] ruby: | { 'hr' => [ 'Mark McGwire', 'Sammy Sosa' ], 'rbi' => [ 'Sammy Sosa', 'Ken Griffey' ] } syck: | struct test_node seq1[] = { { T_STR, 0, "Mark McGwire" }, { T_STR, 0, "Sammy Sosa" }, end_node }; struct test_node seq2[] = { { T_STR, 0, "Sammy Sosa" }, { T_STR, 0, "Ken Griffey" }, end_node }; struct test_node map[] = { { T_STR, 0, "hr" }, { T_SEQ, 0, 0, seq1 }, { T_STR, 0, "rbi" }, { T_SEQ, 0, 0, seq2 }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Node for Sammy Sosa appears twice in this document spec: 2.10 yaml: | --- hr: - Mark McGwire # Following node labeled SS - &SS Sammy Sosa rbi: - *SS # Subsequent occurance - Ken Griffey perl: | { 'hr' => [ 'Mark McGwire', 'Sammy Sosa' ], 'rbi' => [ 'Sammy Sosa', 'Ken Griffey' ] } python: | [{ 'hr': [ 'Mark McGwire', 'Sammy Sosa' ], 'rbi': [ 'Sammy Sosa', 'Ken Griffey' ] }] ruby: | { 'hr' => [ 'Mark McGwire', 'Sammy Sosa' ], 'rbi' => [ 'Sammy Sosa', 'Ken Griffey' ] } syck: | struct test_node seq1[] = { { T_STR, 0, "Mark McGwire" }, { T_STR, 0, "Sammy Sosa" }, end_node }; struct test_node seq2[] = { { T_STR, 0, "Sammy Sosa" }, { T_STR, 0, "Ken Griffey" }, end_node }; struct test_node map[] = { { T_STR, 0, "hr" }, { T_SEQ, 0, 0, seq1 }, { T_STR, 0, "rbi" }, { T_SEQ, 0, 0, seq2 }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Mapping between sequences spec: 2.11 yaml: | ? # PLAY SCHEDULE - Detroit Tigers - Chicago Cubs : - 2001-07-23 ? [ New York Yankees, Atlanta Braves ] : [ 2001-07-02, 2001-08-12, 2001-08-14 ] ruby: | { [ 'Detroit Tigers', 'Chicago Cubs' ] => [ Date.new( 2001, 7, 23 ) ], [ 'New York Yankees', 'Atlanta Braves' ] => [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ] } syck: | struct test_node seq1[] = { { T_STR, 0, "New York Yankees" }, { T_STR, 0, "Atlanta Braves" }, end_node }; struct test_node seq2[] = { { T_STR, 0, "2001-07-02" }, { T_STR, 0, "2001-08-12" }, { T_STR, 0, "2001-08-14" }, end_node }; struct test_node seq3[] = { { T_STR, 0, "Detroit Tigers" }, { T_STR, 0, "Chicago Cubs" }, end_node }; struct test_node seq4[] = { { T_STR, 0, "2001-07-23" }, end_node }; struct test_node map[] = { { T_SEQ, 0, 0, seq3 }, { T_SEQ, 0, 0, seq4 }, { T_SEQ, 0, 0, seq1 }, { T_SEQ, 0, 0, seq2 }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Sequence key shortcut spec: 2.12 yaml: | --- # products purchased - item : Super Hoop quantity: 1 - item : Basketball quantity: 4 - item : Big Shoes quantity: 1 perl: | [ { item => 'Super Hoop', quantity => 1 }, { item => 'Basketball', quantity => 4 }, { item => 'Big Shoes', quantity => 1 } ] ruby: | [ { 'item' => 'Super Hoop', 'quantity' => 1 }, { 'item' => 'Basketball', 'quantity' => 4 }, { 'item' => 'Big Shoes', 'quantity' => 1 } ] python: | [ { 'item': 'Super Hoop', 'quantity': 1 }, { 'item': 'Basketball', 'quantity': 4 }, { 'item': 'Big Shoes', 'quantity': 1 } ] syck: | struct test_node map1[] = { { T_STR, 0, "item" }, { T_STR, 0, "Super Hoop" }, { T_STR, 0, "quantity" }, { T_STR, 0, "1" }, end_node }; struct test_node map2[] = { { T_STR, 0, "item" }, { T_STR, 0, "Basketball" }, { T_STR, 0, "quantity" }, { T_STR, 0, "4" }, end_node }; struct test_node map3[] = { { T_STR, 0, "item" }, { T_STR, 0, "Big Shoes" }, { T_STR, 0, "quantity" }, { T_STR, 0, "1" }, end_node }; struct test_node seq[] = { { T_MAP, 0, 0, map1 }, { T_MAP, 0, 0, map2 }, { T_MAP, 0, 0, map3 }, end_node }; struct test_node stream[] = { { T_SEQ, 0, 0, seq }, end_node }; --- test: Literal perserves newlines spec: 2.13 yaml: | # ASCII Art --- | \//||\/|| // || ||_ perl: | "\\//||\\/||\n// || ||_\n" ruby: | "\\//||\\/||\n// || ||_\n" python: | [ flushLeft( """ \//||\/|| // || ||_ """ ) ] syck: | struct test_node stream[] = { { T_STR, 0, "\\//||\\/||\n// || ||_\n" }, end_node }; --- test: Folded treats newlines as a space spec: 2.14 yaml: | --- Mark McGwire's year was crippled by a knee injury. perl: | "Mark McGwire's year was crippled by a knee injury." ruby: | "Mark McGwire's year was crippled by a knee injury." python: | [ "Mark McGwire's year was crippled by a knee injury." ] syck: | struct test_node stream[] = { { T_STR, 0, "Mark McGwire's year was crippled by a knee injury." }, end_node }; --- test: Newlines preserved for indented and blank lines spec: 2.15 yaml: | --- > Sammy Sosa completed another fine season with great stats. 63 Home Runs 0.288 Batting Average What a year! perl: | "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n" ruby: | "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n" python: | [ flushLeft( """ Sammy Sosa completed another fine season with great stats. 63 Home Runs 0.288 Batting Average What a year! """ ) ] syck: | struct test_node stream[] = { { T_STR, 0, "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n" }, end_node }; --- test: Indentation determines scope spec: 2.16 yaml: | name: Mark McGwire accomplishment: > Mark set a major league home run record in 1998. stats: | 65 Home Runs 0.278 Batting Average perl: | { name => 'Mark McGwire', accomplishment => "Mark set a major league home run record in 1998.\n", stats => "65 Home Runs\n0.278 Batting Average\n" } ruby: | { 'name' => 'Mark McGwire', 'accomplishment' => "Mark set a major league home run record in 1998.\n", 'stats' => "65 Home Runs\n0.278 Batting Average\n" } python: | [ { 'name': 'Mark McGwire', 'accomplishment': 'Mark set a major league home run record in 1998.\n', 'stats': "65 Home Runs\n0.278 Batting Average\n" } ] syck: | struct test_node map[] = { { T_STR, 0, "name" }, { T_STR, 0, "Mark McGwire" }, { T_STR, 0, "accomplishment" }, { T_STR, 0, "Mark set a major league home run record in 1998.\n" }, { T_STR, 0, "stats" }, { T_STR, 0, "65 Home Runs\n0.278 Batting Average\n" }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Quoted scalars spec: 2.17 yaml: | unicode: "Sosa did fine.\u263A" control: "\b1998\t1999\t2000\n" hexesc: "\x0D\x0A is \r\n" single: '"Howdy!" he cried.' quoted: ' # not a ''comment''.' tie-fighter: '|\-*-/|' perl-not-working: | { unicode => "Sosa did fine.\x{263A}", control => "\x081998\t1999\t2000\n", hexesc => "\r\n is \r\n", single => '"Howdy!" he cried.', quoted => " # not a 'comment'.", "tie-fighter" => '|\\-*-/|', } ruby: | { "tie-fighter" => "|\\-*-/|", "control"=>"\0101998\t1999\t2000\n", "unicode"=>"Sosa did fine." + ["263A".hex ].pack('U*'), "quoted"=>" # not a 'comment'.", "single"=>"\"Howdy!\" he cried.", "hexesc"=>"\r\n is \r\n" } python: | [ { 'unicode': u"Sosa did fine.\u263A", 'control': "\b1998\t1999\t2000\n", 'hexesc': "\x0D\x0A is \r\n", 'single': '"Howdy!" he cried.', 'quoted': ' # not a \'comment\'.', 'tie-fighter': '|\-*-/|', } ] --- test: Multiline flow scalars spec: 2.18 yaml: | plain: This unquoted scalar spans many lines. quoted: "So does this quoted scalar.\n" perl-not-working: | { plain => 'This unquoted scalar spans many lines.', quoted => "So does this quoted scalar.\n" } ruby: | { 'plain' => 'This unquoted scalar spans many lines.', 'quoted' => "So does this quoted scalar.\n" } python: | [ { 'plain': 'This unquoted scalar spans many lines.', 'quoted': 'So does this quoted scalar.\n' } ] syck: | struct test_node map[] = { { T_STR, 0, "plain" }, { T_STR, 0, "This unquoted scalar spans many lines." }, { T_STR, 0, "quoted" }, { T_STR, 0, "So does this quoted scalar.\n" }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Integers spec: 2.19 yaml: | canonical: 12345 decimal: +12,345 sexagecimal: 3:25:45 octal: 014 hexadecimal: 0xC perl: | { canonical => 12345, decimal => 12345, octal => oct("014"), hexadecimal => hex("0xC"), } ruby: | { 'canonical' => 12345, 'decimal' => 12345, 'sexagecimal' => 12345, 'octal' => '014'.oct, 'hexadecimal' => '0xC'.hex } python: | [ { 'canonical': 12345, 'decimal': 12345, 'octal': 014, 'hexadecimal': 0xC } ] syck: | struct test_node map[] = { { T_STR, 0, "canonical" }, { T_STR, 0, "12345" }, { T_STR, 0, "decimal" }, { T_STR, 0, "+12,345" }, { T_STR, 0, "sexagecimal" }, { T_STR, 0, "3:25:45" }, { T_STR, 0, "octal" }, { T_STR, 0, "014" }, { T_STR, 0, "hexadecimal" }, { T_STR, 0, "0xC" }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- # FIX: spec shows parens around -inf and NaN test: Floating point spec: 2.20 yaml: | canonical: 1.23015e+3 exponential: 12.3015e+02 sexagecimal: 20:30.15 fixed: 1,230.15 negative infinity: -.inf not a number: .NaN perl: | { 'canonical' => 1230.15, 'exponential' => 1230.15, 'fixed' => 1230.15, 'negative infinity' => "-.inf", 'not a number' => ".NaN", } ruby: | { 'canonical' => 1230.15, 'exponential' => 1230.15, 'sexagecimal' => 1230.15, 'fixed' => 1230.15, 'negative infinity' => -1.0/0.0, 'not a number' => 0.0/0.0 } if obj_y['not a number'].nan? # NaN comparison doesn't work right against 0.0/0.0 obj_r['not a number'] = obj_y['not a number'] end python: | [ { 'canonical': 1.23015e+3, 'exponential': 1.23015e+3, 'fixed': 1230.15, 'negative infinity': '-.inf', 'not a number': '.NaN', } ] syck: | struct test_node map[] = { { T_STR, 0, "canonical" }, { T_STR, 0, "1.23015e+3" }, { T_STR, 0, "exponential" }, { T_STR, 0, "12.3015e+02" }, { T_STR, 0, "sexagecimal" }, { T_STR, 0, "20:30.15" }, { T_STR, 0, "fixed" }, { T_STR, 0, "1,230.15" }, { T_STR, 0, "negative infinity" }, { T_STR, 0, "-.inf" }, { T_STR, 0, "not a number" }, { T_STR, 0, ".NaN" }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Miscellaneous spec: 2.21 yaml: | null: ~ true: y false: n string: '12345' perl: | { null => undef, true => 1, false => 0, string => "12345" } ruby: | { nil => nil, true => true, false => false, 'string' => '12345' } python: | [ { 'null': None, 'true': 1, 'false': 0, 'string': '12345', } ] syck: | struct test_node map[] = { { T_STR, 0, "null" }, { T_STR, 0, "~" }, { T_STR, 0, "true" }, { T_STR, 0, "y" }, { T_STR, 0, "false" }, { T_STR, 0, "n" }, { T_STR, 0, "string" }, { T_STR, 0, "12345" }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Timestamps spec: 2.22 yaml: | canonical: 2001-12-15T02:59:43.1Z iso8601: 2001-12-14t21:59:43.10-05:00 spaced: 2001-12-14 21:59:43.10 -05:00 date: 2002-12-14 # Time is noon UTC perl: | { canonical => "2001-12-15T02:59:43.1Z", iso8601 => "2001-12-14t21:59:43.10-05:00", spaced => "2001-12-14 21:59:43.10 -05:00", date => "2002-12-14", } ruby: | { 'canonical' => YAML::mktime( 2001, 12, 15, 2, 59, 43, 0.10 ), 'iso8601' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), 'spaced' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), 'date' => Date.new( 2002, 12, 14 ) } syck: | struct test_node map[] = { { T_STR, 0, "canonical" }, { T_STR, 0, "2001-12-15T02:59:43.1Z" }, { T_STR, 0, "iso8601" }, { T_STR, 0, "2001-12-14t21:59:43.10-05:00" }, { T_STR, 0, "spaced" }, { T_STR, 0, "2001-12-14 21:59:43.10 -05:00" }, { T_STR, 0, "date" }, { T_STR, 0, "2002-12-14" }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: legacy Timestamps test spec: legacy D4 yaml: | canonical: 2001-12-15T02:59:43.00Z iso8601: 2001-02-28t21:59:43.00-05:00 spaced: 2001-12-14 21:59:43.00 -05:00 date: 2002-12-14 python: | [ { 'canonical': yaml.timestamp('2001-12-15T02:59:43.00Z'), 'iso8601': yaml.timestamp('2001-03-01T02:59:43.00Z'), 'spaced': yaml.timestamp('2001-12-15T02:59:43.00Z'), 'date': yaml.timestamp('2002-12-14T00:00:00.00Z') } ] ruby: | { 'canonical' => Time::utc( 2001, 12, 15, 2, 59, 43, 0 ), 'iso8601' => YAML::mktime( 2001, 2, 28, 21, 59, 43, 0, "-05:00" ), 'spaced' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0, "-05:00" ), 'date' => Date.new( 2002, 12, 14 ) } syck: | struct test_node map[] = { { T_STR, 0, "canonical" }, { T_STR, 0, "2001-12-15T02:59:43.00Z" }, { T_STR, 0, "iso8601" }, { T_STR, 0, "2001-02-28t21:59:43.00-05:00" }, { T_STR, 0, "spaced" }, { T_STR, 0, "2001-12-14 21:59:43.00 -05:00" }, { T_STR, 0, "date" }, { T_STR, 0, "2002-12-14" }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Various explicit families spec: 2.23 yaml: | not-date: !str 2002-04-28 picture: !binary | R0lGODlhDAAMAIQAAP//9/X 17unp5WZmZgAAAOfn515eXv Pz7Y6OjuDg4J+fn5OTk6enp 56enmleECcgggoBADs= application specific tag: !!something | The semantics of the tag above may be different for different documents. ruby-setup: | YAML.add_private_type( "something" ) do |type, val| "SOMETHING: #{val}" end ruby: | { 'not-date' => '2002-04-28', 'picture' => "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236i^\020' \202\n\001\000;", 'application specific tag' => "SOMETHING: The semantics of the tag\nabove may be different for\ndifferent documents.\n" } syck: | struct test_node map[] = { { T_STR, 0, "not-date" }, { T_STR, "tag:yaml.org,2002:str", "2002-04-28" }, { T_STR, 0, "picture" }, { T_STR, "tag:yaml.org,2002:binary", "R0lGODlhDAAMAIQAAP//9/X\n17unp5WZmZgAAAOfn515eXv\nPz7Y6OjuDg4J+fn5OTk6enp\n56enmleECcgggoBADs=\n" }, { T_STR, 0, "application specific tag" }, { T_STR, "x-private:something", "The semantics of the tag\nabove may be different for\ndifferent documents.\n" }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Application specific family spec: 2.24 yaml: | # Establish a tag prefix --- !clarkevans.com,2002/graph/^shape # Use the prefix: shorthand for # !clarkevans.com,2002/graph/circle - !^circle center: &ORIGIN {x: 73, 'y': 129} radius: 7 - !^line # !clarkevans.com,2002/graph/line start: *ORIGIN finish: { x: 89, 'y': 102 } - !^label start: *ORIGIN color: 0xFFEEBB value: Pretty vector drawing. ruby-setup: | YAML.add_domain_type( "clarkevans.com,2002", 'graph/shape' ) { |type, val| if Array === val val << "Shape Container" val else raise YAML::Error, "Invalid graph of class #{ val.class }: " + val.inspect end } one_shape_proc = Proc.new { |type, val| scheme, domain, type = type.split( /:/, 3 ) if val.is_a? ::Hash val['TYPE'] = "Shape: #{type}" val else raise YAML::Error, "Invalid graph of class #{ val.class }: " + val.inspect end } YAML.add_domain_type( "clarkevans.com,2002", 'graph/circle', &one_shape_proc ) YAML.add_domain_type( "clarkevans.com,2002", 'graph/line', &one_shape_proc ) YAML.add_domain_type( "clarkevans.com,2002", 'graph/label', &one_shape_proc ) ruby: | [ { "radius" => 7, "center"=> { "x" => 73, "y" => 129 }, "TYPE" => "Shape: graph/circle" }, { "finish" => { "x" => 89, "y" => 102 }, "TYPE" => "Shape: graph/line", "start" => { "x" => 73, "y" => 129 } }, { "TYPE" => "Shape: graph/label", "value" => "Pretty vector drawing.", "start" => { "x" => 73, "y" => 129 }, "color" => 16772795 }, "Shape Container" ] syck: | struct test_node point1[] = { { T_STR, 0, "x" }, { T_STR, 0, "73" }, { T_STR, 0, "y" }, { T_STR, 0, "129" }, end_node }; struct test_node point2[] = { { T_STR, 0, "x" }, { T_STR, 0, "89" }, { T_STR, 0, "y" }, { T_STR, 0, "102" }, end_node }; struct test_node map1[] = { { T_STR, 0, "center" }, { T_MAP, 0, 0, point1 }, { T_STR, 0, "radius" }, { T_STR, 0, "7" }, end_node }; struct test_node map2[] = { { T_STR, 0, "start" }, { T_MAP, 0, 0, point1 }, { T_STR, 0, "finish" }, { T_MAP, 0, 0, point2 }, end_node }; struct test_node map3[] = { { T_STR, 0, "start" }, { T_MAP, 0, 0, point1 }, { T_STR, 0, "color" }, { T_STR, 0, "0xFFEEBB" }, { T_STR, 0, "value" }, { T_STR, 0, "Pretty vector drawing." }, end_node }; struct test_node seq[] = { { T_MAP, "tag:clarkevans.com,2002:graph/circle", 0, map1 }, { T_MAP, "tag:clarkevans.com,2002:graph/line", 0, map2 }, { T_MAP, "tag:clarkevans.com,2002:graph/label", 0, map3 }, end_node }; struct test_node stream[] = { { T_SEQ, "tag:clarkevans.com,2002:graph/shape", 0, seq }, end_node }; # --- # test: Unordered set # spec: 2.25 # yaml: | # # sets are represented as a # # mapping where each key is # # associated with the empty string # --- !set # ? Mark McGwire # ? Sammy Sosa # ? Ken Griff --- test: Ordered mappings spec: 2.26 yaml: | # ordered maps are represented as # a sequence of mappings, with # each mapping having one key --- !omap - Mark McGwire: 65 - Sammy Sosa: 63 - Ken Griffy: 58 ruby: | YAML::Omap[ 'Mark McGwire', 65, 'Sammy Sosa', 63, 'Ken Griffy', 58 ] syck: | struct test_node map1[] = { { T_STR, 0, "Mark McGwire" }, { T_STR, 0, "65" }, end_node }; struct test_node map2[] = { { T_STR, 0, "Sammy Sosa" }, { T_STR, 0, "63" }, end_node }; struct test_node map3[] = { { T_STR, 0, "Ken Griffy" }, { T_STR, 0, "58" }, end_node }; struct test_node seq[] = { { T_MAP, 0, 0, map1 }, { T_MAP, 0, 0, map2 }, { T_MAP, 0, 0, map3 }, end_node }; struct test_node stream[] = { { T_SEQ, "tag:yaml.org,2002:omap", 0, seq }, end_node }; --- test: Invoice spec: 2.27 yaml: | --- !clarkevans.com,2002/^invoice invoice: 34843 date : 2001-01-23 bill-to: &id001 given : Chris family : Dumars address: lines: | 458 Walkman Dr. Suite #292 city : Royal Oak state : MI postal : 48046 ship-to: *id001 product: - sku : BL394D quantity : 4 description : Basketball price : 450.00 - sku : BL4438H quantity : 1 description : Super Hoop price : 2392.00 tax : 251.42 total: 4443.52 comments: > Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338. ruby-setup: | YAML.add_domain_type( "clarkevans.com,2002", "invoice" ) { |type, val| val } id001 = { 'given' => 'Chris', 'family' => 'Dumars', 'address' => { 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak', 'state' => 'MI', 'postal' => 48046 } } ruby: | { 'invoice' => 34843, 'date' => Date.new( 2001, 1, 23 ), 'bill-to' => id001, 'ship-to' => id001, 'product' => [ { 'sku' => 'BL394D', 'quantity' => 4, 'description' => 'Basketball', 'price' => 450.00 }, { 'sku' => 'BL4438H', 'quantity' => 1, 'description' => 'Super Hoop', 'price' => 2392.00 } ], 'tax' => 251.42, 'total' => 4443.52, 'comments' => "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.\n" } syck: | struct test_node prod1[] = { { T_STR, 0, "sku" }, { T_STR, 0, "BL394D" }, { T_STR, 0, "quantity" }, { T_STR, 0, "4" }, { T_STR, 0, "description" }, { T_STR, 0, "Basketball" }, { T_STR, 0, "price" }, { T_STR, 0, "450.00" }, end_node }; struct test_node prod2[] = { { T_STR, 0, "sku" }, { T_STR, 0, "BL4438H" }, { T_STR, 0, "quantity" }, { T_STR, 0, "1" }, { T_STR, 0, "description" }, { T_STR, 0, "Super Hoop" }, { T_STR, 0, "price" }, { T_STR, 0, "2392.00" }, end_node }; struct test_node products[] = { { T_MAP, 0, 0, prod1 }, { T_MAP, 0, 0, prod2 }, end_node }; struct test_node address[] = { { T_STR, 0, "lines" }, { T_STR, 0, "458 Walkman Dr.\nSuite #292\n" }, { T_STR, 0, "city" }, { T_STR, 0, "Royal Oak" }, { T_STR, 0, "state" }, { T_STR, 0, "MI" }, { T_STR, 0, "postal" }, { T_STR, 0, "48046" }, end_node }; struct test_node id001[] = { { T_STR, 0, "given" }, { T_STR, 0, "Chris" }, { T_STR, 0, "family" }, { T_STR, 0, "Dumars" }, { T_STR, 0, "address" }, { T_MAP, 0, 0, address }, end_node }; struct test_node map[] = { { T_STR, 0, "invoice" }, { T_STR, 0, "34843" }, { T_STR, 0, "date" }, { T_STR, 0, "2001-01-23" }, { T_STR, 0, "bill-to" }, { T_MAP, 0, 0, id001 }, { T_STR, 0, "ship-to" }, { T_MAP, 0, 0, id001 }, { T_STR, 0, "product" }, { T_SEQ, 0, 0, products }, { T_STR, 0, "tax" }, { T_STR, 0, "251.42" }, { T_STR, 0, "total" }, { T_STR, 0, "4443.52" }, { T_STR, 0, "comments" }, { T_STR, 0, "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.\n" }, end_node }; struct test_node stream[] = { { T_MAP, "tag:clarkevans.com,2002:invoice", 0, map }, end_node }; --- test: Log file spec: 2.28 yaml: | --- Time: 2001-11-23 15:01:42 -05:00 User: ed Warning: > This is an error message for the log file --- Time: 2001-11-23 15:02:31 -05:00 User: ed Warning: > A slightly different error message. --- Date: 2001-11-23 15:03:17 -05:00 User: ed Fatal: > Unknown variable "bar" Stack: - file: TopClass.py line: 23 code: | x = MoreObject("345\n") - file: MoreClass.py line: 58 code: |- foo = bar ruby: | y = YAML::Stream.new y.add( { 'Time' => YAML::mktime( 2001, 11, 23, 15, 01, 42, 00, "-05:00" ), 'User' => 'ed', 'Warning' => "This is an error message for the log file\n" } ) y.add( { 'Time' => YAML::mktime( 2001, 11, 23, 15, 02, 31, 00, "-05:00" ), 'User' => 'ed', 'Warning' => "A slightly different error message.\n" } ) y.add( { 'Date' => YAML::mktime( 2001, 11, 23, 15, 03, 17, 00, "-05:00" ), 'User' => 'ed', 'Fatal' => "Unknown variable \"bar\"\n", 'Stack' => [ { 'file' => 'TopClass.py', 'line' => 23, 'code' => "x = MoreObject(\"345\\n\")\n" }, { 'file' => 'MoreClass.py', 'line' => 58, 'code' => "foo = bar" } ] } ) syck: | struct test_node map1[] = { { T_STR, 0, "Time" }, { T_STR, 0, "2001-11-23 15:01:42 -05:00" }, { T_STR, 0, "User" }, { T_STR, 0, "ed" }, { T_STR, 0, "Warning" }, { T_STR, 0, "This is an error message for the log file\n" }, end_node }; struct test_node map2[] = { { T_STR, 0, "Time" }, { T_STR, 0, "2001-11-23 15:02:31 -05:00" }, { T_STR, 0, "User" }, { T_STR, 0, "ed" }, { T_STR, 0, "Warning" }, { T_STR, 0, "A slightly different error message.\n" }, end_node }; struct test_node file1[] = { { T_STR, 0, "file" }, { T_STR, 0, "TopClass.py" }, { T_STR, 0, "line" }, { T_STR, 0, "23" }, { T_STR, 0, "code" }, { T_STR, 0, "x = MoreObject(\"345\\n\")\n" }, end_node }; struct test_node file2[] = { { T_STR, 0, "file" }, { T_STR, 0, "MoreClass.py" }, { T_STR, 0, "line" }, { T_STR, 0, "58" }, { T_STR, 0, "code" }, { T_STR, 0, "foo = bar" }, end_node }; struct test_node stack[] = { { T_MAP, 0, 0, file1 }, { T_MAP, 0, 0, file2 }, end_node }; struct test_node map3[] = { { T_STR, 0, "Date" }, { T_STR, 0, "2001-11-23 15:03:17 -05:00" }, { T_STR, 0, "User" }, { T_STR, 0, "ed" }, { T_STR, 0, "Fatal" }, { T_STR, 0, "Unknown variable \"bar\"\n" }, { T_STR, 0, "Stack" }, { T_SEQ, 0, 0, stack }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map1 }, { T_MAP, 0, 0, map2 }, { T_MAP, 0, 0, map3 }, end_node }; documents: 3 --- test: Throwaway comments yaml: | ### These are four throwaway comment ### ### lines (the second line is empty). ### this: | # Comments may trail lines. contains three lines of text. The third one starts with a # character. This isn't a comment. # These are three throwaway comment # lines (the first line is empty). ruby: | { 'this' => "contains three lines of text.\nThe third one starts with a\n# character. This isn't a comment.\n" } syck: | struct test_node map[] = { { T_STR, 0, "this" }, { T_STR, 0, "contains three lines of text.\nThe third one starts with a\n# character. This isn't a comment.\n" }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Document with a single value yaml: | --- > This YAML stream contains a single text value. The next stream is a log file - a sequence of log entries. Adding an entry to the log is a simple matter of appending it at the end. ruby: | "This YAML stream contains a single text value. The next stream is a log file - a sequence of log entries. Adding an entry to the log is a simple matter of appending it at the end.\n" syck: | struct test_node stream[] = { { T_STR, 0, "This YAML stream contains a single text value. The next stream is a log file - a sequence of log entries. Adding an entry to the log is a simple matter of appending it at the end.\n" }, end_node }; --- test: Document stream yaml: | --- at: 2001-08-12 09:25:00.00 Z type: GET HTTP: '1.0' url: '/index.html' --- at: 2001-08-12 09:25:10.00 Z type: GET HTTP: '1.0' url: '/toc.html' ruby: | y = YAML::Stream.new y.add( { 'at' => Time::utc( 2001, 8, 12, 9, 25, 00 ), 'type' => 'GET', 'HTTP' => '1.0', 'url' => '/index.html' } ) y.add( { 'at' => Time::utc( 2001, 8, 12, 9, 25, 10 ), 'type' => 'GET', 'HTTP' => '1.0', 'url' => '/toc.html' } ) syck: | struct test_node map1[] = { { T_STR, 0, "at" }, { T_STR, 0, "2001-08-12 09:25:00.00 Z" }, { T_STR, 0, "type" }, { T_STR, 0, "GET" }, { T_STR, 0, "HTTP" }, { T_STR, 0, "1.0" }, { T_STR, 0, "url" }, { T_STR, 0, "/index.html" }, end_node }; struct test_node map2[] = { { T_STR, 0, "at" }, { T_STR, 0, "2001-08-12 09:25:10.00 Z" }, { T_STR, 0, "type" }, { T_STR, 0, "GET" }, { T_STR, 0, "HTTP" }, { T_STR, 0, "1.0" }, { T_STR, 0, "url" }, { T_STR, 0, "/toc.html" }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map1 }, { T_MAP, 0, 0, map2 }, end_node }; documents: 2 --- test: Top level mapping yaml: | # This stream is an example of a top-level mapping. invoice : 34843 date : 2001-01-23 total : 4443.52 ruby: | { 'invoice' => 34843, 'date' => Date.new( 2001, 1, 23 ), 'total' => 4443.52 } syck: | struct test_node map[] = { { T_STR, 0, "invoice" }, { T_STR, 0, "34843" }, { T_STR, 0, "date" }, { T_STR, 0, "2001-01-23" }, { T_STR, 0, "total" }, { T_STR, 0, "4443.52" }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Single-line documents yaml: | # The following is a sequence of three documents. # The first contains an empty mapping, the second # an empty sequence, and the last an empty string. --- {} --- [ ] --- '' ruby: | y = YAML::Stream.new y.add( {} ) y.add( [] ) y.add( '' ) syck: | struct test_node map[] = { end_node }; struct test_node seq[] = { end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, { T_SEQ, 0, 0, seq }, { T_STR, 0, "" }, end_node }; documents: 3 --- test: Document with pause yaml: | # A communication channel based on a YAML stream. --- sent at: 2002-06-06 11:46:25.10 Z payload: Whatever # Receiver can process this as soon as the following is sent: ... # Even if the next message is sent long after: --- sent at: 2002-06-06 12:05:53.47 Z payload: Whatever ... ruby: | y = YAML::Stream.new y.add( { 'sent at' => YAML::mktime( 2002, 6, 6, 11, 46, 25, 0.10 ), 'payload' => 'Whatever' } ) y.add( { "payload" => "Whatever", "sent at" => YAML::mktime( 2002, 6, 6, 12, 5, 53, 0.47 ) } ) syck: | struct test_node map1[] = { { T_STR, 0, "sent at" }, { T_STR, 0, "2002-06-06 11:46:25.10 Z" }, { T_STR, 0, "payload" }, { T_STR, 0, "Whatever" }, end_node }; struct test_node map2[] = { { T_STR, 0, "sent at" }, { T_STR, 0, "2002-06-06 12:05:53.47 Z" }, { T_STR, 0, "payload" }, { T_STR, 0, "Whatever" }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map1 }, { T_MAP, 0, 0, map2 }, end_node }; documents: 2 --- test: Explicit typing yaml: | integer: 12 also int: ! "12" string: !str 12 ruby: | { 'integer' => 12, 'also int' => 12, 'string' => '12' } syck: | struct test_node map[] = { { T_STR, 0, "integer" }, { T_STR, "tag:yaml.org,2002:int", "12" }, { T_STR, 0, "also int" }, { T_STR, "tag:yaml.org,2002:int", "12" }, { T_STR, 0, "string" }, { T_STR, "tag:yaml.org,2002:str", "12" }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Private types yaml: | # Both examples below make use of the 'x-private:ball' # type family URI, but with different semantics. --- pool: !!ball number: 8 color: black --- bearing: !!ball material: steel ruby: | y = YAML::Stream.new y.add( { 'pool' => YAML::PrivateType.new( 'ball', { 'number' => 8, 'color' => 'black' } ) } ) y.add( { 'bearing' => YAML::PrivateType.new( 'ball', { 'material' => 'steel' } ) } ) syck: | struct test_node pool[] = { { T_STR, 0, "number" }, { T_STR, 0, "8" }, { T_STR, 0, "color" }, { T_STR, 0, "black" }, end_node }; struct test_node map1[] = { { T_STR, 0, "pool" }, { T_MAP, "x-private:ball", 0, pool }, end_node }; struct test_node bearing[] = { { T_STR, 0, "material" }, { T_STR, 0, "steel" }, end_node }; struct test_node map2[] = { { T_STR, 0, "bearing" }, { T_MAP, "x-private:ball", 0, bearing }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map1 }, { T_MAP, 0, 0, map2 }, end_node }; documents: 2 --- test: Type family under yaml.org yaml: | # The URI is 'tag:yaml.org,2002:str' - !str a Unicode string python: | [ [ 'a Unicode string' ] ] ruby: | [ 'a Unicode string' ] syck: | struct test_node seq[] = { { T_STR, "tag:yaml.org,2002:str", "a Unicode string" }, end_node }; struct test_node stream[] = { { T_SEQ, 0, 0, seq }, end_node }; --- test: Type family under perl.yaml.org yaml: | # The URI is 'tag:perl.yaml.org,2002:Text::Tabs' - !perl/Text::Tabs {} ruby: | [ YAML::DomainType.new( 'perl.yaml.org,2002', 'Text::Tabs', {} ) ] syck: | struct test_node map[] = { end_node }; struct test_node seq[] = { { T_MAP, "tag:perl.yaml.org,2002:Text::Tabs", 0, map }, end_node }; struct test_node stream[] = { { T_SEQ, 0, 0, seq }, end_node }; --- test: Type family under clarkevans.com yaml: | # The URI is 'tag:clarkevans.com,2003-02:timesheet' - !clarkevans.com,2003-02/timesheet {} ruby: | [ YAML::DomainType.new( 'clarkevans.com,2003-02', 'timesheet', {} ) ] syck: | struct test_node map[] = { end_node }; struct test_node seq[] = { { T_MAP, "tag:clarkevans.com,2003-02:timesheet", 0, map }, end_node }; struct test_node stream[] = { { T_SEQ, 0, 0, seq }, end_node }; --- test: URI Escaping yaml: | same: - !domain.tld,2002/type\x30 value - !domain.tld,2002/type0 value different: # As far as the YAML parser is concerned - !domain.tld,2002/type%30 value - !domain.tld,2002/type0 value ruby-setup: | YAML.add_domain_type( "domain.tld,2002", "type0" ) { |type, val| "ONE: #{val}" } YAML.add_domain_type( "domain.tld,2002", "type%30" ) { |type, val| "TWO: #{val}" } ruby: | { 'same' => [ 'ONE: value', 'ONE: value' ], 'different' => [ 'TWO: value', 'ONE: value' ] } syck: | struct test_node same[] = { { T_STR, "tag:domain.tld,2002:type0", "value" }, { T_STR, "tag:domain.tld,2002:type0", "value" }, end_node }; struct test_node diff[] = { { T_STR, "tag:domain.tld,2002:type%30", "value" }, { T_STR, "tag:domain.tld,2002:type0", "value" }, end_node }; struct test_node map[] = { { T_STR, 0, "same" }, { T_SEQ, 0, 0, same }, { T_STR, 0, "different" }, { T_SEQ, 0, 0, diff }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: URI Prefixing yaml: | # 'tag:domain.tld,2002:invoice' is some type family. invoice: !domain.tld,2002/^invoice # 'seq' is shorthand for 'tag:yaml.org,2002:seq'. # This does not effect '^customer' below # because it is does not specify a prefix. customers: !seq # '^customer' is shorthand for the full # notation 'tag:domain.tld,2002:customer'. - !^customer given : Chris family : Dumars ruby-setup: | YAML.add_domain_type( "domain.tld,2002", /(invoice|customer)/ ) { |type, val| if val.is_a? ::Hash scheme, domain, type = type.split( /:/, 3 ) val['type'] = "domain #{type}" val else raise YAML::Error, "Not a Hash in domain.tld/invoice: " + val.inspect end } ruby: | { "invoice"=> { "customers"=> [ { "given"=>"Chris", "type"=>"domain customer", "family"=>"Dumars" } ], "type"=>"domain invoice" } } --- test: Overriding anchors yaml: | anchor : &A001 This scalar has an anchor. override : &A001 > The alias node below is a repeated use of this value. alias : *A001 ruby: | { 'anchor' => 'This scalar has an anchor.', 'override' => "The alias node below is a repeated use of this value.\n", 'alias' => "The alias node below is a repeated use of this value.\n" } syck: | struct test_node map[] = { { T_STR, 0, "anchor" }, { T_STR, 0, "This scalar has an anchor." }, { T_STR, 0, "override" }, { T_STR, 0, "The alias node below is a repeated use of this value.\n" }, { T_STR, 0, "alias" }, { T_STR, 0, "The alias node below is a repeated use of this value.\n" }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Flow and block formatting yaml: | empty: [] flow: [ one, two, three # May span lines, , four, # indentation is five ] # mostly ignored. block: - First item in top sequence - - Subordinate sequence entry - > A folded sequence entry - Sixth item in top sequence ruby: | { 'empty' => [], 'flow' => [ 'one', 'two', 'three', 'four', 'five' ], 'block' => [ 'First item in top sequence', [ 'Subordinate sequence entry' ], "A folded sequence entry\n", 'Sixth item in top sequence' ] } syck: | struct test_node empty[] = { end_node }; struct test_node flow[] = { { T_STR, 0, "one" }, { T_STR, 0, "two" }, { T_STR, 0, "three" }, { T_STR, 0, "four" }, { T_STR, 0, "five" }, end_node }; struct test_node inblock[] = { { T_STR, 0, "Subordinate sequence entry" }, end_node }; struct test_node block[] = { { T_STR, 0, "First item in top sequence" }, { T_SEQ, 0, 0, inblock }, { T_STR, 0, "A folded sequence entry\n" }, { T_STR, 0, "Sixth item in top sequence" }, end_node }; struct test_node map[] = { { T_STR, 0, "empty" }, { T_SEQ, 0, 0, empty }, { T_STR, 0, "flow" }, { T_SEQ, 0, 0, flow }, { T_STR, 0, "block" }, { T_SEQ, 0, 0, block }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Complete mapping test yaml: | empty: {} flow: { one: 1, two: 2 } spanning: { one: 1, two: 2 } block: first : First entry second: key: Subordinate mapping third: - Subordinate sequence - { } - Previous mapping is empty. - A key: value pair in a sequence. A second: key:value pair. - The previous entry is equal to the following one. - A key: value pair in a sequence. A second: key:value pair. !float 12 : This key is a float. ? > ? : This key had to be protected. "\a" : This key had to be escaped. ? > This is a multi-line folded key : Whose value is also multi-line. ? this also works as a key : with a value at the next line. ? - This key - is a sequence : - With a sequence value. ? This: key is a: mapping : with a: mapping value. ruby: | { 'empty' => {}, 'flow' => { 'one' => 1, 'two' => 2 }, 'spanning' => { 'one' => 1, 'two' => 2 }, 'block' => { 'first' => 'First entry', 'second' => { 'key' => 'Subordinate mapping' }, 'third' => [ 'Subordinate sequence', {}, 'Previous mapping is empty.', { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' }, 'The previous entry is equal to the following one.', { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' } ], 12.0 => 'This key is a float.', "?\n" => 'This key had to be protected.', "\a" => 'This key had to be escaped.', "This is a multi-line folded key\n" => "Whose value is also multi-line.", 'this also works as a key' => 'with a value at the next line.', [ 'This key', 'is a sequence' ] => [ 'With a sequence value.' ] } } # Couldn't recreate map exactly, so we'll do a detailed check to be sure it's entact obj_y['block'].keys.each { |k| if Hash === k v = obj_y['block'][k] if k['This'] == 'key' and k['is a'] == 'mapping' and v['with a'] == 'mapping value.' obj_r['block'][k] = v end end } --- test: Literal explicit indentation yaml: | # Explicit indentation must # be given in all the three # following cases. leading spaces: |2 This value starts with four spaces. leading line break: |2 This value starts with a line break. leading comment indicator: |2 # first line starts with a # character. # Explicit indentation may # also be given when it is # not required. redundant: |2 This value is indented 2 spaces. ruby: | { 'leading spaces' => " This value starts with four spaces.\n", 'leading line break' => "\nThis value starts with a line break.\n", 'leading comment indicator' => "# first line starts with a\n# character.\n", 'redundant' => "This value is indented 2 spaces.\n" } --- test: Chomping and keep modifiers yaml: | clipped: | This has one newline. same as "clipped" above: "This has one newline.\n" stripped: |- This has no newline. same as "stripped" above: "This has no newline." kept: |+ This has two newlines. same as "kept" above: "This has two newlines.\n\n" ruby: | { 'clipped' => "This has one newline.\n", 'same as "clipped" above' => "This has one newline.\n", 'stripped' => 'This has no newline.', 'same as "stripped" above' => 'This has no newline.', 'kept' => "This has two newlines.\n\n", 'same as "kept" above' => "This has two newlines.\n\n" } --- test: Literal combinations yaml: | empty: | literal: | The \ ' " characters may be freely used. Leading white space is significant. Line breaks are significant. Thus this value contains one empty line and ends with a single line break, but does not start with one. is equal to: "The \\ ' \" characters may \ be\nfreely used. Leading white\n space \ is significant.\n\nLine breaks are \ significant.\nThus this value contains \ one\nempty line and ends with a\nsingle \ line break, but does\nnot start with one.\n" # Comments may follow a block # scalar value. They must be # less indented. # Modifiers may be combined in any order. indented and chomped: |2- This has no newline. also written as: |-2 This has no newline. both are equal to: " This has no newline." ruby: | { 'empty' => '', 'literal' => "The \\ ' \" characters may be\nfreely used. Leading white\n space " + "is significant.\n\nLine breaks are significant.\nThus this value contains one\n" + "empty line and ends with a\nsingle line break, but does\nnot start with one.\n", 'is equal to' => "The \\ ' \" characters may be\nfreely used. Leading white\n space " + "is significant.\n\nLine breaks are significant.\nThus this value contains one\n" + "empty line and ends with a\nsingle line break, but does\nnot start with one.\n", 'indented and chomped' => ' This has no newline.', 'also written as' => ' This has no newline.', 'both are equal to' => ' This has no newline.' } syck: | struct test_node map[] = { { T_STR, 0, "empty" }, { T_STR, 0, "" }, { T_STR, 0, "literal" }, { T_STR, 0, "The \\ ' \" characters may be\nfreely used. Leading white\n space " "is significant.\n\nLine breaks are significant.\nThus this value contains one\n" "empty line and ends with a\nsingle line break, but does\nnot start with one.\n" }, { T_STR, 0, "is equal to" }, { T_STR, 0, "The \\ ' \" characters may be\nfreely used. Leading white\n space " "is significant.\n\nLine breaks are significant.\nThus this value contains one\n" "empty line and ends with a\nsingle line break, but does\nnot start with one.\n" }, { T_STR, 0, "indented and chomped" }, { T_STR, 0, " This has no newline." }, { T_STR, 0, "also written as" }, { T_STR, 0, " This has no newline." }, { T_STR, 0, "both are equal to" }, { T_STR, 0, " This has no newline." }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Folded combinations yaml: | empty: > one paragraph: > Line feeds are converted to spaces, so this value contains no line breaks except for the final one. multiple paragraphs: >2 An empty line, either at the start or in the value: Is interpreted as a line break. Thus this value contains three line breaks. indented text: > This is a folded paragraph followed by a list: * first entry * second entry Followed by another folded paragraph, another list: * first entry * second entry And a final folded paragraph. above is equal to: | This is a folded paragraph followed by a list: * first entry * second entry Followed by another folded paragraph, another list: * first entry * second entry And a final folded paragraph. # Explicit comments may follow # but must be less indented. ruby: | { 'empty' => '', 'one paragraph' => 'Line feeds are converted to spaces, so this value' + " contains no line breaks except for the final one.\n", 'multiple paragraphs' => "\nAn empty line, either at the start or in the value:\n" + "Is interpreted as a line break. Thus this value contains three line breaks.\n", 'indented text' => "This is a folded paragraph followed by a list:\n" + " * first entry\n * second entry\nFollowed by another folded paragraph, " + "another list:\n\n * first entry\n\n * second entry\n\nAnd a final folded paragraph.\n", 'above is equal to' => "This is a folded paragraph followed by a list:\n" + " * first entry\n * second entry\nFollowed by another folded paragraph, " + "another list:\n\n * first entry\n\n * second entry\n\nAnd a final folded paragraph.\n" } --- test: Single quotes yaml: | empty: '' second: '! : \ etc. can be used freely.' third: 'a single quote '' must be escaped.' span: 'this contains six spaces and one line break' is same as: "this contains six spaces\nand one line break" ruby: | { 'empty' => '', 'second' => '! : \\ etc. can be used freely.', 'third' => "a single quote ' must be escaped.", 'span' => "this contains six spaces\nand one line break", 'is same as' => "this contains six spaces\nand one line break" } --- test: Double quotes yaml: | empty: "" second: "! : etc. can be used freely." third: "a \" or a \\ must be escaped." fourth: "this value ends with an LF.\n" span: "this contains four \ spaces" is equal to: "this contains four spaces" ruby: | { 'empty' => '', 'second' => '! : etc. can be used freely.', 'third' => 'a " or a \\ must be escaped.', 'fourth' => "this value ends with an LF.\n", 'span' => "this contains four spaces", 'is equal to' => "this contains four spaces" } --- test: Unquoted strings yaml: | first: There is no unquoted empty string. second: 12 ## This is an integer. third: !str 12 ## This is a string. span: this contains six spaces and one line break indicators: this has no comments. #:foo and bar# are both text. flow: [ can span lines, # comment like this ] note: { one-line keys: but multi-line values } ruby: | { 'first' => 'There is no unquoted empty string.', 'second' => 12, 'third' => '12', 'span' => "this contains six spaces\nand one line break", 'indicators' => "this has no comments. #:foo and bar# are both text.", 'flow' => [ 'can span lines', 'like this' ], 'note' => { 'one-line keys' => 'but multi-line values' } } --- test: Spanning sequences yaml: | # The following are equal seqs # with different identities. flow: [ one, two ] spanning: [ one, two ] block: - one - two ruby: | { 'flow' => [ 'one', 'two' ], 'spanning' => [ 'one', 'two' ], 'block' => [ 'one', 'two' ] } --- test: Flow mappings yaml: | # The following are equal maps # with different identities. flow: { one: 1, two: 2 } block: one: 1 two: 2 ruby: | { 'flow' => { 'one' => 1, 'two' => 2 }, 'block' => { 'one' => 1, 'two' => 2 } } --- test: Representations of 12 yaml: | - 12 # An integer # The following scalars # are loaded to the # string value '1' '2'. - !str 12 - '12' - "12" - "\ 1\ 2\ " # Strings containing paths and regexps can be unquoted: - /foo/bar - d:/foo/bar - foo/bar - /a.*b/ ruby: | [ 12, '12', '12', '12', '12', '/foo/bar', 'd:/foo/bar', 'foo/bar', '/a.*b/' ] --- test: "Null" yaml: | canonical: ~ english: null # This sequence has five # entries, two with values. sparse: - ~ - 2nd entry - Null - 4th entry - four: This mapping has five keys, only two with values. ruby: | { 'canonical' => nil, 'english' => nil, 'sparse' => [ nil, '2nd entry', nil, '4th entry', nil ], 'four' => 'This mapping has five keys, only two with values.' } --- test: Omap yaml: | # Explicitly typed dictionary. Bestiary: !omap - aardvark: African pig-like ant eater. Ugly. - anteater: South-American ant eater. Two species. - anaconda: South-American constrictor snake. Scary. # Etc. ruby: | { 'Bestiary' => YAML::Omap[ 'aardvark', 'African pig-like ant eater. Ugly.', 'anteater', 'South-American ant eater. Two species.', 'anaconda', 'South-American constrictor snake. Scary.' ] } --- test: Pairs yaml: | # Explicitly typed pairs. tasks: !pairs - meeting: with team. - meeting: with boss. - break: lunch. - meeting: with client. ruby: | { 'tasks' => YAML::Pairs[ 'meeting', 'with team.', 'meeting', 'with boss.', 'break', 'lunch.', 'meeting', 'with client.' ] } --- test: Set yaml: | # Explicitly typed set. baseball players: !set Mark McGwire: Sammy Sosa: Ken Griffey: ruby: | { 'baseball players' => YAML::Set[ 'Mark McGwire', nil, 'Sammy Sosa', nil, 'Ken Griffey', nil ] } --- test: Boolean yaml: | false: used as key logical: true answer: no ruby: | { false => 'used as key', 'logical' => true, 'answer' => false } --- test: Integer yaml: | canonical: 12345 decimal: +12,345 octal: 014 hexadecimal: 0xC ruby: | { 'canonical' => 12345, 'decimal' => 12345, 'octal' => 12, 'hexadecimal' => 12 } --- test: Float yaml: | canonical: 1.23015e+3 exponential: 12.3015e+02 fixed: 1,230.15 negative infinity: -.inf not a number: .NaN ruby: | { 'canonical' => 1230.15, 'exponential' => 1230.15, 'fixed' => 1230.15, 'negative infinity' => -1.0/0.0, 'not a number' => 0.0/0.0 } if obj_y['not a number'].nan? # NaN comparison doesn't work right against 0.0/0.0 obj_r['not a number'] = obj_y['not a number'] end --- test: Timestamp yaml: | canonical: 2001-12-15T02:59:43.1Z valid iso8601: 2001-12-14t21:59:43.10-05:00 space separated: 2001-12-14 21:59:43.10 -05:00 date (noon UTC): 2002-12-14 ruby: | { 'canonical' => YAML::mktime( 2001, 12, 15, 2, 59, 43, 0.10 ), 'valid iso8601' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), 'space separated' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), 'date (noon UTC)' => Date.new( 2002, 12, 14 ) } syck: | struct test_node map[] = { { T_STR, 0, "canonical" }, { T_STR, 0, "2001-12-15T02:59:43.1Z" }, { T_STR, 0, "valid iso8601" }, { T_STR, 0, "2001-12-14t21:59:43.10-05:00" }, { T_STR, 0, "space separated" }, { T_STR, 0, "2001-12-14 21:59:43.10 -05:00" }, { T_STR, 0, "date (noon UTC)" }, { T_STR, 0, "2002-12-14" }, end_node }; struct test_node stream[] = { { T_MAP, 0, 0, map }, end_node }; --- test: Binary yaml: | canonical: !binary "\ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=" base64: !binary | R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= description: > The binary value above is a tiny arrow encoded as a gif image. ruby-setup: | arrow_gif = "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236iiiccc\243\243\243\204\204\204\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371!\376\016Made with GIMP\000,\000\000\000\000\f\000\f\000\000\005, \216\2010\236\343@\024\350i\020\304\321\212\010\034\317\200M$z\357\3770\205p\270\2601f\r\e\316\001\303\001\036\020' \202\n\001\000;" ruby: | { 'canonical' => arrow_gif, 'base64' => arrow_gif, 'description' => "The binary value above is a tiny arrow encoded as a gif image.\n" } --- test: Merge key yaml: | --- - &CENTER { x: 1, y: 2 } - &LEFT { x: 0, y: 2 } - &BIG { r: 10 } - &SMALL { r: 1 } # All the following maps are equal: - # Explicit keys x: 1 y: 2 r: 10 label: center/big - # Merge one map << : *CENTER r: 10 label: center/big - # Merge multiple maps << : [ *CENTER, *BIG ] label: center/big - # Override << : [ *BIG, *LEFT, *SMALL ] x: 1 label: center/big ruby-setup: | center = { 'x' => 1, 'y' => 2 } left = { 'x' => 0, 'y' => 2 } big = { 'r' => 10 } small = { 'r' => 1 } node1 = { 'x' => 1, 'y' => 2, 'r' => 10, 'label' => 'center/big' } node2 = center.dup node2.update( { 'r' => 10, 'label' => 'center/big' } ) node3 = big.dup node3.update( center ) node3.update( { 'label' => 'center/big' } ) node4 = small.dup node4.update( left ) node4.update( big ) node4.update( { 'x' => 1, 'label' => 'center/big' } ) ruby: | [ center, left, big, small, node1, node2, node3, node4 ] --- test: Default key yaml: | --- # Old schema link with: - library1.dll - library2.dll --- # New schema link with: - = : library1.dll version: 1.2 - = : library2.dll version: 2.3 ruby: | y = YAML::Stream.new y.add( { 'link with' => [ 'library1.dll', 'library2.dll' ] } ) obj_h = Hash[ 'version' => 1.2 ] obj_h.default = 'library1.dll' obj_h2 = Hash[ 'version' => 2.3 ] obj_h2.default = 'library2.dll' y.add( { 'link with' => [ obj_h, obj_h2 ] } ) documents: 2 --- test: Special keys yaml: | "!": These three keys "&": had to be quoted "=": and are normal strings. # NOTE: the following node should NOT be serialized this way. encoded node : !special '!' : '!type' !special|canonical '&' : 12 = : value # The proper way to serialize the above node is as follows: node : !!type &12 value ruby: | { '!' => 'These three keys', '&' => 'had to be quoted', '=' => 'and are normal strings.', 'encoded node' => YAML::PrivateType.new( 'type', 'value' ), 'node' => YAML::PrivateType.new( 'type', 'value' ) }