Skip to content

Commit 136fe83

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 136fe83

File tree

2 files changed

+50
-57
lines changed

2 files changed

+50
-57
lines changed

index.js

Lines changed: 43 additions & 57 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,14 +150,10 @@ 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) {
156+
function positionSprites() {
163157
// For each sprite
164158
for (var i in data.sprites) {
165159

@@ -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,30 +248,23 @@ 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
}
273-
}
274260

275-
// Render our template and then save the file
276-
function renderTemplate(file) {
277-
var compiled = mustache.render(file.contents, file.data);
278-
279-
fs.writeFile(file.dest, compiled);
261+
// Save the sprite sheet
262+
saveSpriteSheet.call(this, cb);
280263
}
281264

282-
// Final processing of sprite sheet then we return file to gulp pipe
283-
function saveSpriteSheet(cb) {
284-
// Add padding to even edges up
265+
// Final processing of sprite sheet then we return file to gulp pipe
266+
function saveSpriteSheet(cb) {
267+
// Add padding to even edges up
285268
data.height+=options.padding;
286269
data.width+=options.padding;
287270

@@ -302,23 +285,26 @@ var spriteSVG = function(options) {
302285
data.height = pxToRelative(data.height);
303286
data.width = pxToRelative(data.width);
304287
}
305-
306-
// Save our CSS template file
307-
loadTemplate(options.templateSrc, options.templateDest);
288+
// Save our CSS template file
289+
loadTemplate.call(this, options.templateSrc, options.templateDest);
308290

309291
// If a demo file is required, save that too
310292
if(options.demoDest) {
311-
loadTemplate(options.demoSrc, options.demoDest);
293+
loadTemplate.call(this, options.demoSrc, options.demoDest);
312294
}
313295

314296
// Create a file to pipe back to gulp
315-
var file = new gutil.File({path: './', contents: new Buffer($.xml())});
297+
var file = new gutil.File({
298+
path: path.resolve(options.svgDest),
299+
contents: new Buffer($.xml())
300+
});
316301

317302
// Pipe it baby!
318-
self.push(file);
303+
this.push(file);
304+
cb();
319305
}
320306

321307
return through2.obj(processSVG, processSprites);
322308
};
323309

324-
module.exports = spriteSVG;
310+
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)