'use strict';Dokker.js 0.0.1
http://dokker.oceanhouse21.com
(c) 2014-2015 Georg Schlenkhoff and Oceanhouse21
Dokker.js may be freely distributed under the MIT license.
'use strict';Define required dependencies
var Promise = require('promise');
var fs = require('fs');
var path = require('path');
var read = Promise.denodeify(fs.readFile);
var write = Promise.denodeify(fs.writeFile);
var docco = require('docco');
var docdown = require('docdown');
var marked = require('marked');
var ejs = require('ejs');
var cheerio = require('cheerio');
var exec = require('child_process').exec;
var Dokker = {};
Dokker.VERSION = '0.1.2';Transclude in a ejs template file the HTML snippet that was ultimately created with docdown. Also tweak the HTML page a bit and finally inject the README.md.
Dokker.injectTemplate = function(options) {
return new Promise(function(resolve, reject) {
var template, body, html, readme, $;
return read(options.template, 'utf8')
.then(function(data) {
template = data;
return read(options.readme, 'utf8');
}).then(function(data) {
readme = marked(data);
$ = cheerio.load(readme);
$('h1').remove();
readme = $.html();
return read(options.html, 'utf8');
}).then(function(data) {
$ = cheerio.load(data);
return ejs.render(template, {
apiToc: $('.toc-container').html(),
readme: readme,
apiDoc: $('.doc-container').html(),correctly setting links to your github/pages
page_url: options.site,
title: options.title,
github_url: options.github,fixed reference to generated annotation the ‘literate’ in .dokker.json shall not require a source since it’s never used.
annotated_path: 'annotated/'+options.source
});
}).then(function(data) {
return write(options.html, data, 'utf8');
}).then(function() {
resolve();
}).then(null, function(err) {
reject(err);
});
});
};Create a HTML site from any mocha tests find when executing mocha —reporter doc terminal command.
Dokker.createTests = function(options) {
return new Promise(function(resolve, reject) {
var template, tests;allows specification of mocha.command in .dokker.json, e.g. ‘mocha -u tdd —reporter doc’
var cmd = options.command || 'mocha --reporter doc';
exec(cmd, function(error, stdout) {
if(error) return reject(error);
tests = stdout;
return read(options.template, 'utf8')
.then(function(data) {
template = data;
return ejs.render(template, {tests: tests});
}).then(function(data) {
return write(options.path, data, 'utf8');
}).then(function() {
resolve();
}).then(null, function(err) {
reject(err);
});
});
});
};Extract docs folder to separate git branch and finally push branch to Github repository
Dokker.ghPages = function(){
return new Promise(function(resolve, reject) {
exec('git subtree split -P docs -b gh-pages', function(error, stdout, stderr) {
if(error) return reject(stderr);
exec('git push origin gh-pages', function(error, stdout, stderr) {
if(error) return reject(stderr);
resolve();
});
});
});
};Create an HTML file from any source code comments in the style of literate programming
Dokker.literate = function (options) {
return new Promise(function(resolve, reject) {
var tmpDir = path.join(process.cwd(), '/.tmp');
var tmpFile = path.join(tmpDir, options.source);
return read(path.join(process.cwd(), options.source), 'utf8')
.then(function(data) {
var source = data.replace(/^\s*(\*|\/\*).*[\r\n]/gm, '');
return Dokker.mkdir(tmpDir)
.then(function() {
return write(tmpFile, source, 'utf8');
}).then(function(){
docco.run(['', '', tmpFile, '-o', options.dir]);
resolve();
});
}).then(null, function(err) {
if (err) return reject(err);
});
});
};Convert markdown from any source code comments with docdown module.
Dokker.jsdocMarkdown = function (options) {
return new Promise(function(resolve, reject) {
var source, tmpFile, tmpDir;
return read(path.join(process.cwd(), options.source), 'utf8')
.then(function(data){
source = data.replace(/^\s*(\/\/).*[\r\n]/gm, '');
tmpDir = path.join(process.cwd(), '/.tmp');
return Dokker.mkdir(tmpDir);
}).then(function(){
tmpFile = path.join(tmpDir, options.source);
return write(tmpFile, source, 'utf8');
}).then(function(){
var markdown = docdown({
'path': tmpFile,
'url': options.github,
'toc': 'categories'
});
return write(options.markdown, markdown, 'utf8');
}).then(function() {
resolve();
}).then(null, function(err) {
reject(err);
});
});
};Create an HTML file from any source code comments in the style of literate programming
Dokker.jsdocHtml = function (options) {
return new Promise(function(resolve, reject) {
return read(options.markdown, 'utf8')
.then(function(data) {
var html = marked(data).replace(/<!-- /g,'<').replace(/ -->/g,'>');
return write(options.html, html, 'utf8');
}).then(function() {
resolve();
}).then(null, function(err) {
reject(err);
});
});
};Internal helper function that creates any directory if not existing.
Dokker.mkdir = function(dir) {
return new Promise(function(resolve, reject) {
fs.exists(dir, function(exists) {
if (exists) {
resolve();
} else {
fs.mkdir(dir, function(err) {
if (err) return reject(err);
resolve();
});
}
});
});
};Parses the options file, .Dokker.json, and sets the default parameters.
Dokker.configure = function(options) {
return new Promise(function(resolve, reject){
var file = path.join(process.cwd(), '.dokker.json');
return read(file, 'utf8')
.then(function(data) {
data = JSON.parse(data);
data.jsdoc.template = (data.jsdoc.template) ? path.join(process.cwd(), data.jsdoc.template) : path.join(__dirname, 'templates/index.ejs.html');
data.mocha.template = (data.mocha.template) ? path.join(process.cwd(), data.mocha.template) : path.join(__dirname, 'templates/tests.ejs.html');
data.mocha.path = path.join(process.cwd(), data.dir, data.mocha.path);mocha.command commented out to fix build-breaking bug specifies mocha command in .dokker.json; e.g. mocha -u tdd -R spec data.mocha.command = path.join(process.cwd(), data.dir, data.mocha.command);
data.literate.dir = path.join(process.cwd(), data.dir, data.literate.dir);
data.jsdoc.markdown = path.join(process.cwd(), data.dir, data.jsdoc.markdown);
data.jsdoc.html = path.join(process.cwd(), data.dir, data.jsdoc.html);
data.jsdoc.readme = path.join(process.cwd(), data.jsdoc.readme);
resolve(data);
}).then(null, function(err) {
reject(err);
});
});
};Copy starter template to bootstrap any Dokker project.
Dokker.copyTemplate = function(options) {
return new Promise(function(resolve, reject) {
var templatesDir = path.join(process.cwd(), 'templates');
return Dokker.mkdir(templatesDir)
.then(function() {
var oldStyle = path.join(__dirname, 'templates', 'styles.css');
var newStyle = path.join(process.cwd(), options.dir, 'styles.css');
fs.createReadStream(oldStyle).pipe(fs.createWriteStream(newStyle));
var oldLogo = path.join(__dirname, 'templates', 'logo.png');
var newLogo = path.join(process.cwd(), options.dir, 'logo.png');
fs.createReadStream(oldLogo).pipe(fs.createWriteStream(newLogo));
var oldApp = path.join(__dirname, 'templates', 'app.js');
var newApp = path.join(process.cwd(), options.dir, 'app.js');
fs.createReadStream(oldApp).pipe(fs.createWriteStream(newApp));
resolve();
});
});
};Copies the .Dokker.json file to bootstrap any Dokker project.
Dokker.init = function(){
return new Promise(function(resolve, reject) {
var oldDok = path.join(__dirname, '.dokker.json');
var newDok = path.join(process.cwd(), '.dokker.json');
fs.createReadStream(oldDok).pipe(fs.createWriteStream(newDok));
resolve();
});
};Starts the Node.js/Express server to watch Dokker.js project documentation.
Dokker.watch = function(options) {
var gulpex = require(__dirname + '/gulpfile.js').gulpex;
return gulpex();return new Promise(function(resolve, reject){ exec(‘DIR=’+ options.dir + ‘ node ‘ + options.dir + ‘/app.js’, function(error, stdout, stderr){ if(error) return reject(stderr); }); });
};
module.exports = Dokker;