Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parameter and BBCode simple values with syntax tokens #66

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ composer-update:

test:
docker-compose run --rm php-${PHP} php -v
docker-compose run --rm php-${PHP} php /app/vendor/bin/phpunit -c /app/phpunit.xml.dist
docker-compose run --rm php-${PHP} php /app/vendor/bin/phpunit -c /app/phpunit.xml.dist --filter "${TEST}"
test-local:
php -v
php vendor/bin/phpunit
49 changes: 45 additions & 4 deletions src/Parser/RegularParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ final class RegularParser implements ParserInterface
const TOKEN_STRING = 6;
const TOKEN_WS = 7;

const VALUE_REGULAR = 0x01;
const VALUE_AGGRESSIVE = 0x02;

/** @var int */
public $valueMode = self::VALUE_REGULAR;

public function __construct(SyntaxInterface $syntax = null)
{
$this->lexerRegex = $this->prepareLexer($syntax ?: new CommonSyntax());
Expand Down Expand Up @@ -238,10 +244,18 @@ private function value()
return $this->match(self::TOKEN_DELIMITER, false) ? $value : false;
}

if('' !== $tmp = $this->match(self::TOKEN_STRING, false)) {
$value .= $tmp;
while('' !== $tmp = $this->match(self::TOKEN_STRING, false)) {
$value .= $tmp;
if($this->lookahead(self::TOKEN_STRING) || $this->lookahead(self::TOKEN_MARKER)) {
while(true) {
if($this->lookahead(self::TOKEN_WS) || $this->lookahead(self::TOKEN_CLOSE)) {
break;
}
if($this->lookaheadN(array(self::TOKEN_MARKER, self::TOKEN_CLOSE))) {
if($this->valueMode === self::VALUE_AGGRESSIVE) {
$value .= $this->match(null, false);
}
break;
}
$value .= $this->match(null, false);
}

return $value;
Expand Down Expand Up @@ -302,6 +316,33 @@ private function lookahead($type)
return $this->position < $this->tokensCount && $this->tokens[$this->position][0] === $type;
}

/**
* @param int[] $types
*
* @return bool
*/
private function lookaheadN(array $types)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't lookaheadN() a more general way for lookahead()? If yes, I would probably rewrite lookahead like this:

private function lookahead($type)
{
    return $this->lookaheadN([$type]);
}

{
$count = count($types);
if($this->position + $count > $this->tokensCount) {
return false;
}

$position = $this->position;
foreach($types as $type) {
// note: automatically skips whitespace tokens
if($this->tokens[$position][0] === self::TOKEN_WS) {
$position++;
}
if($type !== $this->tokens[$position][0]) {
return false;
}
$position++;
}

return true;
}

/**
* @param int|null $type
* @param bool $ws
Expand Down
33 changes: 31 additions & 2 deletions tests/ParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,12 @@ public function provideShortcodes()
array($s, '[a=0 b=0]0[/a]', array(
new ParsedShortcode(new Shortcode('a', array('b' => '0'), '0', '0'), '[a=0 b=0]0[/a]', 0),
)),
array($s, '[x=/[/] [y a=/"//] [z=http://url/] [a=http://url ]', array(
new ParsedShortcode(new Shortcode('x', array(), null, '/['), '[x=/[/]', 0),
new ParsedShortcode(new Shortcode('y', array('a' => '/"/'), null, null), '[y a=/"//]', 8),
new ParsedShortcode(new Shortcode('z', array(), null, 'http://url'), '[z=http://url/]', 19),
new ParsedShortcode(new Shortcode('a', array(), null, 'http://url'), '[a=http://url ]', 35),
)),
);

/**
Expand All @@ -246,7 +252,7 @@ public function provideShortcodes()
*
* Tests cases from array above with identifiers in the array below must be skipped.
*/
$wordpressSkip = array(3, 6, 16, 21, 22, 23, 25, 32, 33, 34, 46, 47, 49, 51);
$wordpressSkip = array(3, 6, 16, 21, 22, 23, 25, 32, 33, 34, 46, 47, 49, 51, 52);
$result = array();
foreach($tests as $key => $test) {
$syntax = array_shift($test);
Expand All @@ -270,12 +276,35 @@ public function testIssue77()
new ParsedShortcode(new Shortcode('x', array(), '', null), '[x][/x]', 3),
new ParsedShortcode(new Shortcode('y', array(), 'x', null), '[y]x[/y]', 22),
));

$this->assertShortcodes($parser->parse('[a k="v][x][/x]'), array(
new ParsedShortcode(new Shortcode('x', array(), '', null), '[x][/x]', 8),
));
}

public function testValueModeAggressive()
{
$parser = new RegularParser(new CommonSyntax());
$parser->valueMode = RegularParser::VALUE_AGGRESSIVE;
$parsed = $parser->parse('[x=/[/] [y a=/"//] [z=http://url/] [a=http://url ]');
$tested = array(
new ParsedShortcode(new Shortcode('x', array(), null, '/[/'), '[x=/[/]', 0),
new ParsedShortcode(new Shortcode('y', array('a' => '/"//'), null, null), '[y a=/"//]', 8),
new ParsedShortcode(new Shortcode('z', array(), null, 'http://url/'), '[z=http://url/]', 19),
new ParsedShortcode(new Shortcode('a', array(), null, 'http://url'), '[a=http://url ]', 35),
);

$count = count($tested);
static::assertCount($count, $parsed, 'counts');
for ($i = 0; $i < $count; $i++) {
static::assertSame($tested[$i]->getName(), $parsed[$i]->getName(), 'name');
static::assertSame($tested[$i]->getParameters(), $parsed[$i]->getParameters(), 'parameters');
static::assertSame($tested[$i]->getContent(), $parsed[$i]->getContent(), 'content');
static::assertSame($tested[$i]->getText(), $parsed[$i]->getText(), 'text');
static::assertSame($tested[$i]->getOffset(), $parsed[$i]->getOffset(), 'offset');
static::assertSame($tested[$i]->getBbCode(), $parsed[$i]->getBbCode(), 'bbCode');
}
}

public function testWordPress()
{
$parser = new WordpressParser();
Expand Down