johnny-five
Version:
Firmata based Arduino Programming Framework.
162 lines (132 loc) • 4.27 kB
JavaScript
var inspect = require("util").inspect,
fs = require("fs");
module.exports = function(grunt) {
var task = grunt.task;
var file = grunt.file;
var utils = grunt.utils;
var log = grunt.log;
var verbose = grunt.verbose;
var fail = grunt.fail;
var option = grunt.option;
var config = grunt.config;
var template = grunt.template;
var _ = utils._;
var templates = {
doc: _.template( file.read("tpl/.docs.md") ),
img: _.template( file.read("tpl/.img.md") ),
fritzing: _.template( file.read("tpl/.fritzing.md") ),
doclink: _.template( file.read("tpl/.readme.doclink.md") ),
readme: _.template( file.read("tpl/.readme.md") )
};
// Project configuration.
grunt.initConfig({
pkg: "<json:package.json>",
docs: {
files: ["programs.json"]
},
test: {
files: ["test/board.js"]
},
lint: {
files: ["grunt.js", "lib/**/!(johnny-five)*.js", "test/**/*.js", "eg/**/*.js"]
},
watch: {
files: "<config:lint.files>",
tasks: "default"
},
jshint: {
options: {
curly: true,
eqeqeq: true,
immed: true,
latedef: true,
newcap: true,
noarg: true,
sub: true,
undef: true,
boss: true,
eqnull: true,
node: true,
strict: false,
es5: true
},
globals: {
exports: true,
document: true,
$: true,
Radar: true
}
}
});
// Default task.
grunt.registerTask("default", "lint test");
grunt.registerMultiTask("docs", "generate simple docs from examples", function() {
// Concat specified files.
var files, entries, readme;
entries = JSON.parse(file.read(file.expandFiles( this.file.src )[0]));
readme = [];
entries.forEach(function( entry ) {
var values, devices, eg, md, png, fzz, title,
hasPng, hasFzz, filepath, fritzfile, fritzpath;
if ( Array.isArray(entry) ) {
// Produces:
// "### Heading\n"
readme.push( "\n### " + entry[0] + "\n" );
// TODO: figure out a way to have tiered subheadings
// readme.push(
// entry.reduce(function( prev, val, k ) {
// // Produces:
// // "### Board\n"
// return prev + (Array(k + 4).join("#")) + " " + val + "\n";
// }, "")
// );
}
else {
filepath = "eg/" + entry;
eg = file.read( filepath );
md = "docs/" + entry.replace(".js", ".md");
png = "docs/breadboard/" + entry.replace(".js", ".png");
fzz = "docs/breadboard/" + entry.replace(".js", ".fzz");
title = entry;
devices = [];
// Generate a title string from the file name
[ [ /^.+\//, "" ],
[ /\.js/, "" ],
[ /\-/g, " " ]
].forEach(function( args ) {
title = "".replace.apply( title, args );
});
fritzpath = fzz.split("/");
fritzfile = fritzpath[ fritzpath.length - 1 ];
// Modify code in example to appear as it would if installed via npm
eg = eg.replace("../lib/johnny-five.js", "johnny-five")
.split("\n").filter(function( line ) {
// TODO: Abstract "tag" support into easily extended system
if ( /@device/.test(line) ) {
devices.push( "- " + line.replace(/^\/\/ @device/, "").trim() );
return false;
}
return true;
}).join("\n");
hasPng = fs.existsSync(png);
hasFzz = fs.existsSync(fzz);
values = {
title: _.titleize(title),
command: "node " + filepath,
example: eg,
file: md,
devices: devices.join("\n"),
breadboard: hasPng ? templates.img({ png: png }) : "",
fritzing: hasFzz ? templates.fritzing({ fzz: fzz }) : ""
};
// Write the file to /docs/*
file.write( md, templates.doc(values) );
// Push a rendered markdown link into the readme "index"
readme.push( templates.doclink(values) );
}
});
// Write the readme with doc link index
file.write( "README.md", templates.readme({ doclinks: readme.join("") }) );
log.writeln("Docs created.");
});
};