Skip to content

Instantly share code, notes, and snippets.

@xgvargas
Last active June 25, 2018 09:01
Show Gist options
  • Save xgvargas/3c640f7aa4f3ae9fa187 to your computer and use it in GitHub Desktop.
Save xgvargas/3c640f7aa4f3ae9fa187 to your computer and use it in GitHub Desktop.
Gulp -> Coffeescript, SCSS, Jade, SVG to PNG, array(SVG) to SVG

Folder

You are supposed to have this project layout:

node_modules/
bower_components/
coffee/
jade/
scss/
svg/
  2png/
  icons/
www/
bower.json
package.json
gulpfile.js

Usage

  • gulp build

    • convert coffee/*.coffee to www/*.js
    • convert jade/*.jade to www/*.html
    • convert scss/*.scss to www/*.css
    • convert svg/2png/*.svg to www/*.png see bellow
    • merge svg/icons/*.svg into a single www/mdicons.svg see bellow
  • gulp dist the same build does, but

    • html is not pretty
    • JS is minified
    • JS has no Maps
  • gulp will build and then watch for changes (except for PNG files)

PNG

I like to draw a lot of glyphs in a single SVG file. So I have groups of images per SVG file.

This gulpfile will parse all SVG inside the svg/2png folder, and export to www/*.png all objects that match a regex.

In this case the object name need to start with xx, so, if inside the SVG file you have an object named xxbtn_add it will be extracted as www/btn_add.png.

Also all color #f2f2f2 are going to be converted to none (transparent). So is easy to define a gray rectangle with desired size, put some vectors inside and at the end you will have a transparent PNG image with the correct size and vectors well positioned.

You must have Inkscape in your path.

Icons

Supposing you are using Angular Material.

You can download SVG icons from Material Icons and copy them inside svg/icons/.

This gulpfile will merge them into a single SVG file named www/mdicons.svg.

You need to load this file:

app.config ($mdIconProvider) ->
    $mdIconProvider.defaultIconSet 'mdicons.svg'

And them use it:

//- jade
md-icon(md-svg-icon="search_white")
<!-- html -->
<md-icon md-svg-icon="search_white"></md-icon>

The name search_white came from the original file name i.e. svg/icons/search_white.svg.

Dependencies

Here is a piece of my package.json with all dependencies:

  "dependencies": {
    "gulp": "^3.9.1",
    "gulp-coffee": "^2.3.1",
    "gulp-jade": "^1.1.0",
    "gulp-ng-annotate": "^2.0.0",
    "gulp-sass": "^2.2.0",
    "gulp-sourcemaps": "^1.6.0",
    "gulp-svg-ngmaterial": "^2.0.2",
    "gulp-svgmin": "^1.2.2",
    "gulp-uglify": "^1.5.3",
    "gulp-util": "^3.0.7",
    "shelljs": "^0.6.0"
  }

WHAT?

There is no structure inside www/? You have JS, CSS, HTML, SVG all together?

Yes, I don't care!

My code is organized outside of www/. There is no code to be tweaked inside it. Actually they should be concatenated into a single file (per type), for distribution, so why should I care?

var gulp = require('gulp');
var coffee = require('gulp-coffee');
var sass = require('gulp-sass');
var jade = require('gulp-jade');
var sh = require('shelljs');
var sourcemaps = require('gulp-sourcemaps');
var svgng = require('gulp-svg-ngmaterial');
var gutil = require('gulp-util');
var uglify = require('gulp-uglify');
var ngAnnotate = require('gulp-ng-annotate');
var svgmin = require('gulp-svgmin');
var DEVMODE = true;
var DST = 'www/';
gulp.task('default', ['sass', 'coffee', 'jade', 'icon'], function(){
gulp.watch('scss/**/*.scss', ['sass']);
gulp.watch('coffee/**/*.coffee', ['coffee']);
gulp.watch('jade/**/*.jade', ['jade']);
gulp.watch('svg/icons/**/*.svg', ['icon']);
});
gulp.task('dist', function(){
DEVMODE = false;
gulp.start('build');
});
gulp.task('build', ['sass', 'coffee', 'jade', 'png', 'icon']);
gulp.task('sass', function() {
return gulp.src('scss/*.scss')
.pipe(sass({ errLogToConsole: true })) .on('error', gutil.log)
.pipe(gulp.dest(DST));
});
gulp.task('coffee', function() {
return gulp.src('coffee/*.coffee')
.pipe(DEVMODE ? sourcemaps.init() : gutil.noop())
.pipe(coffee({ bare: false })) .on('error', gutil.log)
.pipe(DEVMODE ? sourcemaps.write() : gutil.noop())
.pipe(ngAnnotate())
.pipe(DEVMODE ? gutil.noop() : uglify()) .on('error', gutil.log)
.pipe(gulp.dest(DST));
});
gulp.task('jade', function() {
return gulp.src('jade/*.jade')
.pipe(jade({
locals: {},
client: false,
pretty: DEVMODE,
})) .on('error', gutil.log)
.pipe(gulp.dest(DST));
});
gulp.task('png', function(done){
var files = sh.ls('svg/2png/*.svg');
var count = 0;
for(var i = 0; i < files.length; i++){
count++;
svgAux({
done: function(){ if(!--count) done(); },
input: files[i],
output: DST,
valid: /xx\w+/,
cut: 2,
cmd: '-e ',
extension: '.png',
replace: [{from: '#f2f2f2', to: 'none'}],
});
}
});
gulp.task('icon', function(){
return gulp.src('svg/icons/**/*.svg')
.pipe(svgmin({
js2svg: {
pretty: DEVMODE
}
}))
.pipe(svgng({ filename: 'mdicons.svg' }))
.pipe(gulp.dest(DST));
});
function svgAux(ops){
if(!sh.which('inkscape')){
gutil.log('OOps! Inkscape must be in your path');
}
else{
var tmp = Math.random().toString(36).substr(7) + '.svg'
sh.cp(ops.input, tmp);
for(var i = 0; i < ops.replace.length; i++){
sh.sed('-i', ops.replace[i].from, ops.replace[i].to, tmp);
}
sh.exec('inkscape -z -S ' + tmp, {silent: true}, function(code, data){
var name = /^([^\n,]+)/gm;
var m, count = 0;
do{
m = name.exec(data);
if(m){
if(ops.valid.test(m[1])){
(function(name){
count++;
sh.exec('inkscape -z -d 90 ' + ops.cmd + ops.output + name + ops.extension + ' -j -i ' +
m[1] + ' ' + tmp, {silent: true}, function(){
gutil.log('Extracted: ' + ops.output + name + ops.extension);
if(!--count){
sh.rm(tmp);
ops.done();
}
});
})(m[1].substring(ops.cut));
}
}
} while(m);
if(!count){
sh.rm(tmp);
ops.done();
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment