Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Documenting JavaScript with Doxygen
FILTER_PATTERNS =*.js=doxygen.js
#!/usr/bin/env node
var fs = require('fs')
var functionName = /^\s+\/\/\/\s+@function\s+(.*)$/;
var type = /^(\s+)\/\/\/\s+@param\s+{(\w*)}\s+(.+?)(\s+.*)$/;
var param = /^(\s+)\/\/\/\s+@param\s+(.+?)\s/;
var resultType = /^(\s+)\/\/\/\s+@return\s+{(\w+)}(\s+.*)$/;
function Section()
{
this.name = '';
this.result = 'undefined';
this.args = [];
this.comments = [];
this.namespaces = [];
}
Section.prototype.handle_function = function (line) {
this.namespaces = line.match(functionName)[1].split('.') || [];
this.name = this.namespaces.pop();
};
Section.prototype.handle_param = function (line) {
var paramType = 'Object';
var name = '';
var m = line.match(type);
var r = line;
if (m) {
paramType = m[2];
name = m[3];
r = m[1] + '/// @param ' + name + m[4];
}
else {
m = line.match(param);
name = m[2];
}
this.args.push({name: name, type: paramType});
this.comments.push(r);
};
Section.prototype.handle_return = function (line) {
this.result = 'undefined';
var m = line.match(resultType);
var r = line;
if (m) {
this.result = m[2];
r = m[1] + '/// @return ' + m[3];
}
this.comments.push(r);
};
Section.prototype.Generate = function () {
var doc = [];
this.namespaces.forEach(function (namespace) {
doc.push('namespace ' + namespace + ' {\n');
});
this.comments.forEach(function (c) {
doc.push(c);
});
var args = [];
this.args.forEach(function (argument) {
args.push(argument.type + ' ' + argument.name);
});
if (this.name) {
doc.push(this.result + ' ' + this.name + '(' + args.join(', ') + ');');
}
this.namespaces.forEach(function (namespace) {
doc.push('}\n');
});
return doc.join('\n');
};
Section.prototype.handle_line = function (line) {
this.comments.push(line);
};
function writeLine(line) {
process.stdout.write(line + '\n');
}
fs.readFile(process.argv[2], 'utf8', function (err, data) {
var lines = data.split('\n');
var comment = /^\s*\/\/\//;
var directive = /@(\w+)\s+(.*)$/;
var inside = false;
var section = new Section();
lines.forEach(function(line) {
if (line.match(comment)) {
var d = line.match(directive);
if (d) {
var handle = Section.prototype['handle_' + d[1]] || Section.prototype.handle_line;
handle.call(section, line);
} else {
section.handle_line(line);
}
inside = true;
} else if (inside) {
writeLine(section.Generate());
inside = false;
section = new Section();
}
});
});
/// @file Sync.js
/// @namespace Sync
/// Module for loading and storing data
var Sync = {
/// @function Sync.load
/// Loads an resource
/// @param {String} id the GUID of the resource
/// @param {Function} success callback to be executed with the data on suceess
/// @param {Function} error callback to be executed with error description in case of failure
/// Loads an resource
load : function (id, success, error) {
},
/// @function Sync.store
/// Store an resource
/// @param {String} id the GUID of the resource
/// @param {Object} data the resource
/// @param {Function} success callback to be executed when the store operation has completed successfully
/// @param {Function} error callback to be executed with error description in case of failure
/// Store an resource
store : function (id, data, success, error) {
},
};
/// @file Sync.js
/// @namespace Sync
/// Module for loading and storing data
namespace Sync {
/// Loads an resource
/// @param id the GUID of the resource
/// @param success callback to be executed with the data on suceess
/// @param error callback to be executed with error description in case of failure
/// Loads an resource
undefined load(String id, Function success, Function error);
}
namespace Sync {
/// Store an resource
/// @param id the GUID of the resource
/// @param data the resource
/// @param success callback to be executed when the store operation has completed successfully
/// @param error callback to be executed with error description in case of failure
/// Store an resource
undefined store(String id, Object data, Function success, Function error);
}
@aendrew

This comment has been minimized.

Copy link

commented Nov 26, 2013

I'm having issues getting this to work. All four files in the same directory, running "doxygen" just documents the .cpp file. Using Doxygen 1.7.6.1 and Node v0.10.22.

Looks like it'd be amazing if it worked, though...

Edit: Just dawned one me that Sync.js.cpp is an intermediary file for Doxygen. If I run /usr/bin/env node doxygen.js Sync.js, I get Sync.js.cpp via stdout. Though, unfortunately, it doesn't seem to want to work for my project, https://github.com/aendrew/ooyala-documentation/blob/master/module-example/module-example.js -- instead of outputting a CPP-style file, I get a blank.

@talarip

This comment has been minimized.

Copy link

commented Mar 18, 2014

I keep getting this error "sh: doxygen.js: command not found"

@jonashw

This comment has been minimized.

Copy link

commented Mar 26, 2014

bummer

@gcbw

This comment has been minimized.

Copy link

commented Feb 14, 2017

@talarip that is a simple bash path problem.

ensure file have execute and read permission. and either add file to path or use the full path in the conf file: FILTER_PATTERNS =*.js=/full/path/to/doxygen.js

@dad72

This comment has been minimized.

Copy link

commented Jul 29, 2018

This does not work for Javascript ES6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.