├── .editorconfig ├── .eslintrc ├── .gitignore ├── .jscsrc ├── LICENSE-MIT ├── command ├── create.js ├── install.js ├── sprity-command.js └── watch.js ├── index.js ├── lib └── log.js ├── package.json └── readme.md /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | env: 2 | node: true 3 | 4 | rules: 5 | indent: [2, 2] 6 | brace-style: [1, "stroustrup"] 7 | comma-style: [1, "last"] 8 | comma-spacing: [1, {"before": false, "after": true}] 9 | default-case: 2 10 | eol-last: [1, true] 11 | guard-for-in: 2 12 | no-floating-decimal: 2 13 | no-nested-ternary: 2 14 | no-undefined: 2 15 | quotes: [1, "single", "avoid-escape"] 16 | radix: 2 17 | space-after-keywords: [2, "always"] 18 | space-before-function-paren: "always" 19 | space-before-blocks: [1, 2] 20 | spaced-line-comment: [1, "always", { exceptions: ["-"]}] 21 | strict: [2, "global"] 22 | valid-jsdoc: [2, { prefer: { "return": "returns"}}] 23 | wrap-iife: 2 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | .DS_Store 4 | *.log 5 | test/dist 6 | test/out 7 | npm-debug.log 8 | test/ 9 | out/ 10 | -------------------------------------------------------------------------------- /.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "requireCurlyBraces": [ "if", "else", "else if", "for", "while", "do", "switch" ], 3 | "requireSpaceAfterKeywords": [ "if", "else", "else if", "for", "while", "do", "switch" ], 4 | "requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], 5 | "requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], 6 | "requireLineFeedAtFileEnd": true, 7 | "requireSpaceBeforeBinaryOperators": true, 8 | "requireSpaceAfterBinaryOperators": true, 9 | "requireKeywordsOnNewLine": ["else", "else if"], 10 | "requireSpacesInFunctionExpression": { 11 | "beforeOpeningCurlyBrace": true, 12 | "beforeOpeningRoundBrace": true 13 | }, 14 | "disallowSpacesInsideParentheses": true, 15 | "disallowSpaceAfterKeywords": [], 16 | "disallowSpaceAfterObjectKeys": true, 17 | "disallowImplicitTypeConversion": [], 18 | "disallowMultipleLineBreaks": true, 19 | "disallowSpacesInsideArrayBrackets": true, 20 | "disallowSpacesInsideObjectBrackets": true, 21 | "disallowSpaceAfterPrefixUnaryOperators": [ "-", "+", "~", "!" ], 22 | "disallowSpaceBeforePostfixUnaryOperators": [ "++", "--" ] 23 | } 24 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Alexander Slansky 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /command/create.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var sprity = require('sprity'); 4 | var log = require('../lib/log'); 5 | var scmd = require('./sprity-command'); 6 | 7 | var command = function (opts) { 8 | opts.cli = true; 9 | opts.logger = log; 10 | if (opts['no-sort']) { 11 | opts.sort = false; 12 | } 13 | 14 | sprity.create(opts, function (err) { 15 | if (err) { 16 | log.error(err.toString()); 17 | if (err.reason) { 18 | log.debug(err.reason); 19 | } 20 | } 21 | else { 22 | log.success('Sprite created in ' + opts.out); 23 | } 24 | }); 25 | }; 26 | 27 | module.exports = function (parser) { 28 | scmd(parser, 'create') 29 | .callback(command) 30 | .help('create sprites'); 31 | }; 32 | -------------------------------------------------------------------------------- /command/install.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var npm = require('npm'); 4 | var _ = require('lodash'); 5 | var Promise = require('bluebird'); 6 | var log = require('../lib/log'); 7 | 8 | var info = function (args) { 9 | return new Promise(function (resolve, reject) { 10 | npm.commands.info(args, true, function (e, r) { 11 | if (e) { 12 | reject(e); 13 | } 14 | else { 15 | resolve(r); 16 | } 17 | }); 18 | }); 19 | }; 20 | 21 | var findModule = function (name) { 22 | return info([name]) 23 | .then(function (res) { 24 | var found = false; 25 | _.each(res, function (mod) { 26 | if (_.includes(mod.keywords, 'sprity')) { 27 | found = mod.name; 28 | } 29 | }); 30 | return found; 31 | }) 32 | .catch(function () { 33 | return false; 34 | }); 35 | }; 36 | 37 | var install = function (name) { 38 | return new Promise(function (resolve, reject) { 39 | npm.commands.install([name], function (e) { 40 | if (e) { 41 | reject(e); 42 | } 43 | else { 44 | resolve(name); 45 | } 46 | }); 47 | }); 48 | }; 49 | 50 | var command = function (opts) { 51 | npm.load({usage: false}, function (err) { 52 | if (err) { 53 | log.error(err.toString()); 54 | } 55 | else { 56 | findModule(opts.name) 57 | .then(function (found) { 58 | if (!found) { 59 | return findModule('sprity-' + opts.name); 60 | } 61 | else { 62 | return found; 63 | } 64 | }) 65 | .then(function (found) { 66 | if (!found) { 67 | throw new Error(opts.name + ' could not be found or is not compatible with sprity'); 68 | } 69 | else { 70 | return install(found); 71 | } 72 | }) 73 | .then(function (name) { 74 | log.success('Successfully installed ' + name); 75 | }) 76 | .catch(function (e) { 77 | log.error(e.toString()); 78 | }); 79 | } 80 | }); 81 | }; 82 | 83 | module.exports = function (parser) { 84 | parser.command('install') 85 | .option('name', { 86 | position: 1, 87 | required: true, 88 | help: 'name of the image engine or style processor to install (e.g. canvas, sass)' 89 | }) 90 | .callback(command) 91 | .help('install image processing engine'); 92 | }; 93 | -------------------------------------------------------------------------------- /command/sprity-command.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function (parser, cmd) { 4 | return parser.command(cmd) 5 | .option('out', { 6 | position: 1, 7 | required: true, 8 | metavar: 'DIR', 9 | default: process.cwd(), 10 | help: 'path of directory to write sprite file to' 11 | }) 12 | .option('src', { 13 | position: 2, 14 | required: true, 15 | list: true, 16 | metavar: 'GLOB', 17 | help: 'glob strings to find source images to put into the sprite' 18 | }) 19 | .option('base64', { 20 | abbr: 'b', 21 | flag: true, 22 | help: 'create css with base64 encoded sprite (css file will be written to )' 23 | }) 24 | .option('cssPath', { 25 | abbr: 'c', 26 | full: 'css-path', 27 | default: '../images', 28 | help: 'path or url of sprites on the web server used to reference the sprite in the styles (relative or absolute path or full url)' 29 | }) 30 | .option('dimension', { 31 | abbr: 'd', 32 | list: true, 33 | default: [{ 34 | ratio: 1, 35 | dpi: 72 36 | }], 37 | transform: function (value) { 38 | value = value.split(':'); 39 | return { 40 | ratio: Number(value[0]), 41 | dpi: Number(value[1]) 42 | }; 43 | }, 44 | help: 'the used dimensions for the sprite. A combination of ratio and dpi. For example -d 2:192 would generate a sprite for device-pixel-ratio:2 and min-resolution: 192dpi. Multiple dimensions are allowed. Defaults to 1:72' 45 | }) 46 | .option('engine', { 47 | abbr: 'e', 48 | default: 'lwip', 49 | help: 'image processing engine' 50 | }) 51 | .option('format', { 52 | abbr: 'f', 53 | help: 'output format of the sprite Default: depends on image processor' 54 | }) 55 | .option('name', { 56 | abbr: 'n', 57 | default: 'sprite', 58 | help: 'name of sprite file without file extension ' 59 | }) 60 | .option('processor', { 61 | abbr: 'p', 62 | default: 'css', 63 | help: 'style processing module' 64 | }) 65 | .option('template', { 66 | abbr: 't', 67 | help: 'output template file, overrides processor option' 68 | }) 69 | .option('style', { 70 | abbr: 's', 71 | help: 'file to write css to, if omitted no css is written (relative to out path)' 72 | }) 73 | .option('background', { 74 | default: '#FFFFFF', 75 | help: 'background color of the sprite in hex' 76 | }) 77 | .option('cachebuster', { 78 | flag: true, 79 | default: false, 80 | help: 'appends a "cache buster" to the background image in the form "?<...>"' 81 | }) 82 | .option('margin', { 83 | default: 4, 84 | help: 'margin in px between tiles' 85 | }) 86 | .option('opacity', { 87 | default: 0, 88 | help: 'background opacity (0 - 100) of the sprite. defaults to 0 when png or 100 when jpg' 89 | }) 90 | .option('orientation', { 91 | choices: ['vertical', 'horizontal', 'binary-tree'], 92 | default: 'vertical', 93 | help: 'orientation of the sprite image (vertical|horizontal|binary-tree)' 94 | }) 95 | .option('prefix', { 96 | help: 'prefix for the class name used in css (without .)' 97 | }) 98 | .option('no-sort', { 99 | flag: true, 100 | help: 'disable sorting of layout' 101 | }) 102 | .option('split', { 103 | flag: true, 104 | default: false, 105 | help: 'create sprite images for every sub folder' 106 | }) 107 | .option('style-indent-char', { 108 | choices: ['space', 'tab'], 109 | default: 'space', 110 | help: 'Character used for indentation of styles (space|tab)' 111 | }) 112 | .option('style-indent-size', { 113 | default: 2, 114 | help: 'Number of characters used for indentation of styles' 115 | }); 116 | }; 117 | -------------------------------------------------------------------------------- /command/watch.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var fs = require('vinyl-fs'); 4 | var sprity = require('sprity'); 5 | var log = require('../lib/log'); 6 | var scmd = require('./sprity-command'); 7 | 8 | var command = function (opts) { 9 | opts.cli = true; 10 | opts.logger = log; 11 | if (opts['no-sort']) { 12 | opts.sort = false; 13 | } 14 | log.log('Watching for file changes ...'); 15 | fs.watch(opts.src, function () { 16 | sprity.create(opts, function () { 17 | log.success('Sprite created in ' + opts.out); 18 | }); 19 | }); 20 | }; 21 | 22 | module.exports = function (parser) { 23 | scmd(parser, 'watch') 24 | .callback(command) 25 | .help('watch for image changes and create sprites on change'); 26 | }; 27 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | var parser = require('nomnom'); 5 | 6 | require('./command/create')(parser); 7 | require('./command/watch')(parser); 8 | require('./command/install')(parser); 9 | 10 | parser.script('sprity').parse(); 11 | -------------------------------------------------------------------------------- /lib/log.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var colors = require('colors'); 4 | 5 | colors.setTheme({ 6 | debug: 'blue', 7 | log: 'reset', 8 | warn: 'yellow', 9 | error: 'red', 10 | success: 'green' 11 | }); 12 | 13 | var out = function (msg, level) { 14 | if (!level) { 15 | level = 'log'; 16 | } 17 | console.log(colors.bold('[sprity] ') + msg[level]); 18 | }; 19 | 20 | module.exports = { 21 | log: function (msg) { 22 | out(msg); 23 | }, 24 | warn: function (msg) { 25 | out(msg, 'warn'); 26 | }, 27 | debug: function (msg) { 28 | out(msg, 'debug'); 29 | }, 30 | error: function (msg) { 31 | out(msg, 'error'); 32 | }, 33 | success: function (msg) { 34 | out(msg, 'success'); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sprity-cli", 3 | "version": "1.0.1", 4 | "description": "Command line interface for sprity", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/sprity/sprity-cli.git" 8 | }, 9 | "homepage": "https://github.com/sprity/sprity-cli", 10 | "bugs": { 11 | "url": "https://github.com/sprity/sprity-cli/issues" 12 | }, 13 | "licenses": [ 14 | { 15 | "type": "MIT", 16 | "url": "https://github.com/sprity/sprity-cli/blob/master/LICENSE-MIT" 17 | } 18 | ], 19 | "author": { 20 | "name": "Alexander Slansky", 21 | "email": "alexander@slansky.net", 22 | "url": "http://slansky.net" 23 | }, 24 | "engines": { 25 | "node": ">=0.10.0" 26 | }, 27 | "bin": { 28 | "sprity": "./index.js" 29 | }, 30 | "scripts": { 31 | "hint": "eslint index.js", 32 | "style": "jscs index.js" 33 | }, 34 | "main": "./index.js", 35 | "keywords": [ 36 | "sprites", 37 | "sprite", 38 | "css-sprite", 39 | "sprity" 40 | ], 41 | "dependencies": { 42 | "bluebird": "^2.9.24", 43 | "colors": "^1.0.3", 44 | "lodash": "^3.7.0", 45 | "nomnom": "^1.8.1", 46 | "npm": "^2.8.4", 47 | "sprity": "^1.0.0", 48 | "vinyl-fs": "^1.0.0" 49 | }, 50 | "devDependencies": { 51 | "chai": "^2.2.0", 52 | "mocha": "^2.2.4" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # sprity-cli 2 | 3 | [![NPM version](https://badge.fury.io/js/sprity-cli.svg)](http://badge.fury.io/js/sprity-cli) [![Dependencies](https://david-dm.org/sprity/sprity-cli.svg)](https://david-dm.org/sprity/sprity-cli) 4 | 5 | > Command line interface for [sprity](https://npmjs.org/package/sprity) 6 | 7 | ## Install 8 | 9 | ```sh 10 | npm install sprity-cli -g 11 | ``` 12 | 13 | ## Usage 14 | 15 | ``` 16 | Usage: sprity 17 | 18 | command 19 | create create sprites 20 | watch watch for image changes and create sprites on change 21 | install install image processing engine or style processors 22 | ``` 23 | 24 | ### Create command 25 | 26 | > create sprites 27 | 28 | ``` 29 | Usage: sprity create ... [options] 30 | 31 | out path of directory to write sprite file to 32 | src glob strings to find source images to put into the sprite 33 | 34 | Options: 35 | -b, --base64 create css with base64 encoded sprite (css file will be written to ) 36 | -c, --css-path path or url of sprites on the web server used to reference the sprite in the styles (relative or absolute path or full url) [../images] 37 | -d, --dimension the used dimensions for the sprite. A combination of ratio and dpi. For example -d 2:192 would generate a sprite for device-pixel-ratio:2 and min-resolution: 192dpi. Multiple dimensions are allowed. Defaults to 1:72 38 | -e, --engine image processing engine [lwip] 39 | -f, --format output format of the sprite Default: depends on image processor 40 | -n, --name name of sprite file without file extension [sprite] 41 | -p, --processor style processing module [css] 42 | -t, --template output template file, overrides processor option 43 | -s, --style file to write css to, if omitted no css is written (relative to out path) 44 | --background background color of the sprite in hex [#FFFFFF] 45 | --cachebuster appends a "cache buster" to the background image in the form "?<...>" [false] 46 | --margin margin in px between tiles [4] 47 | --opacity background opacity (0 - 100) of the sprite. defaults to 0 when png or 100 when jpg [0] 48 | --orientation orientation of the sprite image (vertical|horizontal|binary-tree) [vertical] 49 | --prefix prefix for the class name used in css (without .) 50 | --no-sort disable sorting of layout 51 | --split create sprite images for every sub folder [false] 52 | --style-indent-char Character used for indentation of styles (space|tab) [space] 53 | --style-indent-size Number of characters used for indentation of styles [2] 54 | ``` 55 | 56 | ### Watch command 57 | 58 | > watch for image changes and create sprites on change 59 | 60 | ``` 61 | Usage: sprity watch ... [options] 62 | ``` 63 | 64 | Options: see Create command 65 | 66 | ### Install command 67 | 68 | > install image processing engine 69 | 70 | ``` 71 | Usage: sprity install 72 | 73 | name name of the image engine or style processor to install (e.g. canvas, sass) 74 | ``` 75 | 76 | ## More 77 | 78 | See [sprity](https://npmjs.org/package/sprity) documentation 79 | 80 | 81 | --- 82 | [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/sprity/sprity?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) 83 | --------------------------------------------------------------------------------