From acce5bf0c5c0206e9c3f69b14b2704c543841d37 Mon Sep 17 00:00:00 2001 From: Scott Hyndman Date: Tue, 10 Nov 2015 19:03:51 -0800 Subject: [PATCH] Introduced a Gulpfile for the generation of derived files. SVG/PNG sprites, as well as Iconjar ijmaps can now be generated by running `gulp`. --- .babelrc | 3 + .gitignore | 0 gulpfile.babel.js | 165 ++++++++++++++++++++++++++++++++++++++++ iconfont/iconjar-map.js | 38 --------- package.json | 15 +++- 5 files changed, 182 insertions(+), 39 deletions(-) create mode 100755 .babelrc mode change 100644 => 100755 .gitignore create mode 100755 gulpfile.babel.js delete mode 100755 iconfont/iconjar-map.js diff --git a/.babelrc b/.babelrc new file mode 100755 index 000000000000..c13c5f627fd1 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["es2015"] +} diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/gulpfile.babel.js b/gulpfile.babel.js new file mode 100755 index 000000000000..f103a9c0ca88 --- /dev/null +++ b/gulpfile.babel.js @@ -0,0 +1,165 @@ +'use strict'; + +import _ from 'lodash'; +import File from 'vinyl'; +import gulp from 'gulp'; +import merge from 'merge-stream'; +import sprity from 'sprity'; +import svgSprite from 'gulp-svg-sprite'; +import through2 from 'through2'; +import { humanize, titleize } from 'underscore.string'; + + +/** Names of directories containing icons. */ +const ICON_CATEGORIES = [ + 'action', + 'alert', + 'av', + 'communication', + 'content', + 'editor', + 'file', + 'hardware', + 'image', + 'maps', + 'navigation', + 'notification', + 'places', + 'social', + 'toggle', +]; + + +/** Standard PNG colors. */ +const PNG_COLORS = [ + 'black', + 'white', +]; + + +/** + * Generates PNG sprites and their corresponding CSS files for each category of + * icon, and places them in `sprites/css-sprite`. + * + * TODO(shyndman): Add support for double density sprites. + */ +gulp.task('png-sprites', () => + _(getCategoryColorPairs()) + .map(([ category, color ]) => + sprity.src({ + src: `./${ category }/1x_web/*_${ color }_24dp.png`, + style: `sprite-${ category }-${ color }.css`, + name: `sprite-${ category }-${ color }`, + engine: 'sprity-gm', + orientation: 'left-right' + })) + .thru(merge) + .value() + .pipe(gulp.dest('./sprites/css-sprite/'))); + + +/** + * Generates CSS and Symbol-based SVG sprites for each category, and places + * them in `sprites/svg-sprite`. + */ +gulp.task('svg-sprites', () => + _(ICON_CATEGORIES) + .map((category) => + gulp.src(`./${ category }/svg/production/*_24px.svg`) + .pipe(svgSprite(getSvgSpriteConfig(category)))) + .thru(merge) + .value() + .pipe(gulp.dest('./sprites/svg-sprite'))); + + +/** + * Generates a file to allow the consumption of the icon font by Iconjar + * (http://geticonjar.com/). + */ +gulp.task('iconjar', () => + gulp.src('./iconfont/codepoints') + .pipe(generateIjmap('MaterialIcons-Regular.ijmap')) + .pipe(gulp.dest('./iconfont/'))); + + +/** Runs all tasks. */ +gulp.task('default', ['png-sprites', 'svg-sprites', 'iconjar']); + + +/** + * Returns a stream that transforms between our icon font's codepoint file + * and an Iconjar ijmap. + */ +function generateIjmap(ijmapPath) { + return through2.obj((codepointsFile, encoding, callback) => { + const ijmap = { + icons: codepointsToIjmap(codepointsFile.contents.toString()) + }; + + callback(null, new File({ + path: ijmapPath, + contents: new Buffer(JSON.stringify(ijmap), 'utf8') + })); + + function codepointsToIjmap(codepoints) { + return _(codepoints) + .split('\n') // split into lines + .reject(_.isEmpty) // remove empty lines + .reduce((codepointMap, line) => { // build up the codepoint map + let [ name, codepoint ] = line.split(' '); + codepointMap[codepoint] = { name: titleize(humanize(name)) }; + return codepointMap; + }, {}); + } + }); +} + + +/** + * Returns the SVG sprite configuration for the specified category. + */ +function getSvgSpriteConfig(category) { + return { + shape: { + dimension: { + maxWidth: 24, + maxHeight: 24 + }, + }, + mode: { + css : { + bust: false, + dest: './', + sprite: `./svg-sprite-${ category }.svg`, + example: { + dest: `./svg-sprite-${ category }.html` + }, + render: { + css: { + dest: `./svg-sprite-${ category }.css` + } + } + }, + symbol : { + bust: false, + dest: './', + sprite: `./svg-sprite-${ category }-symbol.svg`, + example: { + dest: `./svg-sprite-${ category }-symbol.html` + } + } + } + }; +} + + +/** + * Returns the catesian product of categories and colors. + */ +function getCategoryColorPairs() { + return _(ICON_CATEGORIES) + .map((category) => + _.zip(_.times(PNG_COLORS.length, () => category), PNG_COLORS)) + .flatten() // flattens 1 level + .value(); +} diff --git a/iconfont/iconjar-map.js b/iconfont/iconjar-map.js deleted file mode 100755 index 2c94a8832de2..000000000000 --- a/iconfont/iconjar-map.js +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env node - -var fileSystem = require('fs'); -var readLine = require('readline'); -var path = require('path'); - -// Output file path -var MAP_FILE_NAME = 'MaterialIcons-Regular.ijmap'; - -// Create a file streaming interface -var readLineHandle = readLine.createInterface({ - input: fileSystem.createReadStream('codepoints'), - output: process.stdout, - terminal: false -}); - -// Read each line by line from the file codepoints file -var json = {icons: {}}; -readLineHandle.on('line', function(line) { - // Match the name, space then any unicode after it - var nameCodepointPair = line.split(' '); - - // Titleize the glyph name - var codepoint = nameCodepointPair[1]; - var name = nameCodepointPair[0].toLowerCase().trim() - .replace(/[^0-9a-z]+/gi, ' ') - .replace(/\b[a-z]/g, function(char) { - return char.toUpperCase(); - }); - - // Assign the codepoint to the name for IconJar - json.icons[codepoint] = {name: name}; -}); - -readLineHandle.on('close', function() { - // Once reading has finished here we can write the file - fileSystem.writeFileSync(MAP_FILE_NAME, JSON.stringify(json)); -}); diff --git a/package.json b/package.json index a49ec20781b4..812e9df6f1c9 100644 --- a/package.json +++ b/package.json @@ -18,5 +18,18 @@ "bugs": { "url": "https://github.com/google/material-design-icons/issues" }, - "homepage": "https://github.com/google/material-design-icons" + "homepage": "https://github.com/google/material-design-icons", + "devDependencies": { + "babel-core": "^6.1.2", + "babel-preset-es2015": "^6.1.2", + "gulp": "^3.9.0", + "gulp-if": "^2.0.0", + "gulp-svg-sprite": "^1.2.13", + "lodash": "^3.10.1", + "sprity": "^1.0.7", + "sprity-gm": "^1.0.2", + "through2": "^2.0.0", + "underscore.string": "^3.2.2", + "vinyl": "^1.1.0" + } }