char-code-to-simple-char-transform.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /**
  2. * The MIT License (MIT)
  3. * Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
  4. */
  5. 'use strict';
  6. var UPPER_A_CP = 'A'.codePointAt(0);
  7. var UPPER_Z_CP = 'Z'.codePointAt(0);
  8. var LOWER_A_CP = 'a'.codePointAt(0);
  9. var LOWER_Z_CP = 'z'.codePointAt(0);
  10. var DIGIT_0_CP = '0'.codePointAt(0);
  11. var DIGIT_9_CP = '9'.codePointAt(0);
  12. /**
  13. * A regexp-tree plugin to transform coded chars into simple chars.
  14. *
  15. * \u0061 -> a
  16. */
  17. module.exports = {
  18. Char: function Char(path) {
  19. var node = path.node,
  20. parent = path.parent;
  21. if (isNaN(node.codePoint) || node.kind === 'simple') {
  22. return;
  23. }
  24. if (parent.type === 'ClassRange') {
  25. if (!isSimpleRange(parent)) {
  26. return;
  27. }
  28. }
  29. if (!isPrintableASCIIChar(node.codePoint)) {
  30. return;
  31. }
  32. var symbol = String.fromCodePoint(node.codePoint);
  33. var newChar = {
  34. type: 'Char',
  35. kind: 'simple',
  36. value: symbol,
  37. symbol: symbol,
  38. codePoint: node.codePoint
  39. };
  40. if (needsEscape(symbol, parent.type)) {
  41. newChar.escaped = true;
  42. }
  43. path.replace(newChar);
  44. }
  45. };
  46. /**
  47. * Checks if a range is included either in 0-9, a-z or A-Z
  48. * @param classRange
  49. * @returns {boolean}
  50. */
  51. function isSimpleRange(classRange) {
  52. var from = classRange.from,
  53. to = classRange.to;
  54. 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;
  55. }
  56. /**
  57. * Checks if a code point in the range of printable ASCII chars
  58. * (DEL char excluded)
  59. * @param codePoint
  60. * @returns {boolean}
  61. */
  62. function isPrintableASCIIChar(codePoint) {
  63. return codePoint >= 0x20 && codePoint <= 0x7e;
  64. }
  65. function needsEscape(symbol, parentType) {
  66. if (parentType === 'ClassRange' || parentType === 'CharacterClass') {
  67. return (/[\]\\^-]/.test(symbol)
  68. );
  69. }
  70. return (/[*[()+?^$./\\|{}]/.test(symbol)
  71. );
  72. }