diff --git a/emitterc.go b/emitterc.go index 0f47c9ca..4cf6349f 100644 --- a/emitterc.go +++ b/emitterc.go @@ -225,6 +225,15 @@ func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_ return true } +// Don't count the sequenceIndicator as part of sequence indentation. +// This maintains sequence indentation consistency with gopkg.in/yaml.v2 +// (https://pkg.go.dev/gopkg.in/yaml.v2#readme-api-documentation) +// and conforms to the YAML 1.2 spec comment +// > both the “-” indicator and the following spaces are considered +// > to be part of the indentation of the nested collection. +// at https://yaml.org/spec/1.2/spec.html#id2772075 +const lenSequenceIndicator = len(`- `) + // Increase the indentation level. func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool { emitter.indents = append(emitter.indents, emitter.indent) @@ -234,14 +243,11 @@ func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool } else { emitter.indent = 0 } - } else if !indentless { - // [Go] This was changed so that indentations are more regular. - if emitter.states[len(emitter.states)-1] == yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE { - // The first indent inside a sequence will just skip the "- " indicator. - emitter.indent += 2 - } else { - // Everything else aligns to the chosen indentation. - emitter.indent = emitter.best_indent*((emitter.indent+emitter.best_indent)/emitter.best_indent) + } else { + emitter.indent += emitter.best_indent + // If inside a block sequence item, discount the space taken by the indicator. + if emitter.best_indent > lenSequenceIndicator && emitter.states[len(emitter.states)-1] == yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE { + emitter.indent -= lenSequenceIndicator } } return true @@ -728,9 +734,13 @@ func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_e // Expect a block item node. func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { if first { + originalIndent := emitter.indent if !yaml_emitter_increase_indent(emitter, false, false) { return false } + if emitter.indent > originalIndent+lenSequenceIndicator { + emitter.indent -= lenSequenceIndicator + } } if event.typ == yaml_SEQUENCE_END_EVENT { emitter.indent = emitter.indents[len(emitter.indents)-1] diff --git a/encode_test.go b/encode_test.go index c512260c..3bb09aa4 100644 --- a/encode_test.go +++ b/encode_test.go @@ -138,25 +138,25 @@ v: "" }, { map[string][]string{"v": []string{"A", "B"}}, ` v: - - A - - B + - A + - B `, }, { map[string][]string{"v": []string{"A", "B\nC"}}, ` v: - - A - - |- - B - C + - A + - |- + B + C `, }, { map[string][]interface{}{"v": []interface{}{"A", 1, map[string][]int{"B": []int{2, 3}}}}, ` v: - - A - - 1 - - B: - - 2 - - 3 + - A + - 1 + - B: + - 2 + - 3 `, }, { map[string]interface{}{"a": map[interface{}]interface{}{"b": "c"}}, ` @@ -214,14 +214,14 @@ a: 1 }, { &struct{ A []int }{[]int{1, 2}}, ` a: - - 1 - - 2 + - 1 + - 2 `, }, { &struct{ A [2]int }{[2]int{1, 2}}, ` a: - - 1 - - 2 + - 1 + - 2 `, }, { &struct { @@ -530,8 +530,8 @@ true map[string]interface{}{"a": map[string]interface{}{"b": []map[string]int{{"c": 1, "d": 2}}}}, ` a: b: - - c: 1 - d: 2 + - c: 1 + d: 2 `, }, @@ -713,7 +713,7 @@ var marshalerTests = []struct { value interface{} }{ {"_:\n hi: there\n", map[interface{}]interface{}{"hi": "there"}}, - {"_:\n - 1\n - A\n", []interface{}{1, "A"}}, + {"_:\n - 1\n - A\n", []interface{}{1, "A"}}, {"_: 10\n", 10}, {"_: null\n", nil}, {"_: BAR!\n", "BAR!"}, @@ -794,24 +794,24 @@ a: b: c: d e: - - 1 - - 2 - - 3 + - 1 + - 2 + - 3 f: - - g - - h + - g + - h ` indentEight = ` a: b: c: d e: - - 1 - - 2 - - 3 + - 1 + - 2 + - 3 f: - - g - - h + - g + - h ` ) diff --git a/node_test.go b/node_test.go index 0ce64386..d845307b 100644 --- a/node_test.go +++ b/node_test.go @@ -681,7 +681,7 @@ a: Kind: yaml.SequenceNode, Tag: "!!seq", Line: 3, - Column: 3, + Column: 1, Content: []*yaml.Node{{ Kind: yaml.MappingNode, Tag: "!!map",