UNPKG

apidoc

Version:

RESTful web API Documentation Generator

231 lines (195 loc) 7.68 kB
var _ = require('lodash'); var apidoc = require('apidoc-core'); var fs = require('fs-extra'); var path = require('path'); var winston = require('winston'); var Markdown = require('markdown-it'); var PackageInfo = require('./package_info'); var defaults = { dest : path.join(__dirname, '../doc/'), template: path.join(__dirname, '../template/'), templateSingleFile: path.join(__dirname, '../template-single/index.html'), debug : false, single : false, // build to single file silent : false, verbose : false, simulate : false, parse : false, // Only parse and return the data, no file creation. colorize : true, markdown : true, config : '', apiprivate: false, encoding : 'utf8' }; var app = { log : {}, markdownParser: null, options : {} }; // Display uncaught Exception. process.on('uncaughtException', function(err) { console.error((new Date()).toUTCString() + ' uncaughtException:', err.message); console.error(err.stack); process.exit(1); }); /** * Create the documentation * * @param {Object} options See defaults and apidoc-core defaults for all options / `apidoc --help` * @returns {Mixed} true = ok, but nothing todo | false = error | Object with parsed data and project-informations. */ function createDoc(options) { var api; var apidocPath = path.join(__dirname, '../'); var markdownParser; var packageInfo; options = _.defaults({}, options, defaults); // Paths. options.dest = path.join(options.dest, './'); if (options.single) { options.template = options.templateSingleFile; options.dest = path.join(options.dest, 'index.html'); } else { options.template = path.join(options.template, './'); } // Line-Ending. if (options.lineEnding) { if (options.lineEnding === 'CRLF') options.lineEnding = '\r\n'; // win32 else if (options.lineEnding === 'CR') options.lineEnding = '\r'; // darwin else options.lineEnding = '\n'; // linux } // Options. app.options = options; // Logger. app.log = winston.createLogger({ transports: [ new (winston.transports.Console)({ level : app.options.debug ? 'debug' : app.options.verbose ? 'verbose' : 'info', silent : app.options.silent, prettyPrint: true, colorize : app.options.colorize, timestamp : false }), ] }); // Markdown Parser: enable / disable / use a custom parser. if(app.options.markdown === true) { markdownParser = new Markdown({ breaks : false, html : true, linkify : false, typographer: false, highlight: function (str, lang) { if (lang) { return '<pre class="prettyprint lang-' + lang + '">' + str + '</pre>'; } return '<pre class="prettyprint">' + str + '</code></pre>'; } }); } else if(app.options.markdown !== false) { // Include custom Parser @see MARKDOWN.md and test/fixtures/custom_markdown_parser.js if (app.options.markdown.substr(0, 2) !== '..' && ((app.options.markdown.substr(0, 1) !== '/' && app.options.markdown.substr(1, 2) !== ':/' && app.options.markdown.substr(1, 2) !== ':\\' && app.options.markdown.substr(0, 1) !== '~') || app.options.markdown.substr(0, 1) === '.')) { app.options.markdown = path.join(process.cwd(), app.options.markdown); } Markdown = require(app.options.markdown); // Overwrite default Markdown. markdownParser = new Markdown(); } app.markdownParser = markdownParser; try { packageInfo = new PackageInfo(app); // generator information var json = JSON.parse( fs.readFileSync(apidocPath + 'package.json', 'utf8') ); apidoc.setGeneratorInfos({ name : json.name, time : new Date(), url : json.homepage, version: json.version }); apidoc.setLogger(app.log); apidoc.setMarkdownParser(markdownParser); apidoc.setPackageInfos(packageInfo.get()); api = apidoc.parse(app.options); if (api === true) { app.log.info('Nothing to do.'); return true; } if (api === false) return false; if (app.options.parse !== true) { if (app.options.single) { createSingleFile(api); } else { createOutputFiles(api); } } if (app.options.verbose) { app.log.info('Done.'); } return api; } catch(e) { app.log.error(e.message); if (e.stack) app.log.debug(e.stack); return false; } } /** * Save parsed data to files * * @param {Object[]} blocks * @param {Object} packageInfos */ function createOutputFiles(api) { if (app.options.simulate) app.log.warn('!!! Simulation !!! No file or dir will be copied or created.'); app.log.verbose('create dir: ' + app.options.dest); if ( ! app.options.simulate) fs.mkdirsSync(app.options.dest); app.log.verbose('copy template ' + app.options.template + ' to: ' + app.options.dest); if ( ! app.options.simulate) fs.copySync(app.options.template, app.options.dest); // Write api_data app.log.verbose('write json file: ' + app.options.dest + 'api_data.json'); if( ! app.options.simulate) fs.writeFileSync(app.options.dest + './api_data.json', api.data + '\n'); app.log.verbose('write js file: ' + app.options.dest + 'api_data.js'); if( ! app.options.simulate) fs.writeFileSync(app.options.dest + './api_data.js', 'define({ "api": ' + api.data + ' });' + '\n'); // Write api_project app.log.verbose('write json file: ' + app.options.dest + 'api_project.json'); if( ! app.options.simulate) fs.writeFileSync(app.options.dest + './api_project.json', api.project + '\n'); app.log.verbose('write js file: ' + app.options.dest + 'api_project.js'); if( ! app.options.simulate) fs.writeFileSync(app.options.dest + './api_project.js', 'define(' + api.project + ');' + '\n'); // Write api_definitions app.log.verbose('write json file: ' + app.options.dest + 'api_definitions.json'); if( ! app.options.simulate && ! app.options.copyDefinitions) fs.writeFileSync(app.options.dest + './api_definition.json', api.definitions + '\n'); app.log.verbose('write js file: ' + app.options.dest + 'api_definitions.js'); if( ! app.options.simulate && ! app.options.copyDefinitions) fs.writeFileSync(app.options.dest + './api_definition.js', 'define({ "api": ' + api.definitions + ' });' + '\n'); } function createSingleFile(api) { if (app.options.simulate) app.log.warn('!!! Simulation !!! No file or dir will be copied or created.'); // dest is file path, not folder var dir = path.join(app.options.dest, '..'); app.log.verbose('create dir: ' + dir); if (!app.options.simulate) fs.mkdirsSync(dir); // create target file and setting data app.log.verbose('generate file: ' + app.options.dest); fs.writeFileSync(app.options.dest, fs .readFileSync(app.options.template) .toString() .replace('__API_DATA__', api.data) .replace('__API_PROJECT__', api.project) ); } module.exports = { createDoc: createDoc };