UNPKG

peasy

Version:

an easy but powerful parser

59 lines (47 loc) 1.94 kB
{inCharset, letters, charset, BaseParser} = peasy = require '../peasy' identifierHeadChars = '$_'+letters endTextCharset = charset(')@'+identifierHeadChars) identifierHeadCharset = charset(identifierHeadChars) exports.TemplateParser = class TemplateParser extends BaseParser constructor: -> super [at, lpar, rpar, exclam] = for c in '@()!' then do(c=c) => @char(c) mayExclam = @may(exclam) error = (msg) => throw @data[@cur-20..@cur+20]+' '+@cur+': '+msg tcall = => (f = tfield()) and lpar() and (args = template()) and ((rpar() and f+'('+args+')') or error('expect )')) tfield = @memo(=> at() and (((id=@identifier()) and mayExclam() and 't.'+id) or error('expect @identifier'))) field = => (id=@identifier()) and mayExclam() and "t.transform(e.#{id})" text = => data = @data start = cur = @cur result = '' while 1 c = data[cur] if (not c) then break else if c=='!' cur++ c = data[cur] if inCharset(c, identifierHeadCharset) @cur = cur id = @identifier() cur = @cur result += id else if c=='!' or c=='@' or c==')' result += c cur++ else if c result += '!'+c cur++ else break else if c=='\n' then cur++; result +='\\n' else if inCharset(c, endTextCharset) then break else result += c; cur++ if cur==start then return @cur = cur if '"' in result then "'"+result+"'" else '"'+result+'"' anySegment = @any(@orp(tcall, tfield, field, text)) template = => (x = anySegment()) and x.join(',') @root = => (t = template()) and ((@eoi() and t) or error('unexpected )')) templateParser = new TemplateParser exports.parseTemplate = parseTemplate = (text) -> templateParser.parse(text)