DoxJavaScript documentation parser for node. Check out the Github Repo for the source and installation guide. | |
| lib/dox/index.js |
Module dependencies.
|
require.paths.unshift(__dirname + '/koala/lib');
var sys = require('sys'),
fs = require('fs'),
path = require('path'),
koala = require('koala'),
utils = require('./utils'),
markdown = require('./markdown/lib/markdown');
|
Library version.
|
var version = '0.0.3';
|
Style name.
|
var style = 'default';
|
Project title.
|
var title = 'Dont forget to use --title to specify me!';
|
Parse JSDoc.
|
var jsdoc = true;
|
Project description.
|
var desc = '';
|
Show private code.
|
var showPrivate = false;
|
Github url for the ribbon.
|
var ribbon = '';
|
Usage documentation.
|
var usage = ''
+ 'Usage: dox [options] <file ...>\n'
+ '\n'
+ 'Options:\n'
+ ' -t, --title STR Project title\n'
+ ' -d, --desc STR Project description (markdown)\n'
+ ' -r, --ribbon URL Github ribbon url\n'
+ ' -s, --style NAME Document style, available: ["default"]\n'
+ ' -J, --no-jsdoc Disable jsdoc parsing (coverts to markdown)\n'
+ ' -p, --private Output private code in documentation\n'
+ ' -v, --version Output dox library version\n'
+ ' -h, --help Display help information'
+ '\n';
|
Parse the given arguments.
param: Array args api: public
|
exports.parse = function(args){
var files = [];
function requireArg(){
if (args.length) {
return args.shift();
} else {
throw new Error(arg + ' requires an argument.');
}
}
while (args.length) {
var arg = args.shift();
switch (arg) {
case '-h':
case '--help':
sys.puts(usage);
process.exit(1);
break;
case '-v':
case '--version':
sys.puts(version);
process.exit(1);
break;
case '-t':
case '--title':
title = requireArg();
break;
case '-d':
case '--desc':
desc = requireArg();
break;
case '-s':
case '--style':
style = requireArg();
break;
case '-J':
case '--no-jsdoc':
jsdoc = false;
break;
case '-p':
case '--private':
showPrivate = true;
break;
case '-r':
case '--ribbon':
ribbon = requireArg();
break;
default:
files.push(arg);
}
}
if (files.length) {
log('parsing ' + files.length + ' file(s)');
var pending = files.length;
log('loading ' + style + ' style');
var head = fs.readFileSync(__dirname + '/styles/' + style + '/head.html', 'utf8');
var foot = fs.readFileSync(__dirname + '/styles/' + style + '/foot.html', 'utf8');
var css = fs.readFileSync(__dirname + '/styles/' + style + '/style.css', 'utf8');
head = head.replace(/\{\{title\}\}/g, title).replace(/\{\{style\}\}/, css);
if (ribbon) {
log('generating ribbon');
sys.print('<a href="' + ribbon + '">'
+ '<img alt="Fork me on GitHub" id="ribbon"'
+ ' src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png">'
+ '</a>');
}
sys.print(head);
sys.print('<table id="source"><tbody>');
var first = true;
files.forEach(function(file){
log('parsing ' + file);
fs.readFile(file, 'utf8', function(err, str){
if (err) throw err;
if (first) {
if (desc) desc = markdown.toHTML(desc);
sys.print('<tr><td><h1>' + title + '</h1>' + desc + '</td><td></td></tr>');
first = false;
}
sys.print('<tr class="filename"><td><h2 id="' + file + '"><a href="#">'
+ path.basename(file, '.js') + '</a></h2></td><td>'
+ file + '</td></tr>');
sys.print(render(str, file));
--pending || sys.print(foot, '</tbody></table>');
});
});
} else {
throw new Error('files required.');
}
};
|
Generate html for the given string of code.
param: String str param: String file return: String api: public
|
var render = exports.render = function(str, file){
var parts = str.split(/\s*\/\*([^]+?)\*\/\s*/g),
blocks = [];
for (var i = 0, len = parts.length; i < len; ++i) {
var part = parts[i],
next = parts[i + 1] || '';
if (/^\s*$/.test(part)) {
continue;
} else if (/^!\s*\*/.test(part)) {
continue;
} else {
++i;
if (utils.ignore(part) || (utils.isPrivate(part) && !showPrivate)) continue;
var part = part.replace(/^ *\* ?/gm, '');
blocks.push({
comment: markdown.toHTML(utils.toMarkdown(part)),
code: koala.render(".js", utils.escape(next))
});
}
}
var html = [];
for (var i = 0, len = blocks.length; i < len; ++i) {
var block = blocks[i];
html.push('<tr class="code">');
html.push('<td class="docs">', block.comment || '', '</td>');
html.push('<td class="code">', block.code
? '<pre><code>' + block.code + '</code></pre>'
: '', '</td>');
html.push('</tr>');
}
return html.join('\n');
};
|
| lib/dox/utils.js |
Check if the given string of docs appears to be private.
param: String str return: Boolean api: public
|
exports.isPrivate = function(str) {
return str.indexOf('@private') >= 0
|| str.indexOf('@api private') >= 0;
}
|
Convert the given string of jsdoc to markdown.
param: String str return: String api: public
|
exports.toMarkdown = function(str) {
var first = true;
return str
.replace(/^((?:[A-Z]\w* ?)+):/gm, '## $1')
.replace(/^ *@(\w+) *\{([^}]+)\}( *[^\n]+)?/gm, function(_, key, type, desc){
var prefix = '';
if (first) {
first = false;
prefix = '## \n';
}
return prefix + '\n - **' + key + '**: _' + type.split(/ *[|\/] */).join(' | ') + '_ ' + (desc || '') + '\n';
})
.replace(/^ *@(\w+) *(\w+)/gm, ' - **$1**: _$2_\n');
}
|
Escape the given string of html.
Examples
escape('<foo>');
// => "<foo>"
param: String html return: String api: public
|
exports.escape = function(html){
return String(html)
.replace(/&(?!\w+;)/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"');
}
|