Skip to content

Instantly share code, notes, and snippets.

@elycruz
Last active November 9, 2016 15:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elycruz/05f0f942661f6dbe6f87f6c6f446e445 to your computer and use it in GitHub Desktop.
Save elycruz/05f0f942661f6dbe6f87f6c6f446e445 to your computer and use it in GitHub Desktop.
/**
* Created by elydelacruz on 11/8/16.
* Simple function to extract delimited content from a string.
*/
'use strict';
/**
* Returns whether our content has opening and closing delimiters.
* @param content {String}
* @param openDelim {String}
* @param closingDelim {String}
* @param minDelimitedContentLen {Number} - Default `1`.
* @returns {boolean}
*/
function hasOpeningAndClosingDelim (content, openDelim, closingDelim, minDelimitedContentLen = 1) {
return (content.indexOf(openDelim) > -1 ||
content.indexOf(closingDelim) > (openDelim.length + minDelimitedContentLen));
}
/**
* Returns normalized aggregator to use for our module.
* @param aggregator
* @returns {*}
*/
function normalizeAggregator (aggregator) {
if (!aggregator.hasOwnProperty('difference')) {
aggregator.difference = '';
}
if (!aggregator.hasOwnProperty('extracted')) {
aggregator.extracted = [];
}
return aggregator;
}
/**
* Returns reduced content and the results it was reduced by; E.g.,
* @todo add extensive example here
* @note Doesn't take care of nested delimiters.
* @param content {String} - Required.
* @param openingDelimiter {String} - Required.
* @param closingDelimiter {String} - Required.
* @param aggregatorLike {Object} - Optional. Default `{}`.
* @param minDelimitedContentLen {Number} - Optional. Default `1`.
* @returns {{difference: String, extracted: Array}}
*/
function reduceByDelimitedContent (content, openingDelimiter, closingDelimiter, aggregatorLike = {}, minDelimitedContentLen = 1) {
var aggregator = normalizeAggregator(aggregatorLike),
argsForRemainingCalls;
// If no opening or closing delimiter return untouched contents
if (!hasOpeningAndClosingDelim(content, openingDelimiter, closingDelimiter)) {
aggregator.difference = content;
return aggregator;
}
// Start processing content
let openingMatch = (new RegExp('(' + openingDelimiter + ')', 'gim')).exec(content),
closingMatch = (new RegExp('(' + closingDelimiter + ')', 'gim')).exec(content),
extractedContent = content.slice(openingMatch.index, closingMatch.index + closingDelimiter.length),
remainingContent = content.slice(0, openingMatch.index) +
content.substring(closingMatch.index + closingDelimiter.length, content.length);
// Push extracted content
aggregator.difference = remainingContent;
aggregator.extracted.push(extractedContent);
// Prepare for further calls
argsForRemainingCalls = [remainingContent, openingDelimiter, closingDelimiter, aggregator, minDelimitedContentLen];
// If content can still be reduced further do so
if (hasOpeningAndClosingDelim.apply(null, argsForRemainingCalls)) {
return reduceByDelimitedContent.apply(null, argsForRemainingCalls);
}
// Returned reduced and extracted content
return aggregator;
}
module.exports = reduceByDelimitedContent;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment