Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
977ad13
Generated .editorconfig file
nael94 Jul 29, 2024
1eb93ca
Fixed issue #7: Error: @forelse with keys failed to return @empty
nael94 Jul 29, 2024
19a1877
Fixed issue #8: prepared ability to combine both conditional and stat…
nael94 Jul 29, 2024
04a2c42
Fixed issue #16: set default namespace for components '\' if not set.…
nael94 Jul 29, 2024
9962928
Fixed issue #10: it's been solved by introducing a way to customize e…
nael94 Jul 29, 2024
81603da
Fixed issue #17: introduced trimmed custom extension for a cleaner re…
nael94 Jul 29, 2024
54ae6e9
linted all files
nael94 Jul 29, 2024
67c7953
Fixed issue #11 and changed the behavior of parsing attributes: dashe…
nael94 Aug 10, 2024
f30b117
fixed suffixed namespaces due to keywords conflicts
nael94 Aug 10, 2024
440f92b
Solved issue #19: prepared notisset method
nael94 Aug 10, 2024
1a19ac5
fixed prefixing the dot only when passing extension value
nael94 Aug 17, 2024
33e9dd5
prepared new two static constants: $global to bypass the $this to be …
nael94 Aug 18, 2024
7f140c8
fixed attributes regex parsing
nael94 Aug 18, 2024
f804cab
fixed passing arrays and objects as attributes parameters
nael94 Aug 18, 2024
3e087c3
fixed issue #23: improved multilines comment block
nael94 Aug 27, 2024
7cb5372
fixed issue #5 by Crow owner but still need to avoid using `disableCo…
nael94 Feb 13, 2025
6af9287
Revert "fixed issue #5 by Crow owner but still need to avoid using `d…
nael94 Feb 13, 2025
95e37ad
fixed added parameter type `null` for php 8.4 compatibility
nael94 Mar 31, 2025
88a97a0
fixed comments regex detection
nael94 Apr 4, 2025
63b274f
Fix comment conversion regex to handle whitespace in template engine …
nael94 May 24, 2025
eb09b4a
Refactor getFilePath to handle file extensions
nael94 Nov 1, 2025
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
12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = crlf
charset = utf-8
trim_trailing_whitespace = false
insert_final_newline = false
200 changes: 98 additions & 102 deletions src/CodeConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,117 +2,113 @@

namespace Corviz\Crow;

final class CodeConverter
{
/**
* @var array
*/
private array $methods = [];

/**
* @param string $templateCode
*
* @return string
*/
public function toPhp(string $templateCode): string
{
while($this->convertMethods($templateCode, 'extends|include'));
while($this->convertMethods($templateCode));
$this->convertComments($templateCode);
$this->convertEscaped($templateCode);
$this->convertUnescaped($templateCode);

return $templateCode;
}
final class CodeConverter {
/**
* @var array
*/
private array $methods = [];

/**
* @param string $method
* @param string $class
*
* @return void
*/
public function addMethod(string $method, string $class): void
{
$this->methods[$method] = ['c' => $class, 'i' => null];
}
/**
* @param string $templateCode
*
* @return string
*/
public function toPhp(string $templateCode): string {
while ($this->convertMethods($templateCode, 'extends|include'));
while ($this->convertMethods($templateCode));
$this->convertComments($templateCode);
$this->convertEscaped($templateCode);
$this->convertUnescaped($templateCode);

/**
* @param string $templateCode
*
* @return void
*/
private function convertEscaped(string &$templateCode): void
{
$templateCode = preg_replace(
'/{{(.*?)}}/',
'<?php echo htmlentities(($1) ?? null) ?>',
$templateCode
);
}
return $templateCode;
}

/**
* @param string $templateCode
* @return void
*/
private function convertUnescaped(string &$templateCode): void
{
$templateCode = preg_replace(
'/{!!(.*?)!!}/',
'<?php echo ($1) ?? null ?>',
$templateCode
);
}
/**
* @param string $method
* @param string $class
*
* @return void
*/
public function addMethod(string $method, string $class): void {
$this->methods[$method] = ['c' => $class, 'i' => null];
}

/**
* @param string $templateCode
* @return void
*/
private function convertComments(string &$templateCode): void
{
$templateCode = preg_replace(
'/{{--(.*?)--}}/',
'<?php /** $1 */ ?>',
$templateCode
);
}
/**
* @param string $templateCode
*
* @return void
*/
private function convertEscaped(string &$templateCode): void {
$templateCode = preg_replace(
'/{{(.*?)}}/',
'<?php echo htmlentities(($1) ?? null) ?>',
$templateCode
);
}

/**
* @param string $templateCode
* @return int
*/
private function convertMethods(string &$templateCode, string $tag = null): int
{
$count = 0;

if (is_null($tag)) {
$methods = array_keys($this->methods);
//Evaluate longer named methods first
usort($methods, function ($a, $b) {
return strlen($b) <=> strlen($a);
});
$tag = implode('|', $methods);
}
/**
* @param string $templateCode
* @return void
*/
private function convertUnescaped(string &$templateCode): void {
$templateCode = preg_replace(
'/{!!(.*?)!!}/',
'<?php echo ($1) ?? null ?>',
$templateCode
);
}

$templateCode = preg_replace_callback(
'/@('.$tag.')\s*(\(((?:[^()]++|(\g<2>))*)\))?/m',
function($match){
if (isset($this->methods[$match[1]])) {
if (!$this->methods[$match[1]]['i']) {
$this->methods[$match[1]]['i'] = $this->methods[$match[1]]['c']::create();
}
/**
* @param string $templateCode
* @return void
*/
private function convertComments(string &$templateCode): void {
$templateCode = preg_replace(
// '/{{--(.*?)--}}/s', // old
'/{{--\s*(.*?)\s*--}}/s',
'<?php /** $1 */ ?>',
$templateCode
);
}

/* @var $method Method */
$method = $this->methods[$match[1]]['i'];
/**
* @param string $templateCode
* @return int
*/
private function convertMethods(string &$templateCode, string|null $tag = null): int {
$count = 0;

return $method->toPhpCode($match[3] ?? null);
}
if (is_null($tag)) {
$methods = array_keys($this->methods);

return $match[0];
},
$templateCode,
count: $count
);
// Evaluate longer named methods first
usort($methods, function ($a, $b) {
return strlen($b) <=> strlen($a);
});

return $count;
$tag = implode('|', $methods);
}

$templateCode = preg_replace_callback(
'/@(' . $tag . ')\s*(\(((?:[^()]++|(\g<2>))*)\))?/m',
function ($match) {
if (isset($this->methods[$match[1]])) {
if (!$this->methods[$match[1]]['i']) {
$this->methods[$match[1]]['i'] = $this->methods[$match[1]]['c']::create();
}

/* @var $method Method */
$method = $this->methods[$match[1]]['i'];

return $method->toPhpCode($match[3] ?? null);
}

return $match[0];
},
$templateCode,
count: $count
);

return $count;
}
}
Loading