84 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			84 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| '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});
 | |
| }
 | 
