blob: f80498ceefa52fc0429fc6a94df54110f95ae791 [file] [log] [blame]
Leo Repp58b9f112021-11-22 11:57:47 +01001'use strict';
2
3var extglob = require('extglob');
4var nanomatch = require('nanomatch');
5var regexNot = require('regex-not');
6var toRegex = require('to-regex');
7var not;
8
9/**
10 * Characters to use in negation regex (we want to "not" match
11 * characters that are matched by other parsers)
12 */
13
14var TEXT = '([!@*?+]?\\(|\\)|\\[:?(?=.*?:?\\])|:?\\]|[*+?!^$.\\\\/])+';
15var createNotRegex = function(opts) {
16 return not || (not = textRegex(TEXT));
17};
18
19/**
20 * Parsers
21 */
22
23module.exports = function(snapdragon) {
24 var parsers = snapdragon.parser.parsers;
25
26 // register nanomatch parsers
27 snapdragon.use(nanomatch.parsers);
28
29 // get references to some specific nanomatch parsers before they
30 // are overridden by the extglob and/or parsers
31 var escape = parsers.escape;
32 var slash = parsers.slash;
33 var qmark = parsers.qmark;
34 var plus = parsers.plus;
35 var star = parsers.star;
36 var dot = parsers.dot;
37
38 // register extglob parsers
39 snapdragon.use(extglob.parsers);
40
41 // custom micromatch parsers
42 snapdragon.parser
43 .use(function() {
44 // override "notRegex" created in nanomatch parser
45 this.notRegex = /^\!+(?!\()/;
46 })
47 // reset the referenced parsers
48 .capture('escape', escape)
49 .capture('slash', slash)
50 .capture('qmark', qmark)
51 .capture('star', star)
52 .capture('plus', plus)
53 .capture('dot', dot)
54
55 /**
56 * Override `text` parser
57 */
58
59 .capture('text', function() {
60 if (this.isInside('bracket')) return;
61 var pos = this.position();
62 var m = this.match(createNotRegex(this.options));
63 if (!m || !m[0]) return;
64
65 // escape regex boundary characters and simple brackets
66 var val = m[0].replace(/([[\]^$])/g, '\\$1');
67
68 return pos({
69 type: 'text',
70 val: val
71 });
72 });
73};
74
75/**
76 * Create text regex
77 */
78
79function textRegex(pattern) {
80 var notStr = regexNot.create(pattern, {contains: true, strictClose: false});
81 var prefix = '(?:[\\^]|\\\\|';
82 return toRegex(prefix + notStr + ')', {strictClose: false});
83}