mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-19 22:40:48 -07:00
fix dependency: strftime
This commit is contained in:
@@ -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]
|
- [ ] 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] 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]
|
- [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]
|
- [x] 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] decrement [Document](https://shopify.github.io/liquid/tags/variable/) [Source](https://github.com/harttle/shopify-liquid/blob/master/tags/.js) [Test][tt]
|
||||||
|
|
||||||
|
|
||||||
## Filters
|
## Filters
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -14,12 +14,9 @@ module.exports = function() {
|
|||||||
|
|
||||||
function construct(str) {
|
function construct(str) {
|
||||||
var match = lexical.filterLine.exec(str.trim());
|
var match = lexical.filterLine.exec(str.trim());
|
||||||
if (!match) {
|
if (!match) error('illegal filter: ' + str);
|
||||||
throw new Error('illegal filter: ' + str);
|
|
||||||
}
|
|
||||||
var k = match[1],
|
|
||||||
v = match[2];
|
|
||||||
|
|
||||||
|
var k = match[1], v = match[2];
|
||||||
return factory(k, [v]);
|
return factory(k, [v]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ const path = require("path");
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const Tag = require('./tag.js');
|
const Tag = require('./tag.js');
|
||||||
const Filter = require('./filter.js');
|
const Filter = require('./filter.js');
|
||||||
|
const error = require('./error.js');
|
||||||
|
|
||||||
const tagsPath = path.join(__dirname, "tags");
|
const tagsPath = path.join(__dirname, "tags");
|
||||||
const filtersPath = path.join(__dirname, "filters");
|
const filtersPath = path.join(__dirname, "filters");
|
||||||
@@ -45,5 +46,6 @@ function factory(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
factory.lexical = lexical;
|
factory.lexical = lexical;
|
||||||
|
factory.error = error;
|
||||||
|
|
||||||
module.exports = factory;
|
module.exports = factory;
|
||||||
|
|||||||
+3
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "shopify-liquid",
|
"name": "shopify-liquid",
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"description": "A Shopify Liquid Implementation in Node.js",
|
"description": "A Shopify Liquid Implementation in Node.js",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/harttle/shopify-liquid#readme",
|
"homepage": "https://github.com/harttle/shopify-liquid#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lodash": "^4.13.1"
|
"lodash": "^4.13.1",
|
||||||
|
"strftime": "^0.9.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"chai": "^3.5.0",
|
"chai": "^3.5.0",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
const lexical = require('./lexical.js');
|
const lexical = require('./lexical.js');
|
||||||
const syntax = require('./syntax.js');
|
const syntax = require('./syntax.js');
|
||||||
|
const error = require('./error.js');
|
||||||
|
|
||||||
module.exports = function(Filter, Tag) {
|
module.exports = function(Filter, Tag) {
|
||||||
function render(tokens, scope) {
|
function render(tokens, scope) {
|
||||||
@@ -17,14 +18,14 @@ module.exports = function(Filter, Tag) {
|
|||||||
html += renderTag(token, tokens, scope);
|
html += renderTag(token, tokens, scope);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`unexpected type: ${token.type}`);
|
error(`unexpected type: ${token.type}`, token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
function evalExp(exp, scope) {
|
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;
|
var operatorREs = lexical.operators;
|
||||||
for (var i = 0; i < operatorREs.length; i++) {
|
for (var i = 0; i < operatorREs.length; i++) {
|
||||||
var operatorRE = operatorREs[i];
|
var operatorRE = operatorREs[i];
|
||||||
@@ -41,7 +42,7 @@ module.exports = function(Filter, Tag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function evalFilter(str, scope){
|
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 filters = str.split('|');
|
||||||
var val = scope.get(filters.shift());
|
var val = scope.get(filters.shift());
|
||||||
return filters
|
return filters
|
||||||
@@ -57,9 +58,7 @@ module.exports = function(Filter, Tag) {
|
|||||||
while ((curToken = tokens.shift()) && curToken.value !== endToken) {
|
while ((curToken = tokens.shift()) && curToken.value !== endToken) {
|
||||||
subTokens.push(curToken);
|
subTokens.push(curToken);
|
||||||
}
|
}
|
||||||
if (!curToken) {
|
if (!curToken) error(`${token.value} not closed`);
|
||||||
throw new Error(`${token.value} not closed`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return tag.render(subTokens, scope);
|
return tag.render(subTokens, scope);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ module.exports = function(liquid) {
|
|||||||
|
|
||||||
liquid.registerTag('assign', {
|
liquid.registerTag('assign', {
|
||||||
render: function(tokens, scope, token, hash) {
|
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];
|
var k = match[1], v = match[2];
|
||||||
scope.set(k, liquid.evaluate(v, scope));
|
scope.set(k, liquid.evaluate(v, scope));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
@@ -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
@@ -1,18 +1,20 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
|
|
||||||
var liquid = require('..')();
|
var liquid = require('..')(),
|
||||||
|
ctx;
|
||||||
var ctx = {
|
|
||||||
one: 1,
|
|
||||||
two: 2,
|
|
||||||
leq: '<=',
|
|
||||||
empty: '',
|
|
||||||
foo: 'bar',
|
|
||||||
arr: [-2, 'a']
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('tags', function() {
|
describe('tags', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
ctx = {
|
||||||
|
one: 1,
|
||||||
|
two: 2,
|
||||||
|
leq: '<=',
|
||||||
|
empty: '',
|
||||||
|
foo: 'bar',
|
||||||
|
arr: [-2, 'a']
|
||||||
|
};
|
||||||
|
});
|
||||||
it('should support assign', function() {
|
it('should support assign', function() {
|
||||||
expect(liquid.render('{% assign foo="bar"%}{{foo}}', ctx)).to.equal('bar');
|
expect(liquid.render('{% assign foo="bar"%}{{foo}}', ctx)).to.equal('bar');
|
||||||
});
|
});
|
||||||
@@ -34,22 +36,31 @@ describe('tags', function() {
|
|||||||
'{%endcase%}')).to.equal('d');
|
'{%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 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 1==2 and one<two %}a{%endif%}', ctx)).to.equal('');
|
||||||
expect(liquid.render('{% if false %}yes{%else%}no{%endif%}', ctx)).to.equal('no');
|
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 %}yes{%else%}no{%endunless%}', ctx)).to.equal('no');
|
||||||
expect(liquid.render('{% unless 1>2 %}yes{%endunless%}', ctx)).to.equal('yes');
|
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(liquid.render('{% capture f %}{{"a" | capitalize}}{%endcapture%}{{f}}', ctx)).to.equal('A');
|
||||||
expect(function(){
|
expect(function() {
|
||||||
liquid.render('{% capture = %}{%endcapture%}', ctx);
|
liquid.render('{% capture = %}{%endcapture%}', ctx);
|
||||||
}).to.throw(/= not valid identifier/);
|
}).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
@@ -1,11 +1,12 @@
|
|||||||
const lexical = require('./lexical.js');
|
const lexical = require('./lexical.js');
|
||||||
|
const error = require('./error.js');
|
||||||
|
|
||||||
function parse(html){
|
function parse(html){
|
||||||
var tokens = [];
|
var tokens = [];
|
||||||
if(!html) return tokens;
|
if(!html) return tokens;
|
||||||
|
|
||||||
var syntax = /({%(.*?)%})|({{(.*?)}})/g;
|
var syntax = /({%(.*?)%})|({{(.*?)}})/g;
|
||||||
var result, htmlFragment;
|
var result, htmlFragment, token;
|
||||||
var idx = 0;
|
var idx = 0;
|
||||||
|
|
||||||
while ((result = syntax.exec(html)) !== null) {
|
while ((result = syntax.exec(html)) !== null) {
|
||||||
@@ -16,29 +17,19 @@ function parse(html){
|
|||||||
value: htmlFragment
|
value: htmlFragment
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var rawTag = result[1],
|
|
||||||
cleanTag = result[2],
|
|
||||||
rawOut = result[3],
|
|
||||||
cleanOut = result[4];
|
|
||||||
|
|
||||||
if(rawTag){
|
if(result[1]){
|
||||||
var match = cleanTag.trim().match(lexical.tagLine);
|
token = factory('tag', 1, result);
|
||||||
if (!match) throw new Error('illegal tag: ' + rawTag);
|
var match = token.value.match(lexical.tagLine);
|
||||||
var name = match[1], args = match[2];
|
if (!match) error('illegal tag', token);
|
||||||
|
|
||||||
tokens.push({
|
token.name = match[1];
|
||||||
type: 'tag',
|
token.args = match[2];
|
||||||
value: cleanTag.trim(),
|
tokens.push(token);
|
||||||
raw: rawTag,
|
|
||||||
args, name
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
tokens.push({
|
token = factory('output', 3, result);
|
||||||
type: 'output',
|
tokens.push(token);
|
||||||
raw: rawOut,
|
|
||||||
value: cleanOut.trim()
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
idx = syntax.lastIndex;
|
idx = syntax.lastIndex;
|
||||||
}
|
}
|
||||||
@@ -51,6 +42,24 @@ function parse(html){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
return tokens;
|
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;
|
exports.parse = parse;
|
||||||
|
|||||||
Reference in New Issue
Block a user