UNPKG

gulp-jsdoc

Version:
118 lines (95 loc) 3.98 kB
/** * This is the documentation generator. * Unfortunately, there is now way we can make it streamy - doc generation is entirely * delegated to the opaqure publish method of each template... * Also, jsdoc structure requires us to: * - manipulate global variables * - copy over templates into node_modules * ... and there is little to be done - apart maybe changing jsdoc organization radically? * :( */ (function(){ 'use strict'; var path = require('path'); var fs = require('fs'); var wrench = require('wrench'); var taffy = require('taffydb').taffy; // Unfortunately, jsdoc rely on globals for the templating output part var env = global.env = {}; // Some templates may need these and crash for the lack of it :/ (function(){ var jsdocPkg = require('jsdoc/package.json'); env.version = { number: jsdocPkg.version, revision: new Date( parseInt(jsdocPkg.revision, 10) ).toUTCString() }; }()); // Init other global objects env.opts = env.opts || {}; env.conf = env.conf || {}; env.conf.templates = env.conf.templates || {}; env.conf.templates['default'] = env.conf.templates['default'] || {}; // We need the location of jsboot module because we MUST copy custom templates there :((( // Also, part of jsdoc won't even boot without this :( var jsdocRoot = env.dirname = path.dirname(require.resolve('jsdoc/cli')); var Generator = function(destination, template, options){ options = options || {}; env.conf.tags = { allowUnknownTags: true }; env.opts['private'] = !!options.showPrivate; env.conf.templates.monospaceLinks = !!options.monospaceLinks; env.conf.templates.cleverLinks = !!options.cleverLinks; env.conf.templates['default'].outputSourceFiles = ('outputSourceFiles' in options) ? options.outputSourceFiles : true; template = template || {}; // Overload conf object with optional template Object.keys(template).forEach(function(key){ if(key != 'path') env.conf.templates[key] = template[key]; }); // Magic do if(template.path == 'ink-docstrap'){ template.path = path.join(__dirname, '..', 'node_modules', 'ink-docstrap', 'template'); } if(template.path && fs.existsSync(template.path)){ env.opts.template = path.join(jsdocRoot, path.basename(path.dirname(path.dirname(template.path))) + '-' + path.basename(path.dirname(template.path)) + '-godamnawful'); // XXX this is god f damn awful jsdoc!!! // Templates SHOULD instead require a separate jsdoc-template module... // No one freakin uses rhino... wrench.copyDirSyncRecursive(template.path, env.opts.template, { forceDelete: true }); }else env.opts.template = path.join(jsdocRoot, 'templates/default'); env.opts.destination = destination || './doc/jsdoc'; var tpl; try { // XXX this is a terrible hack, to fix #1 (function(){ var offendingTpl = require.resolve(env.opts.template + '/publish'); if(offendingTpl in require.cache) delete require.cache[offendingTpl]; var offending = require.resolve('jsdoc/lib/jsdoc/util/templateHelper'); if(offending in require.cache) delete require.cache[offending]; }()); tpl = 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 (!tpl.publish || typeof tpl.publish !== 'function') throw new Error(env.opts.template + ' does not export a "publish" function. Global ' + '"publish" functions are no longer supported.'); this.render = function(vinyl){ env.opts.readme = vinyl.readme; tpl.publish( taffy(vinyl.contents.toString('utf8')), env.opts, {children: []} ); return {}; }; }; module.exports = Generator; }());