Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/stringify/foldFlowLines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ export function foldFlowLines(
let escStart = -1
let escEnd = -1
if (mode === FOLD_BLOCK) {
if (text[0] === ' ' || text[0] === '\t') {
// Unlike the following ones, the first line does not include the block
// indent, which the caller adds. Any white space here is therefore
// content of a more-indented line, which must not be folded.
const nl = text.indexOf('\n')
if (nl === -1) return text
i = nl
}
i = consumeMoreIndentedLines(text, i, indent.length)
if (i !== -1) end = i + endStep
}
Expand Down
16 changes: 9 additions & 7 deletions src/stringify/stringifyString.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,14 @@ function blockString(
return quotedString(value, ctx)
}

// Content starting with a space requires an explicit indentation indicator,
// which is only unambiguous if the block itself is indented as well.
const startsWithSpace = /^[\n ]*[ ]/.test(value)
const indent =
ctx.indent ||
(ctx.forceBlockIndent || containsDocumentMarker(value) ? ' ' : '')
(ctx.forceBlockIndent || startsWithSpace || containsDocumentMarker(value)
? ' '
: '')
const literal =
blockQuote === 'literal'
? true
Expand Down Expand Up @@ -227,14 +232,12 @@ function blockString(
}

// determine indent indicator from whitespace at value start
let startWithSpace = false
let startEnd: number
let startNlPos = -1
for (startEnd = 0; startEnd < value.length; ++startEnd) {
const ch = value[startEnd]
if (ch === ' ') startWithSpace = true
else if (ch === '\n') startNlPos = startEnd
else break
if (ch === '\n') startNlPos = startEnd
else if (ch !== ' ') break
}
let start = value.substring(
0,
Expand All @@ -245,9 +248,8 @@ function blockString(
start = start.replace(/\n+/g, `$&${indent}`)
}

const indentSize = indent ? '2' : '1' // root is at -1
// Leading | or > is added later
let header = (startWithSpace ? indentSize : '') + chomp
let header = (startsWithSpace ? '2' : '') + chomp
if (comment) {
header += ' ' + commentString(comment.replace(/ ?[\r\n]+/g, ' '))
if (onComment) onComment()
Expand Down
3 changes: 2 additions & 1 deletion tests/doc/foldFlowLines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,8 @@ describe('end-to-end', () => {
test('More-indented first line (#55)', () => {
const str = ' first more-indented line\nnext line\n'
const ys = YAML.stringify(str, foldOptions)
expect(ys).toBe('>1\n first more-indented line\nnext line\n')
expect(ys).toBe('>2\n first more-indented line\n next line\n')
expect(YAML.parse(ys)).toBe(str)
})

test('plain string', () => {
Expand Down
32 changes: 32 additions & 0 deletions tests/doc/stringify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,38 @@ describe('Document markers in top-level scalars', () => {
})
})

describe('Block scalars with leading spaces (#692)', () => {
for (const [value, exp] of [
[' a\n b', '|2-\n a\n b\n'],
[' indented\nlines', '|2-\n indented\n lines\n'],
[' a\nb', '|2-\n a\n b\n'],
[' x\n y\nz', '|2-\n x\n y\n z\n'],
[' deep\nshallow', '|2-\n deep\n shallow\n'],
['\n a', '|2-\n \n a\n'],
[' \nabc', '|2-\n \n abc\n'],
[' a\n', '|2\n a\n'],
[' a\n\n', '|2+\n a\n\n']
]) {
test(JSON.stringify(value), () => {
const str = YAML.stringify(value)
expect(str).toBe(exp)
expect(YAML.parse(str)).toBe(value)
})
}

test('as a map value', () => {
const str = YAML.stringify({ key: ' a\n b' })
expect(str).toBe('key: |2-\n a\n b\n')
expect(YAML.parse(str)).toEqual({ key: ' a\n b' })
})

test('as a seq item', () => {
const str = YAML.stringify([' a\n b'])
expect(str).toBe('- |2-\n a\n b\n')
expect(YAML.parse(str)).toEqual([' a\n b'])
})
})

describe('Document markers in top-level map keys (#431)', () => {
test('---', () => {
const str = YAML.stringify({ '--- x': 42 })
Expand Down