| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- 'use strict';
- var typeOf = require('kind-of');
- var extend = require('extend-shallow');
- /**
- * Parse sections in `input` with the given `options`.
- *
- * ```js
- * var sections = require('{%= name %}');
- * var result = sections(input, options);
- * // { content: 'Content before sections', sections: [] }
- * ```
- * @param {String|Buffer|Object} `input` If input is an object, it's `content` property must be a string or buffer.
- * @param {Object} options
- * @return {Object} Returns an object with a `content` string and an array of `sections` objects.
- * @api public
- */
- module.exports = function(input, options) {
- if (typeof options === 'function') {
- options = { parse: options };
- }
- var file = toObject(input);
- var defaults = {section_delimiter: '---', parse: identity};
- var opts = extend({}, defaults, options);
- var delim = opts.section_delimiter;
- var lines = file.content.split(/\r?\n/);
- var sections = null;
- var section = createSection();
- var content = [];
- var stack = [];
- function initSections(val) {
- file.content = val;
- sections = [];
- content = [];
- }
- function closeSection(val) {
- if (stack.length) {
- section.key = getKey(stack[0], delim);
- section.content = val;
- opts.parse(section, sections);
- sections.push(section);
- section = createSection();
- content = [];
- stack = [];
- }
- }
- for (var i = 0; i < lines.length; i++) {
- var line = lines[i];
- var len = stack.length;
- var ln = line.trim();
- if (isDelimiter(ln, delim)) {
- if (ln.length === 3 && i !== 0) {
- if (len === 0 || len === 2) {
- content.push(line);
- continue;
- }
- stack.push(ln);
- section.data = content.join('\n');
- content = [];
- continue;
- }
- if (sections === null) {
- initSections(content.join('\n'));
- }
- if (len === 2) {
- closeSection(content.join('\n'));
- }
- stack.push(ln);
- continue;
- }
- content.push(line);
- }
- if (sections === null) {
- initSections(content.join('\n'));
- } else {
- closeSection(content.join('\n'));
- }
- file.sections = sections;
- return file;
- };
- function isDelimiter(line, delim) {
- if (line.slice(0, delim.length) !== delim) {
- return false;
- }
- if (line.charAt(delim.length + 1) === delim.slice(-1)) {
- return false;
- }
- return true;
- }
- function toObject(input) {
- if (typeOf(input) !== 'object') {
- input = { content: input };
- }
- if (typeof input.content !== 'string' && !isBuffer(input.content)) {
- throw new TypeError('expected a buffer or string');
- }
- input.content = input.content.toString();
- input.sections = [];
- return input;
- }
- function getKey(val, delim) {
- return val ? val.slice(delim.length).trim() : '';
- }
- function createSection() {
- return { key: '', data: '', content: '' };
- }
- function identity(val) {
- return val;
- }
- function isBuffer(val) {
- if (val && val.constructor && typeof val.constructor.isBuffer === 'function') {
- return val.constructor.isBuffer(val);
- }
- return false;
- }
|