Back when Adam Cameron and I launched the ColdFusion UI - The Right Way project, I mentioned that initially we would accept submissions from the community to build out the content before releasing an actual readable version. Turns out I kind of forgot to get around to doing that. The content in the GitHub repo is in Markdown, which is pretty readable, but it isn't exactly in a nice form to hand out to a junior developer.

Earlier this week I got off my rear and actually built a process to make this happen. I decided to give Grunt a try for the process and it worked out rather well. I did run into a few stumbling blocks but I was able to get past them all and I'm very happy with the result. My Grunt script now does all the following with one simple command:

  • Clean out an output directory (to remove earlier versions)
  • Convert the Markdown files to HTML using a template
  • Find the demo folders and zip them
  • Attach a bit of HTML to the files so that folks have a link for the download

I decided to put the output up on a S3 bucket. You can now read the docs here: https://static.raymondcamden.com/cfuitherightway/. I'll update the GitHub readme in a few moments to add this link as well. I'm tempted to extend my Grunt script to also push updates to S3. Heck, I could also have it do the git pull action as well. Anyway, for folks who may be curious, here is the script I'm using.

module.exports = function(grunt) {

	// Project configuration.
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),

		clean: ['./output/'],

		copy: {

			main: {

				files: [

					{expand:true, src:['./chapters/**','!./chapters/**/*.md'], dest: 'output/'} 

				]
			}

		},
		
		markdown:{
			all: {
				files: [
					{
						expand: true,
						src:'./chapters/**/*.md',
						dest:'output/',
						ext:'.html'
					}
				],
				options: {
					template:'template.html',
					preCompile:function(src, context) {
					},
					postCompile:function(src, context) {
						/*
						Unfortunately we don't have access to the current path, 
						so no easy way to skip index.html and introduction.html
						*/
						//set title back to blank
						context.title = "";
						if(src.indexOf('<h1 id="introduction">Introduction</h1>') >= 0) {
							context.title = "Introduction";
							return src;
						}
						if(src.indexOf('<h1 id="coldfusion-ui-the-right-way">ColdFusion UI - The Right Way</h1>') >= 0) {
							context.title = "ColdFusion UI - The Right Way";
							return src;
						}

						var dl = '<p style="text-align:right"><a class="btn btn-info" href="demos.zip">Download Demo</a></p>';
						src = dl + src;

						var titleArr = src.match(/<h1.*?>(.*?)<\/h1>/);
						if(titleArr && titleArr.length >= 2) context.title=titleArr[1];


						return src;
					},
					markdownOptions: {
						highlight:'auto'
					}
				}
			}
		}
	});

	grunt.registerTask('zipDemos', "Zips demos appropriately.", function() {
		var sourceDirs = grunt.file.expand(['./chapters/**/demos','./chapters/**/demo']);
		var zipConfig = {};
		sourceDirs.forEach(function(dir) {
			var outputZip = dir.replace("chapters", "output/chapters");
			//use a uniform demos.zip, not demo
			if(outputZip.charAt(outputZip.length-1) === "o") outputZip += "s";
			outputZip += ".zip";
			dir += "/*";
			zipConfig[dir] = {
				cwd:dir,
				src:dir, 
				dest:outputZip
			};
			grunt.config.set('zip', zipConfig);

		});
	});

	grunt.registerTask('zipCode', ['zipDemos','zip']);

	grunt.loadNpmTasks('grunt-markdown');
	grunt.loadNpmTasks('grunt-contrib-copy');
	grunt.loadNpmTasks('grunt-contrib-clean');
	grunt.loadNpmTasks('grunt-zip');
	
	// Default task(s).
	grunt.registerTask('default', ['clean','markdown', 'copy', 'zipCode']);

};

As always, any comments are welcome.