fix(parsing): end a plain scalar at a tab before a comment
A comment opens after white space, a tab as well as a space, but the plain scalar terminator checked only for a space before `#`. So `c: d\t#X` kept the tab and hash as content, giving the value `d\t#X` rather than `d` with a trailing comment. Treat a tab before `#` as a space there, in both the lookahead from a white space character and the check on the accumulated value's last character. A tab inside a plain scalar with no `#` after it stays content, and a `#` glued to content with no white space is still content. Raises yaml-test-suite value-level conformance to 187/194 (96.4%) with the parse-level and should-error rejection rates unchanged. 448 tests pass.
This commit is contained in:
parent
37ac4d862d
commit
6c322fc5ed
@ -84,6 +84,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Fixed
|
||||
|
||||
- A tab before a `#` now ends a plain scalar and begins a trailing comment, as a space already did,
|
||||
since a comment opens after any white space. `c: d\t#X` is the value `d` with a comment, not the
|
||||
literal `d\t#X`. A tab inside a plain scalar with no `#` after it stays part of the value, and a `#`
|
||||
glued to content with no white space is still content. Raises yaml-test-suite value-level
|
||||
conformance to 187/194 (96.4%), with the parse and should-error rates unchanged.
|
||||
|
||||
- A blank line next to a more-indented line in a folded block scalar (`>`) now keeps both line
|
||||
breaks. Between two non-more-indented lines a blank run of N folds to N breaks (the fold is
|
||||
absorbed into the first), but next to a more-indented line nothing folds, so the absorbed break
|
||||
|
||||
@ -279,10 +279,12 @@ extension PureYAML.Parsing.Scanner {
|
||||
if isLineBreak(character) {
|
||||
return true
|
||||
}
|
||||
if character == " ", state.reader.peek(offset: 1) == "#" {
|
||||
// A comment opens after white space, a tab as well as a space, so a `#` preceded by either
|
||||
// ends the plain scalar: `d\t#X` is the value `d` with a trailing comment.
|
||||
if character == " " || character == "\t", state.reader.peek(offset: 1) == "#" {
|
||||
return true
|
||||
}
|
||||
if character == "#", accumulated.isEmpty || accumulated.last == " " {
|
||||
if character == "#", accumulated.isEmpty || accumulated.last == " " || accumulated.last == "\t" {
|
||||
return true
|
||||
}
|
||||
if character == ":", shouldEndPlainScalarAtMappingValue(state: state) {
|
||||
|
||||
36
Tests/PlainScalarTabCommentTests.swift
Normal file
36
Tests/PlainScalarTabCommentTests.swift
Normal file
@ -0,0 +1,36 @@
|
||||
@testable import PureYAML
|
||||
import Testing
|
||||
|
||||
/// A comment opens after white space, a tab as well as a space, so a `#` preceded by a tab ends a
|
||||
/// plain scalar and begins a trailing comment. A tab inside a plain scalar, with no `#` after it,
|
||||
/// stays part of the value, and a `#` glued directly to content (no white space) is content.
|
||||
@Suite("Plain scalar tab comment")
|
||||
struct PlainScalarTabCommentTests {
|
||||
@Test("A tab before a hash ends the scalar and starts a comment")
|
||||
func test_tabBeforeComment() throws {
|
||||
#expect(try PureYAML.parse("c: d\t#X\n") == .mapping(.init([
|
||||
.init(key: "c", value: .string("d")),
|
||||
])))
|
||||
}
|
||||
|
||||
@Test("A tab inside a plain scalar value is kept")
|
||||
func test_internalTabKept() throws {
|
||||
#expect(try PureYAML.parse("x: a\tb\n") == .mapping(.init([
|
||||
.init(key: "x", value: .string("a\tb")),
|
||||
])))
|
||||
}
|
||||
|
||||
@Test("A hash glued to content with no white space stays content")
|
||||
func test_hashWithoutWhitespaceIsContent() throws {
|
||||
#expect(try PureYAML.parse("c: d#X\n") == .mapping(.init([
|
||||
.init(key: "c", value: .string("d#X")),
|
||||
])))
|
||||
}
|
||||
|
||||
@Test("A space before a hash still ends the scalar")
|
||||
func test_spaceBeforeCommentUnchanged() throws {
|
||||
#expect(try PureYAML.parse("c: d #X\n") == .mapping(.init([
|
||||
.init(key: "c", value: .string("d")),
|
||||
])))
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user