diff --git a/Gruntfile.js b/Gruntfile.js index 6744468..24dc3bf 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,5 +1,4 @@ -var path = require('path'), - parserlib = require('parserlib'); +var path = require('path'); module.exports = function (grunt) { @@ -11,12 +10,9 @@ grunt.initConfig({ // -- Constants ------------------------------------------------------------ - NORMALIZE_LIB: path.join(process.cwd(), '../', 'normalize.css'), - BASE_DIR : 'src/base/', - PREFIX : '.k', + BUILD_COMMENT: 'THIS FILE IS GENERATED BY A BUILD SCRIPT - DO NOT EDIT!', - COMMENT: '/* THIS FILE IS GENERATED BY A BUILD SCRIPT - DO NOT EDIT! */\n', - LICENSE: [ + NORMALIZE_LICENSE: [ '/*! normalize.css v1.1.1 | MIT License | git.io/normalize */', '/*! Copyright (c) Nicolas Gallagher and Jonathan Neal */', '\n' @@ -25,58 +21,152 @@ grunt.initConfig({ // -- Clean Config --------------------------------------------------------- clean: { - build: ['build/'], - base : ['src/base/css/', 'src/base/tests/', 'src/base/LICENSE.md'] + build : ['build/'], + build_res: ['build/*-r.css'], + base : ['src/base/css/', 'src/base/tests/', 'src/base/LICENSE.md'] + }, + + // -- Copy Config ---------------------------------------------------------- + + copy: { + build: { + expand : true, + flatten: true, + src : 'src/**/css/*.css', + dest : 'build/', + + rename: function (dest, src) { + // normalize -> base + src = src.replace(/^normalize(-.+\.css|\.css)$/, 'base$1'); + return path.join(dest, src); + } + }, + + normalize: { + expand : true, + flatten: true, + cwd : '../normalize.css/', + src : '{LICENSE.md,normalize.css,test.html}', + dest : 'src/base/', + + rename: function (dest, file) { + if (grunt.file.isMatch('*.css', file)) { + return path.join(dest, 'css', file); + } + + if (grunt.file.isMatch('*.html', file)) { + return path.join(dest, 'tests', 'manual', file); + } + + return path.join(dest, file); + }, + + options: { + processContent: function (content, file) { + var comment = grunt.config('BUILD_COMMENT'); + + if (grunt.file.isMatch({matchBase: true}, '*.css', file)) { + content = '/* ' + comment + ' */\n' + content; + } else if (grunt.file.isMatch({matchBase: true}, '*.html', file)) { + content = '\n' + content; + } + + return content; + } + } + } + }, + + // -- Concat Config -------------------------------------------------------- + + concat: { + build: { + files: [ + {'build/buttons.css': [ + 'build/buttons-core.css', + 'build/buttons.css' + ]}, + + {'build/forms-nr.css': [ + 'build/forms-core.css', + 'build/forms.css' + ]}, + + {'build/forms.css': [ + 'build/forms-nr.css', + 'build/forms-r.css' + ]}, + + {'build/grids-nr.css': [ + 'build/grids-base.css', + 'build/grids-units.css' + ]}, + + {'build/grids.css': [ + 'build/grids-nr.css', + 'build/grids-r.css' + ]}, + + {'build/menus-nr.css': [ + 'build/menus-core.css', + 'build/menus.css', + 'build/menus-paginator.css' + ]}, + + {'build/menus.css': [ + 'build/menus-nr.css', + 'build/menus-r.css' + ]} + ] + }, + + kimono: { + files: { + 'build/kimono-min.css': [ + 'build/base-min.css', + 'build/buttons-min.css', + 'build/forms-min.css', + 'build/grids-min.css', + 'build/menus-min.css', + 'build/tables-min.css' + ], + + 'build/kimono-nr-min.css': [ + 'build/base-min.css', + 'build/buttons-min.css', + 'build/forms-nr-min.css', + 'build/grids-nr-min.css', + 'build/menus-nr-min.css', + 'build/tables-min.css' + ] + } + } }, // -- CSSMin Config -------------------------------------------------------- cssmin: { options: { - report: 'gzip' + // report: 'gzip' }, - base: { - files: { - 'build/base/base-min.css' : ['src/base/css/normalize.css'], - 'build/base/base-context-min.css': ['src/base/css/normalize-context.css'] - } - }, + files: { + expand: true, + src : 'build/*.css', + ext : '-min.css' + } + }, - forms: { - files: { - 'build/forms/forms-min.css' : ['src/forms/css/*.css'], - 'build/forms/forms-nr-min.css': ['src/forms/css/forms-core.css', - 'src/forms/css/forms.css'] - } - }, + // -- Contextualize Config ------------------------------------------------- - grids: { - files: { - 'build/grids/grids-min.css' : ['src/grids/css/*.css'], - 'build/grids/grids-nr-min.css': ['src/grids/css/cssgrids-base.css', - 'src/grids/css/cssgrids-units.css'] - } - }, + contextualize: { + normalize: { + src : 'src/base/css/normalize.css', + dest: 'src/base/css/normalize-context.css', - menus: { - files: { - 'build/menus/menus-min.css' : ['src/menus/css/*.css'], - 'build/menus/menus-nr-min.css': ['src/menus/css/list-core.css', - 'src/menus/css/list.css', - 'src/menus/css/list-paginator.css'] - } - }, - - tables: { - files: { - 'build/tables/tables-min.css': ['src/tables/css/*.css'] - } - }, - - buttons: { - files: { - 'build/buttons/buttons-min.css': ['src/buttons/css/*.css'] + options: { + prefix: '.k', + banner: '/* <%= BUILD_COMMENT %> */\n<%= NORMALIZE_LICENSE %>' } } } @@ -85,152 +175,106 @@ grunt.initConfig({ // -- Main Tasks --------------------------------------------------------------- grunt.loadNpmTasks('grunt-contrib-clean'); +grunt.loadNpmTasks('grunt-contrib-copy'); +grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.registerTask('default', [ 'clean:build', - 'cssmin' + 'copy:build', + 'concat:build', + 'clean:build_res', + 'cssmin', + 'concat:kimono' ]); -grunt.registerTask('base', ['cssmin:base']); -grunt.registerTask('buttons', ['cssmin:buttons']); -grunt.registerTask('forms', ['cssmin:forms']); -grunt.registerTask('grids', ['cssmin:grids']); -grunt.registerTask('menus', ['cssmin:menus']); -grunt.registerTask('tables', ['cssmin:tables']); +grunt.registerTask('import', [ + 'import-normalize' +]); // -- Import Tasks ------------------------------------------------------------- -grunt.registerTask('base-import-css', 'Import Normalize CSS Files', function () { - var file = 'normalize.css', - src = path.join(grunt.config('NORMALIZE_LIB'), file), - dest = path.join(grunt.config('BASE_DIR'), 'css', file); +grunt.registerTask('import-normalize', [ + 'clean:base', + 'copy:normalize', + 'contextualize:normalize' +]); - if (!grunt.file.exists(src)) { - grunt.fail.fatal('Did you clone normalize.css yet?'); +// -- Contextualize Task ------------------------------------------------------- + +grunt.registerMultiTask('contextualize', 'Makes Contextualized CSS files.', function () { + var Parser = require('parserlib').css.Parser, + done = this.async(), + options = this.options({banner: ''}), + banner = grunt.template.process(options.banner), + processing = 0; + + function oneDone() { + if (!(processing -= 1)) { + done(); + } } - grunt.log.writeln('Copying: '.green + file.cyan + ' to ' + dest.cyan); - grunt.file.write(dest, grunt.config('COMMENT') + grunt.file.read(src)); -}); + this.files.forEach(function (filePair) { + filePair.src.forEach(function (file) { + var src = grunt.file.read(file), + contextual = banner, + parser = new Parser(); -grunt.registerTask('base-import-tests', 'Import Normalize Tests', function () { - var file = 'test.html', - src = path.join(grunt.config('NORMALIZE_LIB'), file), - dest = path.join(grunt.config('BASE_DIR'), 'tests', 'manual', file); + parser.addListener('endstylesheet', function () { + grunt.file.write(filePair.dest, contextual); + grunt.log.writeln('File "' + filePair.dest + '" created.'); + oneDone(); + }); - if (!grunt.file.exists(src)) { - grunt.fail.fatal('Did you clone normalize.css yet?'); - } + // Fired right before CSS properties are parsed for a certain rule. + // Go through and add all the selectors to the `css` string. + parser.addListener('startrule', function (event) { + var prefix = options.prefix; - grunt.log.writeln('Copying: '.green + file.cyan + ' to ' + dest.cyan); - grunt.file.copy(src, dest); -}); + event.selectors.forEach(function (selector, i) { + var nextSelector = event.selectors[i + 1]; -grunt.registerTask('base-import-meta', 'Import Normalize License', function () { - var file = 'LICENSE.md', - src = path.join(grunt.config('NORMALIZE_LIB'), file), - dest = path.join(grunt.config('BASE_DIR'), file); + // If the selector does not contain the html selector, we + // can go ahead and prepend .k in front of it. + if (selector.text.indexOf('html') === -1) { + contextual += prefix + ' ' + selector.text; + } else if (selector.text.indexOf('html') !== -1) { + // If it contains `html`, replace the `html` with `.k`. + // Replace multiple spaces with a single space. This is + // for the case where `html input[type='button']` comes + // through as `html input[type='button']`. + contextual += selector.text.replace('html', prefix).replace(/ +/g, ' '); + } - if (!grunt.file.exists(src)) { - grunt.fail.fatal('Did you clone normalize.css yet?'); - } + // If theres another selector, add a comma. + if (nextSelector) { + contextual += ',\n'; + } else { + // Otherwise, add an opening bracket for properties + contextual += ' {\n'; + } + }); + }); - grunt.log.writeln('Copying: '.green + file.cyan + ' to ' + dest.cyan); - grunt.file.copy(src, dest); -}); + // Fired right after CSS properties are parsed for a certain rule. + // Add the closing bracket to end the CSS Rule. + parser.addListener('endrule', function (event) { + contextual += '}\n'; + }); -grunt.registerTask('base-create-context', 'Make context version', function () { - var context = grunt.config('COMMENT') + grunt.config('LICENSE'), - done = this.async(), - parser = new parserlib.css.Parser(), - raw = grunt.file.read(grunt.config('BASE_DIR') + 'css/normalize.css'); + // Fired for each property that the parser encounters. Add these + // properties to the `css` string with 4 spaces. + parser.addListener('property', function (event) { + // Add 4 spaces tab. + contextual += ' ' + event.property + ': ' + event.value + ';\n'; + }); - parser.addListener('startstylesheet', function () { - grunt.log.ok('Starting to parse style sheet...'); - }); - - parser.addListener('endstylesheet', function () { - var contextFile = path.join(grunt.config('BASE_DIR'), 'css', 'normalize-context.css'); - - grunt.log.ok('Finished parsing style sheet...'); - grunt.file.write(contextFile, context); - grunt.log.ok('Done creating context build!'); - done(); - }); - - // Fired right before CSS properties are parsed for a certain rule. Go - // through and add all the selectors to the `css` string. - parser.addListener('startrule', function (event) { - var prefix = grunt.config('PREFIX'); - - event.selectors.forEach(function (selector, i) { - var nextSelector = event.selectors[i + 1]; - - // If the selector does not contain the html selector, we can go - // ahead and prepend .k in front of it. - if (selector.text.indexOf('html') === -1) { - context += prefix + ' ' + selector.text; - } else if (selector.text.indexOf('html') !== -1) { - // If it contains `html`, replace the `html` with `.k`. Replace - // multiple spaces with a single space. This is for the case - // where `html input[type='button']` comes through as - // `html input[type='button']`. - context += selector.text.replace('html', prefix).replace(/ +/g, ' '); - } - - // If theres another selector, add a comma. - if (nextSelector) { - context += ',\n'; - } else { - // Otherwise, add an opening bracket for properties - context += ' {\n'; - } + // Do the parsing. + processing += 1; + parser.parse(src); }); }); - - // Fired right after CSS properties are parsed for a certain rule. Add the - // closing bracket to end the CSS Rule. - parser.addListener('endrule', function (event) { - context += '}\n'; - }); - - // Fired for each property that the parser encounters. Add these properties - // to the `css` string with 4 spaces. - parser.addListener('property', function (event) { - // Add 4 spaces tab. - context += ' ' + event.property + ': ' + event.value + ';\n'; - }); - - // Do the parsing. - parser.parse(raw); - }); -grunt.registerTask('base-prep', 'Prep Normalize.css import', function () { - var normalize = grunt.config('NORMALIZE_LIB'); - - grunt.log.write('Looking for Normalize.css'.green); - - if (!grunt.file.exists(normalize)) { - grunt.log.writeln(''); - grunt.fail.fatal('Could not locate Normalize.css repo: ' + normalize + '\nDid you clone it as a sibling of the Kimono'); - } - - grunt.log.writeln('...OK'.white); -}); - -grunt.registerTask('base-all', [ - 'base-prep', - 'clean:base', - 'base-import', - 'base-create-context' -]); - -grunt.registerTask('base-import', [ - 'base-import-css', - 'base-import-tests', - 'base-import-meta' -]); - }; diff --git a/package.json b/package.json index 95c76b2..76391d5 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,8 @@ "grunt": "~0.4.1", "parserlib": "~0.2.2", "grunt-contrib-cssmin": "~0.6.0", - "grunt-contrib-clean": "~0.4.1" + "grunt-contrib-clean": "~0.4.1", + "grunt-contrib-copy": "~0.4.1", + "grunt-contrib-concat": "~0.3.0" } }