prism-racket.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. Prism.languages.racket = Prism.languages.extend('scheme', {
  2. 'lambda-parameter': {
  3. // the racket lambda syntax is a lot more complex, so we won't even attempt to capture it.
  4. // this will just prevent false positives of the `function` pattern
  5. pattern: /(\(lambda\s+\()[^()'\s]+/,
  6. lookbehind: true
  7. }
  8. });
  9. // Add brackets to racket
  10. // The basic idea here is to go through all pattens of Scheme and replace all occurrences of "(" with the union of "("
  11. // and "["; Similar for ")". This is a bit tricky because "(" can be escaped or inside a character set. Both cases
  12. // have to be handled differently and, of course, we don't want to destroy groups, so we can only replace literal "("
  13. // and ")".
  14. // To do this, we use a regular expression which will parse any JS regular expression. It works because regexes are
  15. // matches from left to right and already matched text cannot be matched again. We use this to first capture all
  16. // escaped characters (not really, we don't get escape sequences but we don't need them). Because we already captured
  17. // all escaped characters, we know that any "[" character is the start of a character set, so we match that character
  18. // set whole.
  19. // With the regex parsed, we only have to replace all escaped "(" (they cannot be unescaped outside of character sets)
  20. // with /[([]/ and replace all "(" inside character sets.
  21. // Note: This method does not work for "(" that are escaped like this /\x28/ or this /\u0028/.
  22. Prism.languages.DFS(Prism.languages.racket, function (key, value) {
  23. if (Prism.util.type(value) === 'RegExp') {
  24. var source = value.source.replace(/\\(.)|\[\^?((?:\\.|[^\\\]])*)\]/g, function (m, g1, g2) {
  25. if (g1) {
  26. if (g1 === '(') {
  27. // replace all '(' characters outside character sets
  28. return '[([]';
  29. }
  30. if (g1 === ')') {
  31. // replace all ')' characters outside character sets
  32. return '[)\\]]';
  33. }
  34. }
  35. if (g2) {
  36. var prefix = m[1] === '^' ? '[^' : '[';
  37. return prefix + g2.replace(/\\(.)|[()]/g, function (m, g1) {
  38. if (m === '(' || g1 === '(') {
  39. // replace all '(' characters inside character sets
  40. return '([';
  41. }
  42. if (m === ')' || g1 === ')') {
  43. // replace all ')' characters inside character sets
  44. return ')\\]';
  45. }
  46. return m;
  47. }) + ']';
  48. }
  49. return m;
  50. });
  51. this[key] = RegExp(source, value.flags);
  52. }
  53. });
  54. Prism.languages.insertBefore('racket', 'string', {
  55. 'lang': {
  56. pattern: /^#lang.+/m,
  57. greedy: true,
  58. alias: 'keyword'
  59. }
  60. });
  61. Prism.languages.rkt = Prism.languages.racket;