Skip to content

Commit

Permalink
Merge pull request #98 from hannu/external-parser
Browse files Browse the repository at this point in the history
Move variable parsing logic to external lib. Implement initial tests
  • Loading branch information
varya committed Oct 21, 2014
2 parents c888379 + 5a1af7e commit 47f7f69
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 53 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,11 @@ When using the build as a subfolder of your application, tune your server to res
will let Angular application to deal with routing itself. However, the static files should be resolved as they are
stored.

**sassVariables** (string, optional) **(Experimental feature)**
**sassVariables** (string, optional)

Path to the file that contains SASS variables editable in the designer mode.
Note: Designer mode is enabled only when running styleguide's built-in server.
Path to the file containing SASS variables that can be used as modifiers in the KSS notation.

**Desiger tools**: When sassVariables is defined and styleguide is served with the built-in server, designer tools are also enabled. Designer tool is experimental feature that allow SASS variable editing in the browser and saving changed variables back to the source file.

## Demo

Expand Down
4 changes: 4 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ gulp.task('demo', function() {
sourcePath = __dirname + '/demo/source';
// We need to re-parse options since configPath has changed
parseOptions();
// Watch changed styles in demo mode
gulp.watch(sourcePath + '/**/*.scss', function() {
runSequence('sass', 'styleguide');
});
// Run serve first so socketIO options is enabled when building styleguide
return runSequence('serve', 'styleguide');
});
Expand Down
2 changes: 1 addition & 1 deletion lib/app/js/directives/design.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ angular.module('sgApp')
templateUrl: 'views/partials/design.html',
link: function(scope) {
scope.onChange = function(key, value) {
Variables.setValue('$' + key, value);
Variables.setValue(key, value);
$rootScope.config.settings[key] = value;
};

Expand Down
2 changes: 1 addition & 1 deletion lib/app/views/partials/section.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ <h4 ng-show="getLevel(section) === 'sub-sub-sub'" ng-show="" class="sg section-h

<ul ng-if="section.modifiers.length" class="sg modifier-list">
<li class="item" ng-repeat="mod in section.modifiers">
<strong ng-bind-html="mod.name | unsafe"></strong><span ng-bind-html="mod.description | unsafe"></span>
<strong ng-bind-html="mod.name | unsafe"></strong> <span ng-bind-html="mod.description | unsafe"></span>
</li>
</ul>

Expand Down
49 changes: 15 additions & 34 deletions lib/io.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var fs = require('fs');
var fs = require('fs'),
parser = require('./parser')();

module.exports = function(io, options) {

Expand All @@ -12,50 +13,30 @@ module.exports = function(io, options) {
loadVariables = function(socket) {
return function() {
fs.readFile(options.sassVariables, {encoding: 'utf8'}, function(err, data) {
var line, splitData, values = {};
var values = {};
if (err) {
return console.error(err);
}
splitData = data.split('\n');
for (var i = 0;i < splitData.length;i++) {
if (splitData[i] && splitData[i].charAt(0) !== '#') {
line = splitData[i].trim().replace(/;$/, '').split(': ');
values[line[0]] = line[1];
}
}
values = parser.parseVariables(data);
socket.emit('variables from server', values);
console.log('EVENT: variables from server');
});
};
};

saveVariables = function(socket) {
return function(data) {
var lines = [], sassVariables, sassVariableNames = [];

console.log(data);
sassVariables = data;

// Order variable names TODO: better sorting and/or block system
for (var variableName in sassVariables) {
if (sassVariables.hasOwnProperty(variableName)) {
sassVariableNames.push(variableName);
}
}
sassVariableNames.sort();

for (var i = 0;i < sassVariableNames.length;i++) {
lines.push(sassVariableNames[i] + ': ' + sassVariables[sassVariableNames[i]] + ';');
}

fs.writeFile(options.sassVariables, lines.join('\n'), function(err, data) {
if (err) {
return console.error(err);
}
socket.emit('variables saved to server', sassVariables);
console.log('EVENT: variables saved to server');
return function(variables) {
console.log('received', variables);
fs.readFile(options.sassVariables, {encoding: 'utf8'}, function(err, originalData) {
var data = parser.setVariables(originalData, variables);
fs.writeFile(options.sassVariables, data, function(err, data) {
if (err) {
return console.error(err);
}
socket.emit('variables saved to server', data);
console.log('EVENT: variables saved to server');
});
});

};
};

Expand Down
39 changes: 39 additions & 0 deletions lib/parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module.exports = function() {
var parseVariables;

// Parse SASS variables to object
parseVariables = function(string) {
var out = {},
re = /\$(.*?)\;/g,
match,
varParts;
while (match = re.exec(string)) {
varParts = match[1].match(/(.*)\:(.*)/);
if (varParts) {
out[varParts[1]] = varParts[2].trim();
}
}
return out;
}

// Modifies string so that variables passed in object are updated
setVariables = function(string, variables) {
var sorted = [], lines = [];
// TODO: This is temporary solution that just re-generates whole file
for (var variableName in variables) {
if (variables.hasOwnProperty(variableName)) {
sorted.push(variableName);
}
}
sorted.sort();
for (var i = 0; i < sorted.length; i++) {
lines.push('$' + sorted[i] + ': ' + variables[sorted[i]] + ';');
}
return lines.join('\n');
}

return {
parseVariables: parseVariables,
setVariables: setVariables
}
}
16 changes: 2 additions & 14 deletions lib/styleguide.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ var through = require('through2'),
marked = require('gulp-marked'),
mkdirp = require('mkdirp'),
mustache = require('gulp-mustache'),
parser = require('./parser')(),
File = require('vinyl'),
distPath = __dirname + '/dist',
callbackCount;
Expand Down Expand Up @@ -99,7 +100,7 @@ module.exports = function(opt) {

// If settings file is found, generate settings object
if (opt.sassVariables) {
styleguide.config.settings = parseSettings(fs.readFileSync(opt.sassVariables));
styleguide.config.settings = parser.parseVariables(fs.readFileSync(opt.sassVariables));
}

// Create JSON containing KSS data
Expand Down Expand Up @@ -254,16 +255,3 @@ function jsonModifiers(modifiers) {
}
});
}

// Parses _styleguide_settings.scss
function parseSettings(string) {
var out = {},
re = /\$(.*?)\;/g,
match,
a;
while (match = re.exec(string)) {
a = match[1].match(/(.*)\:(.*)/);
out[a[1]] = a[2].trim();
}
return out;
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"karma-sinon-chai": "^0.2.0",
"main-bower-files": "^2.0.0",
"mocha": "^1.21.4",
"multiline": "^1.0.1",
"sinon": "^1.10.3",
"sinon-chai": "^2.6.0",
"tiny-lr": "^0.1.4"
Expand Down
73 changes: 73 additions & 0 deletions test/parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
var gulp = require('gulp'),
chai = require('chai'),
expect = chai.expect,
multiline = require('multiline'),
parser = require('../lib/parser')();

describe('Parser', function() {
describe('variable parser', function() {
it('should parse basic variables', function() {
var str = multiline(function() {
/*
$mycolor: #00ff00;
$mypadding: 3px;
$myfont: "Helvetica Neue", Helvetica, Arial, sans-serif;
*/
}),
result = {
mycolor: '#00ff00',
mypadding: '3px',
myfont: '"Helvetica Neue", Helvetica, Arial, sans-serif'
};
expect(parser.parseVariables(str)).eql(result);
});

it('should parse variables from file with containing comments and intended lines', function() {
var str = multiline(function() {
/*
$mycolor: #00ff00;
// Test comment
$mypadding: 3px; // Test comment 2
$myfont: "Helvetica Neue", Helvetica, Arial, sans-serif;
*/
}),
result = {
mycolor: '#00ff00',
mypadding: '3px',
myfont: '"Helvetica Neue", Helvetica, Arial, sans-serif'
};
expect(parser.parseVariables(str)).eql(result);
});

it('should parse variables correct when there are multiple variables in a single line', function() {
var str = multiline(function() {
/*
$color1: #ff0000; $color2: #00ff00; $color3: #0000ff;
*/
}),
result = {
color1: '#ff0000',
color2: '#00ff00',
color3: '#0000ff'
};
});
});

describe('variable setter', function() {
it('should generate valid SASS file when original file is empty', function() {
var variables = {
mycolor: '#00ff00',
mypadding: '3px',
myfont: '"Helvetica Neue", Helvetica, Arial, sans-serif'
},
result = multiline(function() {
/*
$mycolor: #00ff00;
$myfont: "Helvetica Neue", Helvetica, Arial, sans-serif;
$mypadding: 3px;
*/
});
expect(parser.setVariables('', variables)).eql(result);
});
});
});

0 comments on commit 47f7f69

Please sign in to comment.