mirror of
https://github.com/fenom-template/fenom.git
synced 2023-08-10 21:13:07 +03:00
commit
00eaafc39f
@ -13,4 +13,4 @@ script:
|
|||||||
- phpunit
|
- phpunit
|
||||||
|
|
||||||
after_script:
|
after_script:
|
||||||
- php vendor/bin/coveralls
|
- CODECLIMATE_REPO_TOKEN=6739bff0f9a6eb7eaa5cfd1b086b55a3413aff24991d793b5b12da91c3803471 ./vendor/bin/test-reporter
|
@ -16,7 +16,7 @@
|
|||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "*",
|
"phpunit/phpunit": "*",
|
||||||
"satooshi/php-coveralls": "dev-master"
|
"codeclimate/php-test-reporter": "dev-master"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-0": { "Fenom\\": "src/" },
|
"psr-0": { "Fenom\\": "src/" },
|
||||||
|
@ -11,7 +11,7 @@ instead of `ematch` for frontend search expression input may be way more conveni
|
|||||||
|
|
||||||
Special pattern symbols:
|
Special pattern symbols:
|
||||||
|
|
||||||
* `?` — match one or zero unknown characters. `?at` matches `Cat`, `cat`, `Bat` or `bat`, `but` not `at`.
|
* `?` — match one or zero unknown characters. `?at` matches `Cat`, `cat`, `Bat` or `bat` but not `at`.
|
||||||
* `*` — match any number of unknown characters. `Law*` matches `Law`, `Laws`, or `Lawyer`.
|
* `*` — match any number of unknown characters. `Law*` matches `Law`, `Laws`, or `Lawyer`.
|
||||||
* `[characters]` — Match a character as part of a group of characters. `[CB]at` matches `Cat` or `Bat` but not `cat`, `rat` or `bat`.
|
* `[characters]` — Match a character as part of a group of characters. `[CB]at` matches `Cat` or `Bat` but not `cat`, `rat` or `bat`.
|
||||||
* `\` - Escape character. `Law\*` will only match `Law*`
|
* `\` - Escape character. `Law\*` will only match `Law*`
|
||||||
|
@ -39,6 +39,5 @@
|
|||||||
</filter>
|
</filter>
|
||||||
<logging>
|
<logging>
|
||||||
<log type="coverage-clover" target="build/logs/clover.xml"/>
|
<log type="coverage-clover" target="build/logs/clover.xml"/>
|
||||||
<!--<log type="coverage-php" target="build/cov/coverage.cov"/>-->
|
|
||||||
</logging>
|
</logging>
|
||||||
</phpunit>
|
</phpunit>
|
@ -49,12 +49,6 @@ class Template extends Render
|
|||||||
*/
|
*/
|
||||||
public $blocks = array();
|
public $blocks = array();
|
||||||
|
|
||||||
/**
|
|
||||||
* Escape outputs value
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
public $escape = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string|null
|
* @var string|null
|
||||||
*/
|
*/
|
||||||
@ -195,11 +189,9 @@ class Template extends Render
|
|||||||
public function compile()
|
public function compile()
|
||||||
{
|
{
|
||||||
$end = $pos = 0;
|
$end = $pos = 0;
|
||||||
$this->escape = $this->_options & Fenom::AUTO_ESCAPE;
|
|
||||||
foreach ($this->_fenom->getPreFilters() as $filter) {
|
foreach ($this->_fenom->getPreFilters() as $filter) {
|
||||||
$this->_src = call_user_func($filter, $this, $this->_src);
|
$this->_src = call_user_func($filter, $this, $this->_src);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (($start = strpos($this->_src, '{', $pos)) !== false) { // search open-symbol of tags
|
while (($start = strpos($this->_src, '{', $pos)) !== false) { // search open-symbol of tags
|
||||||
switch ($this->_src[$start + 1]) { // check next character
|
switch ($this->_src[$start + 1]) { // check next character
|
||||||
case "\n":
|
case "\n":
|
||||||
@ -232,37 +224,35 @@ class Template extends Render
|
|||||||
}
|
}
|
||||||
$tag = substr(
|
$tag = substr(
|
||||||
$this->_src,
|
$this->_src,
|
||||||
$start,
|
$start + 1, // skip '{'
|
||||||
$end - $start + 1
|
$end - $start - 1 // skip '}'
|
||||||
); // variable $tag contains fenom tag '{...}'
|
);
|
||||||
|
|
||||||
$_tag = substr($tag, 1, -1); // strip delimiters '{' and '}'
|
|
||||||
|
|
||||||
if ($this->_ignore) { // check ignore
|
if ($this->_ignore) { // check ignore
|
||||||
if ($_tag === '/' . $this->_ignore) { // turn off ignore
|
if ($tag === '/' . $this->_ignore) { // turn off ignore
|
||||||
$this->_ignore = false;
|
$this->_ignore = false;
|
||||||
} else { // still ignore
|
} else { // still ignore
|
||||||
$this->_appendText($tag);
|
$this->_appendText('{' . $tag . '}');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->_tag_filters) {
|
if ($this->_tag_filters) {
|
||||||
foreach ($this->_tag_filters as $filter) {
|
foreach ($this->_tag_filters as $filter) {
|
||||||
$_tag = call_user_func($filter, $_tag, $this);
|
$tag = call_user_func($filter, $tag, $this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$tokens = new Tokenizer($_tag); // tokenize the tag
|
$tokens = new Tokenizer($tag); // tokenize the tag
|
||||||
if ($tokens->isIncomplete()) { // all strings finished?
|
if ($tokens->isIncomplete()) { // all strings finished?
|
||||||
$need_more = true;
|
$need_more = true;
|
||||||
} else {
|
} else {
|
||||||
$this->_appendCode($this->parseTag($tokens), $tag); // start the tag lexer
|
$this->_appendCode($this->parseTag($tokens), '{' . $tag . '}'); // start the tag lexer
|
||||||
if ($tokens->key()) { // if tokenizer have tokens - throws exceptions
|
if ($tokens->key()) { // if tokenizer have tokens - throws exceptions
|
||||||
throw new CompileException("Unexpected token '" . $tokens->current() . "' in {$this} line {$this->_line}, near '{" . $tokens->getSnippetAsString(0, 0) . "' <- there", 0, E_ERROR, $this->_name, $this->_line);
|
throw new CompileException("Unexpected token '" . $tokens->current() . "' in {$this} line {$this->_line}, near '{" . $tokens->getSnippetAsString(0, 0) . "' <- there", 0, E_ERROR, $this->_name, $this->_line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while ($need_more);
|
} while ($need_more);
|
||||||
unset($_tag, $tag); // cleanup
|
unset($tag); // cleanup
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$pos = $end + 1; // move search-pointer to end of the tag
|
$pos = $end + 1; // move search-pointer to end of the tag
|
||||||
@ -272,17 +262,13 @@ class Template extends Render
|
|||||||
$this->_appendText(substr($this->_src, $end ? $end + 1 : 0)); // append tail of the template
|
$this->_appendText(substr($this->_src, $end ? $end + 1 : 0)); // append tail of the template
|
||||||
if ($this->_stack) {
|
if ($this->_stack) {
|
||||||
$_names = array();
|
$_names = array();
|
||||||
$_line = 0;
|
|
||||||
foreach ($this->_stack as $scope) {
|
foreach ($this->_stack as $scope) {
|
||||||
if (!$_line) {
|
|
||||||
$_line = $scope->line;
|
|
||||||
}
|
|
||||||
$_names[] = '{' . $scope->name . '} opened on line ' . $scope->line;
|
$_names[] = '{' . $scope->name . '} opened on line ' . $scope->line;
|
||||||
}
|
}
|
||||||
throw new CompileException("Unclosed tag" . (count($_names) == 1 ? "" : "s") . ": " . implode(
|
throw new CompileException("Unclosed tag" . (count($_names) > 1 ? "s" : "") . ": " . implode(
|
||||||
", ",
|
", ",
|
||||||
$_names
|
$_names
|
||||||
), 0, 1, $this->_name, $_line);
|
), 0, 1, $this->_name, $scope->line); // $scope already defined there!
|
||||||
}
|
}
|
||||||
$this->_src = ""; // cleanup
|
$this->_src = ""; // cleanup
|
||||||
if ($this->_post) {
|
if ($this->_post) {
|
||||||
@ -778,12 +764,12 @@ class Template extends Render
|
|||||||
$unary = "";
|
$unary = "";
|
||||||
}
|
}
|
||||||
if ($tokens->is(T_LNUMBER, T_DNUMBER)) {
|
if ($tokens->is(T_LNUMBER, T_DNUMBER)) {
|
||||||
$code = $unary . $this->parseScalar($tokens, true);
|
return $unary . $this->parseScalar($tokens, true);
|
||||||
} elseif ($tokens->is(T_CONSTANT_ENCAPSED_STRING, '"', T_ENCAPSED_AND_WHITESPACE)) {
|
} elseif ($tokens->is(T_CONSTANT_ENCAPSED_STRING, '"', T_ENCAPSED_AND_WHITESPACE)) {
|
||||||
if ($unary) {
|
if ($unary) {
|
||||||
throw new UnexpectedTokenException($tokens->back());
|
throw new UnexpectedTokenException($tokens->back());
|
||||||
}
|
}
|
||||||
$code = $this->parseScalar($tokens, true);
|
return $this->parseScalar($tokens, true);
|
||||||
} elseif ($tokens->is(T_VARIABLE)) {
|
} elseif ($tokens->is(T_VARIABLE)) {
|
||||||
$code = $unary . $this->parseVariable($tokens);
|
$code = $unary . $this->parseVariable($tokens);
|
||||||
if ($tokens->is("(") && $tokens->hasBackList(T_STRING, T_OBJECT_OPERATOR)) {
|
if ($tokens->is("(") && $tokens->hasBackList(T_STRING, T_OBJECT_OPERATOR)) {
|
||||||
@ -803,28 +789,30 @@ class Template extends Render
|
|||||||
} else {
|
} else {
|
||||||
$is_var = true;
|
$is_var = true;
|
||||||
}
|
}
|
||||||
|
return $code;
|
||||||
} elseif ($tokens->is('$')) {
|
} elseif ($tokens->is('$')) {
|
||||||
$var = $this->parseAccessor($tokens, $is_var);
|
$var = $this->parseAccessor($tokens, $is_var);
|
||||||
$code = $unary . $var;
|
return $unary . $var;
|
||||||
} elseif ($tokens->is(Tokenizer::MACRO_INCDEC)) {
|
} elseif ($tokens->is(Tokenizer::MACRO_INCDEC)) {
|
||||||
$code = $unary . $tokens->getAndNext() . $this->parseVariable($tokens);
|
return $unary . $tokens->getAndNext() . $this->parseVariable($tokens);
|
||||||
} elseif ($tokens->is("(")) {
|
} elseif ($tokens->is("(")) {
|
||||||
$tokens->next();
|
$tokens->next();
|
||||||
$code = $unary . "(" . $this->parseExpr($tokens) . ")";
|
$code = $unary . "(" . $this->parseExpr($tokens) . ")";
|
||||||
$tokens->need(")")->next();
|
$tokens->need(")")->next();
|
||||||
|
return $code;
|
||||||
} elseif ($tokens->is(T_STRING)) {
|
} elseif ($tokens->is(T_STRING)) {
|
||||||
if ($tokens->isSpecialVal()) {
|
if ($tokens->isSpecialVal()) {
|
||||||
$code = $unary . $tokens->getAndNext();
|
return $unary . $tokens->getAndNext();
|
||||||
} elseif ($tokens->isNext("(") && !$tokens->getWhitespace()) {
|
} elseif ($tokens->isNext("(") && !$tokens->getWhitespace()) {
|
||||||
$func = $this->_fenom->getModifier($tokens->current(), $this);
|
$func = $this->_fenom->getModifier($tokens->current(), $this);
|
||||||
if (!$func) {
|
if (!$func) {
|
||||||
throw new \Exception("Function " . $tokens->getAndNext() . " not found");
|
throw new \Exception("Function " . $tokens->getAndNext() . " not found");
|
||||||
}
|
}
|
||||||
$code = $unary . $func . $this->parseArgs($tokens->next());
|
return $unary . $func . $this->parseArgs($tokens->next());
|
||||||
} elseif ($tokens->isNext(T_NS_SEPARATOR, T_DOUBLE_COLON)) {
|
} elseif ($tokens->isNext(T_NS_SEPARATOR, T_DOUBLE_COLON)) {
|
||||||
$method = $this->parseStatic($tokens);
|
$method = $this->parseStatic($tokens);
|
||||||
$args = $this->parseArgs($tokens);
|
$args = $this->parseArgs($tokens);
|
||||||
$code = $unary . $method . $args;
|
return $unary . $method . $args;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -833,6 +821,7 @@ class Template extends Render
|
|||||||
if ($tokens->is("(") && $tokens->isNext(T_VARIABLE)) {
|
if ($tokens->is("(") && $tokens->isNext(T_VARIABLE)) {
|
||||||
$code = $unary . $func . "(" . $this->parseVariable($tokens->next()) . ")";
|
$code = $unary . $func . "(" . $this->parseVariable($tokens->next()) . ")";
|
||||||
$tokens->need(')')->next();
|
$tokens->need(')')->next();
|
||||||
|
return $code;
|
||||||
} else {
|
} else {
|
||||||
throw new TokenizeException("Unexpected token " . $tokens->getNext() . ", isset() and empty() accept only variables");
|
throw new TokenizeException("Unexpected token " . $tokens->getNext() . ", isset() and empty() accept only variables");
|
||||||
}
|
}
|
||||||
@ -840,14 +829,12 @@ class Template extends Render
|
|||||||
if ($unary) {
|
if ($unary) {
|
||||||
throw new UnexpectedTokenException($tokens->back());
|
throw new UnexpectedTokenException($tokens->back());
|
||||||
}
|
}
|
||||||
$code = $this->parseArray($tokens);
|
return $this->parseArray($tokens);
|
||||||
} elseif ($unary) {
|
} elseif ($unary) {
|
||||||
throw new UnexpectedTokenException($tokens->back());
|
throw new UnexpectedTokenException($tokens->back());
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user