Skip to content

Commit

Permalink
Added support for LESS output (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
jkphl committed Feb 21, 2014
1 parent 20df851 commit d1f9480
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 13 deletions.
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ Options:
-V, --version output the version number
-o, --out <css-directory> Output directory for the CSS file and the sprite subdirectory
--sassout <sass-directory> Optional: separate output directory for Sass files [defaults to --out]
--lessout <less-directory> Optional: separate output directory for LESS files [defaults to --out]
-c, --css [css-filename] Render CSS file (optionally provide a CSS file name, defaults to "sprite")
-s, --sass [sass-filename] Render Sass file (optionally provide a Sass file name, defaults to "sprite")
-l, --less [less-filename] Render LESS file (optionally provide a LESS file name, defaults to "sprite")
--spritedir <sprite-directory> Sprite subdirectory name [svg]
--sprite <sprite-filename> Sprite file name [sprite]
-p, --prefix <selector-prefix> CSS selector prefix [svg]
Expand Down Expand Up @@ -122,17 +124,19 @@ These are the options you may pass as the `createSprite()` method's third argume
Property | Type | Description
------------- | ---------------- | ----------------
`css` | Boolean / String | If given and non-empty, a CSS file will be rendered, with the value being the file name (preceding the `.css` extension). If set to `TRUE`, the file name will be *sprite*.
`sass` | Boolean / String | If given and non-empty, a Sass file (SCSS) will be rendered, with the value being the file name (preceding the `.scss` extension). If set to `TRUE`, the file name will be *sprite*.
`sass` | Boolean / String | If given and non-empty, a [Sass](http://sass-lang.com) file (SCSS) will be rendered, with the value being the file name (preceding the `.scss` extension). If set to `TRUE`, the file name will be *sprite*.
`sassout` | Directory path | Output directory for the Sass file (also see the `sass` option above, which needs to be set to create a Sass file). Defaults to the general output directory (second argument to `createSprite()`).
`less` | Boolean / String | If given and non-empty, a [LESS](http://lesscss.org) file will be rendered, with the value being the file name (preceding the `.less` extension). If set to `TRUE`, the file name will be *sprite*.
`lessout` | Directory path | Output directory for the LESS file (also see the `less` option above, which needs to be set to create a LESS file). Defaults to the general output directory (second argument to `createSprite()`).
`spritedir` | Directory path | Directory relative to the general CSS output directory where the SVG sprite will be created. Defaults to *svg*.
`sprite` | String | Filename of the SVG sprite (preceding the `.svg` extension). Defaults to *sprite*.
`prefix` | String | Prefix for all CSS rules (CSS and Sass file). Defaults to *svg* (results in `.svg-*` CSS selectors)
`prefix` | String | Prefix for all CSS rules (CSS, Sass & LESS file). Defaults to *svg* (results in `.svg-*` CSS selectors)
`common` | String | If given and not empty, it will be used for creating a CSS selector that commonly defines the `background-image` and `background-repeat` properties for all the sprite images (thus saving some bytes by not unnecessarily repeating these properties for each image)
`maxwidth` | Integer | Maximum width of single SVG images. Will be downscaled if necessary. Defaults to `1000`.
`maxheight` | Integer | Maximum height of single SVG images. Will be downscaled if necessary. Defaults to `1000`.
`padding` | Integer | Padding around the single SVG images in the sprite. Defaults to `0`.
`pseudo` | String | Char to determine the usage of CSS pseudo classes. See the [iconizr documentation](https://github.com/jkphl/iconizr#css-pseudo-classes) for details. Defaults to *~*.
`dims` | - | If present, additional CSS rules will be rendered (both CSS and Sass) that set the dimensions of the single images. You can use these CSS rules for sizing your elements appropriately. In general, the suffix `-dims` will be used in conjunction with the regular CSS selector for the image, but please have a look at the generated CSS file as well as the [iconizr documentation](https://github.com/jkphl/iconizr#css-pseudo-classes) for some special rules regarding CSS pseudo classes.
`dims` | - | If present, additional CSS rules will be rendered (CSS, Sass & LESS) that set the dimensions of the single images. You can use these CSS rules for sizing your elements appropriately. In general, the suffix `-dims` will be used in conjunction with the regular CSS selector for the image, but please have a look at the generated CSS file as well as the [iconizr documentation](https://github.com/jkphl/iconizr#css-pseudo-classes) for some special rules regarding CSS pseudo classes.
`keep` | - | If present, the single optimized intermediate SVG images used for creating the sprite will not be discarded, but kept in the `spritedir` as well.
`verbose` | Integer | Set to a value > `0` to get some output. Defaults to `0`.
`cleanwith` | String | Select the module used for optimizing the single SVG images. Currently, the Node.js modules [svg-cleaner](https://npmjs.org/package/svg-cleaner) (loosely based on [Scour](http://www.codedread.com/scour)) and [SVGO](https://github.com/svg/svgo) are supported, so use either *scour* or *svgo* for this option. Set it to `FALSE` or `NULL` to skip the SVG optimization altogether. Defaults to *scour* (but this may change in the future).
Expand All @@ -149,6 +153,9 @@ Known problems / To-do
Release history
---------------
#### v0.0.8
* Added support for LESS output ([#4](https://github.com/jkphl/svg-sprite/issues/4))
#### v0.0.7
* Fixed incomplete Sass output ([#3](https://github.com/jkphl/grunt-svg-sprite/issues/3))
Expand Down
14 changes: 11 additions & 3 deletions bin/svg-sprite.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,21 @@ function createSprite(cmd) {
console.log('Converting the SVG files in directory "%s" to an SVG sprite ...', cmd);
}
var options = {};
if (typeof this.sassout != 'undefined') {
options.sassout = this.sassout;
}
if (typeof this.css != 'undefined') {
options.css = this.css.length ? this.css : true;
}
if (typeof this.sass != 'undefined') {
options.sass = this.sass.length ? this.sass : true;
}
if (typeof this.sassout != 'undefined') {
options.sassout = this.sassout;
}
if (typeof this.less != 'undefined') {
options.less = this.less.length ? this.less : true;
}
if (typeof this.lessout != 'undefined') {
options.lessout = this.lessout;
}
if (typeof this.spritedir != 'undefined') {
options.spritedir = this.spritedir;
}
Expand Down Expand Up @@ -79,8 +85,10 @@ program
.version('0.0.1')
.option('-o, --out <css-directory>', 'Output directory for the CSS file and the sprite subdirectory')
.option('--sassout <sass-directory>', 'Optional: separate output directory for Sass files [defaults to --out]')
.option('--lessout <less-directory>', 'Optional: separate output directory for LESS files [defaults to --out]')
.option('-c, --css [css-filename]', 'Render CSS file (optionally provide a CSS file name, defaults to "sprite")')
.option('-s, --sass [sass-filename]', 'Render Sass file (optionally provide a Sass file name, defaults to "sprite")')
.option('-l, --less [less-filename]', 'Render LESS file (optionally provide a LESS file name, defaults to "sprite")')
.option('--spritedir <sprite-directory>', 'Sprite subdirectory name [svg]')
.option('--sprite <sprite-filename>', 'Sprite file name [sprite]')
.option('-p, --prefix <selector-prefix>', 'CSS selector prefix [svg]')
Expand Down
74 changes: 68 additions & 6 deletions lib/svg-sprite.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ var _ = require('underscore'),
SVGObj = require('./svg-obj.js'),
defaultOptions = {
sassout : null,
lessout : null,
css : true,
sass : false,
less : false,
spritedir : 'svg',
sprite : 'sprite',
prefix : 'svg',
Expand Down Expand Up @@ -66,11 +68,14 @@ function SVGSprite(inputDir, outputDir, options) {

// Validate & prepare the options
this._options = _.extend(defaultOptions, options);
var sassout = (new String(this._options.sassout || '')).trim();
var sassout = (new String(this._options.sassout || '')).trim(),
lessout = (new String(this._options.lessout || '')).trim();
this._options.cssout = path.resolve(outputDir);
this._options.sassout = sassout.length ? path.resolve(sassout) : this._options.cssout;
this._options.lessout = lessout.length ? path.resolve(lessout) : this._options.lessout;
this._options.css = (this._options.css === true) ? 'sprite' : ((new String(this._options.css || '')).trim() || false);
this._options.sass = (this._options.sass === true) ? 'sprite' : ((new String(this._options.sass || '')).trim() || false);
this._options.less = (this._options.less === true) ? 'sprite' : ((new String(this._options.less || '')).trim() || false);
this._options.spritedir = (new String(this._options.spritedir || '').trim()) || 'svg';
this._options.sprite = (new String(this._options.sprite || '').trim()) || 'sprite';
this._options.prefix = (new String(this._options.prefix || '').trim()) || 'svg';
Expand Down Expand Up @@ -119,6 +124,7 @@ SVGSprite.prototype._reset = function() {
this.sprite = [];
this.css = [];
this.sass = [];
this.less = [];
this.result = {success: false, length: 0, files: {}};
}

Expand Down Expand Up @@ -198,6 +204,20 @@ SVGSprite.prototype._writeFilesSync = function(callback) {
}
}

// If there's LESS to be written
if (this.less.length) {
var spriteLess = this.less.join('\n'),
spriteLessPath = path.join(this._options.lessout, this._options.less + '.less');
try {
fs.writeFileSync(spriteLessPath, spriteLess, 'utf-8')
this.result.files[spriteLessPath] = spriteLess.length;
++this.result.length;
} catch(error) {
callback(error);
return;
}
}

callback(null);
}

Expand Down Expand Up @@ -270,6 +290,21 @@ SVGSprite.prototype.createSprite = function(callback) {
}
},

// Optionally create the Less output directory
function(_callback){
if (that._options.lessout) {
mkdirp(that._options.lessout, 511, function(error) {
if (error && (typeof(error) == 'object') && ('message' in error)) {
error = new Error(error.message);
error.errno = 1391854708;
}
_callback(error);
});
} else {
_callback();
}
},

// Process all SVG files
function(_callback){
that._processFiles(_callback);
Expand Down Expand Up @@ -337,7 +372,8 @@ SVGSprite.prototype._addToSprite = function(svgID, svgInfo) {
// Determine the CSS class name and pseudo class
var cls = svgID.split(this._options.pseudo),
spriteUrl = path.join(this._options.spritedir, this._options.sprite + '.svg'),
sassExtend = '%' + this._options.prefix;
sassExtend = '%' + this._options.prefix,
lessMixin = '.' + this._options.prefix + '()';

// If a common class is to be used
if (this._options.common) {
Expand All @@ -347,10 +383,23 @@ SVGSprite.prototype._addToSprite = function(svgID, svgInfo) {
if (this._options.sass.length && !this.sass.length) {
this.sass.push('.' + this._options.common + ' {\n background-image:url(' + spriteUrl + ');\n background-repeat:no-repeat\n}');
}
if (this._options.less.length && !this.less.length) {
this.less.push('.' + this._options.common + ' {\n background-image:url(' + spriteUrl + ');\n background-repeat:no-repeat\n}');
console.log(this.less);
}

// Else: Register the Sass extension class
} else if (this._options.sass.length && !this.sass.length) {
this.sass.push(sassExtend + ' {\n background-image: url(' + spriteUrl + ');\n background-repeat: no-repeat;\n}');
// Else: Register the Sass placeholder / LESS mixin
} else {

// Sass placeholder
if (this._options.sass.length && !this.sass.length) {
this.sass.push(sassExtend + ' {\n background-image: url(' + spriteUrl + ');\n background-repeat: no-repeat;\n}');
}

// LESS mixin
if (this._options.less.length && !this.less.length) {
this.less.push(lessMixin + ' {\n background-image: url(' + spriteUrl + ');\n background-repeat: no-repeat;\n}');
}
}

// Create the CSS rules
Expand All @@ -370,7 +419,7 @@ SVGSprite.prototype._addToSprite = function(svgID, svgInfo) {
if (this._options.sass.length) {
var selectors = ['.' + this._options.prefix + '-' + cls.join(':')];
selectors.push('.' + this._options.prefix + '-' + ((cls.length > 1) ? cls.join('\\:') : (cls[0] + '\\:regular')));
this.sass.push(selectors.join(',\n') + ' {\n @extend ' + sassExtend + ';\n background-position: 0 ' + (-this.height) + (this.height ? 'px' : '') + ';\n}');
this.sass.push(selectors.join(',\n') + ' {\n' + (this._options.common ? '' : ' @extend ' + sassExtend + ';\n') + ' background-position: 0 ' + (-this.height) + (this.height ? 'px' : '') + ';\n}');

// Optionally record the image dimensions as well
if (this._options.dims) {
Expand All @@ -379,6 +428,19 @@ SVGSprite.prototype._addToSprite = function(svgID, svgInfo) {
}
}

// Create the LESS rules
if (this._options.less.length) {
var selectors = ['.' + this._options.prefix + '-' + cls.join(':')];
selectors.push('.' + this._options.prefix + '-' + ((cls.length > 1) ? cls.join('\\:') : (cls[0] + '\\:regular')));
this.less.push(selectors.join(',\n') + ' {\n' + (this._options.common ? '' : ' ' + lessMixin + ';\n') + ' background-position: 0 ' + (-this.height) + (this.height ? 'px' : '') + ';\n}');

// Optionally record the image dimensions as well
if (this._options.dims) {
var dimSelectors = (cls.length == 1) ? ['.' + this._options.prefix + '-' + cls[0] + '-dims'] : ['.' + this._options.prefix + '-' + cls[0] + '-dims:' + cls[1], '.' + this._options.prefix + '-' + cls[0] + '\\:' + cls[1] + '-dims'];
this.less.push(dimSelectors.join(',') + ' {\n width: ' + dimensions.width + 'px;\n height: ' + dimensions.height + 'px;\n}');
}
}

// Increment sprite dimensions
this.width = Math.max(this.width, dimensions.width);
this.height = Math.ceil(this.height + dimensions.height);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "svg-sprite",
"version": "0.0.7",
"version": "0.0.8",
"author": "Joschi Kuphal <joschi@kuphal.net>",
"description": "Creates an SVG sprite plus suitable CSS / Sass resources of a folder of SVG files",
"main": "lib/svg-sprite.js",
Expand Down

0 comments on commit d1f9480

Please sign in to comment.