From 40ee3ab5abeafdbe292ece69a01a061566d2c4cb Mon Sep 17 00:00:00 2001 From: brettlangdon Date: Mon, 26 Jan 2015 09:10:10 -0500 Subject: [PATCH] add basic prototype of custom formatter --- .gitignore | 1 + bin/docast | 29 ++++++++++-------- lib/formatter.js | 76 +++++++++++++++++++++++++++++++++++++++++++++++ lib/index.jade | 9 ++++++ lib/index.js | 5 ++++ lib/template.jade | 18 +++++++++++ package.json | 5 +++- 7 files changed, 130 insertions(+), 13 deletions(-) create mode 100644 lib/formatter.js create mode 100644 lib/index.jade create mode 100644 lib/template.jade diff --git a/.gitignore b/.gitignore index 3c3629e..dd87e2d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules +build diff --git a/bin/docast b/bin/docast index 3a75daa..8049677 100755 --- a/bin/docast +++ b/bin/docast @@ -9,32 +9,37 @@ var doc = [ ' docast (-h | --help)', ' docast (-v | --version)', ' docast extract [-o ] ...', - ' docast generate ...', + ' docast generate [-f ] [-b ] ...', '', 'Options:', - ' -h --help Show this help text', - ' -v --version Show docast version information', + ' -h --help Show this help text', + ' -v --version Show docast version information', 'Extract:', ' Parse docs from javascript files and output as json to a file', - ' -o --output File to output to [default: out.json]', - ' List of javascript files to fetch docs from', + ' -o --output File to output to [default: out.json]', + ' List of javascript files to fetch docs from', 'Generate:', ' Provide a script used to generate documentation from the parsed docs', - ' Script which exports a `function(comments)` used to generate docs from comments', - ' List of javascript files to fetch docs from', + ' -b --build Folderto output to [default: build]', + ' -f --formatter Script to import as formatter, default uses internal', + ' List of javascript files to fetch docs from', ].join('\r\n'); var args = docopt.docopt(doc, {version: require('../package.json').version}); -var comments = []; +var comments = {}; args[''].forEach(function(file){ - comments = comments.concat(docast.parse(file)); + comments[file] = docast.parse(file); }); if(args.extract){ fs.writeFileSync(args['--output'], JSON.stringify(comments)); } else if(args.generate){ - var loc = path.join(process.cwd(), args['']); - var formatter = require(loc); - formatter(comments); + var options = {build: args['--build']}; + var formatter = new docast.formatter(options); + if(args['--formatter']){ + var loc = path.join(process.cwd(), args['--formatter']); + formatter = new (require(loc))(options); + } + formatter.format(comments); } diff --git a/lib/formatter.js b/lib/formatter.js new file mode 100644 index 0000000..4921dc6 --- /dev/null +++ b/lib/formatter.js @@ -0,0 +1,76 @@ +var fs = require('fs'); +var jade = require('jade'); +var mkdirp = require('mkdirp'); +var path = require('path'); +var yaml = require('js-yaml'); + +var Formatter = function(options){ + this.options = options || {}; + this.build = options.build || 'build'; + this.yaml = (options.yaml === undefined)? true : options.yaml; + + var defaultTemplate = path.join(__dirname, 'template.jade'); + this.template = (options.template === undefined)? defaultTemplate : options.template; + this.renderer = JSON.stringify; + if(this.template){ + this.renderer = jade.compileFile(this.template); + } + + var defaultIndexTemplate = path.join(__dirname, 'index.jade'); + this.indexTemplate = (options.indexTemplate === undefined)? defaultIndexTemplate : options.indexTemplate; + this.indexRenderer = JSON.stringify; + if(this.indexTemplate){ + this.indexRenderer = jade.compileFile(this.indexTemplate); + } + + this.output = path.join(process.cwd(), this.build); + mkdirp.sync(this.output); +}; + +Formatter.prototype.format = function(data){ + for(var filename in data){ + this.formatFile(filename, data[filename]); + } + var data = { + index: this.buildIndex(this.output), + }; + fs.writeFileSync(path.join(this.output, 'index.html'), this.indexRenderer(data)); +}; + +Formatter.prototype.buildIndex = function(dir){ + var files = fs.readdirSync(dir); + var index = []; + files.forEach(function(filename){ + absFilename = path.join(dir, filename); + var stats = fs.statSync(absFilename); + if(stats.isDirectory()){ + index = index.concat(this.buildIndex(absFilename)); + } else { + index.push(absFilename.replace(this.output + '/', '')); + } + }.bind(this)); + return index; +}; + +Formatter.prototype.formatFile = function(filename, comments){ + var out = path.join(this.output, filename); + var dir = path.dirname(out); + var base = path.basename(out, '.js'); + out = path.join(dir, base + '.html'); + mkdirp.sync(path.dirname(out)); + + if(this.yaml){ + for(var i in comments){ + comments[i].doc = yaml.safeLoad(comments[i].doc); + } + } + + var data = { + filename: filename, + comments: comments, + }; + var rendered = this.renderer(data); + fs.writeFileSync(out, rendered); +}; + +module.exports = Formatter; diff --git a/lib/index.jade b/lib/index.jade new file mode 100644 index 0000000..0f789f7 --- /dev/null +++ b/lib/index.jade @@ -0,0 +1,9 @@ +doctype html +html + head + body + h1=dir + ul + each file in index + li + a(href=file)=file diff --git a/lib/index.js b/lib/index.js index b4662d6..b3bbf74 100644 --- a/lib/index.js +++ b/lib/index.js @@ -15,6 +15,10 @@ var traverseForType = function(type, expr, callback){ if(expr.type === 'BlockStatement'){ expr.body.forEach(function(expr){ if(expr.type === type){ + // probably a blank return or throw statement + if(!expr.argument){ + return; + } if(expr.argument.type === 'NewExpression'){ callback(expr.argument.callee.name); } else if(expr.argument.type === 'Literal'){ @@ -183,3 +187,4 @@ module.exports.parseContents = function(contents, options){ }; module.exports.parse = module.exports.parseFile; +module.exports.formatter = require('./formatter'); diff --git a/lib/template.jade b/lib/template.jade new file mode 100644 index 0000000..e29d61b --- /dev/null +++ b/lib/template.jade @@ -0,0 +1,18 @@ +doctype html +html +body + h1=filename + each comment in comments + h3=comment.name + '(' + comment.params.join(', ') + ')' + pre=comment.doc.comment + if comment.doc.params + h5 Params + ul + each param in comment.doc.params + li=param.name + ' [' + param.type + ']' + pre=param.comment + if comment.doc.returns + h5 Returns + ul + li='[' + comment.doc.returns.type + ']' + pre=comment.doc.returns.comment diff --git a/package.json b/package.json index eee41ad..ce8bb9b 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,10 @@ "homepage": "https://github.com/brettlangdon/docast", "dependencies": { "docopt": "^0.4.1", - "esprima": "^1.2.3" + "esprima": "^1.2.3", + "jade": "^1.9.1", + "mkdirp": "^0.5.0", + "yaml": "^0.2.3" }, "devDependencies": { "mocha": "^2.1.0"