Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 4 additions & 3 deletions h2o/datatype.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,12 @@ static function exec($args, $context) {
* $type of token, Block | Variable
*/
class H2o_Token {
function __construct ($type, $content, $position) {
function __construct ($type, $content, $position, $raw) {
$this->type = $type;
$this->content = $content;
$this->result='';
$this->position = $position;
$this->raw = $raw;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to correctly capture the whitespace associated with tokens an extra field capturing the entire match is required.

I have assumed capturing whitespace is important in almost all use cases of {% raw %} tag

}

function write($content){
Expand Down Expand Up @@ -98,10 +99,10 @@ function pop() {
return array_pop($this->stream);
}

function feed($type, $contents, $position) {
function feed($type, $contents, $position, $raw) {
if ($this->closed)
throw new Exception('cannot feed closed stream');
$this->stream[] = new H2o_Token($type, $contents, $position);
$this->stream[] = new H2o_Token($type, $contents, $position, $raw);
}

function push($token) {
Expand Down
41 changes: 34 additions & 7 deletions h2o/parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,20 @@ function tokenize($source) {

foreach ($matches as $match) {
if ($match[1])
$result->feed('text', $match[1], $pos);
$tagpos = $pos + strlen($match[1]);
$result->feed('text', $match[1], $pos, $match[1]);
$pretext_len = strlen($match[1]);
$tagpos = $pos + $pretext_len;
$raw_text = substr($match[0], $pretext_len);
if ($match[2])
$result->feed('block', trim($match[2]), $tagpos);
$result->feed('block', trim($match[2]), $tagpos, $raw_text);
elseif ($match[3])
$result->feed('variable', trim($match[3]), $tagpos);
$result->feed('variable', trim($match[3]), $tagpos, $raw_text);
elseif ($match[4])
$result->feed('comment', trim($match[4]), $tagpos);
$result->feed('comment', trim($match[4]), $tagpos, $raw_text);
$pos += strlen($match[0]);
}
if ($pos < strlen($source)){
$result->feed('text', substr($source, $pos), $pos);
$result->feed('text', substr($source, $pos), $pos, substr($source, $pos));
}
$result->close();
return $result;
Expand Down Expand Up @@ -65,7 +67,7 @@ function __construct($source, $filename, $runtime, $options) {
function &parse() {
$until = func_get_args();
$nodelist = new NodeList($this);
while($token = $this->tokenstream->next()) {
while($token = $this->tokenstream->next()) {
//$token = $this->tokenstream->current();
switch($token->type) {
case 'text' :
Expand Down Expand Up @@ -100,6 +102,31 @@ function &parse() {
return $nodelist;
}

function &parseRaw() {
$until = func_get_args();
$nodelist = new NodeList($this);
while($token = $this->tokenstream->next()) {
//$token = $this->tokenstream->current();
switch ($token->type) {
case 'block':
if (in_array($token->content, $until)) {
$this->token = $token;
return $nodelist;
}
default:
$node = new TextNode($token->raw, $token->position);
}
$this->searching = join(',',$until);
$this->first = false;
$nodelist->append($node);
}

if ($until) {
throw new TemplateSyntaxError('Unclose tag, expecting '. $until[0]);
}
return $nodelist;
}

function skipTo($until) {
$this->parse($until);
return null;
Expand Down
12 changes: 11 additions & 1 deletion h2o/tags.php
Original file line number Diff line number Diff line change
Expand Up @@ -486,5 +486,15 @@ function render($context, $stream) {
}
}

H2o::addTag(array('block', 'extends', 'include', 'if', 'ifchanged', 'for', 'with', 'cycle', 'load', 'debug', 'comment', 'now', 'autoescape', 'csrf_token'));
class Raw_Tag extends H2o_Node {
private $body;
function __construct($argstring, $parser, $pos=0){
$this->body = $parser->parseRaw('endraw');
}
function render($context, $stream){
$this->body->render($context, $stream);
}
}

H2o::addTag(array('block', 'extends', 'include', 'if', 'ifchanged', 'for', 'with', 'cycle', 'load', 'debug', 'comment', 'now', 'autoescape', 'csrf_token', 'raw'));
?>