Просмотр исходного кода

Fix and improve indentation of sequences in maps.

Gustavo Niemeyer 7 лет назад
Родитель
Сommit
55513cacd4
2 измененных файлов с 26 добавлено и 11 удалено
  1. 14 5
      emitterc.go
  2. 12 6
      encode_test.go

+ 14 - 5
emitterc.go

@@ -236,6 +236,10 @@ func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool
 		}
 	} else if !indentless {
 		emitter.indent += emitter.best_indent
+		// [Go] If inside a block sequence item, discount the space taken by the indicator.
+		if emitter.best_indent > 2 && emitter.states[len(emitter.states)-1] == yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE {
+			emitter.indent -= 2
+		}
 	}
 	return true
 }
@@ -714,9 +718,16 @@ 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 {
-		if !yaml_emitter_increase_indent(emitter, false, emitter.mapping_context && !emitter.indention) {
+		// [Go] The original logic here would not indent the sequence when inside a mapping.
+		// In Go we always indent it, but take the sequence indicator out of the indentation.
+		indentless := emitter.best_indent == 2 && emitter.mapping_context && !emitter.indention
+		original := emitter.indent
+		if !yaml_emitter_increase_indent(emitter, false, indentless) {
 			return false
 		}
+		if emitter.indent > original+2 {
+			emitter.indent -= 2
+		}
 	}
 	if event.typ == yaml_SEQUENCE_END_EVENT {
 		emitter.indent = emitter.indents[len(emitter.indents)-1]
@@ -764,10 +775,8 @@ func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_ev
 	if !yaml_emitter_process_head_comment(emitter) {
 		return false
 	}
-	if !first || emitter.states[len(emitter.states)-1] != yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE {
-		if !yaml_emitter_write_indent(emitter) {
-			return false
-		}
+	if !yaml_emitter_write_indent(emitter) {
+		return false
 	}
 	if yaml_emitter_check_simple_key(emitter) {
 		emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)

+ 12 - 6
encode_test.go

@@ -113,13 +113,13 @@ var marshalTests = []struct {
 		"v: \"\"\n",
 	}, {
 		map[string][]string{"v": []string{"A", "B"}},
-		"v:\n- A\n- B\n",
+		"v:\n  - A\n  - B\n",
 	}, {
 		map[string][]string{"v": []string{"A", "B\nC"}},
-		"v:\n- A\n- |-\n    B\n    C\n",
+		"v:\n  - A\n  - |-\n    B\n    C\n",
 	}, {
 		map[string][]interface{}{"v": []interface{}{"A", 1, map[string][]int{"B": []int{2, 3}}}},
-		"v:\n- A\n- 1\n- B:\n    - 2\n    - 3\n",
+		"v:\n  - A\n  - 1\n  - B:\n      - 2\n      - 3\n",
 	}, {
 		map[string]interface{}{"a": map[interface{}]interface{}{"b": "c"}},
 		"a:\n    b: c\n",
@@ -164,10 +164,10 @@ var marshalTests = []struct {
 		"a: 1\n",
 	}, {
 		&struct{ A []int }{[]int{1, 2}},
-		"a:\n- 1\n- 2\n",
+		"a:\n  - 1\n  - 2\n",
 	}, {
 		&struct{ A [2]int }{[2]int{1, 2}},
-		"a:\n- 1\n- 2\n",
+		"a:\n  - 1\n  - 2\n",
 	}, {
 		&struct {
 			B int "a"
@@ -405,6 +405,12 @@ var marshalTests = []struct {
 		&marshalerType{&marshalerType{true}},
 		"true\n",
 	},
+
+	// Check indentation of maps inside sequences inside maps.
+	{
+		map[string]interface{}{"a": map[string]interface{}{"b": []map[string]int{{"c": 1, "d": 2}}}},
+		"a:\n    b:\n      - c: 1\n        d: 2\n",
+	},
 }
 
 func (s *S) TestMarshal(c *C) {
@@ -505,7 +511,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!"},