33
index.js
@@ -16,4 +16,6 @@ // http://stackoverflow.com/questions/14970224/anyone-know-of-a-good-way-to-convert-from-less-to-sass | ||
.includeMixins() | ||
.convertExtend() | ||
.convertColourHelpers() | ||
.convertFileExtensions(); | ||
.convertFileExtensions() | ||
.convertFunctionUnit(); | ||
@@ -31,6 +33,22 @@ return this.file; | ||
Less2Sass.prototype.convertMixins = function() { | ||
var mixinRegex = /^(\s*?)\.([\w\-]*?)\s*\(([\s\S][^\)]+?)\)+\s*\{$/gm; | ||
// Simple form: no semicolons. | ||
const mixinRegexNoSemicolon = /^(\s*?)\.([\w\-]*?)\s*\(([\s\S][^\;]+?)?\)\s*\{$/gm; | ||
this.file = this.file.replace(mixinRegexNoSemicolon, '$1@mixin $2($3) {'); | ||
// With semicolons. | ||
const mixinRegexWithSemicolon = /^(\s*?)\.([\w\-]*?)\s*\(([\s\S][^\,]+?)?\)\s*\{$/gm; | ||
this.file = this.file.replace(mixinRegexWithSemicolon, function (match, g1, g2, g3) { | ||
return g1 + '@mixin ' + g2 + '(' + g3.replace(/;/g, ',') + ') {'; | ||
}); | ||
return this; | ||
}; | ||
this.file = this.file.replace(mixinRegex, '$1@mixin $2($3) {'); | ||
Less2Sass.prototype.convertFunctionUnit = function() { | ||
// Two-args. | ||
const unitTwoArgRegex = /unit\((\S+),(\S+)\)/g; | ||
this.file = this.file.replace(unitTwoArgRegex, '0$2 + $1'); | ||
// One-arg. | ||
const unitOneArgRegex = /unit\(([^,]+)\)/g; | ||
this.file = this.file.replace(unitOneArgRegex, 'unit-less($1)'); | ||
@@ -40,2 +58,11 @@ return this; | ||
Less2Sass.prototype.convertExtend = function() { | ||
// http://lesscss.org/features/#extend-feature | ||
// &:extend syntax. | ||
const andExtendRegex = /&:extend\((.[\w]*)\);/g; | ||
this.file = this.file.replace(andExtendRegex, '@extend $1;'); | ||
return this; | ||
}; | ||
Less2Sass.prototype.convertColourHelpers = function() { | ||
@@ -42,0 +69,0 @@ var helperRegex = /spin\(/g; |
{ | ||
"name": "less2sass", | ||
"description": "A quick less to sass converter", | ||
"version": "1.0.2", | ||
"version": "1.0.3", | ||
"license": "MIT", | ||
@@ -6,0 +6,0 @@ "author": { |
@@ -18,3 +18,3 @@ var less2sass = require('..'); | ||
it('converts multiple variables in the same line', function() { | ||
var result = less2sass.convert(fixture); | ||
const result = less2sass.convert(fixture); | ||
assert.equal(result, expected); | ||
@@ -26,3 +26,3 @@ }); | ||
it('converts interpolated variables to #{$', function() { | ||
var result = less2sass.convert('@san-serif-stack: helvetica, arial; @standard-fonts: ~\'@{san-serif-stack}, sans-serif\';'); | ||
const result = less2sass.convert('@san-serif-stack: helvetica, arial; @standard-fonts: ~\'@{san-serif-stack}, sans-serif\';'); | ||
assert.equal(result, '$san-serif-stack: helvetica, arial; $standard-fonts: \'#{$san-serif-stack}, sans-serif\';'); | ||
@@ -32,3 +32,3 @@ }); | ||
it('converts @ for variables to $', function() { | ||
var result = less2sass.convert('@var1: #000;'); | ||
const result = less2sass.convert('@var1: #000;'); | ||
assert.equal(result, '$var1: #000;'); | ||
@@ -38,3 +38,3 @@ }); | ||
it('converts multiple variables in the same line', function() { | ||
var result = less2sass.convert('@var1: #000; @var2: #fff;'); | ||
const result = less2sass.convert('@var1: #000; @var2: #fff;'); | ||
assert.equal(result, '$var1: #000; $var2: #fff;'); | ||
@@ -44,3 +44,3 @@ }); | ||
it('still converts variables have the word "media" in them', function() { | ||
var result = less2sass.convert('@mediaType: screen;'); | ||
const result = less2sass.convert('@mediaType: screen;'); | ||
assert.equal(result, '$mediaType: screen;'); | ||
@@ -50,3 +50,3 @@ }); | ||
it('still converts variables have the word "import" in them', function() { | ||
var result = less2sass.convert('@importType: screen;'); | ||
const result = less2sass.convert('@importType: screen;'); | ||
assert.equal(result, '$importType: screen;'); | ||
@@ -56,3 +56,3 @@ }); | ||
it('still converts variables have the word "import" in them', function() { | ||
var result = less2sass.convert('@mixinType: screen;'); | ||
const result = less2sass.convert('@mixinType: screen;'); | ||
assert.equal(result, '$mixinType: screen;'); | ||
@@ -62,3 +62,3 @@ }); | ||
it('does not convert @ to $ for media queries', function() { | ||
var result = less2sass.convert('@media(min-width:768px) {}'); | ||
const result = less2sass.convert('@media(min-width:768px) {}'); | ||
assert.equal(result, '@media(min-width:768px) {}'); | ||
@@ -68,3 +68,3 @@ }); | ||
it('does not convert @ to $ for @mixin statements', function() { | ||
var result = less2sass.convert('@mixin screen() {}'); | ||
const result = less2sass.convert('@mixin screen() {}'); | ||
assert.equal(result, '@mixin screen() {}'); | ||
@@ -74,3 +74,3 @@ }); | ||
it('does not convert @ to $ for @import statements', function() { | ||
var result = less2sass.convert('@import "common"'); | ||
const result = less2sass.convert('@import "common"'); | ||
assert.equal(result, '@import "common"'); | ||
@@ -80,3 +80,3 @@ }); | ||
it('does not convert @ to $ for @font-face statements', function() { | ||
var result = less2sass.convert('@font-face {}'); | ||
const result = less2sass.convert('@font-face {}'); | ||
assert.equal(result, '@font-face {}'); | ||
@@ -86,3 +86,3 @@ }); | ||
it('does not convert @ to $ for @keyframes statements', function() { | ||
var result = less2sass.convert('@keyframes {}'); | ||
const result = less2sass.convert('@keyframes {}'); | ||
assert.equal(result, '@keyframes {}'); | ||
@@ -94,3 +94,3 @@ }); | ||
it('converts ~\'\' to \'\'', function() { | ||
var result = less2sass.convert('~\'san-serif\''); | ||
const result = less2sass.convert('~\'san-serif\''); | ||
assert.equal(result, '\'san-serif\''); | ||
@@ -100,3 +100,3 @@ }); | ||
it('converts ~"" to ""', function() { | ||
var result = less2sass.convert('~"san-serif"'); | ||
const result = less2sass.convert('~"san-serif"'); | ||
assert.equal(result, '"san-serif"'); | ||
@@ -108,10 +108,16 @@ }); | ||
it('converts spin function to adjust-hue', function() { | ||
var result = less2sass.convert('spin(#aaaaaa, 10)'); | ||
const result = less2sass.convert('spin(#aaaaaa, 10)'); | ||
assert.equal(result, 'adjust-hue(#aaaaaa, 10)'); | ||
}); | ||
}); | ||
describe("extend", function() { | ||
it('converts &:extend syntax', function() { | ||
const result = less2sass.convert('.bar {\n &:extend(.foo2);\n}'); | ||
assert.equal(result, '.bar {\n @extend .foo2;\n}'); | ||
}); | ||
}); | ||
describe("mixins", function() { | ||
it('converts mixin declarations to use the @mixins syntax', function() { | ||
var result = less2sass.convert('.drop-shadow(@x-axis: 0, @y-axis: 1px, @blur: 2px, @alpha: 0.1) {\n}'); | ||
const result = less2sass.convert('.drop-shadow(@x-axis: 0, @y-axis: 1px, @blur: 2px, @alpha: 0.1) {\n}'); | ||
assert.equal(result, '@mixin drop-shadow($x-axis: 0, $y-axis: 1px, $blur: 2px, $alpha: 0.1) {\n}'); | ||
@@ -121,8 +127,32 @@ }); | ||
it('converts mixin declarations with new lines in param list and retains the new lines', function() { | ||
var result = less2sass.convert('.drop-shadow(\n @x-axis: 0,\n @y-axis: 1px,\n @blur: 2px,\n @alpha: 0.1) {\n}'); | ||
const result = less2sass.convert('.drop-shadow(\n @x-axis: 0,\n @y-axis: 1px,\n @blur: 2px,\n @alpha: 0.1) {\n}'); | ||
assert.equal(result, '@mixin drop-shadow(\n $x-axis: 0,\n $y-axis: 1px,\n $blur: 2px,\n $alpha: 0.1) {\n}'); | ||
}); | ||
it('converts mixin declarations with semicolons in param list and treat them as params', function() { | ||
// http://lesscss.org/features/#mixins-parametric-feature-mixins-with-multiple-parameters | ||
// Semicolons separated params. | ||
const result = less2sass.convert('.button-variant(@color; @background; @border) {\n /**/\n}'); | ||
assert.equal(result, '@mixin button-variant($color, $background, $border) {\n /**/\n}'); | ||
}); | ||
it('do not converts mixin declarations with semicolons and colons mixed in param list', function() { | ||
// http://lesscss.org/features/#mixins-parametric-feature-mixins-with-multiple-parameters | ||
const result = less2sass.convert('.name(1, 2, 3; something, else) {\n}'); | ||
// TODO Flag the case as ambiguous? | ||
assert.equal(result, '.name(1, 2, 3; something, else) {\n}'); | ||
}); | ||
it('converts mixin declarations with mixin call inlined', function() { | ||
const result = less2sass.convert('.setTapColor(@c:rgba(0,0,0,0)) {\n -webkit-tap-highlight-color: @c;\n}'); | ||
assert.equal(result, '@mixin setTapColor($c:rgba(0,0,0,0)) {\n -webkit-tap-highlight-color: $c;\n}'); | ||
}); | ||
it('converts mixin declarations with zero param', function() { | ||
const result = less2sass.convert('.foo() {\n display: block;\n}'); | ||
assert.equal(result, '@mixin foo() {\n display: block;\n}'); | ||
}); | ||
it('converts mixin call without argments to use the @include syntax', function() { | ||
var result = less2sass.convert('.box-sizing();'); | ||
const result = less2sass.convert('.box-sizing();'); | ||
assert.equal(result, '@include box-sizing();'); | ||
@@ -132,3 +162,3 @@ }); | ||
it('converts mixin call in shorthand form to use the @include syntax', function() { | ||
var result = less2sass.convert('.box-sizing;'); | ||
const result = less2sass.convert('.box-sizing;'); | ||
assert.equal(result, '@include box-sizing;'); | ||
@@ -138,3 +168,3 @@ }); | ||
it('converts mixin call with arguments to use the @include syntax', function() { | ||
var result = less2sass.convert('.drop-shadow(0, 2px, 4px, 0.4);'); | ||
const result = less2sass.convert('.drop-shadow(0, 2px, 4px, 0.4);'); | ||
assert.equal(result, '@include drop-shadow(0, 2px, 4px, 0.4);'); | ||
@@ -144,3 +174,3 @@ }); | ||
it('does not convert .foo .bar', function() { | ||
var result = less2sass.convert('.foo .bar {}'); | ||
const result = less2sass.convert('.foo .bar {}'); | ||
assert.equal(result, '.foo .bar {}'); | ||
@@ -150,3 +180,3 @@ }); | ||
it('does not convert .5em (or similar)', function() { | ||
var result = less2sass.convert('font-size: .5em;'); | ||
const result = less2sass.convert('font-size: .5em;'); | ||
assert.equal(result, 'font-size: .5em;'); | ||
@@ -158,3 +188,3 @@ }); | ||
it('convert imports with the .less extension to .scss', function() { | ||
var result = less2sass.convert('@import \'app/app.less\';'); | ||
const result = less2sass.convert('@import \'app/app.less\';'); | ||
assert.equal(result, '@import \'app/app.scss\';'); | ||
@@ -164,2 +194,26 @@ }); | ||
describe('functions', function() { | ||
describe('unit', function() { | ||
// http://lesscss.org/functions/#misc-functions-unit | ||
it('convert one param call of less unit to sass unit-less', function() { | ||
// http://sass-lang.com/documentation/Sass/Script/Functions.html#unitless-instance_method | ||
const result = less2sass.convert('unit(5em)'); | ||
assert.equal(result, 'unit-less(5em)'); | ||
}); | ||
it('convert two param call of less unit without unit in first param to dimension + unit', function() { | ||
const result = less2sass.convert('unit(42,px)'); | ||
assert.equal(result, '0px + 42'); | ||
}); | ||
it('convert two param call of less unit with unit in first param to unit conversion', function() { | ||
// https://www.sitepoint.com/understanding-sass-units/ | ||
const result = less2sass.convert('unit(5in,px)'); | ||
assert.equal(result, '0px + 5in'); | ||
}); | ||
it('manage variable in first param', function() { | ||
const result = less2sass.convert('unit($size,px)'); | ||
assert.equal(result, '0px + $size'); | ||
}); | ||
}); | ||
}); | ||
describe("control flow", function() { | ||
@@ -166,0 +220,0 @@ it.skip('strips out { and }', function() { |
21633
20.79%251
41.01%