UNPKG

metalsmith-better-excerpts

Version:

A Metalsmith plugin to extract/generate an excerpt from file content or metadata with multiple options.

96 lines (85 loc) 2.67 kB
'use strict'; var _ = require('lodash'), v = require('voca'), path = require('path'), cheerio = require('cheerio'); /** * default options * @type {Object} */ var defaultOptions = { moreRegExp: /\s*<!--\s*more\s*-->/i, stripTags: true, pruneLength: 140, pruneString: '…' }; /** * plugin expose function * * @param {Object} options custom options * @return {Function} plugin function */ module.exports = function(options) { options = _.merge({}, defaultOptions, options); return function(files, metalsmith, done) { setImmediate(done); _.forEach(files, function(file, filename) { if (!isHtml(filename)) { return; } var excerpt = file.excerpt || getExcerptByMoreTag(file, options.moreRegExp) || getExcerptByFirstParagraph(file) || ''; if (options.stripTags) { excerpt = v.stripTags(excerpt); if (options.pruneLength > 0) { excerpt = v.prune(excerpt, options.pruneLength, options.pruneString); } } file.excerpt = excerpt && excerpt.length > 0 ? excerpt : false; }); }; }; /** * retrieve excerpt from file object by extracting contents until a 'more' tag * * @param {Object} file file object * @param {RegExp} regExp 'more' tag regexp * @return {mixed} excerpt string or false */ function getExcerptByMoreTag(file, regExp) { var excerpt = false, contents = file.contents.toString(); contents = cheerio.load('<root>' + contents + '</root>', {decodeEntities: false})('root').html(); var match = contents.search(regExp); if (match > -1) { excerpt = contents.slice(0, match); excerpt = v.unescapeHtml(excerpt); } return excerpt; } /** * retrieve excerpt from file object by extracting the first p's contents * * @param {Object} file file object * @return {mixed} excerpt string or false */ function getExcerptByFirstParagraph(file) { var $ = cheerio.load(file.contents.toString(), {decodeEntities: false}), p = $('p').first(), excerpt = p.length ? p.html().trim() : false; if (excerpt) { excerpt = v.unescapeHtml(excerpt); } return excerpt; } /** * Check if a filename has an html extension * * @param {String} filename path to check * @return {Boolean} test result */ function isHtml(filename) { return /\.html?/.test(path.extname(filename)) ? true : false; }