diff --git a/.gitignore b/.gitignore index 67be992..f81f8ff 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,7 @@ public/js/cheatsheet.min.js app.js # ignore less-generated css file -public/js/main.min.css +public/css/main.min.css # ignore diff files *.diff diff --git a/Gruntfile.js b/Gruntfile.js index 7e9bf51..34f0915 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,4 +1,4 @@ -var md5 = require('md5'); +const md5 = require('md5'); module.exports = function(grunt) { 'use strict'; @@ -87,11 +87,11 @@ function extractSnowflakeClasses(filename, pattern) { } function snowflakeCount() { - var cssClasses = extractSnowflakeClasses("public/css/main.min.css"), - jsServer = extractSnowflakeClasses("app.js"), - jsClient = extractSnowflakeClasses('public/js/cheatsheet.min.js'), - docs = extractSnowflakeClasses('public/docs.json'), - jsClasses = jsServer.concat(jsClient, docs); + const cssClasses = extractSnowflakeClasses("public/css/main.min.css"); + const jsServer = extractSnowflakeClasses("app.js"); + const jsClient = extractSnowflakeClasses('public/js/cheatsheet.min.js'); + const docs = extractSnowflakeClasses('public/docs.json'); + const jsClasses = jsServer.concat(jsClient, docs); console.log(cssClasses.length + " class names found in css/main.min.css"); console.log(jsClasses.length + " class names found in JS files"); @@ -100,73 +100,11 @@ function snowflakeCount() { console.log( difference(jsClasses, cssClasses) ); } -// http://tinyurl.com/looyyvc -function hexavigesimal(a) { - a += 1; - var c = 0; - var x = 1; - while (a >= x) { - c++; - a -= x; - x *= 26; - } - - var s = ""; - for (var i = 0; i < c; i++) { - s = "abcdefghijklmnopqrstuvwxyz".charAt(a % 26) + s; - a = Math.floor(a/26); - } - - return s; -} - -// given a unique array of class names, returns an object of them -// mapped to short versions -// input: ["foo-91c46", "bar-aedf3", "baz-2a44d", etc] -// output: {"foo-91c46":"a", "bar-aedf3":"b", "baz-2a44d":"c", etc} -function shrinkClassNames(classes, prefix) { - if (! prefix) { - prefix = ""; - } - - var o = {}; - for (var i = 0; i < classes.length; i++) { - o[ classes[i] ] = prefix + hexavigesimal(i); - } - return o; -} - -function squeezeClasses() { - var cssFile = '00-publish/css/main.min.css', - cssClasses = extractSnowflakeClasses(cssFile), - cssContents = grunt.file.read(cssFile), - jsFile = '00-publish/js/cheatsheet.min.js', - jsClasses = extractSnowflakeClasses(jsFile), - jsContents = grunt.file.read(jsFile), - allClasses = keys(arrToObj(cssClasses.concat(jsClasses))).sort(), - squeezedClasses = shrinkClassNames(allClasses); - - for (var i in squeezedClasses) { - if (squeezedClasses.hasOwnProperty(i) !== true) continue; - var regex = new RegExp(i, "g"); - - if (jsContents.search(regex) === -1) { - console.log("class \"" + i + "\" not found in cheatsheet.min.js"); - } - - cssContents = cssContents.replace(regex, squeezedClasses[i]); - jsContents = jsContents.replace(regex, squeezedClasses[i]); - } - - grunt.file.write(cssFile, cssContents); - grunt.file.write(jsFile, jsContents); -} - //------------------------------------------------------------------------------ // Cheatsheet Publish //------------------------------------------------------------------------------ -function buildCheatsheetSanityCheck() { +function preBuildSanityCheck() { if (! grunt.file.exists('public/index.html')) { grunt.fail.warn('Could not find public/index.html! Aborting...'); } @@ -176,14 +114,16 @@ function buildCheatsheetSanityCheck() { } // TODO: check to make sure the ctime on cheatsheet.min.js is pretty fresh (< 5 minutes) + + grunt.log.writeln('Everything looks ok for a build.'); } -function hashCheatsheetFiles() { - var cssFile = grunt.file.read('00-publish/css/main.min.css'), - cssHash = md5(cssFile).substr(0, 8), - jsFile = grunt.file.read('00-publish/js/cheatsheet.min.js'), - jsHash = md5(jsFile).substr(0, 8), - htmlFile = grunt.file.read('00-publish/index.html'); +function hashAssets() { + const cssFile = grunt.file.read('00-publish/css/main.min.css'); + const cssHash = md5(cssFile).substr(0, 8); + const jsFile = grunt.file.read('00-publish/js/cheatsheet.min.js'); + const jsHash = md5(jsFile).substr(0, 8); + const htmlFile = grunt.file.read('00-publish/index.html'); // write the new files grunt.file.write('00-publish/css/main.min.' + cssHash + '.css', cssFile); @@ -262,23 +202,21 @@ grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-contrib-less'); grunt.loadNpmTasks('grunt-contrib-watch'); -grunt.registerTask('build-cheatsheet-sanity-check', buildCheatsheetSanityCheck); -grunt.registerTask('hash-cheatsheet', hashCheatsheetFiles); - -// TODO: this is unfinished -//grunt.registerTask('squeeze-classes', squeezeClasses); +// custom tasks +grunt.registerTask('pre-build-sanity-check', preBuildSanityCheck); +grunt.registerTask('hash-assets', hashAssets); -grunt.registerTask('build-cheatsheet', [ - 'build-cheatsheet-sanity-check', +grunt.registerTask('build', [ + 'pre-build-sanity-check', 'clean:pre', 'less', 'copy:cheatsheet', 'clean:post', - 'hash-cheatsheet' + 'hash-assets' ]); grunt.registerTask('snowflake', snowflakeCount); -grunt.registerTask('default', 'less'); +grunt.registerTask('default', 'watch'); // end module.exports }; diff --git a/README.md b/README.md index cce7fc3..33f650f 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,50 @@ # A ClojureScript Cheatsheet +This project produces the cheatsheet found at [cljs.info/cheatsheet]. + +## Design + TODO: write this section ## Development Setup -TODO: write this section +##### First time setup -## Design +Install [Leiningen] and [Node.js] -TODO: write this section +```sh +# install node_modules +npm install +``` + +##### Development workflow + +You may wish to run these commands in separate console tabs / screens. + +```sh +# compile LESS into CSS whenever a .less file changes +grunt watch + +# run a local web server on port 9224 +# the port is configurable and defaults to 8888 if not provided +node server.js 9224 + +# compile ClojureScript files +lein clean && lein cljsbuild auto + +# build public/index.html +# NOTE: app.js is generated from "lein cljsbuild auto" above +node app.js + +# create a build into the 00-publish directory +grunt build +``` ## License All code licensed under the terms of the [MIT License]. -[cheatsheet]:http://cljs.info/cheatsheet +[cljs.info/cheatsheet]:http://cljs.info/cheatsheet [Leiningen]:http://leiningen.org [Node.js]:http://nodejs.org [MIT License]:https://github.com/oakmac/cljs-cheatsheet/blob/master/LICENSE.md diff --git a/package.json b/package.json index 04b0c79..abe9551 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,6 @@ "grunt-contrib-copy": "0.8.2", "grunt-contrib-less": "0.11.4", "grunt-contrib-watch": "0.6.1", - "grunt-hash": "0.5.0", "marked": "0.3.5", "md5": "2.0.0", "moment": "2.6.0" diff --git a/server.js b/server.js index 20b1170..27e2a05 100644 --- a/server.js +++ b/server.js @@ -1,6 +1,11 @@ -// This file exists for developer convenience to host a quick file server out -// of the public/ folder. -// append ?_slow=true to files to simulate slow loading times +// This file exists for developer convenience to host a web server out of the +// public/ folder. +// +// Pass a port argument to this script to host on a port of your choice. +// ie: node server.js 9224 +// +// append the ?_slow=true query parameter to files to simulate slow loading times +// ie: http://127.0.0.1:8888/api/data.json?_slow=true var express = require('express'), app = express();