Here's a grammar off the top of my head. Feel free to challenge this if you think something's wrong. I won't be checking for insane edge-cases that are hidden in here. For instance I don't think this explains how backticks work, but that sounds like a lot of work.
emotibars
= (string lodid)* string
= (string openblock emotistatement closeblock)* string
closeblock
= yay _ blocktype _ yay
openblock
= ohnoes _ blocktype _ id _ ohnoes
lodid
= openlod id closelod
= lod
blocktype
= if|unless|each
backtick
= `
yay
= \\o/
ohnoes
= /o\\
lod
= \u0CA0_\u0CA0
closelod
= _\u0CA0
openlod
= \u0CA0_
string
= _ (_ chars _)*
id
= [a-zA-Z$_][^ \t\n\r,.+={}]*
chars
= char+
char
= [^{}\\\0-\x1F\x7f \t\n\r]
digits
= [0-9]+
hexDigit
= [0-9a-fA-F]
_ "whitespace"
= whitespace*
whitespace
= [ \t\n\r]
emotibars('My name is ಠ_ಠ.', 'alex');
> My name is alex.
emotibars('My name is ಠ_name_ಠ.', {name: 'alex'});
> My name is alex.
emotibars('Our names are: /o\\each names/o\\\n - ಠ_ಠ\\o/each\\o/', ['alex', 'michelle', 'batman']);
> Our names are:
- alex
- michelle
- batman
emotibars('My name is `ಠ_name`_ಠ.');
> My name is ಠ_name_ಠ.
emotibars('My name is ``ಠ_name_ಠ.', {name: 'alex'});
> My name is `alex.
emotibars(template, data)
// returns the rendered template
emotibars.parse(template)
// returns an AST
emotibars.compile(AST)
// returns an executable javascript function that:
// - takes one argument (the data passed to the template)
// - returns the rendered template
// optional:
emotibars.precompile(template)
// returns the string representation of the function expected from emotibars.compile
- No compile to js
- No parser-generators
- Error messages are important (parse and run-time)
- Document your code
(All latest)
- node
- chrome
- firefox