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