Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

better parser for powerful filters

  • Loading branch information...
commit 36c9d0145fa79c8a243f79037913ec42a23d3d54 1 parent f16161f
@shaunlee authored
Showing with 78 additions and 14 deletions.
  1. +29 −1 lib/filters.js
  2. +49 −13 lib/jst.js
View
30 lib/filters.js
@@ -2,10 +2,38 @@
const htmlCodes = {'&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;'},
htmlre = /[&<>"]/g,
- htmlEscape = function (src) { return htmlCodes[src]; };
+ htmlEscape = function (src) { return htmlCodes[src]; },
+ linere = /(\r\n|\r|\n)/g,
+ filterCodes = {
+ 'e(': 'jst_filter_escape(',
+ 'br(': 'jst_filter_linebreaks(',
+ 'md(': 'jst_filter_markdown(',
+ '_(': 'jst_filter_gettext('
+ },
+ filterre = /^(e|br|md|_)\(/g,
+ filterConvert = function(src) { return filterCodes[src]; };
+
+exports.convert = function(src) {
+ return src.replace(filterre, filterConvert);
+}
// e(src)
jst_filter_escape = function(src) {
return typeof src !== 'string' ? src : src.replace(htmlre, htmlEscape);
}
+// br(src)
+jst_filter_linebreaks = function(src) {
+ return src.replace(linere, '<br>$1');
+}
+
+// md(src)
+jst_filter_markdown = function(src) {
+ return src; // TODO:
+}
+
+// _(src)
+jst_filter_gettext = function(src) {
+ return src; // TODO:
+}
+
View
62 lib/jst.js
@@ -5,7 +5,8 @@
*/
var fs = require('fs'),
- crypto = require('crypto');
+ crypto = require('crypto'),
+ filters = require('./filters');
exports.version = '0.0.5';
@@ -26,22 +27,57 @@ exports.configure = function(options) {
// compiler
-require('./filters');
+const prefixes = {
+ s: {s: '', c: '"; ', v: '" + '},
+ c: {s: ' out += "', c: ' ', v: ' out += '},
+ v: {s: ' + "', c: '; ', v: ' + '},
+ end: {s: '"; ', c: ' ', v: '; '}
+ },
+ codere = /\{[%\{] (.+?) [%\}]\}/g;
var compile = exports.compile = function(ctx) {
+ var m, s, i = 0, code = 'var out = "', last = 's';
+
_options.useIt = /{{ (e\()?it\./.test(ctx);
- var code = (_options.useIt ? 'var out = "' : 'var out = ""; with(it) { out += "')
- + ctx.replace(/[\t\r\n]/g, '')
- .replace(/"/g, '\\"')
- .replace(/\{\{ (.+?) \}\}/g, '" + $1 + "')
- .replace(/\{% (.+?) %\}/g, '"; $1 out += "')
- .replace(/\{#.+?#\}/g, '')
- .replace(/ e\(/g, ' jst_filter_escape(')
- + (_options.useIt ? '"; return out;' : '"; } return out;');
- //console.log(code.replace(' out += "";', ''));
-
- return new Function('it', code.replace(' out += "";', ''));
+ ctx = ctx.replace(/[\t\r\n]/g, '').replace(/\{#.+?#\}/g, '')
+
+ if (!_options.useIt) {
+ code += '"; with(it) {';
+ last = 'c';
+ }
+
+ while ((m = codere.exec(ctx)) !== null) {
+ if (m.index > 0) {
+ code += prefixes[last]['s'] + ctx.substring(i, m.index).replace(/"/g, '\\"');
+ last = 's';
+ }
+
+ if (m[0].indexOf('{%') === 0) {
+ code += prefixes[last]['c'] + m[1];
+ last = 'c';
+ } else if (m[0].indexOf('{{') === 0) {
+ code += prefixes[last]['v'] + filters.convert(m[1]);
+ last = 'v';
+ }
+
+ i = m.index + m[0].length;
+ }
+
+ if (i < ctx.length) {
+ code += prefixes[last]['s'] + ctx.substring(i).replace(/"/g, '\\"');
+ last = 's';
+ }
+
+ code += prefixes['end'][last];
+
+ if (!_options.useIt)
+ code += '} ';
+
+ code += 'return out;';
+ //console.log(code);
+
+ return new Function('it', code);
}
var render = exports.render = function(ctx, args) {
Please sign in to comment.
Something went wrong with that request. Please try again.