Skip to content

Commit 1055835

Browse files
committed
* combined loadTemplate + renderTemplate
* stream through all files (sprite.svg, sprite.css, [optional] sprite.html), instead of some coming from stream, some being written by 'fs' * added svgDest option to allow configuration of the output .svg file name + path * changed to use some of the best practices of writting gulp plugin * fixed various bugs (e.g. end the stream)
1 parent d43e982 commit 1055835

File tree

2 files changed

+63
-59
lines changed

2 files changed

+63
-59
lines changed

index.js

Lines changed: 56 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22

33
var cheerio = require('cheerio'),
4-
events = require('events'),
54
fs = require('fs'),
65
gutil = require('gulp-util'),
76
mustache = require('mustache'),
@@ -16,13 +15,14 @@ var PLUGIN_NAME = 'gulp-svg-spritesheet';
1615
var defaults = {
1716
cssPathNoSvg: '', // Leave blank if you dont want to specify a fallback
1817
cssPathSvg: './test.svg', // CSS path to generated SVG
19-
demoDest: '', // Leave blank if you don't want a demo file
20-
demoSrc: '../demo.tpl', // The souce or the demo template
18+
demoDest: './sprite.html', // Leave blank if you don't want a demo file
19+
demoSrc: path.resolve(__dirname, 'demo.tpl'), // The souce or the demo template
2120
padding: 0, // Add some padding between sprites
2221
pixelBase: 16, // Used to calculate em/rem values
2322
positioning: 'vertical', // vertical, horizontal, diagonal or packed
24-
templateSrc: '../template.tpl', // The source of the CSS template
25-
templateDest: './sprite.scss',
23+
templateSrc: path.resolve(__dirname, 'template.tpl'), // The source of the CSS template
24+
templateDest: './sprite.scss',
25+
svgDest: './sprite.svg',
2626
units: 'px', // px, em or rem
2727
x: 0, // Starting X position
2828
y: 0 // Starting Y position
@@ -55,7 +55,7 @@ var sort = {
5555

5656
// This is where the magic happens
5757
var spriteSVG = function(options) {
58-
58+
5959
options = options || {};
6060

6161
// Extend our defaults with any passed options
@@ -74,45 +74,43 @@ var spriteSVG = function(options) {
7474
units: options.units,
7575
width: 0
7676
},
77-
eventEmitter = new events.EventEmitter(),
78-
self,
7977
x = options.x,
8078
y = options.y;
8179

82-
// When a template file is loaded, render it
83-
eventEmitter.on("loadedTemplate", renderTemplate);
84-
8580
// Generate relative em/rem untis from pixels
8681
function pxToRelative(value) {
8782
return value / options.pixelBase;
8883
}
8984

9085
// Load a template file and then render it
9186
function loadTemplate(src, dest) {
92-
fs.readFile(src, function(err, contents) {
93-
if(err) {
94-
new gutil.PluginError(PLUGIN_NAME, err);
95-
}
96-
97-
var file = {
98-
contents: contents.toString(),
99-
data: data,
100-
dest: dest
101-
};
102-
103-
eventEmitter.emit("loadedTemplate", file);
104-
});
87+
var self = this;
88+
var src = path.resolve(src);
89+
var dest = path.resolve(dest);
90+
91+
try {
92+
var contents = fs.readFileSync(src, 'utf8');
93+
var compiled = mustache.render(contents, data);
94+
var file = new gutil.File({
95+
path: dest,
96+
contents: new Buffer(compiled)
97+
});
98+
99+
self.push(file);
100+
} catch (err) {
101+
throw new gutil.PluginError(PLUGIN_NAME, err);
102+
}
105103
}
106104

107-
// Position sprites using Jake Gordon's bin packing algorithm
105+
// Position sprites using Jake Gordon's bin packing algorithm
108106
// https://github.com/jakesgordon/bin-packing
109-
function packSprites(cb) {
107+
function packSprites() {
110108
var packer = new GrowingPacker();
111109

112110
// Get coordinates of sprites
113111
packer.fit(data.sprites);
114112

115-
// For each sprite
113+
// For each sprite
116114
for (var i in data.sprites) {
117115
var sprite = data.sprites[i],
118116
// Create, initialise and populate an SVG
@@ -152,22 +150,18 @@ var spriteSVG = function(options) {
152150

153151
// Add the SVG to the sprite sheet
154152
$sprite.append($svg);
155-
156153
}
157-
158-
// Save the sprite sheet
159-
saveSpriteSheet(cb);
160154
}
161155

162-
function positionSprites(cb) {
163-
// For each sprite
156+
function positionSprites() {
157+
// For each sprite
164158
for (var i in data.sprites) {
165159

166160
var sprite = data.sprites[i];
167161

168162
// Add padding
169-
sprite.x = x+options.padding;
170-
sprite.y = y+options.padding;
163+
sprite.x = x + options.padding;
164+
sprite.y = y + options.padding;
171165

172166
// Create, initialise and populate an SVG
173167
var $svg = $('<svg/>')
@@ -212,14 +206,10 @@ var spriteSVG = function(options) {
212206
sprite.x = pxToRelative(sprite.x);
213207
sprite.y = pxToRelative(sprite.y);
214208
}
215-
209+
216210
// Add the SVG to the sprite sheet
217211
$sprite.append($svg);
218-
219212
}
220-
221-
// Save the sprite sheet
222-
saveSpriteSheet(cb);
223213
}
224214

225215
function processSVG(file, encoding, cb) {
@@ -258,32 +248,36 @@ var spriteSVG = function(options) {
258248
}
259249

260250
function processSprites(cb) {
261-
// Save this for referencing in positioning functions
262-
self = this;
263251
// Sort the sprites so the biggest are first to avoid this issue:
264252
// https://github.com/jakesgordon/bin-packing/blob/master/js/packer.growing.js#L10
265253
data.sprites.sort(sort.maxside);
266-
267-
// Lay out the sprites
254+
// Lay out the sprites
268255
if(options.positioning==='packed') {
269256
packSprites(cb);
270257
} else {
271258
positionSprites(cb);
272259
}
260+
261+
// Save the sprite sheet
262+
saveSpriteSheet.call(this, cb);
273263
}
274264

275265
// Render our template and then save the file
276266
function renderTemplate(file) {
277267
var compiled = mustache.render(file.contents, file.data);
268+
var file = new gutil.File({
269+
path: file.dest,
270+
contents: new Buffer(compiled)
271+
});
272+
self.push(file);
273+
// fs.writeFile(file.dest, compiled);
274+
}
278275

279-
fs.writeFile(file.dest, compiled);
280-
}
281-
282-
// Final processing of sprite sheet then we return file to gulp pipe
283-
function saveSpriteSheet(cb) {
284-
// Add padding to even edges up
285-
data.height+=options.padding;
286-
data.width+=options.padding;
276+
// Final processing of sprite sheet then we return file to gulp pipe
277+
function saveSpriteSheet(cb) {
278+
// Add padding to even edges up
279+
data.height += options.padding;
280+
data.width += options.padding;
287281

288282
// If there is a non-svg fallback send the path to the template
289283
if(options.cssPathNoSvg) {
@@ -302,23 +296,26 @@ var spriteSVG = function(options) {
302296
data.height = pxToRelative(data.height);
303297
data.width = pxToRelative(data.width);
304298
}
305-
306-
// Save our CSS template file
307-
loadTemplate(options.templateSrc, options.templateDest);
299+
// Save our CSS template file
300+
loadTemplate.call(this, options.templateSrc, options.templateDest);
308301

309302
// If a demo file is required, save that too
310303
if(options.demoDest) {
311-
loadTemplate(options.demoSrc, options.demoDest);
304+
loadTemplate.call(this, options.demoSrc, options.demoDest);
312305
}
313306

314307
// Create a file to pipe back to gulp
315-
var file = new gutil.File({path: './', contents: new Buffer($.xml())});
308+
var file = new gutil.File({
309+
path: path.resolve(options.svgDest),
310+
contents: new Buffer($.xml())
311+
});
316312

317313
// Pipe it baby!
318-
self.push(file);
314+
this.push(file);
315+
cb();
319316
}
320317

321318
return through2.obj(processSVG, processSprites);
322319
};
323320

324-
module.exports = spriteSVG;
321+
module.exports = spriteSVG;

readme.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ gulp.task('default', function () {
3535
padding: 10,
3636
pixelBase: 16,
3737
positioning: 'diagonal',
38+
svgDest: './sprinte.svg',
3839
templateSrc: 'sass.tpl',
3940
templateDest: 'sass/sprite.scss',
4041
units: 'em'
@@ -62,6 +63,12 @@ Default: `./test.svg`
6263

6364
CSS `background-image` path which will be used in the `templateDest` file. The path should be relative to that final destination file.
6465

66+
####svgDest
67+
Type: `string`
68+
Default: `./sprite.svg`
69+
70+
The destination of the generated .svg file. If relative path is used, it will be set to `path.resolve('./some/relative/path.svg')`.
71+
6572
####demoDest
6673
Type: `string`
6774
Default: `<empty>`

0 commit comments

Comments
 (0)