<?php
defined('ENTRANCE') or die('ACCESS DENIED');
require_once 'Twig/Autoloader.php';
Twig_Autoloader::register();
function tpl_tokenize($name, $base_indent = 0) {
$tokens = array();
$lines = explode("\n", file_get_contents(dirname(__FILE__) . '/../templates/' . $name));
foreach ($lines as $l) {
$l = rtrim($l);
$indent = strlen($l) - strlen(ltrim($l)) + $base_indent;
$l = trim($l);
if (strlen($l) == 0) {
continue;
}
else if ($l[0] == '+') { #include
foreach (tpl_tokenize(substr(trim($l), 1), $indent) as $t) {
$tokens[] = $t;
}
}
else if ($l[0] == '-') { #comment
continue;
}
else {
$slices = explode(' / ', $l);
for ($si = 0; $si < sizeof($slices); ++$si) {
$inner_slices = explode(' | ', $slices[$si]);
foreach ($inner_slices as $inner) {
$tokens[] = array($indent + $si, $inner);
}
}
}
}
return $tokens;
}
function tpl_parse(&$tokens) {
$ret = array();
$stack = array();
$t = tpl_parse_token(array_shift($tokens));
while ($t != NULL) {
if ($t['type'] == 'nstt') {
if (!$t['opened']) {
$ret[] = str_repeat(' ', $t['indent']);
$ret[] = '<' . $t['tag'];
if (!empty($t['attr'])) {
$ret[] = ' ' . $t['attr'];
}
if (in_array($t['tag'], array(
'textarea',
))) {
$ret[] = ">";
}
else {
$ret[] = ">\n";
}
$t['opened'] = true;
}
if (empty($tokens)) {
tpl_print_close($t, $ret);
tpl_print_stack($stack, 0, $ret);
break;
}
$next = $tokens[0];
if ($next[0] > $t['indent']) { #child
array_push($stack, $t);
$t = tpl_parse_token(array_shift($tokens));
continue;
}
else if ($next[0] == $t['indent']) { #sibling
tpl_print_close($t, $ret);
$t = tpl_parse_token(array_shift($tokens));
continue;
}
else { #father
tpl_print_close($t, $ret);
tpl_print_stack($stack, $next[0], $ret);
$t = tpl_parse_token(array_shift($tokens));
continue;
}
}
else if ($t['type'] == 'stt') {
$ret[] = str_repeat(' ', $t['indent']);
$ret[] = '<' .$t['tag'] . ' ' . $t['attr'] . " />\n";
if (empty($tokens)) {
tpl_print_stack($stack, 0, $ret);
break;
}
$next = $tokens[0];
if ($next[0] > $t['indent']) {
die('template error'); #raw或者stt不能有子token
}
else if ($next[0] == $t['indent']) {
$t = tpl_parse_token(array_shift($tokens));
continue;
}
else {
tpl_print_stack($stack, $next[0], $ret);
$t = tpl_parse_token(array_shift($tokens));
continue;
}
}
else if ($t['type'] == 'raw' || $t['type'] == 'rawe') {
$ret[] = str_repeat(' ', $t['indent']);
$ret[] = $t['attr'] . "\n";
if (empty($tokens)) {
tpl_print_stack($stack, 0, $ret);
break;
}
$next = $tokens[0];
if ($next[0] > $t['indent']) {
die('template error'); #raw或者stt不能有子token
}
else if ($next[0] == $t['indent']) {
$t = tpl_parse_token(array_shift($tokens));
continue;
}
else {
tpl_print_stack($stack, $next[0], $ret);
$t = tpl_parse_token(array_shift($tokens));
continue;
}
}
}
$ret = implode('', $ret);
return $ret;
}
function tpl_print_stack(&$stack, $indent, &$ret) {
while (!empty($stack) && $stack[sizeof($stack)-1]['indent'] >= $indent) {
tpl_print_close(array_pop($stack), $ret);
}
}
function tpl_print_close($t, &$ret) {
if (!in_array($t['tag'], array(
'textarea',
))) {
$ret[] = str_repeat(' ', $t['indent']);
}
$ret[] = '</' . $t['tag'] . '>';
if (isset($t['id'])) {
$ret[] = "<!-- /{$t['id']} -->\n";
}
else {
$ret[] = "\n";
}
};
function tpl_parse_token($t) {
if ($t == NULL) {
return NULL;
}
$ret = array(
'indent' => $t[0],
'opened' => false,
);
$tok = trim(strtok($t[1], " \t"));
$ret['tag'] = $tok;
$ret['type'] = token_type($tok);
if ($ret['type'] == 'raw') {
$ret['attr'] = $t[1];
}
else if ($ret['type'] == 'rawe') {
$ret['attr'] = substr($t[1], 1);
}
else {
$classes = array();
$tag_id = null;
$attr = '';
while ($tok !== false) {
$tok = strtok(" \t");
if ($tok[0] == '.') {
$classes[] = substr($tok, 1);
}
else if ($tok[0] == '#') {
$tag_id = substr($tok, 1);
$ret['id'] = $tag_id;
}
else {
$attr .= ' ' . $tok;
}
}
if (!empty($classes)) {
$attr = 'class="' . implode(' ', $classes) . '" ' . $attr;
}
if ($tag_id != null) {
$attr = 'id="' . $tag_id . '" ' . $attr;
}
$ret['attr'] = trim($attr);
}
return $ret;
}
function tpl_compile($s, $vars = array()) {
static $loader = NULL;
$loader == NULL && $loader = new Twig_Loader_String();
static $twig = NULL;
if ($twig == NULL) {
$twig = new Twig_Environment($loader);
$twig->addFilter('url', new Twig_Filter_Function('hook_url'));
}
$template = $twig->loadTemplate($s);
$template->display($vars);
}
function tpl(&$context) {
$name = $context['tpl_name'];
$vars = $context['tpl_vars'];
if (isset($context['warnings'])) {
$vars['warnings'] = array_merge($vars['warnings'], $context['warnings']);
}
tpl_compile(tpl_parse(tpl_tokenize($name)), $vars);
}
function token_type($s) {
$non_self_terminating_tags = array(
'a', 'abbr', 'acronym', 'address',
'b', 'bdo', 'big', 'blockquote', 'body', 'button',
'caption', 'cite', 'code', 'colgroup',
'dd', 'del', 'dfn', 'div', 'dl', 'dt',
'em', 'fieldset', 'form', 'frameset',
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'html',
'i', 'iframe', 'ins', 'kbd', 'label', 'legend', 'li',
'map', 'menu', 'noframes', 'noscript', 'object', 'ol', 'optgroup',
'option', 'p', 'pre', 'q', 'samp', 'script', 'select', 'small',
'span', 'strong', 'style', 'sub', 'sup', 'table', 'tbody', 'td',
'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'tt', 'ul', 'var',
);
$self_terminating_tags = array(
'area', 'base', 'br', 'col', 'frame', 'hr', 'img', 'input',
'link', 'meta', 'param',
);
if ($s[0] == '=') {
return 'rawe';
}
if (in_array($s, $non_self_terminating_tags)) {
return 'nstt';
}
if (in_array($s, $self_terminating_tags)) {
return 'stt';
}
return 'raw';
}