Skip to content

Commit 5f26d3f

Browse files
committed
Improve Plain Style support
1 parent db3eb34 commit 5f26d3f

File tree

1 file changed

+39
-26
lines changed

1 file changed

+39
-26
lines changed

lib/js-yaml/dumper.js

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -194,32 +194,45 @@ function isPrintable(c) {
194194
// [34] ns-char ::= nb-char - s-white
195195
// [27] nb-char ::= c-printable - b-char - c-byte-order-mark
196196
// [26] b-char ::= b-line-feed | b-carriage-return
197-
// [24] b-line-feed ::= #xA /* LF */
198-
// [25] b-carriage-return ::= #xD /* CR */
199-
// [3] c-byte-order-mark ::= #xFEFF
200-
function isNsChar(c) {
201-
return isPrintable(c) && !isWhitespace(c)
202-
&& c !== CHAR_BOM
203-
// - b-char
197+
// Including s-white (for some reason, examples doesn't match specs in this aspect)
198+
// ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark
199+
function isNsCharOrWhitespace(c) {
200+
return isPrintable(c)
201+
&& c !== CHAR_BOM
202+
// - b-char
204203
&& c !== CHAR_CARRIAGE_RETURN
205204
&& c !== CHAR_LINE_FEED;
206205
}
207206

208-
// Simplified test for values allowed after the first character in plain style.
209-
function isPlainSafe(c, prev) {
210-
// Uses a subset of nb-char - c-flow-indicator - ":" - "#"
211-
// where nb-char ::= c-printable - b-char - c-byte-order-mark.
212-
return isPrintable(c) && c !== 0xFEFF
213-
// - c-flow-indicator
214-
&& c !== CHAR_COMMA
215-
&& c !== CHAR_LEFT_SQUARE_BRACKET
216-
&& c !== CHAR_RIGHT_SQUARE_BRACKET
217-
&& c !== CHAR_LEFT_CURLY_BRACKET
218-
&& c !== CHAR_RIGHT_CURLY_BRACKET
219-
// - ":" - "#"
220-
// /* An ns-char preceding */ "#"
221-
&& c !== CHAR_COLON
222-
&& ((c !== CHAR_SHARP) || (prev && isNsChar(prev)));
207+
// [127] ns-plain-safe(c) ::= c = flow-out ⇒ ns-plain-safe-out
208+
// c = flow-in ⇒ ns-plain-safe-in
209+
// c = block-key ⇒ ns-plain-safe-out
210+
// c = flow-key ⇒ ns-plain-safe-in
211+
// [128] ns-plain-safe-out ::= ns-char
212+
// [129] ns-plain-safe-in ::= ns-char - c-flow-indicator
213+
// [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - “:” - “#” )
214+
// | ( /* An ns-char preceding */ “#” )
215+
// | ( “:” /* Followed by an ns-plain-safe(c) */ )
216+
function isPlainSafe(state, c, prev) {
217+
var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c);
218+
var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c);
219+
return (
220+
// ns-plain-safe
221+
state.flowLevel < 0 ? // c = flow-in
222+
cIsNsCharOrWhitespace
223+
: cIsNsCharOrWhitespace
224+
// - c-flow-indicator
225+
&& c !== CHAR_COMMA
226+
&& c !== CHAR_LEFT_SQUARE_BRACKET
227+
&& c !== CHAR_RIGHT_SQUARE_BRACKET
228+
&& c !== CHAR_LEFT_CURLY_BRACKET
229+
&& c !== CHAR_RIGHT_CURLY_BRACKET
230+
)
231+
// ns-plain-char
232+
&& c !== CHAR_SHARP // false on '#'
233+
&& !(prev === CHAR_COLON && !cIsNsChar) // false on ': '
234+
|| (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#'
235+
|| (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]'
223236
}
224237

225238
// Simplified test for values allowed as the first character in plain style.
@@ -274,7 +287,7 @@ var STYLE_PLAIN = 1,
274287
// STYLE_PLAIN or STYLE_SINGLE => no \n are in the string.
275288
// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1).
276289
// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1).
277-
function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, testAmbiguousType) {
290+
function chooseScalarStyle(state, string, singleLineOnly, indentPerLevel, lineWidth, testAmbiguousType) {
278291
var i;
279292
var char, prev_char;
280293
var hasLineBreak = false;
@@ -293,7 +306,7 @@ function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, te
293306
return STYLE_DOUBLE;
294307
}
295308
prev_char = i > 0 ? string.charCodeAt(i - 1) : null;
296-
plain = plain && isPlainSafe(char, prev_char);
309+
plain = plain && isPlainSafe(state, char, prev_char);
297310
}
298311
} else {
299312
// Case: block styles permitted.
@@ -313,7 +326,7 @@ function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, te
313326
return STYLE_DOUBLE;
314327
}
315328
prev_char = i > 0 ? string.charCodeAt(i - 1) : null;
316-
plain = plain && isPlainSafe(char, prev_char);
329+
plain = plain && isPlainSafe(state, char, prev_char);
317330
}
318331
// in case the end is missing a \n
319332
hasFoldableLine = hasFoldableLine || (shouldTrackWidth &&
@@ -373,7 +386,7 @@ function writeScalar(state, string, level, iskey) {
373386
return testImplicitResolving(state, string);
374387
}
375388

376-
switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth, testAmbiguity)) {
389+
switch (chooseScalarStyle(state, string, singleLineOnly, state.indent, lineWidth, testAmbiguity)) {
377390
case STYLE_PLAIN:
378391
return string;
379392
case STYLE_SINGLE:

0 commit comments

Comments
 (0)