diff --git a/gradient-parser.js b/gradient-parser.js index 77e8410..20b2a1a 100644 --- a/gradient-parser.js +++ b/gradient-parser.js @@ -19,49 +19,127 @@ var GradientParser = module.exports = (function() { ] }; - function Constructor() { + var tokens = { + linearGradient: /^linear\-gradient/i, + sideOrCorner: /^to (left (top|bottom)|right (top|bottom)|left|right|top|bottom)/i, + startCall: /^\(/, + endCall: /^\)/, + comma: /^,/ + }; + + function Constructor(input) { + this.input = input; + this.cursor = 0; } var def = Constructor.prototype; def.parse = function(input) { - return null; - } + if (input) { + this.input = input; + } + return this.listDefinitions(); + }; + + def.listDefinitions = function() { + var definitions = [], + definition = this.definition(); + + if (definition) { + definitions.push(definition); + while (this.scan(tokens.comma)) { + definition = this.definition(); + if (definition) { + definitions.push(definition); + } else { + // throw error + } + } + } + + return definitions; + }; + + def.definition = function() { + return this.linearGradient(); + }; + + def.linearGradient = function() { + var captures = this.scan(tokens.linearGradient), + orientation, + colorStops; + + + if (captures) { + this.scan(tokens.startCall); + orientation = this.orientation(); + this.scan(tokens.comma); + colorStops = this.colorStops(); + this.scan(tokens.endCall); + + return { + type: 'linear-gradient', + orientation: orientation, + colorStops: colorStops + }; + } + }; + + def.orientation = function() { + return this.sideOrCorner(); + }; + + def.sideOrCorner = function() { + var captures = this.scan(tokens.sideOrCorner); + if (captures) { + return { + type: 'directional', + value: captures[1].toLowerCase() + }; + } + }; + + def.colorStops = function() { + var literalColors = /^([a-zA-Z]+)/, + captures = this.scan(literalColors), + colors = []; + + if (captures) { + colors.push(captures[0].toLowerCase()); + while (this.scan(tokens.comma)) { + captures = this.scan(literalColors); + if (captures) { + colors.push(captures[0].toLowerCase()); + } else { + // trow error + } + } + } + + return colors; + }; + + def.scan = function(regexp) { + var captures, + blankCaptures; + + blankCaptures = /^[\n\r\t\s]+/.exec(this.input); + if (blankCaptures) { + this.consume(blankCaptures[0].length); + } + + captures = regexp.exec(this.input); + if (captures) { + this.consume(captures[0].length); + } + + return captures; + }; + + def.consume = function(size) { + this.cursor += size; + this.input = this.input.substr(size); + }; return Constructor; })(); - - -var p = new GradientParser('linear-gradient(to right, transparent 10px, #c2c2c2 10px)'); -var ast = p.parse(); - -if (ast == [ - { - type: 'linear-gradient', - orientation: { - type: 'directional', - value: 'right' - }, - colorStops: [ - { - type: 'literal', - value: 'transparent', - length: { - value: '10', - type: 'px' - } - }, - { - type: 'hex', - value: 'c2c2c2', - length: { - value: '10', - type: 'px' - } - } - ] - }]) { - console.log('Done!'); -} else { - console.log('Keep working...'); -} diff --git a/spec/gradient-parser.spec.js b/spec/gradient-parser.spec.js index 303ab48..794720b 100644 --- a/spec/gradient-parser.spec.js +++ b/spec/gradient-parser.spec.js @@ -3,6 +3,34 @@ var expect = require('expect.js'); var GradientParser = require('gradient-parser'); +// [ +// { +// type: 'linear-gradient', +// orientation: { +// type: 'directional', +// value: 'right' +// }, +// colorStops: [ +// { +// type: 'literal', +// value: 'transparent', +// length: { +// value: '10', +// type: 'px' +// } +// }, +// { +// type: 'hex', +// value: 'c2c2c2', +// length: { +// value: '10', +// type: 'px' +// } +// } +// ] +// } +// ] + describe('gradient-parser.js', function () { it('should exist', function () { expect(typeof GradientParser).to.equal('function'); @@ -13,7 +41,8 @@ describe('gradient-parser.js', function () { beforeEach(function() { var parser = new GradientParser(); - ast = parser.parse('linar-gradient(to right, transparent 10px, blue)'); + ast = parser.parse('linear-gradient(to right bottom, red, blue)'); + console.log(ast); }); it('should get the gradient type', function () {