'use strict'; var sort = require('./lib/sort'), nest = require('./lib/nest'), filterAccess = require('./lib/filter_access'), filterJS = require('./lib/filter_js'), dependency = require('./lib/input/dependency'), shallow = require('./lib/input/shallow'), parseJavaScript = require('./lib/parsers/javascript'), polyglot = require('./lib/parsers/polyglot'), github = require('./lib/github'), hierarchy = require('./lib/hierarchy'), inferName = require('./lib/infer/name'), inferKind = require('./lib/infer/kind'), inferParams = require('./lib/infer/params'), inferProperties = require('./lib/infer/properties'), inferMembership = require('./lib/infer/membership'), inferReturn = require('./lib/infer/return'), formatLint = require('./lib/lint').formatLint, lintComments = require('./lib/lint').lintComments; /** * Build a pipeline of comment handlers. * @param {...Function|null} args - Pipeline elements. Each is a function that accepts * a comment and can return a comment or undefined (to drop that comment). * @returns {Function} pipeline * @private */ function pipeline() { var elements = arguments; return function (comment) { for (var i = 0; comment && i < elements.length; i++) { if (elements[i]) { comment = elements[i](comment); } } return comment; }; } /** * Given an array of indexes and options for whether to resolve shallow * or deep dependencies, resolve dependencies. * * @param {Array|string} indexes files to process * @param {Object} options options * @param {Function} callback called with results * @returns {undefined} */ function expandInputs(indexes, options, callback) { var inputFn = (options.polyglot || options.shallow) ? shallow : dependency; inputFn(indexes, options, callback); } /** * Generate JavaScript documentation as a list of parsed JSDoc * comments, given a root file as a path. * * @name documentation * @param {Array|string} indexes files to process * @param {Object} options options * @param {Array} options.external a string regex / glob match pattern * that defines what external modules will be whitelisted and included in the * generated documentation. * @param {boolean} [options.polyglot=false] parse comments with a regex rather than * a proper parser. This enables support of non-JavaScript languages but * reduces documentation's ability to infer structure of code. * @param {boolean} [options.shallow=false] whether to avoid dependency parsing * even in JavaScript code. With the polyglot option set, this has no effect. * @param {Array} [options.order=[]] optional array that * defines sorting order of documentation * @param {Object} [options.hljs] hljs optional options * @param {boolean} [options.hljs.highlightAuto=false] hljs automatically detect language * @param {Array} [options.hljs.languages] languages for hljs to choose from * @param {Function} callback to be called when the documentation generation * is complete, with (err, result) argumentsj * @returns {undefined} calls callback */ module.exports = function (indexes, options, callback) { options = options || {}; options.hljs = options.hljs || {}; if (typeof indexes === 'string') { indexes = [indexes]; } var parseFn = (options.polyglot) ? polyglot : parseJavaScript; return expandInputs(indexes, options, function (error, inputs) { if (error) { return callback(error); } try { callback(null, filterAccess( options.private ? [] : undefined, hierarchy( inputs .filter(filterJS(options.extension)) .reduce(function (memo, file) { return memo.concat(parseFn(file)); }, []) .map(pipeline( inferName(), inferKind(), inferParams(), inferProperties(), inferReturn(), inferMembership(), nest, options.github && github )) .filter(Boolean) .sort(sort.bind(undefined, options.order))))); } catch (e) { callback(e); } }); }; /** * Lint files for non-standard or incorrect documentation * information, returning a potentially-empty string * of lint information intended for human-readable output. * * @param {Array|string} indexes files to process * @param {Object} options options * @param {Array} options.external a string regex / glob match pattern * that defines what external modules will be whitelisted and included in the * generated documentation. * @param {boolean} [options.polyglot=false] parse comments with a regex rather than * a proper parser. This enables support of non-JavaScript languages but * reduces documentation's ability to infer structure of code. * @param {boolean} [options.shallow=false] whether to avoid dependency parsing * even in JavaScript code. With the polyglot option set, this has no effect. * @param {Function} callback to be called when the documentation generation * is complete, with (err, result) argumentsj * @returns {undefined} calls callback */ module.exports.lint = function lint(indexes, options, callback) { options = options || {}; if (typeof indexes === 'string') { indexes = [indexes]; } var parseFn = (options.polyglot) ? polyglot : parseJavaScript; return expandInputs(indexes, options, function (error, inputs) { if (error) { return callback(error); } callback(null, formatLint(hierarchy( inputs .filter(filterJS(options.extension)) .reduce(function (memo, file) { return memo.concat(parseFn(file)); }, []) .map(pipeline( lintComments, inferName(), inferKind(), inferParams(), inferProperties(), inferReturn(), inferMembership(), nest)) .filter(Boolean)))); }); }; module.exports.expandInputs = expandInputs; module.exports.formats = { html: require('./lib/output/html'), md: require('./lib/output/markdown'), json: require('./lib/output/json') };