diff --git a/lib/dumper.js b/lib/dumper.js index f357a6ae..a16d74e3 100644 --- a/lib/dumper.js +++ b/lib/dumper.js @@ -199,6 +199,12 @@ function isPrintable(c) { || (0x10000 <= c && c <= 0x10FFFF); } +// Return true if the char is printable or a tab. +// derived from nb-char - #x85 - #xA0 - #x2028 - #x2029. +function isPrintableWithTabs(c) { + return isPrintable(c) || c === CHAR_TAB; +} + // [34] ns-char ::= nb-char - s-white // [27] nb-char ::= c-printable - b-char - c-byte-order-mark // [26] b-char ::= b-line-feed | b-carriage-return @@ -332,7 +338,7 @@ function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, // Check for disallowed characters to rule out plain and single. for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { char = codePointAt(string, i); - if (!isPrintable(char)) { + if (!isPrintableWithTabs(char)) { return STYLE_DOUBLE; } plain = plain && isPlainSafe(char, prevChar, inblock); @@ -352,7 +358,7 @@ function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, string[previousLineBreak + 1] !== ' '); previousLineBreak = i; } - } else if (!isPrintable(char)) { + } else if (!isPrintableWithTabs(char)) { return STYLE_DOUBLE; } plain = plain && isPlainSafe(char, prevChar, inblock); diff --git a/test/issues/0682-1.yml b/test/issues/0682-1.yml new file mode 100644 index 00000000..1a73c3f2 --- /dev/null +++ b/test/issues/0682-1.yml @@ -0,0 +1,3 @@ +value: |- + a + b diff --git a/test/issues/0682-2.yml b/test/issues/0682-2.yml new file mode 100644 index 00000000..ab05b490 --- /dev/null +++ b/test/issues/0682-2.yml @@ -0,0 +1,7 @@ +value: |2 + + some text + less indented text +other: |2 + some text + less indented text diff --git a/test/issues/0682.js b/test/issues/0682.js new file mode 100644 index 00000000..0a2a0fe0 --- /dev/null +++ b/test/issues/0682.js @@ -0,0 +1,33 @@ +'use strict'; + +const assert = require('assert'); +const fs = require('fs'); +const yaml = require('../..'); + + +it('Should serialize strings with tabs as blocks', function () { + const expected = fs.readFileSync(require('path').join(__dirname, '/0682-1.yml'), 'utf8'); + const result = yaml.dump({ value: 'a\n\tb' }); + assert.strictEqual(expected, result); +}); + +it('Should serialize strings with tabs and carriage returns as blocks and deserialize them', function () { + const data = { + value: '\r\n \tsome text\r\n more text but less indented \r\neven less indentation' + }; + const result = yaml.dump(data); + const loaded = yaml.load(result); + assert.deepEqual(data, loaded); +}); + +it('Should serialize strings where the initial whitespace is less than the following', function () { + const data = { + value: ' \nsome text\n less indented text\n', + other: ' some text\nless indented text\n' + }; + const result = yaml.dump(data); + const loaded = yaml.load(result); + assert.deepEqual(data, loaded); + const expected = fs.readFileSync(require('path').join(__dirname, '/0682-2.yml'), 'utf8'); + assert.strictEqual(expected, result); +}); diff --git a/test/issues/0682.yml b/test/issues/0682.yml new file mode 100644 index 00000000..1a73c3f2 --- /dev/null +++ b/test/issues/0682.yml @@ -0,0 +1,3 @@ +value: |- + a + b