diff --git a/package.json b/package.json index ea7fd64..1c35e18 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sass-variable-loader", - "version": "0.1.2", + "version": "0.2.0", "description": "Sass variable loader module for webpack", "main": "dist/index.js", "scripts": { diff --git a/src/get-variables.js b/src/get-variables.js index 220d5de..e5d46e0 100644 --- a/src/get-variables.js +++ b/src/get-variables.js @@ -1,7 +1,7 @@ import stripComments from 'strip-json-comments'; export default function getVariables(content) { - const variableRegex = /\$(.+):\s+(.+);?/; + const variableRegex = /\$(.+?):\s+(.+);?/; const variables = []; stripComments(content).split('\n').forEach(line => { diff --git a/src/parse-variables.js b/src/parse-variables.js index 41e0340..5df1b35 100644 --- a/src/parse-variables.js +++ b/src/parse-variables.js @@ -1,12 +1,30 @@ import sass from 'node-sass'; import camelCase from 'lodash.camelcase'; +const mapRegex = /([^(].+?):\s?([0-9A-z-_$#'"\\]+),?\s?/g; + function constructSassString(variables) { const asVariables = variables .map(variable => `$${variable.name}: ${variable.value};`) .join('\n'); const asClasses = variables - .map(variable => `.${variable.name} { value: ${variable.value} }`) + .map(variable => { + if (variable.value.startsWith('(')) { // is a map + let matches = mapRegex.exec(variable.value); + const map = []; + while (matches !== null) { + map.push([matches[1], matches[2]]); + matches = mapRegex.exec(variable.value); + } + const mapVars = map.reduce( + (acc, mapVar) => + `${acc}\n${mapVar[0]}: ${mapVar[1]};`, + '' + ); + return `.${variable.name} { ${mapVars} }`; + } + return `.${variable.name} { value: ${variable.value} }`; + }) .join('\n'); return `${asVariables}\n${asClasses}`; @@ -17,10 +35,20 @@ export default function parseVariables(variables, opts = {}) { data: constructSassString(variables), outputStyle: 'compact', }).css.toString(); - const parsedVariables = result.split(/\n/) .filter(line => line && line.length) .map(variable => { + if ((variable.match(/;/g) || []).length > 1) { // is a map + const name = /\.(.+) {/.exec(variable)[1]; + const varRegex = /\s([A-z-_]+?): ([0-9A-z-_$#'"\\]+?);/g; + let matches = varRegex.exec(variable); + const vars = {}; + while (matches !== null) { + vars[matches[1]] = matches[2]; + matches = varRegex.exec(variable); + } + return { [name]: vars }; + } const [, name, value] = /\.(.+) { value: (.+); }/.exec(variable); const obj = {}; diff --git a/test/index.test.js b/test/index.test.js index 1ee2fb8..4e23689 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -57,6 +57,30 @@ $x: $one; }); }) +context('maps', function() { + const sass = '$map: (one: 1, two: #eee);'; + const variables = getVariables(sass); + + describe('getVariables()', function() { + it('should return an array with 1 item', () => { + console.log(variables); + expect(variables).to.be.a('array'); + expect(variables).to.have.length(1); + }); + }); + + describe('parseVariables()', function() { + it('should return maps', function() { + const result = parseVariables(variables); + expect(result.map).to.be.a('object'); + expect(result.map).to.include.keys('one'); + expect(result.map).to.include.keys('two'); + expect(result.map.one).to.equal('1'); // may want to parse ints? + expect(result.map.two).to.equal('#eee'); + }); + }); +}); + context('.sass format', function() { const sass = `$one: 123 $x: $one