|
|
@@ -42,6 +42,7 @@ var Mustache = function() { |
|
|
createParserContext: function(tokens, partials, openTag, closeTag) { |
|
|
createParserContext: function(tokens, partials, openTag, closeTag) { |
|
|
return { |
|
|
return { |
|
|
tokens: tokens, |
|
|
tokens: tokens, |
|
|
|
|
|
token: function() { return this.tokens[this.index]; }, |
|
|
index: 0, |
|
|
index: 0, |
|
|
length: tokens.length, |
|
|
length: tokens.length, |
|
|
partials: partials, |
|
|
partials: partials, |
|
|
@@ -157,19 +158,19 @@ var Mustache = function() { |
|
|
|
|
|
|
|
|
stateMachine: { |
|
|
stateMachine: { |
|
|
text: function(parserContext, contextStack) { |
|
|
text: function(parserContext, contextStack) { |
|
|
switch (parserContext.tokens[parserContext.index]) { |
|
|
|
|
|
|
|
|
switch (parserContext.token()) { |
|
|
case parserContext.openTag: |
|
|
case parserContext.openTag: |
|
|
this.commandSet.text.call(this); |
|
|
this.commandSet.text.call(this); |
|
|
|
|
|
|
|
|
return 'openMustache'; |
|
|
return 'openMustache'; |
|
|
default: |
|
|
default: |
|
|
this.send_func(parserContext.tokens[parserContext.index]); |
|
|
|
|
|
|
|
|
this.send_func(parserContext.token()); |
|
|
|
|
|
|
|
|
return 'text'; |
|
|
return 'text'; |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
openMustache: function(parserContext, contextStack) { |
|
|
openMustache: function(parserContext, contextStack) { |
|
|
switch (parserContext.tokens[parserContext.index]) { |
|
|
|
|
|
|
|
|
switch (parserContext.token()) { |
|
|
case '{': |
|
|
case '{': |
|
|
parserContext.stack.push({tagType:'unescapedVariable', subtype: 'tripleMustache'}); |
|
|
parserContext.stack.push({tagType:'unescapedVariable', subtype: 'tripleMustache'}); |
|
|
return 'keyName'; |
|
|
return 'keyName'; |
|
|
@@ -205,24 +206,24 @@ var Mustache = function() { |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
closeMustache: function(parserContext, contextStack) { |
|
|
closeMustache: function(parserContext, contextStack) { |
|
|
if (this.isWhitespace(parserContext.tokens[parserContext.index])) { |
|
|
|
|
|
|
|
|
if (this.isWhitespace(parserContext.token())) { |
|
|
return 'closeMustache'; |
|
|
return 'closeMustache'; |
|
|
} else if (parserContext.tokens[parserContext.index]===parserContext.closeTag) { |
|
|
|
|
|
|
|
|
} else if (parserContext.token()===parserContext.closeTag) { |
|
|
return this.dispatchCommand(parserContext, contextStack); |
|
|
return this.dispatchCommand(parserContext, contextStack); |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
expectClosingMustache: function(parserContext, contextStack) { |
|
|
expectClosingMustache: function(parserContext, contextStack) { |
|
|
if (parserContext.closeTag==='}}' && |
|
|
if (parserContext.closeTag==='}}' && |
|
|
parserContext.tokens[parserContext.index]==='}}') { |
|
|
|
|
|
|
|
|
parserContext.token()==='}}') { |
|
|
return 'expectClosingParenthesis'; |
|
|
return 'expectClosingParenthesis'; |
|
|
} else if (parserContext.tokens[parserContext.index]==='}') { |
|
|
|
|
|
|
|
|
} else if (parserContext.token()==='}') { |
|
|
return 'closeMustache'; |
|
|
return 'closeMustache'; |
|
|
} else { |
|
|
} else { |
|
|
throw new ParserException('Unexpected token encountered.'); |
|
|
throw new ParserException('Unexpected token encountered.'); |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
expectClosingParenthesis: function(parserContext, contextStack) { |
|
|
expectClosingParenthesis: function(parserContext, contextStack) { |
|
|
if (parserContext.tokens[parserContext.index]==='}') { |
|
|
|
|
|
|
|
|
if (parserContext.token()==='}') { |
|
|
return this.dispatchCommand(parserContext, contextStack); |
|
|
return this.dispatchCommand(parserContext, contextStack); |
|
|
} else { |
|
|
} else { |
|
|
throw new ParserException('Unexpected token encountered.'); |
|
|
throw new ParserException('Unexpected token encountered.'); |
|
|
@@ -253,59 +254,59 @@ var Mustache = function() { |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
simpleKeyName: function(parserContext, contextStack) { |
|
|
simpleKeyName: function(parserContext, contextStack) { |
|
|
if (this.isWhitespace(parserContext.tokens[parserContext.index])) { |
|
|
|
|
|
|
|
|
if (this.isWhitespace(parserContext.token())) { |
|
|
return 'simpleKeyName'; |
|
|
return 'simpleKeyName'; |
|
|
} else { |
|
|
} else { |
|
|
parserContext.stack.push(parserContext.tokens[parserContext.index]); |
|
|
|
|
|
|
|
|
parserContext.stack.push(parserContext.token()); |
|
|
|
|
|
|
|
|
return 'closeMustache'; |
|
|
return 'closeMustache'; |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
setDelimiterStart: function(parserContext, contextStack) { |
|
|
setDelimiterStart: function(parserContext, contextStack) { |
|
|
if (this.isWhitespace(parserContext.tokens[parserContext.index]) || |
|
|
|
|
|
parserContext.tokens[parserContext.index]==='=') { |
|
|
|
|
|
|
|
|
if (this.isWhitespace(parserContext.token()) || |
|
|
|
|
|
parserContext.token()==='=') { |
|
|
throw new ParserException('Syntax error in Set Delimiter tag'); |
|
|
throw new ParserException('Syntax error in Set Delimiter tag'); |
|
|
} else { |
|
|
} else { |
|
|
parserContext.stack.push(parserContext.tokens[parserContext.index]); |
|
|
|
|
|
|
|
|
parserContext.stack.push(parserContext.token()); |
|
|
return 'setDelimiterStartOrWhitespace'; |
|
|
return 'setDelimiterStartOrWhitespace'; |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
setDelimiterStartOrWhitespace: function(parserContext, contextStack) { |
|
|
setDelimiterStartOrWhitespace: function(parserContext, contextStack) { |
|
|
if (this.isWhitespace(parserContext.tokens[parserContext.index])) { |
|
|
|
|
|
|
|
|
if (this.isWhitespace(parserContext.token())) { |
|
|
return 'setDelimiterEnd'; |
|
|
return 'setDelimiterEnd'; |
|
|
} else if (parserContext.tokens[parserContext.index]==='='){ |
|
|
|
|
|
|
|
|
} else if (parserContext.token()==='='){ |
|
|
throw new ParserException('Syntax error in Set Delimiter tag'); |
|
|
throw new ParserException('Syntax error in Set Delimiter tag'); |
|
|
} else { |
|
|
} else { |
|
|
parserContext.stack.push(parserContext.stack.pop() + parserContext.tokens[parserContext.index]); |
|
|
|
|
|
|
|
|
parserContext.stack.push(parserContext.stack.pop() + parserContext.token()); |
|
|
|
|
|
|
|
|
return 'setDelimiterStartOrWhitespace'; |
|
|
return 'setDelimiterStartOrWhitespace'; |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
setDelimiterEnd: function(parserContext, contextStack) { |
|
|
setDelimiterEnd: function(parserContext, contextStack) { |
|
|
if (this.isWhitespace(parserContext.tokens[parserContext.index])) { |
|
|
|
|
|
|
|
|
if (this.isWhitespace(parserContext.token())) { |
|
|
return 'setDelimiterEnd'; |
|
|
return 'setDelimiterEnd'; |
|
|
} else if (parserContext.tokens[parserContext.index]==='=') { |
|
|
|
|
|
|
|
|
} else if (parserContext.token()==='=') { |
|
|
throw new ParserException('Syntax error in Set Delimiter tag'); |
|
|
throw new ParserException('Syntax error in Set Delimiter tag'); |
|
|
} else { |
|
|
} else { |
|
|
parserContext.stack.push(parserContext.tokens[parserContext.index]); |
|
|
|
|
|
|
|
|
parserContext.stack.push(parserContext.token()); |
|
|
|
|
|
|
|
|
return 'setDelimiterEndOrEqualSign'; |
|
|
return 'setDelimiterEndOrEqualSign'; |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
setDelimiterEndOrEqualSign: function(parserContext, contextStack) { |
|
|
setDelimiterEndOrEqualSign: function(parserContext, contextStack) { |
|
|
if (parserContext.tokens[parserContext.index]==='=') { |
|
|
|
|
|
|
|
|
if (parserContext.token()==='=') { |
|
|
return 'setDelimiterExpectClosingTag'; |
|
|
return 'setDelimiterExpectClosingTag'; |
|
|
} else if (this.isWhitespace(parserContext.tokens[parserContext.index])) { |
|
|
|
|
|
|
|
|
} else if (this.isWhitespace(parserContext.token())) { |
|
|
throw new ParserException('Syntax error in Set Delimiter tag'); |
|
|
throw new ParserException('Syntax error in Set Delimiter tag'); |
|
|
} else { |
|
|
} else { |
|
|
parserContext.stack.push(parserContext.stack.pop() + parserContext.tokens[parserContext.index]); |
|
|
|
|
|
|
|
|
parserContext.stack.push(parserContext.stack.pop() + parserContext.token()); |
|
|
|
|
|
|
|
|
return 'setDelimiterEndOrEqualSign'; |
|
|
return 'setDelimiterEndOrEqualSign'; |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
setDelimiterExpectClosingTag: function(parserContext, contextStack) { |
|
|
setDelimiterExpectClosingTag: function(parserContext, contextStack) { |
|
|
if (parserContext.tokens[parserContext.index]===parserContext.closeTag) { |
|
|
|
|
|
|
|
|
if (parserContext.token()===parserContext.closeTag) { |
|
|
var newCloseTag = parserContext.stack.pop(); |
|
|
var newCloseTag = parserContext.stack.pop(); |
|
|
var newOpenTag = parserContext.stack.pop(); |
|
|
var newOpenTag = parserContext.stack.pop(); |
|
|
var command = parserContext.stack.pop(); |
|
|
var command = parserContext.stack.pop(); |
|
|
@@ -337,32 +338,32 @@ var Mustache = function() { |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
endSectionScan: function(parserContext, contextStack) { |
|
|
endSectionScan: function(parserContext, contextStack) { |
|
|
switch (parserContext.tokens[parserContext.index]) { |
|
|
|
|
|
|
|
|
switch (parserContext.token()) { |
|
|
case parserContext.openTag: |
|
|
case parserContext.openTag: |
|
|
return 'expectSectionOrEndSection'; |
|
|
return 'expectSectionOrEndSection'; |
|
|
default: |
|
|
default: |
|
|
parserContext.stack[parserContext.stack.length-1].content.push(parserContext.tokens[parserContext.index]); |
|
|
|
|
|
|
|
|
parserContext.stack[parserContext.stack.length-1].content.push(parserContext.token()); |
|
|
return 'endSectionScan'; |
|
|
return 'endSectionScan'; |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
expectSectionOrEndSection: function(parserContext, contextStack) { |
|
|
expectSectionOrEndSection: function(parserContext, contextStack) { |
|
|
switch (parserContext.tokens[parserContext.index]) { |
|
|
|
|
|
|
|
|
switch (parserContext.token()) { |
|
|
case '#': |
|
|
case '#': |
|
|
case '^': |
|
|
case '^': |
|
|
parserContext.stack[parserContext.stack.length-1].depth++; |
|
|
parserContext.stack[parserContext.stack.length-1].depth++; |
|
|
parserContext.stack[parserContext.stack.length-1].content.push(parserContext.openTag + parserContext.tokens[parserContext.index]); |
|
|
|
|
|
|
|
|
parserContext.stack[parserContext.stack.length-1].content.push(parserContext.openTag + parserContext.token()); |
|
|
return 'endSectionScan'; |
|
|
return 'endSectionScan'; |
|
|
case '/': |
|
|
case '/': |
|
|
parserContext.stack.push({tagType:'endSection'}); |
|
|
parserContext.stack.push({tagType:'endSection'}); |
|
|
return 'simpleKeyName'; |
|
|
return 'simpleKeyName'; |
|
|
default: |
|
|
default: |
|
|
parserContext.stack[parserContext.stack.length-1].content.push(parserContext.openTag + parserContext.tokens[parserContext.index]); |
|
|
|
|
|
|
|
|
parserContext.stack[parserContext.stack.length-1].content.push(parserContext.openTag + parserContext.token()); |
|
|
return 'endSectionScan'; |
|
|
return 'endSectionScan'; |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
discard: function(parserContext, contextStack) { |
|
|
discard: function(parserContext, contextStack) { |
|
|
if (parserContext.tokens[parserContext.index]===parserContext.closeTag) { |
|
|
|
|
|
|
|
|
if (parserContext.token()===parserContext.closeTag) { |
|
|
return 'text'; |
|
|
return 'text'; |
|
|
} else { |
|
|
} else { |
|
|
return 'discard'; |
|
|
return 'discard'; |
|
|
@@ -381,10 +382,8 @@ var Mustache = function() { |
|
|
|
|
|
|
|
|
switch (command.tagType) { |
|
|
switch (command.tagType) { |
|
|
case 'section': |
|
|
case 'section': |
|
|
parserContext.stack.push({sectionType:'section', key:key, content:[], depth:1}); |
|
|
|
|
|
return 'endSectionScan'; |
|
|
|
|
|
case 'invertedSection': |
|
|
case 'invertedSection': |
|
|
parserContext.stack.push({sectionType:'invertedSection', key:key, content:[], depth:1}); |
|
|
|
|
|
|
|
|
parserContext.stack.push({sectionType:command.tagType, key:key, content:[], depth:1}); |
|
|
return 'endSectionScan'; |
|
|
return 'endSectionScan'; |
|
|
case 'variable': |
|
|
case 'variable': |
|
|
this.commandSet.variable.call(this, key, contextStack); |
|
|
this.commandSet.variable.call(this, key, contextStack); |
|
|
|