crystal.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. Language: Crystal
  3. Author: TSUYUSATO Kitsune <[email protected]>
  4. */
  5. function(hljs) {
  6. var NUM_SUFFIX = '(_[uif](8|16|32|64))?';
  7. var CRYSTAL_IDENT_RE = '[a-zA-Z_]\\w*[!?=]?';
  8. var RE_STARTER = '!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|' +
  9. '>>|>|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~';
  10. var CRYSTAL_METHOD_RE = '[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\][=?]?';
  11. var CRYSTAL_KEYWORDS = {
  12. keyword:
  13. 'abstract alias as asm begin break case class def do else elsif end ensure enum extend for fun if ifdef ' +
  14. 'include instance_sizeof is_a? lib macro module next of out pointerof private protected rescue responds_to? ' +
  15. 'return require self sizeof struct super then type typeof union unless until when while with yield ' +
  16. '__DIR__ __FILE__ __LINE__',
  17. literal: 'false nil true'
  18. };
  19. var SUBST = {
  20. className: 'subst',
  21. begin: '#{', end: '}',
  22. keywords: CRYSTAL_KEYWORDS
  23. };
  24. var EXPANSION = {
  25. className: 'template-variable',
  26. variants: [
  27. {begin: '\\{\\{', end: '\\}\\}'},
  28. {begin: '\\{%', end: '%\\}'}
  29. ],
  30. keywords: CRYSTAL_KEYWORDS
  31. };
  32. function recursiveParen(begin, end) {
  33. var
  34. contains = [{begin: begin, end: end}];
  35. contains[0].contains = contains;
  36. return contains;
  37. }
  38. var STRING = {
  39. className: 'string',
  40. contains: [hljs.BACKSLASH_ESCAPE, SUBST],
  41. variants: [
  42. {begin: /'/, end: /'/},
  43. {begin: /"/, end: /"/},
  44. {begin: /`/, end: /`/},
  45. {begin: '%w?\\(', end: '\\)', contains: recursiveParen('\\(', '\\)')},
  46. {begin: '%w?\\[', end: '\\]', contains: recursiveParen('\\[', '\\]')},
  47. {begin: '%w?{', end: '}', contains: recursiveParen('{', '}')},
  48. {begin: '%w?<', end: '>', contains: recursiveParen('<', '>')},
  49. {begin: '%w?/', end: '/'},
  50. {begin: '%w?%', end: '%'},
  51. {begin: '%w?-', end: '-'},
  52. {begin: '%w?\\|', end: '\\|'},
  53. ],
  54. relevance: 0,
  55. };
  56. var REGEXP = {
  57. begin: '(' + RE_STARTER + ')\\s*',
  58. contains: [
  59. {
  60. className: 'regexp',
  61. contains: [hljs.BACKSLASH_ESCAPE, SUBST],
  62. variants: [
  63. {begin: '//[a-z]*', relevance: 0},
  64. {begin: '/', end: '/[a-z]*'},
  65. {begin: '%r\\(', end: '\\)', contains: recursiveParen('\\(', '\\)')},
  66. {begin: '%r\\[', end: '\\]', contains: recursiveParen('\\[', '\\]')},
  67. {begin: '%r{', end: '}', contains: recursiveParen('{', '}')},
  68. {begin: '%r<', end: '>', contains: recursiveParen('<', '>')},
  69. {begin: '%r/', end: '/'},
  70. {begin: '%r%', end: '%'},
  71. {begin: '%r-', end: '-'},
  72. {begin: '%r\\|', end: '\\|'},
  73. ]
  74. }
  75. ],
  76. relevance: 0
  77. };
  78. var REGEXP2 = {
  79. className: 'regexp',
  80. contains: [hljs.BACKSLASH_ESCAPE, SUBST],
  81. variants: [
  82. {begin: '%r\\(', end: '\\)', contains: recursiveParen('\\(', '\\)')},
  83. {begin: '%r\\[', end: '\\]', contains: recursiveParen('\\[', '\\]')},
  84. {begin: '%r{', end: '}', contains: recursiveParen('{', '}')},
  85. {begin: '%r<', end: '>', contains: recursiveParen('<', '>')},
  86. {begin: '%r/', end: '/'},
  87. {begin: '%r%', end: '%'},
  88. {begin: '%r-', end: '-'},
  89. {begin: '%r\\|', end: '\\|'},
  90. ],
  91. relevance: 0
  92. };
  93. var ATTRIBUTE = {
  94. className: 'meta',
  95. begin: '@\\[', end: '\\]',
  96. contains: [
  97. hljs.inherit(hljs.QUOTE_STRING_MODE, {className: 'meta-string'})
  98. ]
  99. };
  100. var CRYSTAL_DEFAULT_CONTAINS = [
  101. EXPANSION,
  102. STRING,
  103. REGEXP,
  104. REGEXP2,
  105. ATTRIBUTE,
  106. hljs.HASH_COMMENT_MODE,
  107. {
  108. className: 'class',
  109. beginKeywords: 'class module struct', end: '$|;',
  110. illegal: /=/,
  111. contains: [
  112. hljs.HASH_COMMENT_MODE,
  113. hljs.inherit(hljs.TITLE_MODE, {begin: '[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?'}),
  114. {begin: '<'} // relevance booster for inheritance
  115. ]
  116. },
  117. {
  118. className: 'class',
  119. beginKeywords: 'lib enum union', end: '$|;',
  120. illegal: /=/,
  121. contains: [
  122. hljs.HASH_COMMENT_MODE,
  123. hljs.inherit(hljs.TITLE_MODE, {begin: '[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?'}),
  124. ],
  125. relevance: 10
  126. },
  127. {
  128. className: 'function',
  129. beginKeywords: 'def', end: /\B\b/,
  130. contains: [
  131. hljs.inherit(hljs.TITLE_MODE, {
  132. begin: CRYSTAL_METHOD_RE,
  133. endsParent: true
  134. })
  135. ]
  136. },
  137. {
  138. className: 'function',
  139. beginKeywords: 'fun macro', end: /\B\b/,
  140. contains: [
  141. hljs.inherit(hljs.TITLE_MODE, {
  142. begin: CRYSTAL_METHOD_RE,
  143. endsParent: true
  144. })
  145. ],
  146. relevance: 5
  147. },
  148. {
  149. className: 'symbol',
  150. begin: hljs.UNDERSCORE_IDENT_RE + '(\\!|\\?)?:',
  151. relevance: 0
  152. },
  153. {
  154. className: 'symbol',
  155. begin: ':',
  156. contains: [STRING, {begin: CRYSTAL_METHOD_RE}],
  157. relevance: 0
  158. },
  159. {
  160. className: 'number',
  161. variants: [
  162. { begin: '\\b0b([01_]*[01])' + NUM_SUFFIX },
  163. { begin: '\\b0o([0-7_]*[0-7])' + NUM_SUFFIX },
  164. { begin: '\\b0x([A-Fa-f0-9_]*[A-Fa-f0-9])' + NUM_SUFFIX },
  165. { begin: '\\b(([0-9][0-9_]*[0-9]|[0-9])(\\.[0-9_]*[0-9])?([eE][+-]?[0-9_]*[0-9])?)' + NUM_SUFFIX}
  166. ],
  167. relevance: 0
  168. }
  169. ];
  170. SUBST.contains = CRYSTAL_DEFAULT_CONTAINS;
  171. EXPANSION.contains = CRYSTAL_DEFAULT_CONTAINS.slice(1); // without EXPANSION
  172. return {
  173. aliases: ['cr'],
  174. lexemes: CRYSTAL_IDENT_RE,
  175. keywords: CRYSTAL_KEYWORDS,
  176. contains: CRYSTAL_DEFAULT_CONTAINS
  177. };
  178. }