Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F102874247
parsers.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Tue, Feb 25, 02:25
Size
7 KB
Mime Type
text/x-Algol68
Expires
Thu, Feb 27, 02:25 (1 d, 20 h)
Engine
blob
Format
Raw Data
Handle
24446572
Attached To
R8244 Eawag_Swing_Weight_Elicitation
parsers.js
View Options
'use strict';
var regexNot = require('regex-not');
var toRegex = require('to-regex');
/**
* Characters to use in negation regex (we want to "not" match
* characters that are matched by other parsers)
*/
var cached;
var NOT_REGEX = '[\\[!*+?$^"\'.\\\\/]+';
var not = createTextRegex(NOT_REGEX);
/**
* Nanomatch parsers
*/
module.exports = function(nanomatch, options) {
var parser = nanomatch.parser;
var opts = parser.options;
parser.state = {
slashes: 0,
paths: []
};
parser.ast.state = parser.state;
parser
/**
* Beginning-of-string
*/
.capture('prefix', function() {
if (this.parsed) return;
var m = this.match(/^\.[\\/]/);
if (!m) return;
this.state.strictOpen = !!this.options.strictOpen;
this.state.addPrefix = true;
})
/**
* Escape: "\\."
*/
.capture('escape', function() {
if (this.isInside('bracket')) return;
var pos = this.position();
var m = this.match(/^(?:\\(.)|([$^]))/);
if (!m) return;
return pos({
type: 'escape',
val: m[2] || m[1]
});
})
/**
* Quoted strings
*/
.capture('quoted', function() {
var pos = this.position();
var m = this.match(/^["']/);
if (!m) return;
var quote = m[0];
if (this.input.indexOf(quote) === -1) {
return pos({
type: 'escape',
val: quote
});
}
var tok = advanceTo(this.input, quote);
this.consume(tok.len);
return pos({
type: 'quoted',
val: tok.esc
});
})
/**
* Negations: "!"
*/
.capture('not', function() {
var parsed = this.parsed;
var pos = this.position();
var m = this.match(this.notRegex || /^!+/);
if (!m) return;
var val = m[0];
var isNegated = (val.length % 2) === 1;
if (parsed === '' && !isNegated) {
val = '';
}
// if nothing has been parsed, we know `!` is at the start,
// so we need to wrap the result in a negation regex
if (parsed === '' && isNegated && this.options.nonegate !== true) {
this.bos.val = '(?!^(?:';
this.append = ')$).*';
val = '';
}
return pos({
type: 'not',
val: val
});
})
/**
* Dot: "."
*/
.capture('dot', function() {
var parsed = this.parsed;
var pos = this.position();
var m = this.match(/^\.+/);
if (!m) return;
var val = m[0];
this.state.dot = val === '.' && (parsed === '' || parsed.slice(-1) === '/');
return pos({
type: 'dot',
dotfiles: this.state.dot,
val: val
});
})
/**
* Plus: "+"
*/
.capture('plus', /^\+(?!\()/)
/**
* Question mark: "?"
*/
.capture('qmark', function() {
var parsed = this.parsed;
var pos = this.position();
var m = this.match(/^\?+(?!\()/);
if (!m) return;
this.state.metachar = true;
this.state.qmark = true;
return pos({
type: 'qmark',
parsed: parsed,
val: m[0]
});
})
/**
* Globstar: "**"
*/
.capture('globstar', function() {
var parsed = this.parsed;
var pos = this.position();
var m = this.match(/^\*{2}(?![*(])(?=[,)/]|$)/);
if (!m) return;
var type = opts.noglobstar !== true ? 'globstar' : 'star';
var node = pos({type: type, parsed: parsed});
this.state.metachar = true;
while (this.input.slice(0, 4) === '/**/') {
this.input = this.input.slice(3);
}
node.isInside = {
brace: this.isInside('brace'),
paren: this.isInside('paren')
};
if (type === 'globstar') {
this.state.globstar = true;
node.val = '**';
} else {
this.state.star = true;
node.val = '*';
}
return node;
})
/**
* Star: "*"
*/
.capture('star', function() {
var pos = this.position();
var starRe = /^(?:\*(?![*(])|[*]{3,}(?!\()|[*]{2}(?![(/]|$)|\*(?=\*\())/;
var m = this.match(starRe);
if (!m) return;
this.state.metachar = true;
this.state.star = true;
return pos({
type: 'star',
val: m[0]
});
})
/**
* Slash: "/"
*/
.capture('slash', function() {
var pos = this.position();
var m = this.match(/^\//);
if (!m) return;
this.state.slashes++;
return pos({
type: 'slash',
val: m[0]
});
})
/**
* Backslash: "\\"
*/
.capture('backslash', function() {
var pos = this.position();
var m = this.match(/^\\(?![*+?(){}[\]'"])/);
if (!m) return;
var val = m[0];
if (this.isInside('bracket')) {
val = '\\';
} else if (val.length > 1) {
val = '\\\\';
}
return pos({
type: 'backslash',
val: val
});
})
/**
* Square: "[.]"
*/
.capture('square', function() {
if (this.isInside('bracket')) return;
var pos = this.position();
var m = this.match(/^\[([^!^\\])\]/);
if (!m) return;
return pos({
type: 'square',
val: m[1]
});
})
/**
* Brackets: "[...]" (basic, this can be overridden by other parsers)
*/
.capture('bracket', function() {
var pos = this.position();
var m = this.match(/^(?:\[([!^]?)([^\]]+|\]-)(\]|[^*+?]+)|\[)/);
if (!m) return;
var val = m[0];
var negated = m[1] ? '^' : '';
var inner = (m[2] || '').replace(/\\\\+/, '\\\\');
var close = m[3] || '';
if (m[2] && inner.length < m[2].length) {
val = val.replace(/\\\\+/, '\\\\');
}
var esc = this.input.slice(0, 2);
if (inner === '' && esc === '\\]') {
inner += esc;
this.consume(2);
var str = this.input;
var idx = -1;
var ch;
while ((ch = str[++idx])) {
this.consume(1);
if (ch === ']') {
close = ch;
break;
}
inner += ch;
}
}
return pos({
type: 'bracket',
val: val,
escaped: close !== ']',
negated: negated,
inner: inner,
close: close
});
})
/**
* Text
*/
.capture('text', function() {
if (this.isInside('bracket')) return;
var pos = this.position();
var m = this.match(not);
if (!m || !m[0]) return;
return pos({
type: 'text',
val: m[0]
});
});
/**
* Allow custom parsers to be passed on options
*/
if (options && typeof options.parsers === 'function') {
options.parsers(nanomatch.parser);
}
};
/**
* Advance to the next non-escaped character
*/
function advanceTo(input, endChar) {
var ch = input.charAt(0);
var tok = { len: 1, val: '', esc: '' };
var idx = 0;
function advance() {
if (ch !== '\\') {
tok.esc += '\\' + ch;
tok.val += ch;
}
ch = input.charAt(++idx);
tok.len++;
if (ch === '\\') {
advance();
advance();
}
}
while (ch && ch !== endChar) {
advance();
}
return tok;
}
/**
* Create text regex
*/
function createTextRegex(pattern) {
if (cached) return cached;
var opts = {contains: true, strictClose: false};
var not = regexNot.create(pattern, opts);
var re = toRegex('^(?:[*]\\((?=.)|' + not + ')', opts);
return (cached = re);
}
/**
* Expose negation string
*/
module.exports.not = NOT_REGEX;
Event Timeline
Log In to Comment