UNPKG

verb

Version:

Verb makes it easy to build project documentation using simple markdown templates, with zero configuration required.

248 lines (195 loc) 5.95 kB
/** * Verb <https://github.com/assemble/verb> * Generate markdown documentation for GitHub projects. * * Copyright (c) 2014 Jon Schlinkert, Brian Woodward, contributors. * Licensed under the MIT license. */ 'use strict'; var path = require('path'); var file = require('fs-utils'); var configFile = require('config-file'); var cwd = require('cwd'); var _ = require('lodash'); /** * verb */ var verb = module.exports = {}; verb.cwd = cwd; verb.base = cwd; verb.file = _.defaults(require('./lib/file'), file); // Logging and utils verb.colors = require('./lib/colors'); verb.utils = require('./lib/utils/index'); verb.log = require('./lib/log'); verb.verbose = verb.log.verbose; verb.mode = {}; verb.mode.verbose = false; // Extensions verb.plugins = require('./lib/plugins'); verb.filters = require('./lib/filters'); verb.tags = require('./lib/tags'); // Templates verb.scaffolds = require('./lib/scaffolds'); verb.template = require('./lib/template'); // Data verb.data = require('./lib/data'); verb.matter = require('./lib/matter'); verb.exclusions = require('./lib/exclusions'); verb.ext = '.md'; // Adds the `runner` property to the context, for // thirdy-party tools using Verb to be specified verb.runner = { name: 'Verb', url: 'https://github.com/assemble/verb' }; /** * runtime config */ verb.verbrc = {}; if (file.exists('.verbrc')) { verb.verbrc = configFile.load('.verbrc'); } else if (file.exists('.verbrc.yml')) { verb.verbrc = configFile.load('.verbrc.yml'); } /** * verb.init */ verb.init = function (options) { if (verb.initalized) { return; } verb.initalized = true; var opts = _.extend({verbose: false}, options); verb.mode.verbose = opts.verbose; // Initialize mixins _.fn = require('./lib/mixins.js'); _.mixin(_.fn); }; /** * verb.process */ verb.process = function(src, options) { var opts = _.extend({toc: {maxDepth: 2}}, options); verb.init(opts); // Add runtime config var runtimeConfig; if(opts.verbrc) { runtimeConfig = configFile.load(cwd(opts.verbrc)); } else { runtimeConfig = verb.verbrc; } _.extend(opts, runtimeConfig); verb.options = opts; verb.config = require('./lib/config').init(opts.config); verb.context = _.extend({}, verb.config); delete verb.context.config; src = src || ''; // Extend `verb` verb.layout = require('./lib/layout')(verb); // Build up the context _.extend(verb.context, opts); _.extend(verb.context, opts.metadata || {}); _.extend(verb.context, require('./lib/data').init(opts)); // Template settings var settings = _.defaults({}, opts.settings); // Initialize Lo-Dash tags and filters _.extend(verb.context, verb.tags.init(verb)); _.extend(verb.context, verb.filters.init(verb)); // Initialize `options.data` _.extend(verb.context, verb.data.init(opts)); // Extract and parse front matter verb.page = verb.matter.init(src, opts); _.extend(verb.context, verb.page.context); // Exclusion patterns, to omit certain options from context verb.context = verb.exclusions(verb.context, opts); _.extend(verb.context, {runner: verb.runner}); // Initialize plugins _.extend(verb.context, verb.plugins.init(verb)); // Process templates and render content var renderDone = false; var rendered = verb.template(verb.page.content, verb.context, settings); verb.tags.resolve(verb, rendered, function (err, results) { rendered = results; renderDone = true; }); while (!renderDone) { process.nextTick(); } var result = verb.utils.postProcess(rendered, opts); // Generate a TOC from <!-- toc --> after all content is included. result = require('marked-toc').insert(result, opts.toc); return { verb: verb, context: verb.context, content: result, original: src }; }; // Read a file, then process with Verb verb.read = function(src, options) { options = options || {}; verb.init(options); verb.options = verb.options || {}; _.extend(verb.options, options) var content = file.readFileSync(src); return verb.process(content, options).content; }; // Read a file, process it with Verb, then write it. verb.copy = function(src, dest, options) { options = options || {}; verb.init(options); verb.options = _.extend(verb.options || {}, options); verb.options.dest = dest || verb.cwd(); file.writeFileSync(dest, verb.read(src, options)); verb.log.success('Saved to:', dest); }; // Expand filepaths verb.expandMapping = function(src, dest, options) { var opts = _.extend({concat: false}, options); verb.init(opts); dest = dest || verb.cwd(); verb.options = _.extend(verb.options || {}, options); verb.options.dest = verb.cwd(dest) || verb.cwd(); var defaults = { cwd: opts.cwd || verb.cwd('.'), ext: verb.ext || opts.ext, destBase: dest }; defaults.srcBase = defaults.cwd; var concat = opts.concat || file.hasExt(dest) || false; var defer = []; var count = 0; file.expandMapping(src, defaults).map(function(fp) { fp.src.filter(function(filepath) { if (!file.exists(filepath)) { verb.log.error('>> Source file "' + filepath + '" not found.'); return false; } else { return true; } }).map(function(filepath) { verb.options.src = filepath; if(!concat) { count++; file.writeFileSync(fp.dest, verb.read(filepath, opts)); verb.log.success('Saved to', fp.dest); } else { defer.push(filepath); } }); }); if(concat) { count = 1; var blob = _.flatten(defer).map(function(filepath) { return verb.read(filepath, opts); }).join('\n'); file.writeFileSync(dest, blob); verb.log.success('Saved to', dest); } if(count >= 1) { verb.log.success('Done\n'); } else { verb.log.error('Failed.\n'); } };