bug #15482 [Yaml] Improve newline handling in folded scalar blocks (teohhanhui)
This PR was merged into the 2.3 branch.
Discussion
----------
[Yaml] Improve newline handling in folded scalar blocks
| Q | A
| ------------- | ---
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #15477
| License | MIT
| Doc PR | N/A
Commits
-------
73366d5
[Yaml] Improve newline handling in folded scalar blocks
This commit is contained in:
commit
c0ff4bfbbc
@ -20,7 +20,9 @@ use Symfony\Component\Yaml\Exception\ParseException;
|
|||||||
*/
|
*/
|
||||||
class Parser
|
class Parser
|
||||||
{
|
{
|
||||||
const FOLDED_SCALAR_PATTERN = '(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments> +#.*)?';
|
const BLOCK_SCALAR_HEADER_PATTERN = '(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments> +#.*)?';
|
||||||
|
// BC - wrongly named
|
||||||
|
const FOLDED_SCALAR_PATTERN = self::BLOCK_SCALAR_HEADER_PATTERN;
|
||||||
|
|
||||||
private $offset = 0;
|
private $offset = 0;
|
||||||
private $lines = array();
|
private $lines = array();
|
||||||
@ -337,8 +339,8 @@ class Parser
|
|||||||
|
|
||||||
$isItUnindentedCollection = $this->isStringUnIndentedCollectionItem($this->currentLine);
|
$isItUnindentedCollection = $this->isStringUnIndentedCollectionItem($this->currentLine);
|
||||||
|
|
||||||
// Comments must not be removed inside a string block (ie. after a line ending with "|")
|
// Comments must not be removed inside a block scalar
|
||||||
$removeCommentsPattern = '~'.self::FOLDED_SCALAR_PATTERN.'$~';
|
$removeCommentsPattern = '~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~';
|
||||||
$removeComments = !preg_match($removeCommentsPattern, $this->currentLine);
|
$removeComments = !preg_match($removeCommentsPattern, $this->currentLine);
|
||||||
|
|
||||||
while ($this->moveToNextLine()) {
|
while ($this->moveToNextLine()) {
|
||||||
@ -427,10 +429,10 @@ class Parser
|
|||||||
return $this->refs[$value];
|
return $this->refs[$value];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preg_match('/^'.self::FOLDED_SCALAR_PATTERN.'$/', $value, $matches)) {
|
if (preg_match('/^'.self::BLOCK_SCALAR_HEADER_PATTERN.'$/', $value, $matches)) {
|
||||||
$modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : '';
|
$modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : '';
|
||||||
|
|
||||||
return $this->parseFoldedScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers));
|
return $this->parseBlockScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers));
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -444,15 +446,15 @@ class Parser
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a folded scalar.
|
* Parses a block scalar.
|
||||||
*
|
*
|
||||||
* @param string $separator The separator that was used to begin this folded scalar (| or >)
|
* @param string $style The style indicator that was used to begin this block scalar (| or >)
|
||||||
* @param string $indicator The indicator that was used to begin this folded scalar (+ or -)
|
* @param string $chomping The chomping indicator that was used to begin this block scalar (+ or -)
|
||||||
* @param int $indentation The indentation that was used to begin this folded scalar
|
* @param int $indentation The indentation indicator that was used to begin this block scalar
|
||||||
*
|
*
|
||||||
* @return string The text value
|
* @return string The text value
|
||||||
*/
|
*/
|
||||||
private function parseFoldedScalar($separator, $indicator = '', $indentation = 0)
|
private function parseBlockScalar($style, $chomping = '', $indentation = 0)
|
||||||
{
|
{
|
||||||
$notEOF = $this->moveToNextLine();
|
$notEOF = $this->moveToNextLine();
|
||||||
if (!$notEOF) {
|
if (!$notEOF) {
|
||||||
@ -507,17 +509,23 @@ class Parser
|
|||||||
$this->moveToPreviousLine();
|
$this->moveToPreviousLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace all non-trailing single newlines with spaces in folded blocks
|
// folded style
|
||||||
if ('>' === $separator) {
|
if ('>' === $style) {
|
||||||
|
// folded lines
|
||||||
|
// replace all non-leading/non-trailing single newlines with spaces
|
||||||
preg_match('/(\n*)$/', $text, $matches);
|
preg_match('/(\n*)$/', $text, $matches);
|
||||||
$text = preg_replace('/(?<!\n)\n(?!\n)/', ' ', rtrim($text, "\n"));
|
$text = preg_replace('/(?<!\n|^)\n(?!\n)/', ' ', rtrim($text, "\n"));
|
||||||
$text .= $matches[1];
|
$text .= $matches[1];
|
||||||
|
|
||||||
|
// empty separation lines
|
||||||
|
// remove one newline from each group of non-leading/non-trailing newlines
|
||||||
|
$text = preg_replace('/[^\n]\n+\K\n(?=[^\n])/', '', $text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// deal with trailing newlines as indicated
|
// deal with trailing newlines
|
||||||
if ('' === $indicator) {
|
if ('' === $chomping) {
|
||||||
$text = preg_replace('/\n+$/', "\n", $text);
|
$text = preg_replace('/\n+$/', "\n", $text);
|
||||||
} elseif ('-' === $indicator) {
|
} elseif ('-' === $chomping) {
|
||||||
$text = preg_replace('/\n+$/', '', $text);
|
$text = preg_replace('/\n+$/', '', $text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,9 +51,9 @@ php: |
|
|||||||
'~',
|
'~',
|
||||||
)
|
)
|
||||||
---
|
---
|
||||||
test: Empty lines in folded blocks
|
test: Empty lines in literal blocks
|
||||||
brief: >
|
brief: >
|
||||||
Empty lines in folded blocks
|
Empty lines in literal blocks
|
||||||
yaml: |
|
yaml: |
|
||||||
foo:
|
foo:
|
||||||
bar: |
|
bar: |
|
||||||
@ -65,6 +65,20 @@ yaml: |
|
|||||||
php: |
|
php: |
|
||||||
array('foo' => array('bar' => "foo\n\n\n \nbar\n"))
|
array('foo' => array('bar' => "foo\n\n\n \nbar\n"))
|
||||||
---
|
---
|
||||||
|
test: Empty lines in folded blocks
|
||||||
|
brief: >
|
||||||
|
Empty lines in folded blocks
|
||||||
|
yaml: |
|
||||||
|
foo:
|
||||||
|
bar: >
|
||||||
|
|
||||||
|
foo
|
||||||
|
|
||||||
|
|
||||||
|
bar
|
||||||
|
php: |
|
||||||
|
array('foo' => array('bar' => "\nfoo\n\nbar\n"))
|
||||||
|
---
|
||||||
test: IP addresses
|
test: IP addresses
|
||||||
brief: >
|
brief: >
|
||||||
IP addresses
|
IP addresses
|
||||||
|
Reference in New Issue
Block a user