diff --git a/src/ast/presenter.ts b/src/ast/presenter.ts index cafea13d..6a424b87 100644 --- a/src/ast/presenter.ts +++ b/src/ast/presenter.ts @@ -257,7 +257,14 @@ function isPlainSafe (c: number, prev: number, inblock: boolean) { !(prev === CHAR_COLON && !cIsNsChar) ) || // false on ': ' (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) || // change to true on '[^ ]#' - (prev === CHAR_COLON && cIsNsChar) // change to true on ':[^ ]' + (prev === CHAR_COLON && cIsNsChar && + // outside block context a following c-flow-indicator is not ns-plain-safe + (inblock || + (c !== CHAR_COMMA && + c !== CHAR_LEFT_SQUARE_BRACKET && + c !== CHAR_RIGHT_SQUARE_BRACKET && + c !== CHAR_LEFT_CURLY_BRACKET && + c !== CHAR_RIGHT_CURLY_BRACKET))) // change to true on ':[^ ]' } // Simplified test for values allowed as the first character in plain style. diff --git a/test/core/units/dump-options.test.mjs b/test/core/units/dump-options.test.mjs index 16d54ac6..d8edfe8f 100644 --- a/test/core/units/dump-options.test.mjs +++ b/test/core/units/dump-options.test.mjs @@ -1,6 +1,6 @@ import { describe, it } from 'node:test' import assert from 'node:assert/strict' -import { dump, JSON_SCHEMA, CORE_SCHEMA, defineMappingTag, realMapTag, YAMLException } from 'js-yaml' +import { dump, load, JSON_SCHEMA, CORE_SCHEMA, defineMappingTag, realMapTag, YAMLException } from 'js-yaml' describe('dump options', () => { it('schema — decides which plain scalars need quoting', () => { @@ -96,6 +96,16 @@ describe('dump options', () => { assert.equal(dump({ a: [1, 2] }, { flowLevel: 1 }), 'a: [1, 2]\n') }) + it('flowLevel — quotes a colon followed by a flow indicator', () => { + // In flow context a `:` followed by a flow indicator ({ } [ ] ,) is not + // plain-safe (ns-plain-safe-in excludes c-flow-indicator), so the value + // must be quoted for the output to re-parse. + for (const value of [':{', ':[', ':,', ':}', ':]', 'x:{']) { + assert.deepStrictEqual(load(dump([value], { flowLevel: 0 })), [value]) + assert.deepStrictEqual(load(dump({ k: value }, { flowLevel: 0 })), { k: value }) + } + }) + it('transform — mutates the generated documents before presentation', () => { const output = dump({ values: [1, 2] }, { flowLevel: 1,