From b3cb0ff9fac49b70dfb9a332c78943624b3bb49b Mon Sep 17 00:00:00 2001 From: Inhere Date: Sun, 8 Jan 2023 23:31:58 +0800 Subject: [PATCH] up: compiler support unwrap php tag for custom directive --- src/Compiler/AbstractCompiler.php | 17 +++++++++++++++-- src/Compiler/PregCompiler.php | 23 +++++++++++++---------- test/Compiler/PregCompilerTest.php | 2 +- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/Compiler/AbstractCompiler.php b/src/Compiler/AbstractCompiler.php index b2c78f2..1c4d0f5 100644 --- a/src/Compiler/AbstractCompiler.php +++ b/src/Compiler/AbstractCompiler.php @@ -97,6 +97,11 @@ abstract class AbstractCompiler implements CompilerInterface */ protected array $directiveNames = []; + /** + * @var array will not wrap PHP tag to directive result. + */ + protected array $unwrapDirectives = []; + /** * @return static */ @@ -216,12 +221,20 @@ public function addFilter(string $name, string $callExpr): self /** * @param string $name * @param callable $handler + * @param bool $unwrap * * @return static */ - public function addDirective(string $name, callable $handler): static + public function addDirective(string $name, callable $handler, bool $unwrap = false): static { - $this->directiveNames[] = $name; + if (!isset($this->customDirectives[$name])) { + $this->directiveNames[] = $name; + } + + if ($unwrap) { + $this->unwrapDirectives[] = $name; + } + $this->customDirectives[$name] = $handler; return $this; diff --git a/src/Compiler/PregCompiler.php b/src/Compiler/PregCompiler.php index d32688b..4b4c3a6 100644 --- a/src/Compiler/PregCompiler.php +++ b/src/Compiler/PregCompiler.php @@ -10,6 +10,7 @@ namespace PhpPkg\EasyTpl\Compiler; use function addslashes; +use function in_array; use function preg_match; use function preg_replace; use function preg_replace_callback; @@ -87,7 +88,12 @@ public function compile(string $tplCode): string return preg_replace_callback( "~$openTagE\s*(.+?)$closeTagE~s", // Amixu, iu, s function (array $matches) { - return $this->parseCodeBlock($matches[1]); + // empty line, keep it. + if (!$trimmed = trim($matches[1])) { + return $matches[1]; + } + + return $this->parseCodeBlock($trimmed); }, $tplCode, -1, @@ -129,24 +135,20 @@ protected function buildMatchPatterns(): void * - 'include' * - 'block' * - * @param string $block + * @param string $trimmed trimmed block string. * * @return string */ - public function parseCodeBlock(string $block): string + public function parseCodeBlock(string $trimmed): string { - // empty line, keep it. - if (!$trimmed = trim($block)) { - return $block; - } - // special '}' - end char for `if, for, foreach, switch` if ($trimmed === '}') { return self::PHP_TAG_OPEN . ' } ' . self::PHP_TAG_CLOSE; } $directive = ''; - $isInline = !str_contains($trimmed, "\n"); + $unwrapRet = false; + $isInline = !str_contains($trimmed, "\n"); // default is define statement. $type = Token::T_DEFINE; @@ -197,6 +199,7 @@ public function parseCodeBlock(string $block): string // support user add special directives. $directive = $type = $matches[1]; $handlerFn = $this->customDirectives[$directive]; + $unwrapRet = in_array($directive, $this->unwrapDirectives, true); $trimmed = $handlerFn(substr($trimmed, strlen($directive)), $directive); } elseif ($isInline && !str_contains($trimmed, '=')) { @@ -207,7 +210,7 @@ public function parseCodeBlock(string $block): string // not need continue handle if ($directive || Token::isAloneToken($type)) { - return $open . $trimmed . $close; + return $unwrapRet ? $trimmed : $open . $trimmed . $close; } // inline echo support filters diff --git a/test/Compiler/PregCompilerTest.php b/test/Compiler/PregCompilerTest.php index 36c8878..5fc219e 100644 --- a/test/Compiler/PregCompilerTest.php +++ b/test/Compiler/PregCompilerTest.php @@ -92,7 +92,7 @@ public function testCompileCode_inline_echo():void ['{{= __LINE__ }}', ''], ['{{ echo __LINE__ }}', ''], ['{{ SomeClass::NAME }}', ''], - ['{{ echo SomeClass::NAME }}', ''], + ['{{ echo SomeClass::NAME }}', ''], // prop ['{{ SomeClass::$name }}', ''], // var