84 lines
2.1 KiB
JavaScript
84 lines
2.1 KiB
JavaScript
/**
|
|
* The MIT License (MIT)
|
|
* Copyright (c) 2017-present Dmitry Soshnikov <[email protected]>
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var UPPER_A_CP = 'A'.codePointAt(0);
|
|
var UPPER_Z_CP = 'Z'.codePointAt(0);
|
|
var LOWER_A_CP = 'a'.codePointAt(0);
|
|
var LOWER_Z_CP = 'z'.codePointAt(0);
|
|
var DIGIT_0_CP = '0'.codePointAt(0);
|
|
var DIGIT_9_CP = '9'.codePointAt(0);
|
|
|
|
/**
|
|
* A regexp-tree plugin to transform coded chars into simple chars.
|
|
*
|
|
* \u0061 -> a
|
|
*/
|
|
module.exports = {
|
|
Char: function Char(path) {
|
|
var node = path.node,
|
|
parent = path.parent;
|
|
|
|
if (isNaN(node.codePoint) || node.kind === 'simple') {
|
|
return;
|
|
}
|
|
|
|
if (parent.type === 'ClassRange') {
|
|
if (!isSimpleRange(parent)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (!isPrintableASCIIChar(node.codePoint)) {
|
|
return;
|
|
}
|
|
|
|
var symbol = String.fromCodePoint(node.codePoint);
|
|
var newChar = {
|
|
type: 'Char',
|
|
kind: 'simple',
|
|
value: symbol,
|
|
symbol: symbol,
|
|
codePoint: node.codePoint
|
|
};
|
|
if (needsEscape(symbol, parent.type)) {
|
|
newChar.escaped = true;
|
|
}
|
|
path.replace(newChar);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Checks if a range is included either in 0-9, a-z or A-Z
|
|
* @param classRange
|
|
* @returns {boolean}
|
|
*/
|
|
function isSimpleRange(classRange) {
|
|
var from = classRange.from,
|
|
to = classRange.to;
|
|
|
|
return from.codePoint >= DIGIT_0_CP && from.codePoint <= DIGIT_9_CP && to.codePoint >= DIGIT_0_CP && to.codePoint <= DIGIT_9_CP || from.codePoint >= UPPER_A_CP && from.codePoint <= UPPER_Z_CP && to.codePoint >= UPPER_A_CP && to.codePoint <= UPPER_Z_CP || from.codePoint >= LOWER_A_CP && from.codePoint <= LOWER_Z_CP && to.codePoint >= LOWER_A_CP && to.codePoint <= LOWER_Z_CP;
|
|
}
|
|
|
|
/**
|
|
* Checks if a code point in the range of printable ASCII chars
|
|
* (DEL char excluded)
|
|
* @param codePoint
|
|
* @returns {boolean}
|
|
*/
|
|
function isPrintableASCIIChar(codePoint) {
|
|
return codePoint >= 0x20 && codePoint <= 0x7e;
|
|
}
|
|
|
|
function needsEscape(symbol, parentType) {
|
|
if (parentType === 'ClassRange' || parentType === 'CharacterClass') {
|
|
return (/[\]\\^-]/.test(symbol)
|
|
);
|
|
}
|
|
|
|
return (/[*[()+?^$./\\|{}]/.test(symbol)
|
|
);
|
|
} |