diff --git a/CHANGELOG.md b/CHANGELOG.md index 08d595c..3263151 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 win, earlier sources win, inherited-then-local ordering) now have one source of truth. No behavior change. +### Fixed + +- Classify the block scalar keep chomping indicator (`|+` / `>+`) as a distinct + `keep` chomping instead of silently treating it as clip. Full keep semantics + (preserving trailing blank lines) still depend on scanner blank-line capture, + tracked in #57. + ### Documentation - Correct `SECURITY.md`: fix the reporting contact address and replace the diff --git a/Sources/Parsing/BlockScalarChomping.swift b/Sources/Parsing/BlockScalarChomping.swift index 68298d5..6ce330e 100644 --- a/Sources/Parsing/BlockScalarChomping.swift +++ b/Sources/Parsing/BlockScalarChomping.swift @@ -2,6 +2,7 @@ extension PureYAML.Parsing { enum BlockScalarChomping: String, Equatable, CustomStringConvertible { case clip case strip + case keep var description: String { rawValue diff --git a/Sources/Parsing/Scanner.swift b/Sources/Parsing/Scanner.swift index d8c0542..cf1c01a 100644 --- a/Sources/Parsing/Scanner.swift +++ b/Sources/Parsing/Scanner.swift @@ -301,6 +301,8 @@ extension PureYAML.Parsing.Scanner { while let character = state.reader.peek(), isBlockScalarHeaderCharacter(character) { if character == "-" { chomping = .strip + } else if character == "+" { + chomping = .keep } else if character.isNumber { indentationIndicator = Int(String(character)) } diff --git a/Sources/Parsing/TokenEventParser.Block.swift b/Sources/Parsing/TokenEventParser.Block.swift index 363b3a0..821bd58 100644 --- a/Sources/Parsing/TokenEventParser.Block.swift +++ b/Sources/Parsing/TokenEventParser.Block.swift @@ -249,7 +249,13 @@ extension PureYAML.Parsing.TokenEventParser { switch chomping { case .strip: return content - case .clip: + case .clip, .keep: + // Clip and keep currently coincide: both append the single final + // line break. They diverge only over trailing blank lines, which the + // scanner does not yet capture into `lines`, so keep cannot preserve + // them today. That gap (and the related dropping of internal blank + // lines and folded-paragraph breaks) is tracked separately. Strip is + // the only branch that omits the final break. return content + "\n" } } diff --git a/Tests/ScannerTests.swift b/Tests/ScannerTests.swift index 01f10c4..7bc06cf 100644 --- a/Tests/ScannerTests.swift +++ b/Tests/ScannerTests.swift @@ -333,7 +333,7 @@ private func expectFlowAndBlockScalarKinds(_ tokens: [String]) { "mappingKey", "scalar value=\"text\" style=plain", "mappingValue", - "blockScalarHeader style=literal", + "blockScalarHeader style=literal chomping=keep", "indent width=2", "scalar value=\"line\" style=plain", "dedent width=0", @@ -357,7 +357,7 @@ private func expectFlowAndBlockScalarRequiredKinds(_ tokens: [String]) { "tag value=!Thing", "anchor name=item", "alias name=item", - "blockScalarHeader style=literal", + "blockScalarHeader style=literal chomping=keep", "blockScalarHeader style=folded chomping=strip", ]) }