compilers.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. 'use strict';
  2. var posix = require('posix-character-classes');
  3. module.exports = function(brackets) {
  4. brackets.compiler
  5. /**
  6. * Escaped characters
  7. */
  8. .set('escape', function(node) {
  9. return this.emit('\\' + node.val.replace(/^\\/, ''), node);
  10. })
  11. /**
  12. * Text
  13. */
  14. .set('text', function(node) {
  15. return this.emit(node.val.replace(/([{}])/g, '\\$1'), node);
  16. })
  17. /**
  18. * POSIX character classes
  19. */
  20. .set('posix', function(node) {
  21. if (node.val === '[::]') {
  22. return this.emit('\\[::\\]', node);
  23. }
  24. var val = posix[node.inner];
  25. if (typeof val === 'undefined') {
  26. val = '[' + node.inner + ']';
  27. }
  28. return this.emit(val, node);
  29. })
  30. /**
  31. * Non-posix brackets
  32. */
  33. .set('bracket', function(node) {
  34. return this.mapVisit(node.nodes);
  35. })
  36. .set('bracket.open', function(node) {
  37. return this.emit(node.val, node);
  38. })
  39. .set('bracket.inner', function(node) {
  40. var inner = node.val;
  41. if (inner === '[' || inner === ']') {
  42. return this.emit('\\' + node.val, node);
  43. }
  44. if (inner === '^]') {
  45. return this.emit('^\\]', node);
  46. }
  47. if (inner === '^') {
  48. return this.emit('^', node);
  49. }
  50. if (/-/.test(inner) && !/(\d-\d|\w-\w)/.test(inner)) {
  51. inner = inner.split('-').join('\\-');
  52. }
  53. var isNegated = inner.charAt(0) === '^';
  54. // add slashes to negated brackets, per spec
  55. if (isNegated && inner.indexOf('/') === -1) {
  56. inner += '/';
  57. }
  58. if (isNegated && inner.indexOf('.') === -1) {
  59. inner += '.';
  60. }
  61. // don't unescape `0` (octal literal)
  62. inner = inner.replace(/\\([1-9])/g, '$1');
  63. return this.emit(inner, node);
  64. })
  65. .set('bracket.close', function(node) {
  66. var val = node.val.replace(/^\\/, '');
  67. if (node.parent.escaped === true) {
  68. return this.emit('\\' + val, node);
  69. }
  70. return this.emit(val, node);
  71. });
  72. };