fix dependency: strftime

This commit is contained in:
harttle
2016-06-16 01:02:00 +08:00
parent 2498e6c202
commit 9fe49e9872
11 changed files with 115 additions and 51 deletions
+2 -2
View File
@@ -35,8 +35,8 @@ Documentation: <https://shopify.github.io/liquid/basics/introduction/#tags>
- [ ] tablerow [Document: cols,limit,offset,range](https://shopify.github.io/liquid/tags/iteration/) [Source](https://github.com/harttle/shopify-liquid/blob/master/tags/.js) [Test][tt]
- [x] assign [Document](https://shopify.github.io/liquid/tags/variable/) [Source](https://github.com/harttle/shopify-liquid/blob/master/tags/assign.js) [Test][tt]
- [x] capture [Document](https://shopify.github.io/liquid/tags/variable/) [Source](https://github.com/harttle/shopify-liquid/blob/master/tags/.js) [Test][tt]
- [ ] increment [Document](https://shopify.github.io/liquid/tags/variable/) [Source](https://github.com/harttle/shopify-liquid/blob/master/tags/.js) [Test][tt]
- [ ] decrement [Document](https://shopify.github.io/liquid/tags/variable/) [Source](https://github.com/harttle/shopify-liquid/blob/master/tags/.js) [Test][tt]
- [x] increment [Document](https://shopify.github.io/liquid/tags/variable/) [Source](https://github.com/harttle/shopify-liquid/blob/master/tags/.js) [Test][tt]
- [x] decrement [Document](https://shopify.github.io/liquid/tags/variable/) [Source](https://github.com/harttle/shopify-liquid/blob/master/tags/.js) [Test][tt]
## Filters
+11
View File
@@ -0,0 +1,11 @@
function factory(msg, token){
var err = new Error(msg || 'unkown error');
if(token){
err.token = token.raw;
err.line = token.line;
}
throw err;
}
module.exports = factory;
+2 -5
View File
@@ -14,12 +14,9 @@ module.exports = function() {
function construct(str) {
var match = lexical.filterLine.exec(str.trim());
if (!match) {
throw new Error('illegal filter: ' + str);
}
var k = match[1],
v = match[2];
if (!match) error('illegal filter: ' + str);
var k = match[1], v = match[2];
return factory(k, [v]);
}
+2
View File
@@ -6,6 +6,7 @@ const path = require("path");
const fs = require('fs');
const Tag = require('./tag.js');
const Filter = require('./filter.js');
const error = require('./error.js');
const tagsPath = path.join(__dirname, "tags");
const filtersPath = path.join(__dirname, "filters");
@@ -45,5 +46,6 @@ function factory(){
}
factory.lexical = lexical;
factory.error = error;
module.exports = factory;
+3 -2
View File
@@ -1,6 +1,6 @@
{
"name": "shopify-liquid",
"version": "1.0.1",
"version": "1.0.2",
"description": "A Shopify Liquid Implementation in Node.js",
"main": "index.js",
"scripts": {
@@ -21,7 +21,8 @@
},
"homepage": "https://github.com/harttle/shopify-liquid#readme",
"dependencies": {
"lodash": "^4.13.1"
"lodash": "^4.13.1",
"strftime": "^0.9.2"
},
"devDependencies": {
"chai": "^3.5.0",
+5 -6
View File
@@ -1,5 +1,6 @@
const lexical = require('./lexical.js');
const syntax = require('./syntax.js');
const error = require('./error.js');
module.exports = function(Filter, Tag) {
function render(tokens, scope) {
@@ -17,14 +18,14 @@ module.exports = function(Filter, Tag) {
html += renderTag(token, tokens, scope);
break;
default:
throw new Error(`unexpected type: ${token.type}`);
error(`unexpected type: ${token.type}`, token);
}
}
return html;
}
function evalExp(exp, scope) {
if(!scope) throw new Error('unable to evalExp: scope undefined');
if(!scope) error('unable to evalExp: scope undefined');
var operatorREs = lexical.operators;
for (var i = 0; i < operatorREs.length; i++) {
var operatorRE = operatorREs[i];
@@ -41,7 +42,7 @@ module.exports = function(Filter, Tag) {
}
function evalFilter(str, scope){
if(!scope) throw new Error('unable to evalFilter: scope undefined');
if(!scope) error('unable to evalFilter: scope undefined');
var filters = str.split('|');
var val = scope.get(filters.shift());
return filters
@@ -57,9 +58,7 @@ module.exports = function(Filter, Tag) {
while ((curToken = tokens.shift()) && curToken.value !== endToken) {
subTokens.push(curToken);
}
if (!curToken) {
throw new Error(`${token.value} not closed`);
}
if (!curToken) error(`${token.value} not closed`);
}
return tag.render(subTokens, scope);
}
+1 -1
View File
@@ -6,7 +6,7 @@ module.exports = function(liquid) {
liquid.registerTag('assign', {
render: function(tokens, scope, token, hash) {
var match = token.value.match(re);
var match = token.args.match(re);
var k = match[1], v = match[2];
scope.set(k, liquid.evaluate(v, scope));
}
+17
View File
@@ -0,0 +1,17 @@
const Liquid = require('..');
const lexical = Liquid.lexical;
const error = Liquid.error;
module.exports = function(liquid) {
liquid.registerTag('decrement', {
render: function(tokens, scope, token, hash) {
var match = token.args.match(lexical.identifier);
if(!match) error(`illegal identifier ${token.args}`, token);
var k = match[0], v = scope.get(k);
if(typeof v !== 'number') v = 0;
scope.set(k, v-1);
}
});
};
+17
View File
@@ -0,0 +1,17 @@
const Liquid = require('..');
const lexical = Liquid.lexical;
const error = Liquid.error;
module.exports = function(liquid) {
liquid.registerTag('increment', {
render: function(tokens, scope, token, hash) {
var match = token.args.match(lexical.identifier);
if(!match) error(`illegal identifier ${token.args}`, token);
var k = match[0], v = scope.get(k);
if(typeof v !== 'number') v = 0;
scope.set(k, v+1);
}
});
};
+26 -15
View File
@@ -1,18 +1,20 @@
const chai = require("chai");
const expect = chai.expect;
var liquid = require('..')();
var ctx = {
one: 1,
two: 2,
leq: '<=',
empty: '',
foo: 'bar',
arr: [-2, 'a']
};
var liquid = require('..')(),
ctx;
describe('tags', function() {
beforeEach(function() {
ctx = {
one: 1,
two: 2,
leq: '<=',
empty: '',
foo: 'bar',
arr: [-2, 'a']
};
});
it('should support assign', function() {
expect(liquid.render('{% assign foo="bar"%}{{foo}}', ctx)).to.equal('bar');
});
@@ -34,22 +36,31 @@ describe('tags', function() {
'{%endcase%}')).to.equal('d');
});
it('should support if', function(){
it('should support if', function() {
expect(liquid.render('{% if 2==3 %}yes{%else%}no{%endif%}', ctx)).to.equal('no');
expect(liquid.render('{% if 1==2 and one<two %}a{%endif%}', ctx)).to.equal('');
expect(liquid.render('{% if false %}yes{%else%}no{%endif%}', ctx)).to.equal('no');
});
it('should support unless', function(){
it('should support unless', function() {
expect(liquid.render('{% unless 1 %}yes{%else%}no{%endunless%}', ctx)).to.equal('no');
expect(liquid.render('{% unless 1>2 %}yes{%endunless%}', ctx)).to.equal('yes');
});
it('should support capture', function(){
it('should support capture', function() {
expect(liquid.render('{% capture f %}{{"a" | capitalize}}{%endcapture%}{{f}}', ctx)).to.equal('A');
expect(function(){
expect(function() {
liquid.render('{% capture = %}{%endcapture%}', ctx);
}).to.throw(/= not valid identifier/);
});
});
it('should support increment', function() {
expect(liquid.render('{% increment foo %}{%increment foo%}{{foo}}', ctx)).to.equal('2');
expect(liquid.render('{% increment one %}{{one}}', ctx)).to.equal('2');
});
it('should support decrement', function() {
expect(liquid.render('{% decrement foo %}{%decrement foo%}{{foo}}', ctx)).to.equal('-2');
expect(liquid.render('{% decrement one %}{{one}}', ctx)).to.equal('0');
});
});
+29 -20
View File
@@ -1,11 +1,12 @@
const lexical = require('./lexical.js');
const error = require('./error.js');
function parse(html){
var tokens = [];
if(!html) return tokens;
var syntax = /({%(.*?)%})|({{(.*?)}})/g;
var result, htmlFragment;
var result, htmlFragment, token;
var idx = 0;
while ((result = syntax.exec(html)) !== null) {
@@ -16,29 +17,19 @@ function parse(html){
value: htmlFragment
});
}
var rawTag = result[1],
cleanTag = result[2],
rawOut = result[3],
cleanOut = result[4];
if(rawTag){
var match = cleanTag.trim().match(lexical.tagLine);
if (!match) throw new Error('illegal tag: ' + rawTag);
var name = match[1], args = match[2];
if(result[1]){
token = factory('tag', 1, result);
var match = token.value.match(lexical.tagLine);
if (!match) error('illegal tag', token);
tokens.push({
type: 'tag',
value: cleanTag.trim(),
raw: rawTag,
args, name
});
token.name = match[1];
token.args = match[2];
tokens.push(token);
}
else{
tokens.push({
type: 'output',
raw: rawOut,
value: cleanOut.trim()
});
token = factory('output', 3, result);
tokens.push(token);
}
idx = syntax.lastIndex;
}
@@ -51,6 +42,24 @@ function parse(html){
});
}
return tokens;
function factory(type, offset, match){
var token = {
type,
raw: match[offset],
value: match[offset + 1].trim(),
line: crCount(match.index) + 1
};
return token;
}
var lastIdx = -1;
var lastCount = 0;
function crCount(idx){
lastCount += html.slice(lastIdx+1, idx);
lastIdx = idx;
return lastCount;
}
}
exports.parse = parse;