pantoninho/file-interpolator

View on GitHub
src/match-finder.js

Summary

Maintainability
A
0 mins
Test Coverage
module.exports = function(data, markers) {

    var matches = findFullMatches(data, markers);
    var partialMatch = findPartialMatch(data, markers);

    if (partialMatch) {
        matches.push(partialMatch);
    }

    return matches;
};

function findFullMatches(data, markers) {

    var matches = [];

    markers.forEach(function(marker) {

        var match, markerPosition;
        markerPosition = data.indexOf(marker);

        // find all positive matches for this marker inside this data
        while (markerPosition !== -1) {

            match = createMatch(marker, markerPosition);
            matches.push(match);

            // try to find the next marker
            markerPosition = data.indexOf(match.marker, match.at + match.marker.length);
        }
    });

    // sort finds using their index (ascending)
    matches.sort(function(a, b) {
        return a.at - b.at;
    });

    return matches;
}

function findPartialMatch(data, markers) {

    var partialMatch, exists;

    exists = markers.some(function(marker) {

        var reverseMark, possiblePartial, partialStart;

        reverseMark = marker.split('').reverse();
        possiblePartial = data.substring(data.length - reverseMark.length).split('').reverse();
        partialStart = reverseMark.indexOf(possiblePartial[0]);

        if (partialStart === -1) {
            return false;
        }

        reverseMark = reverseMark.slice(partialStart);

        return reverseMark.every(function(char, i) {
            partialStart = data.length - (i + 1);
            partialMatch = createMatch(marker, partialStart, true);
            return char === possiblePartial[i];
        });
    });

    if (exists) {
        return partialMatch;
    }

}

function createMatch(marker, position, partial) {
    return {
        marker: marker,
        at: position,
        partial: partial || false
    };
}