Skip to content

Commit

Permalink
feature #21114 [Yaml] parse multi-line strings (xabbuh)
Browse files Browse the repository at this point in the history
This PR was merged into the 3.3-dev branch.

Discussion
----------

[Yaml] parse multi-line strings

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

When working on #21084, I discovered that the YAML parser does not support (unquoted) multi-line strings (neither as plain strings nor as values for mappings). This PR adds support for them.

Commits
-------

ec593b923b [Yaml] parse multi-line strings
  • Loading branch information
fabpot committed Jan 8, 2017
2 parents 22c2fd4 + e06c215 commit a5c421b
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
36 changes: 36 additions & 0 deletions Parser.php
Expand Up @@ -295,6 +295,42 @@ public function parse($value, $flags = 0)
return $value;
}

// try to parse the value as a multi-line string as a last resort
if (0 === $this->currentLineNb) {
$parseError = false;
$previousLineWasNewline = false;
$value = '';

foreach ($this->lines as $line) {
try {
$parsedLine = Inline::parse($line, $flags, $this->refs);

if (!is_string($value)) {
$parseError = true;
break;
}

if ('' === trim($parsedLine)) {
$value .= "\n";
$previousLineWasNewline = true;
} elseif ($previousLineWasNewline) {
$value .= trim($parsedLine);
$previousLineWasNewline = false;
} else {
$value .= ' '.trim($parsedLine);
$previousLineWasNewline = false;
}
} catch (ParseException $e) {
$parseError = true;
break;
}
}

if (!$parseError) {
return trim($value);
}
}

switch (preg_last_error()) {
case PREG_INTERNAL_ERROR:
$error = 'Internal PCRE error.';
Expand Down
26 changes: 26 additions & 0 deletions Tests/ParserTest.php
Expand Up @@ -1465,6 +1465,32 @@ public function testParseMultiLineUnquotedString()

$this->assertSame(array('foo' => 'bar baz foobar foo', 'bar' => 'baz'), $this->parser->parse($yaml));
}

public function testParseMultiLineString()
{
$this->assertEquals("foo bar\nbaz", $this->parser->parse("foo\nbar\n\nbaz"));
}

public function testParseMultiLineMappingValue()
{
$yaml = <<<'EOF'
foo:
- bar:
one
two
three
EOF;
$expected = array(
'foo' => array(
array(
'bar' => "one\ntwo three",
),
),
);

$this->assertEquals($expected, $this->parser->parse($yaml));
}
}

class B
Expand Down

0 comments on commit a5c421b

Please sign in to comment.