mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
This reverts commit aad7b4896e503b66a29f46c02cc08f84e5535f42. Conflicts: test/specs/jsdoc/util/templateHelper.js
438 lines
13 KiB
JavaScript
438 lines
13 KiB
JavaScript
/*global app: true, args: true, env: true, Packages: true, publish: true */
|
|
/**
|
|
* @project jsdoc
|
|
* @author Michael Mathews <micmath@gmail.com>
|
|
* @license See LICENSE.md file included in this distribution.
|
|
*/
|
|
|
|
// try: $ java -classpath build-files/java/classes/js.jar org.mozilla.javascript.tools.shell.Main main.js `pwd` script/to/parse.js
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
|
|
|
var hasOwnProp = Object.prototype.hasOwnProperty;
|
|
|
|
/** Data representing the environment in which this app is running.
|
|
@namespace
|
|
*/
|
|
env = {
|
|
/** Running start and finish times. */
|
|
run: {
|
|
start: new Date(),
|
|
finish: null
|
|
},
|
|
|
|
/**
|
|
The type of VM that is executing jsdoc.
|
|
@type string
|
|
*/
|
|
vm: '',
|
|
|
|
/**
|
|
The command line arguments passed into jsdoc.
|
|
@type Array
|
|
*/
|
|
args: [],
|
|
|
|
/**
|
|
The parsed JSON data from the configuration file.
|
|
@type Object
|
|
*/
|
|
conf: {},
|
|
|
|
/**
|
|
The absolute path to the base directory of the jsdoc application.
|
|
@type string
|
|
*/
|
|
dirname: '.',
|
|
|
|
/**
|
|
The command line arguments, parsed into a key/value hash.
|
|
@type Object
|
|
@example if (env.opts.help) { print 'Helpful message.'; }
|
|
*/
|
|
opts: {}
|
|
};
|
|
|
|
args = Array.prototype.slice.call(arguments, 0);
|
|
|
|
// rhino has no native way to get the base dirname of the currently running script
|
|
// so this information must be manually passed in from the command line
|
|
for (var i = 0; i < args.length; i++) {
|
|
if ( /^--dirname(?:=(.+?)(\/|\/\.)?)?$/i.test(args[i]) ) {
|
|
if (RegExp.$1) {
|
|
env.dirname = RegExp.$1; // last wins
|
|
args.splice(i--, 1); // remove --dirname opt from arguments
|
|
}
|
|
else {
|
|
env.dirname = args[i + 1];
|
|
args.splice(i--, 2);
|
|
}
|
|
}
|
|
}
|
|
|
|
env.args = args;
|
|
|
|
load(env.dirname + '/lib/rhino-shim.js');
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
|
|
|
|
|
/** @global
|
|
@param {string} filepath The path to the script file to include (read and execute).
|
|
*/
|
|
function include(filepath) {
|
|
try {
|
|
filepath = include.resolve(filepath);
|
|
load(filepath);
|
|
}
|
|
catch (e) {
|
|
console.log('Cannot include "' + env.dirname + '/' + filepath + '": '+e);
|
|
}
|
|
}
|
|
include.resolve = function(filepath) {
|
|
if (filepath.indexOf('/') === 0) {
|
|
return filepath;
|
|
}
|
|
|
|
return env.dirname + '/' + filepath;
|
|
};
|
|
|
|
/** Print string/s out to the console.
|
|
@param {string} ... String/s to print out to console.
|
|
*/
|
|
function print() {
|
|
for (var i = 0, leni = arguments.length; i < leni; i++) {
|
|
java.lang.System.out.println('' + arguments[i]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Try to recursively print out all key/values in an object.
|
|
@global
|
|
@param {Object} ... Object/s to dump out to console.
|
|
*/
|
|
function dump() {
|
|
var doop = require('jsdoc/util/doop').doop;
|
|
var _dump = require('jsdoc/util/dumper').dump;
|
|
for (var i = 0, l = arguments.length; i < l; i++) {
|
|
print( _dump(doop(arguments[i])) );
|
|
}
|
|
}
|
|
|
|
function installPlugins(plugins, p) {
|
|
var dictionary = require('jsdoc/tag/dictionary'),
|
|
parser = p || app.jsdoc.parser;
|
|
|
|
// allow user-defined plugins to...
|
|
for (var i = 0, leni = plugins.length; i < leni; i++) {
|
|
var plugin = require(plugins[i]);
|
|
|
|
//...register event handlers
|
|
if (plugin.handlers) {
|
|
for (var eventName in plugin.handlers) {
|
|
if ( hasOwnProp.call(plugin.handlers, eventName) ) {
|
|
parser.on(eventName, plugin.handlers[eventName]);
|
|
}
|
|
}
|
|
}
|
|
|
|
//...define tags
|
|
if (plugin.defineTags) {
|
|
plugin.defineTags(dictionary);
|
|
}
|
|
|
|
//...add a node visitor
|
|
if (plugin.nodeVisitor) {
|
|
parser.addNodeVisitor(plugin.nodeVisitor);
|
|
}
|
|
}
|
|
}
|
|
|
|
function indexAll(docs) {
|
|
var lookupTable = {};
|
|
|
|
docs.forEach(function(doc) {
|
|
if ( !hasOwnProp.call(lookupTable, doc.longname) ) {
|
|
lookupTable[doc.longname] = [];
|
|
}
|
|
lookupTable[doc.longname].push(doc);
|
|
});
|
|
docs.index = lookupTable;
|
|
}
|
|
|
|
|
|
/**
|
|
Data that must be shared across the entire application.
|
|
@namespace
|
|
*/
|
|
app = {
|
|
jsdoc: {
|
|
scanner: new (require('jsdoc/src/scanner').Scanner)(),
|
|
parser: new (require('jsdoc/src/parser').Parser)(),
|
|
name: require('jsdoc/name')
|
|
}
|
|
};
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
|
|
|
|
|
/**
|
|
Run the jsdoc application.
|
|
*/
|
|
function main() {
|
|
var sourceFiles,
|
|
packageJson,
|
|
docs,
|
|
jsdoc = {
|
|
opts: {
|
|
args: require('jsdoc/opts/args'),
|
|
}
|
|
},
|
|
resolver,
|
|
_ = require('underscore'),
|
|
fs = require('fs'),
|
|
path = require('path'),
|
|
taffy = require('taffydb').taffy,
|
|
Config = require('jsdoc/config');
|
|
|
|
/**
|
|
Detect the type of VM running jsdoc.
|
|
**Note**: Rhino is the only VM that is currently supported.
|
|
@return {string} rhino|node
|
|
*/
|
|
function detectVm() {
|
|
if (typeof Packages === "object" &&
|
|
Object.prototype.toString.call(Packages) === "[object JavaPackage]") {
|
|
return "rhino";
|
|
} else if ( require && require.main && module && (require.main === module) ) {
|
|
return "node";
|
|
} else {
|
|
// unknown VM
|
|
return;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* If the current VM is Rhino, convert a path to a URI that meets the operating system's
|
|
* requirements. Otherwise, return the original path.
|
|
* @param {string} path The path to convert.
|
|
* @return {string} A URI that meets the operating system's requirements, or the original path.
|
|
*/
|
|
function pathToUri(_path) {
|
|
var result = _path;
|
|
|
|
if (env.vm === 'rhino') {
|
|
result = new java.io.File(result).toURI() + '';
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* If the current VM is Rhino, convert a URI to a path that meets the operating system's
|
|
* requirements. Otherwise, assume the "URI" is really a path, and return the original path.
|
|
* @param {string} uri The URI to convert.
|
|
* @return {string} A path that meets the operating system's requirements.
|
|
*/
|
|
function uriToPath(uri) {
|
|
var result = uri;
|
|
|
|
if (env.vm === 'rhino') {
|
|
result = new java.io.File( new java.net.URI(result) ) + '';
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
Retrieve the fully resolved path to the requested template.
|
|
|
|
@param {string} template - The path to the requested template. May be an absolute path;
|
|
a path relative to the current working directory; or a path relative to the JSDoc directory.
|
|
@return {string} The fully resolved path (or, on Rhino, a URI) to the requested template.
|
|
*/
|
|
function getTemplatePath(template) {
|
|
var result;
|
|
template = template || 'templates/default';
|
|
|
|
function pathExists(_path) {
|
|
try {
|
|
fs.readdirSync(_path);
|
|
}
|
|
catch(e) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// first, try resolving it relative to the current working directory (or just normalize it
|
|
// if it's an absolute path)
|
|
result = path.resolve(template);
|
|
if ( !pathExists(result) ) {
|
|
// next, try resolving it relative to the JSDoc directory
|
|
result = path.resolve(env.dirname, template);
|
|
if ( !pathExists(result) ) {
|
|
result = null;
|
|
}
|
|
}
|
|
|
|
// this only messes with the path on Rhino
|
|
if (result) {
|
|
result = pathToUri(result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
env.vm = detectVm();
|
|
|
|
var defaultOpts = {
|
|
destination: './out/'
|
|
};
|
|
|
|
env.opts = jsdoc.opts.args.parse(env.args);
|
|
|
|
try {
|
|
env.conf = new Config( fs.readFileSync( env.opts.configure || path.join(env.dirname, 'conf.json') ) ).get();
|
|
}
|
|
catch (e) {
|
|
try {
|
|
// Use the example file if possible
|
|
var example = fs.readFileSync(path.join(env.dirname, 'conf.json.EXAMPLE'), 'utf8');
|
|
env.conf = JSON.parse(example);
|
|
}
|
|
catch(e) {
|
|
throw('Configuration file cannot be evaluated. ' + e);
|
|
}
|
|
}
|
|
|
|
// look for options on the command line, in the config file, and in the defaults, in that order
|
|
env.opts = _.defaults(env.opts, env.conf.opts, defaultOpts);
|
|
|
|
// which version of javascript will be supported? (rhino only)
|
|
if (typeof version === 'function') {
|
|
version(env.conf.jsVersion || 180);
|
|
}
|
|
|
|
if (env.opts.help) {
|
|
console.log( jsdoc.opts.args.help() );
|
|
process.exit(0);
|
|
} else if (env.opts.test) {
|
|
include('test/runner.js');
|
|
process.exit(0);
|
|
}
|
|
|
|
if (env.conf.plugins) {
|
|
installPlugins(env.conf.plugins);
|
|
}
|
|
|
|
// any source file named package.json or README.md is treated special
|
|
for (var i = 0, l = env.opts._.length; i < l; i++ ) {
|
|
if (/\bpackage\.json$/i.test(env.opts._[i])) {
|
|
packageJson = require('fs').readFileSync( env.opts._[i] );
|
|
env.opts._.splice(i--, 1);
|
|
}
|
|
|
|
if (/(\bREADME|\.md)$/i.test(env.opts._[i])) {
|
|
var Readme = require('jsdoc/readme');
|
|
env.opts.readme = new Readme(env.opts._[i]).html;
|
|
env.opts._.splice(i--, 1);
|
|
}
|
|
}
|
|
|
|
if (env.conf.source && env.conf.source.include) {
|
|
env.opts._ = (env.opts._ || []).concat(env.conf.source.include);
|
|
}
|
|
|
|
if (env.conf.source && env.opts._.length > 0) { // are there any files to scan and parse?
|
|
var filter = new (require('jsdoc/src/filter').Filter)(env.conf.source);
|
|
|
|
sourceFiles = app.jsdoc.scanner.scan(env.opts._, (env.opts.recurse? 10 : undefined), filter);
|
|
|
|
require('jsdoc/src/handlers').attachTo(app.jsdoc.parser);
|
|
|
|
docs = app.jsdoc.parser.parse(sourceFiles, env.opts.encoding);
|
|
|
|
//The files are ALWAYS useful for the templates to have
|
|
//If there is no package.json, just create an empty package
|
|
var packageDocs = new (require('jsdoc/package').Package)(packageJson);
|
|
packageDocs.files = sourceFiles || [];
|
|
docs.push(packageDocs);
|
|
|
|
indexAll(docs);
|
|
|
|
require('jsdoc/augment').addInherited(docs);
|
|
require('jsdoc/borrow').resolveBorrows(docs);
|
|
|
|
if (env.opts.explain) {
|
|
console.log(docs);
|
|
process.exit(0);
|
|
}
|
|
|
|
// load this module anyway to ensure root instance exists
|
|
// it's not a problem since without tutorials root node will have empty children list
|
|
resolver = require('jsdoc/tutorial/resolver');
|
|
|
|
if (env.opts.tutorials) {
|
|
resolver.load(env.opts.tutorials);
|
|
resolver.resolve();
|
|
}
|
|
|
|
env.opts.template = getTemplatePath(env.opts.template) || env.opts.template;
|
|
|
|
var template;
|
|
try {
|
|
template = require(env.opts.template + '/publish');
|
|
}
|
|
catch(e) {
|
|
throw new Error("Unable to load template: " + e.message || e);
|
|
}
|
|
|
|
// templates should include a publish.js file that exports a "publish" function
|
|
if (template.publish && typeof template.publish === 'function') {
|
|
// convert this from a URI back to a path if necessary
|
|
env.opts.template = uriToPath(env.opts.template);
|
|
template.publish(
|
|
taffy(docs),
|
|
env.opts,
|
|
resolver.root
|
|
);
|
|
}
|
|
else {
|
|
// old templates define a global "publish" function, which is deprecated
|
|
include(env.opts.template + '/publish.js');
|
|
if (publish && typeof publish === 'function') {
|
|
console.log( env.opts.template + ' uses a global "publish" function, which is ' +
|
|
'deprecated and may not be supported in future versions. ' +
|
|
'Please update the template to use "exports.publish" instead.' );
|
|
// convert this from a URI back to a path if necessary
|
|
env.opts.template = uriToPath(env.opts.template);
|
|
publish(
|
|
taffy(docs),
|
|
env.opts,
|
|
resolver.root
|
|
);
|
|
}
|
|
else {
|
|
throw new Error( env.opts.template + " does not export a 'publish' function." );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
try {
|
|
main();
|
|
env.run.finish = new Date();
|
|
process.exit(0);
|
|
}
|
|
catch(e) {
|
|
env.run.finish = new Date();
|
|
if (e.rhinoException != null) {
|
|
e.rhinoException.printStackTrace();
|
|
} else {
|
|
throw e;
|
|
}
|
|
}
|