Skip to content

Commit

Permalink
[Dumper] Trim leading newlines when checking if value begins with a s…
Browse files Browse the repository at this point in the history
…pace
  • Loading branch information
bradtreloar authored and fabpot committed Apr 23, 2023
1 parent 3713e20 commit 4cd2e3e
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 9 deletions.
28 changes: 19 additions & 9 deletions Dumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,7 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0):
}

if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value) && false !== strpos($value, "\n") && false === strpos($value, "\r")) {
// If the first line starts with a space character, the spec requires a blockIndicationIndicator
// http://www.yaml.org/spec/1.2/spec.html#id2793979
$blockIndentationIndicator = (' ' === substr($value, 0, 1)) ? (string) $this->indentation : '';
$blockIndentationIndicator = $this->getBlockIndentationIndicator($value);

if (isset($value[-2]) && "\n" === $value[-2] && "\n" === $value[-1]) {
$blockChompingIndicator = '+';
Expand All @@ -98,9 +96,7 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0):
$output .= sprintf('%s%s !%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', $value->getTag());

if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && false !== strpos($value->getValue(), "\n") && false === strpos($value->getValue(), "\r\n")) {
// If the first line starts with a space character, the spec requires a blockIndicationIndicator
// http://www.yaml.org/spec/1.2/spec.html#id2793979
$blockIndentationIndicator = (' ' === substr($value->getValue(), 0, 1)) ? (string) $this->indentation : '';
$blockIndentationIndicator = $this->getBlockIndentationIndicator($value->getValue());
$output .= sprintf(' |%s', $blockIndentationIndicator);

foreach (explode("\n", $value->getValue()) as $row) {
Expand Down Expand Up @@ -145,9 +141,7 @@ private function dumpTaggedValue(TaggedValue $value, int $inline, int $indent, i
$output = sprintf('%s!%s', $prefix ? $prefix.' ' : '', $value->getTag());

if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && false !== strpos($value->getValue(), "\n") && false === strpos($value->getValue(), "\r\n")) {
// If the first line starts with a space character, the spec requires a blockIndicationIndicator
// http://www.yaml.org/spec/1.2/spec.html#id2793979
$blockIndentationIndicator = (' ' === substr($value->getValue(), 0, 1)) ? (string) $this->indentation : '';
$blockIndentationIndicator = $this->getBlockIndentationIndicator($value->getValue());
$output .= sprintf(' |%s', $blockIndentationIndicator);

foreach (explode("\n", $value->getValue()) as $row) {
Expand All @@ -163,4 +157,20 @@ private function dumpTaggedValue(TaggedValue $value, int $inline, int $indent, i

return $output."\n".$this->dump($value->getValue(), $inline - 1, $indent, $flags);
}

private function getBlockIndentationIndicator(string $value): string
{
$lines = explode("\n", $value);

// If the first line (that is neither empty nor contains only spaces)
// starts with a space character, the spec requires a block indentation indicator
// http://www.yaml.org/spec/1.2/spec.html#id2793979
foreach ($lines as $line) {
if ('' !== trim($line, ' ')) {
return (' ' === substr($line, 0, 1)) ? (string) $this->indentation : '';
}
}

return '';
}
}
36 changes: 36 additions & 0 deletions Tests/DumperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,42 @@ public function testDumpMultiLineStringAsScalarBlockWhenFirstLineHasLeadingSpace
$this->assertSame($data, $this->parser->parse($yml));
}

public function testDumpMultiLineStringAsScalarBlockWhenFirstLineIsEmptyAndSecondLineHasLeadingSpace()
{
$data = [
'data' => [
'multi_line' => "\n the second line has leading spaces\nThe third line does not.",
],
];

$expected = "data:\n multi_line: |4-\n\n the second line has leading spaces\n The third line does not.";

$yml = $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK);
$this->assertSame($expected, $yml);
$this->assertSame($data, $this->parser->parse($yml));
}

public function testDumpMultiLineStringAsScalarBlockWhenFirstLineHasOnlySpaces()
{
$data = [
'data' => [
'multi_line' => " \nthe second line\nThe third line.",
],
];

$expectedData = [
'data' => [
'multi_line' => "\nthe second line\nThe third line.",
],
];

$expectedYml = "data:\n multi_line: |-\n \n the second line\n The third line.";

$yml = $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK);
$this->assertSame($expectedYml, $yml);
$this->assertSame($expectedData, $this->parser->parse($yml));
}

public function testCarriageReturnFollowedByNewlineIsMaintainedWhenDumpingAsMultiLineLiteralBlock()
{
$data = ["a\r\nb\nc"];
Expand Down

0 comments on commit 4cd2e3e

Please sign in to comment.