diff --git a/docs/04_documents.md b/docs/04_documents.md index 7993dac8..677af66b 100644 --- a/docs/04_documents.md +++ b/docs/04_documents.md @@ -159,7 +159,8 @@ See [Options](#options) for more information on the optional parameter. const doc = new Document() doc.directives > { - marker: null, // set true to force the doc-start marker + docStart: null, // set true to force the doc-start marker + docEnd: false, // set true to force the doc-end marker tags: { '!!': 'tag:yaml.org,2002:' }, // Record yaml: { explicit: false, version: '1.2' } } diff --git a/src/compose/compose-doc.ts b/src/compose/compose-doc.ts index dadc2dbb..4948ddac 100644 --- a/src/compose/compose-doc.ts +++ b/src/compose/compose-doc.ts @@ -37,7 +37,7 @@ export function composeDoc( startOnNewline: true }) if (props.found) { - doc.directives.marker = true + doc.directives.docStart = true if ( value && (value.type === 'block-map' || value.type === 'block-seq') && diff --git a/src/compose/composer.ts b/src/compose/composer.ts index 85f031b5..82b3a6ed 100644 --- a/src/compose/composer.ts +++ b/src/compose/composer.ts @@ -96,7 +96,7 @@ export class Composer { const dc = doc.contents if (afterDoc) { doc.comment = doc.comment ? `${doc.comment}\n${comment}` : comment - } else if (afterEmptyLine || doc.directives.marker || !dc) { + } else if (afterEmptyLine || doc.directives.docStart || !dc) { doc.commentBefore = comment } else if (isCollection(dc) && !dc.flow && dc.items.length > 0) { let it = dc.items[0] @@ -167,11 +167,11 @@ export class Composer { token, this.onError ) - if (this.atDirectives && !doc.directives.marker) + if (this.atDirectives && !doc.directives.docStart) this.onError( token, 'MISSING_CHAR', - 'Missing directives-end indicator line' + 'Missing directives-end/doc-start indicator line' ) this.decorate(doc, false) if (this.doc) yield this.doc @@ -207,6 +207,7 @@ export class Composer { ) break } + this.doc.directives.docEnd = true const end = resolveEnd( token.end, token.offset + token.source.length, diff --git a/src/doc/directives.ts b/src/doc/directives.ts index 680d617f..73ddb1b0 100644 --- a/src/doc/directives.ts +++ b/src/doc/directives.ts @@ -25,7 +25,10 @@ export class Directives { * The directives-end/doc-start marker `---`. If `null`, a marker may still be * included in the document's stringified representation. */ - marker: true | null = null + docStart: true | null = null + + /** The doc-end marker `...`. */ + docEnd = false /** * Used when parsing YAML 1.1, where: @@ -42,7 +45,7 @@ export class Directives { clone(): Directives { const copy = new Directives(this.yaml, this.tags) - copy.marker = this.marker + copy.docStart = this.docStart return copy } diff --git a/src/stringify/stringifyDocument.ts b/src/stringify/stringifyDocument.ts index abe0358b..c2a36192 100644 --- a/src/stringify/stringifyDocument.ts +++ b/src/stringify/stringifyDocument.ts @@ -19,7 +19,7 @@ export function stringifyDocument( if (dir) { lines.push(dir) hasDirectives = true - } else if (doc.directives.marker) hasDirectives = true + } else if (doc.directives.docStart) hasDirectives = true } if (hasDirectives) lines.push('---') @@ -65,12 +65,26 @@ export function stringifyDocument( } else { lines.push(stringify(doc.contents, ctx)) } - let dc = doc.comment - if (dc && chompKeep) dc = dc.replace(/^\n+/, '') - if (dc) { - if ((!chompKeep || contentComment) && lines[lines.length - 1] !== '') - lines.push('') - lines.push(indentComment(commentString(dc), '')) + if (doc.directives?.docEnd) { + if (doc.comment) { + const cs = commentString(doc.comment) + if (cs.includes('\n')) { + lines.push('...') + lines.push(indentComment(cs, '')) + } else { + lines.push(`... ${cs}`) + } + } else { + lines.push('...') + } + } else { + let dc = doc.comment + if (dc && chompKeep) dc = dc.replace(/^\n+/, '') + if (dc) { + if ((!chompKeep || contentComment) && lines[lines.length - 1] !== '') + lines.push('') + lines.push(indentComment(commentString(dc), '')) + } } return lines.join('\n') + '\n' } diff --git a/src/test-events.ts b/src/test-events.ts index d26d4eb2..165c10d2 100644 --- a/src/test-events.ts +++ b/src/test-events.ts @@ -47,22 +47,18 @@ export function testEvents(src: string) { const doc = docs[i] let root = doc.contents if (Array.isArray(root)) root = root[0] - // eslint-disable-next-line no-sparse-arrays - const [rootStart, , rootEnd] = doc.range || [0, , 0] + const [rootStart] = doc.range || [0] const error = doc.errors[0] if (error && (!error.pos || error.pos[0] < rootStart)) throw new Error() let docStart = '+DOC' - if (doc.directives.marker) docStart += ' ---' + if (doc.directives.docStart) docStart += ' ---' else if (doc.contents && doc.contents.range[2] === doc.contents.range[0]) continue events.push(docStart) addEvents(events, doc, error?.pos[0] ?? -1, root) let docEnd = '-DOC' - if (rootEnd) { - const post = src.slice(rootStart, rootEnd) - if (/^\.\.\.($|\s)/m.test(post)) docEnd += ' ...' - } + if (doc.directives.docEnd) docEnd += ' ...' events.push(docEnd) } } catch (e) { diff --git a/tests/doc/YAML-1.1.spec.js b/tests/doc/YAML-1.1.spec.js index 6f7c642c..0355b552 100644 --- a/tests/doc/YAML-1.1.spec.js +++ b/tests/doc/YAML-1.1.spec.js @@ -47,9 +47,9 @@ test('Use preceding directives if none defined', () => { } ]) expect(docs.map(String)).toMatchObject([ - '!bar "First document"\n', + '!bar "First document"\n...\n', '%TAG ! !foo\n---\n!bar "With directives"\n', - '%TAG ! !foo\n---\n!bar "Using previous TAG directive"\n', + '%TAG ! !foo\n---\n!bar "Using previous TAG directive"\n...\n', '%YAML 1.1\n---\n!bar "Reset settings"\n', '%YAML 1.1\n---\n!bar "Using previous YAML directive"\n' ]) diff --git a/tests/doc/YAML-1.2.spec.js b/tests/doc/YAML-1.2.spec.js index 1cfe8bad..180543bb 100644 --- a/tests/doc/YAML-1.2.spec.js +++ b/tests/doc/YAML-1.2.spec.js @@ -1823,7 +1823,7 @@ for (const section in spec) { }) if (special) special(src) if (!errors) { - const src2 = documents.map(doc => String(doc)).join('\n...\n') + const src2 = documents.map(String).join('') const documents2 = YAML.parseAllDocuments(src2, { prettyErrors: false }) diff --git a/tests/yaml-test-suite.ts b/tests/yaml-test-suite.ts index eaf06ff6..ffb993ee 100644 --- a/tests/yaml-test-suite.ts +++ b/tests/yaml-test-suite.ts @@ -123,9 +123,7 @@ for (const dir of testDirs) { if (!error) { if (json) { test_('stringfy+re-parse', () => { - const src2 = - docs.map(doc => String(doc).replace(/\n$/, '')).join('\n...\n') + - '\n' + const src2 = docs.map(String).join('') const docs2 = parseAllDocuments(src2, { resolveKnownTags: false }) testJsonMatch(docs2, json) })