mirror of
https://github.com/thomaspark/bootswatch.git
synced 2025-10-08 02:24:05 +00:00
261 lines
9.5 KiB
JavaScript
261 lines
9.5 KiB
JavaScript
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');
|
|
grunt.loadNpmTasks('grunt-contrib-watch');
|
|
|
|
var configBridge = grunt.file.readJSON('./bower_components/bootstrap/grunt/configBridge.json', { encoding: 'utf8' });
|
|
|
|
// Project configuration.
|
|
grunt.initConfig({
|
|
pkg: grunt.file.readJSON('package.json'),
|
|
builddir: '.',
|
|
buildtheme: '',
|
|
banner: '/*!\n' +
|
|
' * <%= pkg.name %> v<%= pkg.version %>\n' +
|
|
' * Homepage: <%= pkg.homepage %>\n' +
|
|
' * Copyright 2012-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
|
|
' * Licensed under <%= pkg.license %>\n' +
|
|
' * Based on Bootstrap\n' +
|
|
'*/\n',
|
|
swatch: {
|
|
amelia:{}, cerulean:{}, cosmo:{}, cyborg:{}, darkly:{},
|
|
flatly:{}, journal:{}, lumen:{}, paper:{}, readable:{},
|
|
sandstone:{}, simplex:{}, slate:{}, spacelab:{}, superhero:{},
|
|
united:{}, yeti:{}, custom:{}
|
|
},
|
|
clean: {
|
|
build: {
|
|
src: ['*/build.less', '*/build.scss', '!global/build.less', '!global/build.scss']
|
|
}
|
|
},
|
|
concat: {
|
|
options: {
|
|
banner: '<%= banner %>',
|
|
stripBanners: false
|
|
},
|
|
dist: {
|
|
src: [],
|
|
dest: ''
|
|
}
|
|
},
|
|
less: {
|
|
dist: {
|
|
options: {
|
|
compress: false,
|
|
strictMath: true
|
|
},
|
|
files: {}
|
|
}
|
|
},
|
|
autoprefixer: {
|
|
options: {
|
|
browsers: configBridge.config.autoprefixerBrowsers
|
|
},
|
|
dist: {
|
|
src: '*/bootstrap.css'
|
|
}
|
|
},
|
|
watch: {
|
|
files: ['*/variables.less', '*/bootswatch.less', '*/index.html'],
|
|
tasks: 'build',
|
|
options: {
|
|
livereload: true,
|
|
nospawn: true
|
|
}
|
|
},
|
|
connect: {
|
|
base: {
|
|
options: {
|
|
port: 3000,
|
|
livereload: true,
|
|
open: true
|
|
}
|
|
},
|
|
keepalive: {
|
|
options: {
|
|
port: 3000,
|
|
livereload: true,
|
|
keepalive: true,
|
|
open: true
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
grunt.registerTask('none', function() {});
|
|
|
|
grunt.registerTask('build', 'build a regular theme', function(theme, compress) {
|
|
var theme = theme == undefined ? grunt.config('buildtheme') : theme;
|
|
var compress = compress == undefined ? true : compress;
|
|
|
|
var isValidTheme = grunt.file.exists(theme, 'variables.less') && grunt.file.exists(theme, 'bootswatch.less');
|
|
|
|
// cancel the build (without failing) if this directory is not a valid theme
|
|
if (!isValidTheme) {
|
|
return;
|
|
}
|
|
|
|
var concatSrc;
|
|
var concatDest;
|
|
var lessDest;
|
|
var lessSrc;
|
|
var files = {};
|
|
var dist = {};
|
|
concatSrc = 'global/build.less';
|
|
concatDest = theme + '/build.less';
|
|
lessDest = '<%=builddir%>/' + theme + '/bootstrap.css';
|
|
lessSrc = [ theme + '/' + 'build.less' ];
|
|
|
|
dist = {src: concatSrc, dest: concatDest};
|
|
grunt.config('concat.dist', dist);
|
|
files = {}; files[lessDest] = lessSrc;
|
|
grunt.config('less.dist.files', files);
|
|
grunt.config('less.dist.options.compress', false);
|
|
|
|
grunt.task.run(['concat', 'less:dist', 'prefix:' + lessDest, 'clean:build',
|
|
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');
|
|
});
|
|
|
|
grunt.registerTask('compress', 'compress a generic css', function(fileSrc, fileDst) {
|
|
var files = {}; files[fileDst] = fileSrc;
|
|
grunt.log.writeln('compressing file ' + fileSrc);
|
|
|
|
grunt.config('less.dist.files', files);
|
|
grunt.config('less.dist.options.compress', true);
|
|
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);
|
|
});
|
|
|
|
/**
|
|
* 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, '')
|
|
// 11. replace icon-font-path value with conditional for asset helpers
|
|
.replace(/(\$icon-font-path:).*;/g, '$1 if($bootstrap-sass-asset-helper, "bootstrap/", "../fonts/bootstrap/");')
|
|
// 12. set bootswatch's web-font-path value as !default
|
|
.replace(/(\$web-font-path:.*);/g, '$1 !default;')
|
|
// 13. Remove the web-font mixin which breaks in libsass
|
|
.replace(/[\s\S][\s\S]@mixin web-font.*([\s\S]*?).*;([\s\S]*?)}([\s\S]*?)/,"")
|
|
// 14. Replace usage of the web-font mixin with variable interpolation
|
|
.replace(/@include web-font/,'@import url');
|
|
|
|
if (/\/variables.less$/.test(lessFile)) {
|
|
// 15. set default value of $bootstrap-sass-asset-helper to false
|
|
out = "$bootstrap-sass-asset-helper: false;\n" + out;
|
|
// 16. only assign variables if they haven't been previously set e.g. $var: #f00; > $var: #f00 !default;
|
|
out = out.replace(/^(\$.*);/gm, '$1 !default;');
|
|
}
|
|
|
|
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']);
|
|
};
|