Skip to content

Commit 704b25d

Browse files
committed
Quote document markers followed by whitespace
1 parent 42dea28 commit 704b25d

2 files changed

Lines changed: 25 additions & 3 deletions

File tree

src/ast/presenter.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,21 @@ function isWhitespace (c: number) {
183183
return c === CHAR_SPACE || c === CHAR_TAB
184184
}
185185

186+
// Mirrors parser.testDocumentSeparator(): `---` and `...` are document
187+
// markers when followed by separation whitespace, a line break, or EOF.
188+
function startsWithDocumentSeparator (string: string) {
189+
const marker = string.charCodeAt(0)
190+
191+
if ((marker !== CHAR_MINUS && marker !== 0x2E/* . */) ||
192+
string.charCodeAt(1) !== marker || string.charCodeAt(2) !== marker) return false
193+
194+
if (string.length === 3) return true
195+
196+
const following = string.charCodeAt(3)
197+
return isWhitespace(following) ||
198+
following === CHAR_CARRIAGE_RETURN || following === CHAR_LINE_FEED
199+
}
200+
186201
// Returns true if the character can be printed without escaping.
187202
// From YAML 1.2: "any allowed characters known to be non-printable
188203
// should also be escaped. [However,] This isn’t mandatory"
@@ -358,7 +373,7 @@ function chooseScalarStyle (state: PresenterState, string: string, layout: Retur
358373
let previousLineBreak = -1 // count the first line correctly
359374
// Document markers are recognized as whole tokens at the start of a line,
360375
// so character-level plain-scalar checks alone cannot reject them.
361-
let plain = string !== '---' && string !== '...' &&
376+
let plain = !startsWithDocumentSeparator(string) &&
362377
isPlainSafeAtStart(string, inblock) &&
363378
isPlainSafeLast(codePointAt(string, string.length - 1))
364379

test/core/units/dump-scalar-styles.test.mjs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,18 @@ describe('Scalar style dump:', () => {
3838
})
3939

4040
describe('Single- and double-quoted styles', () => {
41-
it('quotes strings that collide with YAML structural tokens', () => {
41+
it('handles strings resembling YAML structural tokens', () => {
4242
const cases = [
43-
// Document boundary markers.
43+
// Document boundary markers, including a following plain scalar.
4444
['---', "'---'\n"],
4545
['...', "'...'\n"],
46+
['--- x', "'--- x'\n"],
47+
['... x', "'... x'\n"],
48+
// Similar strings that are not document markers stay plain.
49+
['---x', '---x\n'],
50+
['...x', '...x\n'],
51+
['....', '....\n'],
52+
['x...', 'x...\n'],
4653
// Block sequence/mapping indicators followed by separation whitespace.
4754
['- value', "'- value'\n"],
4855
['? value', "'? value'\n"]

0 commit comments

Comments
 (0)