w0rm / gulp-svgstore

Combine svg files into one with symbol elements

Home Page:https://www.npmjs.com/package/gulp-svgstore

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Create multiple files

ghetolay opened this issue · comments

commented

For now svgstore takes a bunch of files as input and output a single merged file.

What about generating multiple output file ?

I'm thinking about 2 simple way of doing it :

  1. With some option like recurse:true we would expect a 2 level folder hierarchy like that :
    .
    ├── theme1
    │   ├── sprite1.svg
    │   ├── sprite2.svg
    │   ├── ....
    ├── theme2
    │   ├── sprite1.svg
    │   ├── sprite2.svg
    │   ├── ....
    ├── ....

=> theme1.svg, theme2.svg

So each folder represent an output and its content the input.

  1. Through a callback function that would match each input file to an output file. If function returns same value for multiple files they'll be merged into the same output. The return value could be the output filename or filepath.

Of course both solution may coexist, actually 1) would just be some alias to define the callback function of 2).

@ghetolay I am against this feature, it doesn't feel lightweight. Can be done relatively easy with gulp by creating multiple streams and then using event-stream to merge them together into one.

commented

Well as I see it, it would be pretty simple, straightforward and lightweight. Just need to introduce a map of output :

var outputs = {}

For each file we call the function to define which output we'll use :

stream._transform = function transform (file, encoding, cb) {
   var output = getOutput(file)
   var context = outputs[output]
   if (!context) {
   /* initialize context as we did globally
     could also be done through an object and a new statement */
      var $ = cheerio.load(resultSvg, { xmlMode: true })
      outputs[output] = context = {
          ids : {},
          namespaces : {},
          isEmpty : true,
          $combinedSvg = $('svg'),
          $combinedDefs = $('defs'),
   }
   //Do what we do
}

Then on flush basically do the same thing inside a loop :

stream._flush = function flush (cb) {
    for(var fileName in outputs){
        var context = outputs[fileName]
        //do what we do
    }
}

Only thing left is the function getOutput(file) configurable by user and with a default value like that :

var getOutput = option.getOutput || function(file){
    return path.dirname(file.path);
}

No if you still think it's heavy work or really don't want that feature it's your choice.

Think of gulp-svgstore as gulp-concat. This feature is beyond the scope.

According to gulp plugin guidelines, it should do one thing. I don't want to turn it in full blown solution that can be built on top of it in the gulp task.

commented

Ok fine, was just answering the lightweight part.

@ghetolay I meant lightweight in terms of feature set.

@ghetolay this is how I would have solved it:

var es = require('event-stream');
var gulp = require('gulp');
var svgstore = require('gulp-svgstore');
var fs = require('fs');

gulp.task('default', function () {

    var streams = fs.readdirSync('src')
        .map(function (theme) {
            return gulp
                .src('src/' + theme + '/*.svg', {base: 'src/' + theme})
                .pipe(svgstore());
        });

    return es
        .merge(streams)
        .pipe(gulp.dest('dest'));

});