| 'use strict'; |
| |
| var extglob = require('extglob'); |
| var nanomatch = require('nanomatch'); |
| var regexNot = require('regex-not'); |
| var toRegex = require('to-regex'); |
| var not; |
| |
| /** |
| * Characters to use in negation regex (we want to "not" match |
| * characters that are matched by other parsers) |
| */ |
| |
| var TEXT = '([!@*?+]?\\(|\\)|\\[:?(?=.*?:?\\])|:?\\]|[*+?!^$.\\\\/])+'; |
| var createNotRegex = function(opts) { |
| return not || (not = textRegex(TEXT)); |
| }; |
| |
| /** |
| * Parsers |
| */ |
| |
| module.exports = function(snapdragon) { |
| var parsers = snapdragon.parser.parsers; |
| |
| // register nanomatch parsers |
| snapdragon.use(nanomatch.parsers); |
| |
| // get references to some specific nanomatch parsers before they |
| // are overridden by the extglob and/or parsers |
| var escape = parsers.escape; |
| var slash = parsers.slash; |
| var qmark = parsers.qmark; |
| var plus = parsers.plus; |
| var star = parsers.star; |
| var dot = parsers.dot; |
| |
| // register extglob parsers |
| snapdragon.use(extglob.parsers); |
| |
| // custom micromatch parsers |
| snapdragon.parser |
| .use(function() { |
| // override "notRegex" created in nanomatch parser |
| this.notRegex = /^\!+(?!\()/; |
| }) |
| // reset the referenced parsers |
| .capture('escape', escape) |
| .capture('slash', slash) |
| .capture('qmark', qmark) |
| .capture('star', star) |
| .capture('plus', plus) |
| .capture('dot', dot) |
| |
| /** |
| * Override `text` parser |
| */ |
| |
| .capture('text', function() { |
| if (this.isInside('bracket')) return; |
| var pos = this.position(); |
| var m = this.match(createNotRegex(this.options)); |
| if (!m || !m[0]) return; |
| |
| // escape regex boundary characters and simple brackets |
| var val = m[0].replace(/([[\]^$])/g, '\\$1'); |
| |
| return pos({ |
| type: 'text', |
| val: val |
| }); |
| }); |
| }; |
| |
| /** |
| * Create text regex |
| */ |
| |
| function textRegex(pattern) { |
| var notStr = regexNot.create(pattern, {contains: true, strictClose: false}); |
| var prefix = '(?:[\\^]|\\\\|'; |
| return toRegex(prefix + notStr + ')', {strictClose: false}); |
| } |