summaryrefslogtreecommitdiff
path: root/Gruntfile.js
diff options
context:
space:
mode:
Diffstat (limited to 'Gruntfile.js')
-rw-r--r--Gruntfile.js99
1 files changed, 97 insertions, 2 deletions
diff --git a/Gruntfile.js b/Gruntfile.js
index 7abe1795..247d3c40 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -1,6 +1,7 @@
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.loadNpmTasks('grunt-contrib-less');
+ grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-clean');
@@ -28,7 +29,7 @@ module.exports = function (grunt) {
},
clean: {
build: {
- src: ['*/build.less', '!global/build.less']
+ src: ['*/build.less', '*/build.scss', '!global/build.less', '!global/build.scss']
}
},
concat: {
@@ -118,6 +119,40 @@ module.exports = function (grunt) {
compress ? 'compress:'+lessDest+':'+'<%=builddir%>/' + theme + '/bootstrap.min.css':'none']);
});
+grunt.registerTask('build_scss', 'build a regular theme from scss', function(theme, compress) {
+ var theme = theme == undefined ? grunt.config('buildtheme') : theme;
+ var compress = compress == undefined ? true : compress;
+
+ var isValidTheme = grunt.file.exists(theme, '_variables.scss') && grunt.file.exists(theme, '_bootswatch.scss');
+
+ // cancel the build (without failing) if this directory is not a valid theme
+ if (!isValidTheme) {
+ return;
+ }
+ var concatSrc;
+ var concatDest;
+ var scssDest;
+ var scssSrc;
+ var files = {};
+ var dist = {};
+ concatSrc = 'global/build.scss';
+ concatDest = theme + '/build.scss';
+ scssDest = '<%=builddir%>/' + theme + '/bootstrap.css';
+ scssSrc = [theme + '/' + 'build.scss'];
+
+ dist = {src: concatSrc, dest: concatDest};
+ grunt.config('concat.dist', dist);
+ files = {};
+ files[scssDest] = scssSrc;
+ grunt.config('sass.dist.files', files);
+ grunt.config('sass.dist.options.style', 'expanded');
+ grunt.config('sass.dist.options.precision', 8);
+ grunt.config('sass.dist.options.unix-newlines', true);
+
+ grunt.task.run(['concat', 'sass:dist', 'prefix:' + scssDest, 'clean:build',
+ compress ? 'compress_scss:' + scssDest + ':' + '<%=builddir%>/' + theme + '/bootstrap.min.css' : 'none']);
+ });
+
grunt.registerTask('prefix', 'autoprefix a generic css', function(fileSrc) {
grunt.config('autoprefixer.dist.src', fileSrc);
grunt.task.run('autoprefixer');
@@ -132,18 +167,78 @@ module.exports = function (grunt) {
grunt.task.run(['less:dist']);
});
+ grunt.registerTask('compress_scss', 'compress a generic css with sass', function(fileSrc, fileDst) {
+ var files = {}; files[fileDst] = fileSrc;
+ grunt.log.writeln('compressing file ' + fileSrc);
+
+ grunt.config('sass.dist.files', files);
+ grunt.config('sass.dist.options.style', 'compressed');
+ grunt.task.run(['sass:dist']);
+ });
+
grunt.registerMultiTask('swatch', 'build a theme', function() {
var t = this.target;
grunt.task.run('build:'+t);
});
+ grunt.registerTask('swatch_scss', 'build a theme from scss ', function (theme) {
+ var t = theme;
+ if (!t) {
+ for (var t in grunt.config('swatch')) {
+ grunt.task.run('build_scss:' + t);
+ }
+ } else {
+ grunt.task.run('build_scss:' + t);
+ }
+ });
+
grunt.event.on('watch', function(action, filepath) {
var path = require('path');
var theme = path.dirname(filepath);
grunt.config('buildtheme', theme);
});
- grunt.registerTask('server', 'connect:keepalive')
+ /**
+ * Regex borrowed form
+ * https://gist.github.com/rosskevin/ddfe895091de2ca5f931
+ * */
+ grunt.registerTask('convert_less', 'Convert less to scss using regular expression', function () {
+ var convertBaseDir = '';
+ grunt.file.expand(convertBaseDir + '*/*.less').forEach(function (lessFile) {
+ if (lessFile !=="global/build.less"){
+ var srcContents = grunt.file.read(lessFile);
+ var out = srcContents
+ // 1. replace @ with $
+ .replace(/@(?!import|media|keyframes|-)/g, '$')
+ // 2. replace mixins
+ .replace(/[\.#](?![0-9])([\w\-]*)\s*\((.*)\)\s*\{/g, '@mixin $1($2){')
+ // 3. In LESS, bootstrap namespaces mixins, in SASS they are just prefixed e.g #gradient > .vertical-three-colors becomes @include gradient-vertical-three-colors
+ .replace(/[\.#](?![0-9])([\w\-]*)\s>\s\.(.*;)/g, '@include $1-$2')
+ // 4. replace includes
+ .replace(/[\.#](?![0-9])([\w\-].*\(.*;)/g, '@include $1')
+ // 5. replace no param mixin includes with empty parens
+ .replace(/@include\s([\w\-]*\s*);/g, '@include $1();')
+ // 6. replace extends .class; @extend .class;
+ .replace(/(\.(?![0-9])([\w\-]+);)/g, '@extend $1')
+ // 7. replace string literals
+ .replace(/~"(.*)"/g, '#{"$1"}')
+ // 8. replace interpolation ${var} > #{$var}
+ .replace(/\$\{(.*)\}/g, '#{$$$1}')
+ // 9. replace spin to adjust-hue (function name diff)
+ .replace(/spin\(/g, 'adjust-hue(')
+ // 10. replace bower and imports in build.scss
+ .replace(/bootstrap\/less\//g, 'bootstrap-sass-official/assets/stylesheets/')
+ .replace(/\.less/g, '');
+
+ var baseDirRegex = new RegExp("^" + convertBaseDir, "g");
+ var sassFile = lessFile.replace(baseDirRegex, '').replace(/\.less$/, '.scss').replace(/(bootswatch|variables)/, '_$1');
+ grunt.file.write(sassFile, out);
+ grunt.log.writeln('Converted less file: ', lessFile, Array(27 - lessFile.length).join(' '),'> ', sassFile);
+ }
+ });
+ });
+
+ grunt.registerTask('server', 'connect:keepalive');
grunt.registerTask('default', ['connect:base', 'watch']);
};