ruby.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. Language: Ruby
  3. Description: Ruby is a dynamic, open source programming language with a focus on simplicity and productivity.
  4. Website: https://www.ruby-lang.org/
  5. Author: Anton Kovalyov <anton@kovalyov.net>
  6. Contributors: Peter Leonov <gojpeg@yandex.ru>, Vasily Polovnyov <vast@whiteants.net>, Loren Segal <lsegal@soen.ca>, Pascal Hurni <phi@ruby-reactive.org>, Cedric Sohrauer <sohrauer@googlemail.com>
  7. Category: common
  8. */
  9. function ruby(hljs) {
  10. var RUBY_METHOD_RE = '[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?';
  11. var RUBY_KEYWORDS = {
  12. keyword:
  13. 'and then defined module in return redo if BEGIN retry end for self when ' +
  14. 'next until do begin unless END rescue else break undef not super class case ' +
  15. 'require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor',
  16. literal:
  17. 'true false nil'
  18. };
  19. var YARDOCTAG = {
  20. className: 'doctag',
  21. begin: '@[A-Za-z]+'
  22. };
  23. var IRB_OBJECT = {
  24. begin: '#<', end: '>'
  25. };
  26. var COMMENT_MODES = [
  27. hljs.COMMENT(
  28. '#',
  29. '$',
  30. {
  31. contains: [YARDOCTAG]
  32. }
  33. ),
  34. hljs.COMMENT(
  35. '^\\=begin',
  36. '^\\=end',
  37. {
  38. contains: [YARDOCTAG],
  39. relevance: 10
  40. }
  41. ),
  42. hljs.COMMENT('^__END__', '\\n$')
  43. ];
  44. var SUBST = {
  45. className: 'subst',
  46. begin: '#\\{', end: '}',
  47. keywords: RUBY_KEYWORDS
  48. };
  49. var STRING = {
  50. className: 'string',
  51. contains: [hljs.BACKSLASH_ESCAPE, SUBST],
  52. variants: [
  53. {begin: /'/, end: /'/},
  54. {begin: /"/, end: /"/},
  55. {begin: /`/, end: /`/},
  56. {begin: '%[qQwWx]?\\(', end: '\\)'},
  57. {begin: '%[qQwWx]?\\[', end: '\\]'},
  58. {begin: '%[qQwWx]?{', end: '}'},
  59. {begin: '%[qQwWx]?<', end: '>'},
  60. {begin: '%[qQwWx]?/', end: '/'},
  61. {begin: '%[qQwWx]?%', end: '%'},
  62. {begin: '%[qQwWx]?-', end: '-'},
  63. {begin: '%[qQwWx]?\\|', end: '\\|'},
  64. {
  65. // \B in the beginning suppresses recognition of ?-sequences where ?
  66. // is the last character of a preceding identifier, as in: `func?4`
  67. begin: /\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/
  68. },
  69. { // heredocs
  70. begin: /<<[-~]?'?(\w+)(?:.|\n)*?\n\s*\1\b/,
  71. returnBegin: true,
  72. contains: [
  73. { begin: /<<[-~]?'?/ },
  74. hljs.END_SAME_AS_BEGIN({
  75. begin: /(\w+)/, end: /(\w+)/,
  76. contains: [hljs.BACKSLASH_ESCAPE, SUBST],
  77. })
  78. ]
  79. }
  80. ]
  81. };
  82. var PARAMS = {
  83. className: 'params',
  84. begin: '\\(', end: '\\)', endsParent: true,
  85. keywords: RUBY_KEYWORDS
  86. };
  87. var RUBY_DEFAULT_CONTAINS = [
  88. STRING,
  89. IRB_OBJECT,
  90. {
  91. className: 'class',
  92. beginKeywords: 'class module', end: '$|;',
  93. illegal: /=/,
  94. contains: [
  95. hljs.inherit(hljs.TITLE_MODE, {begin: '[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?'}),
  96. {
  97. begin: '<\\s*',
  98. contains: [{
  99. begin: '(' + hljs.IDENT_RE + '::)?' + hljs.IDENT_RE
  100. }]
  101. }
  102. ].concat(COMMENT_MODES)
  103. },
  104. {
  105. className: 'function',
  106. beginKeywords: 'def', end: '$|;',
  107. contains: [
  108. hljs.inherit(hljs.TITLE_MODE, {begin: RUBY_METHOD_RE}),
  109. PARAMS
  110. ].concat(COMMENT_MODES)
  111. },
  112. {
  113. // swallow namespace qualifiers before symbols
  114. begin: hljs.IDENT_RE + '::'
  115. },
  116. {
  117. className: 'symbol',
  118. begin: hljs.UNDERSCORE_IDENT_RE + '(\\!|\\?)?:',
  119. relevance: 0
  120. },
  121. {
  122. className: 'symbol',
  123. begin: ':(?!\\s)',
  124. contains: [STRING, {begin: RUBY_METHOD_RE}],
  125. relevance: 0
  126. },
  127. {
  128. className: 'number',
  129. begin: '(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b',
  130. relevance: 0
  131. },
  132. {
  133. begin: '(\\$\\W)|((\\$|\\@\\@?)(\\w+))' // variables
  134. },
  135. {
  136. className: 'params',
  137. begin: /\|/, end: /\|/,
  138. keywords: RUBY_KEYWORDS
  139. },
  140. { // regexp container
  141. begin: '(' + hljs.RE_STARTERS_RE + '|unless)\\s*',
  142. keywords: 'unless',
  143. contains: [
  144. IRB_OBJECT,
  145. {
  146. className: 'regexp',
  147. contains: [hljs.BACKSLASH_ESCAPE, SUBST],
  148. illegal: /\n/,
  149. variants: [
  150. {begin: '/', end: '/[a-z]*'},
  151. {begin: '%r{', end: '}[a-z]*'},
  152. {begin: '%r\\(', end: '\\)[a-z]*'},
  153. {begin: '%r!', end: '![a-z]*'},
  154. {begin: '%r\\[', end: '\\][a-z]*'}
  155. ]
  156. }
  157. ].concat(COMMENT_MODES),
  158. relevance: 0
  159. }
  160. ].concat(COMMENT_MODES);
  161. SUBST.contains = RUBY_DEFAULT_CONTAINS;
  162. PARAMS.contains = RUBY_DEFAULT_CONTAINS;
  163. var SIMPLE_PROMPT = "[>?]>";
  164. var DEFAULT_PROMPT = "[\\w#]+\\(\\w+\\):\\d+:\\d+>";
  165. var RVM_PROMPT = "(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>";
  166. var IRB_DEFAULT = [
  167. {
  168. begin: /^\s*=>/,
  169. starts: {
  170. end: '$', contains: RUBY_DEFAULT_CONTAINS
  171. }
  172. },
  173. {
  174. className: 'meta',
  175. begin: '^('+SIMPLE_PROMPT+"|"+DEFAULT_PROMPT+'|'+RVM_PROMPT+')',
  176. starts: {
  177. end: '$', contains: RUBY_DEFAULT_CONTAINS
  178. }
  179. }
  180. ];
  181. return {
  182. name: 'Ruby',
  183. aliases: ['rb', 'gemspec', 'podspec', 'thor', 'irb'],
  184. keywords: RUBY_KEYWORDS,
  185. illegal: /\/\*/,
  186. contains: COMMENT_MODES.concat(IRB_DEFAULT).concat(RUBY_DEFAULT_CONTAINS)
  187. };
  188. }
  189. module.exports = ruby;