diff options
Diffstat (limited to 'Gruntfile.js')
-rw-r--r-- | Gruntfile.js | 99 |
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']); }; |