klein/klein.php
2015-12-02 00:39:27 +03:00

48 lines
1.6 KiB
PHP

<?php
class Klein {
private $code;
function compile($html) {
$arg = function($name) {
$list = explode(".", $name);
$first = array_shift($list);
return "$first" . implode("", array_map(function($x) { return "['$x']"; }, $list));
};
$rx = function ($grammar) use ($arg) {
list($pattern, $result) = $grammar;
$body = strtr($pattern, [" " => "\s*", "+" => "\s+", ":v" => "(\w+(\s*\.\s*\w+)*)", ":x" => "(\w+)"]);
return ["/$body/",
function ($x) use ($result, $arg) {
$body = preg_replace_callback("/#(\d+)/", function ($s) use($x, $arg) {
return $arg($x[$s[1]]);
}, $result);
return "<?php $body ?>";
}];
};
$pattern = array_map($rx, [
["{% for+:v+in+:v %}", "foreach(\$#3 as \$n => \$#1): \$loop = ['first' => \$n == 0];"],
["{% endfor %}", "endforeach;"],
["{% if+:v %}", "if(isset(\$#1) && \$#1 ):"],
["{% endif %}", "endif;"],
["{{ :v }}", "echo \$#1;"],
["{{ :v\|:x }}", "echo #3(\$#1);"]
]);
$result = file_get_contents($html);
foreach($pattern as $arg) {
list($key, $value) = $arg;
$result = preg_replace_callback($key, $value, $result);
}
$this->code = $result;
}
function render($vars) {
extract($vars);
ob_start();
eval(" ?>".$this->code."<?php ");
return ob_get_clean();
}
}