public function parse($string) { $lastCond = null; $keywords = array('ifnot', 'if', 'else', 'for', 'loop', '@', '/ifnot', '/if', '/for', '/loop'); foreach (array_keys($this->template->getFunctions()) as $function) { $keywords[] = $function; } $stack = array('children' => array(array('type' => 'string', 'body' => ''))); $stack['children'][0]['parent'] =& $stack; $current =& $stack['children'][0]; while (!empty($string)) { $current['body'] .= $this->readUntil('{', $string); if (!empty($string)) { $gotKeyword = false; foreach ($keywords as $keyword) { $kwLen = strlen($keyword) + 1; if (substr($string, 0, $kwLen) == '{' . $keyword) { $gotKeyword = true; $item = array('type' => $keyword, 'cond' => '', 'children' => ''); $string = substr($string, $kwLen); $cond = trim($this->readUntil('}', $string)); $item['cond'] = $cond; $lastCond = $cond; $string = substr($string, 1); if (substr($string, 0, 1) == "\n") { $string = substr($string, 1); } if (array_key_exists($keyword, $this->template->getFunctions())) { $item['function_name'] = $keyword; $item['type'] = 'function'; } $str = array('type' => 'string', 'body' => ''); $parent =& $current['parent']; if (substr($current['body'], 0 - strlen(PHP_EOL)) === PHP_EOL) { $current['body'] = substr($current['body'], 0, strlen($current['body']) - strlen(PHP_EOL)); } $item['parent'] =& $parent; $parent['children'][] = $item; if ($keyword == '@' || $item['type'] == 'function') { // If we're processing a variable, add a string to the parent // and move up to that as current. $parent['children'][] = $str; $current =& $parent['children'][count($parent['children']) - 1]; $current['parent'] =& $parent; } elseif (substr($keyword, 0, 1) == '/') { // If we're processing the end of a block (if/loop), add a string to the // parent's parent and move up to that. $parent =& $parent['parent']; $parent['children'][] = $str; $current =& $parent['children'][count($parent['children']) - 1]; $current['parent'] =& $parent; } else { $parent['children'][count($parent['children']) - 1]['children'][] = $str; $current =& $parent['children'][count($parent['children']) - 1]['children'][0]; $current['parent'] =& $parent['children'][count($parent['children']) - 1]; } break; } } if (!$gotKeyword) { $current['body'] .= substr($string, 0, 1); $string = substr($string, 1); } } } return $this->processStack($stack); }