Skip to content

Commit 4a4f539

Browse files
committed
Add test case for tabs in multi-line strings
1 parent 13509ad commit 4a4f539

File tree

2 files changed

+43
-16
lines changed

2 files changed

+43
-16
lines changed

kyaml/kyaml.go

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,15 @@ func (ky *Encoder) renderScalar(node *yaml.Node, indent int, flags flagMask, out
278278

279279
const kyamlFoldStr = "\\\n"
280280

281+
var regularEscapeMap = map[rune]string{
282+
'\n': "\\n" + kyamlFoldStr, // use YAML's line folding to make the output more readable
283+
'\t': "\t", // literal tab
284+
}
285+
var compactEscapeMap = map[rune]string{
286+
'\n': "\\n",
287+
'\t': "\\t",
288+
}
289+
281290
// renderString processes a string (either single-line or multi-line),
282291
// rendering it to the output. This DOES NOT render a trailing newline.
283292
func (ky *Encoder) renderString(val string, indent int, flags flagMask, out io.Writer) error {
@@ -290,11 +299,10 @@ func (ky *Encoder) renderString(val string, indent int, flags flagMask, out io.W
290299
return nil
291300
}
292301

293-
// What to print when we find a newline in the input.
294-
newline := "\\n"
295-
if !compact {
296-
// We use YAML's line folding to make the output more readable.
297-
newline += kyamlFoldStr
302+
// Special cases for certain input.
303+
escapeOverrides := regularEscapeMap
304+
if compact {
305+
escapeOverrides = compactEscapeMap
298306
}
299307

300308
//
@@ -325,7 +333,7 @@ func (ky *Encoder) renderString(val string, indent int, flags flagMask, out io.W
325333
fmt.Fprintf(buf, "%02x", s[0])
326334
continue
327335
}
328-
ky.appendEscapedRune(r, indent, newline, buf)
336+
ky.appendEscapedRune(r, indent, escapeOverrides, buf)
329337
}
330338

331339
// closing quote
@@ -485,7 +493,7 @@ func parseTimestamp(s string) (time.Time, bool) {
485493
}
486494

487495
// We use a buffer here so we can peek backwards.
488-
func (ky *Encoder) appendEscapedRune(r rune, indent int, newline string, buf *bytes.Buffer) {
496+
func (ky *Encoder) appendEscapedRune(r rune, indent int, escapeOverrides map[rune]string, buf *bytes.Buffer) {
489497
afterNewline := buf.Bytes()[len(buf.Bytes())-1] == '\n'
490498

491499
if afterNewline {
@@ -504,6 +512,10 @@ func (ky *Encoder) appendEscapedRune(r rune, indent int, newline string, buf *by
504512
buf.WriteRune(' ')
505513
}
506514
}
515+
if s, found := escapeOverrides[r]; found {
516+
buf.WriteString(s)
517+
return
518+
}
507519
if r == '"' || r == '\\' { // always escaped
508520
buf.WriteRune('\\')
509521
buf.WriteRune(r)
@@ -521,7 +533,7 @@ func (ky *Encoder) appendEscapedRune(r rune, indent int, newline string, buf *by
521533
case '\f':
522534
buf.WriteString(`\f`)
523535
case '\n':
524-
buf.WriteString(newline)
536+
buf.WriteString(`\n`)
525537
case '\r':
526538
buf.WriteString(`\r`)
527539
case '\t':

kyaml/kyaml_test.go

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1870,10 +1870,14 @@ func TestKYAMLFromYAML(t *testing.T) {
18701870
simple: |
18711871
This is a multi-line string.
18721872
It has multiple lines.
1873-
leading_space: |
1873+
leading_spaces: |
18741874
This is a multi-line string.
18751875
It can
1876-
retain indentation.
1876+
retain space indentation.
1877+
leading_tabs: |
1878+
This is a multi-line string.
1879+
It can
1880+
retain tab indentation.
18771881
blank_lines: |
18781882
This is a multi-line string.
18791883
@@ -1886,10 +1890,15 @@ func TestKYAMLFromYAML(t *testing.T) {
18861890
This is a multi-line string.\n\
18871891
It has multiple lines.\n\
18881892
",
1889-
leading_space: "\
1893+
leading_spaces: "\
18901894
This is a multi-line string.\n\
18911895
\ It can\n\
1892-
\ retain indentation.\n\
1896+
\ retain space indentation.\n\
1897+
",
1898+
leading_tabs: "\
1899+
This is a multi-line string.\n\
1900+
\ It can\n\
1901+
\ retain tab indentation.\n\
18931902
",
18941903
blank_lines: "\
18951904
This is a multi-line string.\n\
@@ -1904,7 +1913,8 @@ func TestKYAMLFromYAML(t *testing.T) {
19041913
name: "multi-line strings dquoted",
19051914
input: `
19061915
simple: "This is a multi-line string.\nIt has multiple lines.\n"
1907-
eading_space: "This is a multi-line string.\n It can\n retain indentation.\n"
1916+
leading_spaces: "This is a multi-line string.\n It can\n retain space indentation.\n"
1917+
leading_tabs: "This is a multi-line string.\n\tIt can\n\t\tretain tab indentation.\n"
19081918
blank_lines: "This is a multi-line string.\n\nIt can retain blank lines.\n"
19091919
`,
19101920
expected: `
@@ -1914,10 +1924,15 @@ func TestKYAMLFromYAML(t *testing.T) {
19141924
This is a multi-line string.\n\
19151925
It has multiple lines.\n\
19161926
",
1917-
leading_space: "\
1927+
leading_spaces: "\
19181928
This is a multi-line string.\n\
19191929
\ It can\n\
1920-
\ retain indentation.\n\
1930+
\ retain space indentation.\n\
1931+
",
1932+
leading_tabs: "\
1933+
This is a multi-line string.\n\
1934+
\ It can\n\
1935+
\ retain tab indentation.\n\
19211936
",
19221937
blank_lines: "\
19231938
This is a multi-line string.\n\
@@ -2419,7 +2434,7 @@ func TestRenderStringEscapes(t *testing.T) {
24192434
}, {
24202435
name: "tab",
24212436
input: '\t',
2422-
expect: `"\t"`,
2437+
expect: "\"\t\"",
24232438
}, {
24242439
name: "vtab",
24252440
input: '\v',

0 commit comments

Comments
 (0)