fix
This commit is contained in:
448
book/node_modules/highlight.js/lib/languages/ruby.js
generated
vendored
Normal file
448
book/node_modules/highlight.js/lib/languages/ruby.js
generated
vendored
Normal file
@ -0,0 +1,448 @@
|
||||
/*
|
||||
Language: Ruby
|
||||
Description: Ruby is a dynamic, open source programming language with a focus on simplicity and productivity.
|
||||
Website: https://www.ruby-lang.org/
|
||||
Author: Anton Kovalyov <anton@kovalyov.net>
|
||||
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>
|
||||
Category: common, scripting
|
||||
*/
|
||||
|
||||
function ruby(hljs) {
|
||||
const regex = hljs.regex;
|
||||
const RUBY_METHOD_RE = '([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)';
|
||||
// TODO: move concepts like CAMEL_CASE into `modes.js`
|
||||
const CLASS_NAME_RE = regex.either(
|
||||
/\b([A-Z]+[a-z0-9]+)+/,
|
||||
// ends in caps
|
||||
/\b([A-Z]+[a-z0-9]+)+[A-Z]+/,
|
||||
)
|
||||
;
|
||||
const CLASS_NAME_WITH_NAMESPACE_RE = regex.concat(CLASS_NAME_RE, /(::\w+)*/);
|
||||
// very popular ruby built-ins that one might even assume
|
||||
// are actual keywords (despite that not being the case)
|
||||
const PSEUDO_KWS = [
|
||||
"include",
|
||||
"extend",
|
||||
"prepend",
|
||||
"public",
|
||||
"private",
|
||||
"protected",
|
||||
"raise",
|
||||
"throw"
|
||||
];
|
||||
const RUBY_KEYWORDS = {
|
||||
"variable.constant": [
|
||||
"__FILE__",
|
||||
"__LINE__",
|
||||
"__ENCODING__"
|
||||
],
|
||||
"variable.language": [
|
||||
"self",
|
||||
"super",
|
||||
],
|
||||
keyword: [
|
||||
"alias",
|
||||
"and",
|
||||
"begin",
|
||||
"BEGIN",
|
||||
"break",
|
||||
"case",
|
||||
"class",
|
||||
"defined",
|
||||
"do",
|
||||
"else",
|
||||
"elsif",
|
||||
"end",
|
||||
"END",
|
||||
"ensure",
|
||||
"for",
|
||||
"if",
|
||||
"in",
|
||||
"module",
|
||||
"next",
|
||||
"not",
|
||||
"or",
|
||||
"redo",
|
||||
"require",
|
||||
"rescue",
|
||||
"retry",
|
||||
"return",
|
||||
"then",
|
||||
"undef",
|
||||
"unless",
|
||||
"until",
|
||||
"when",
|
||||
"while",
|
||||
"yield",
|
||||
...PSEUDO_KWS
|
||||
],
|
||||
built_in: [
|
||||
"proc",
|
||||
"lambda",
|
||||
"attr_accessor",
|
||||
"attr_reader",
|
||||
"attr_writer",
|
||||
"define_method",
|
||||
"private_constant",
|
||||
"module_function"
|
||||
],
|
||||
literal: [
|
||||
"true",
|
||||
"false",
|
||||
"nil"
|
||||
]
|
||||
};
|
||||
const YARDOCTAG = {
|
||||
className: 'doctag',
|
||||
begin: '@[A-Za-z]+'
|
||||
};
|
||||
const IRB_OBJECT = {
|
||||
begin: '#<',
|
||||
end: '>'
|
||||
};
|
||||
const COMMENT_MODES = [
|
||||
hljs.COMMENT(
|
||||
'#',
|
||||
'$',
|
||||
{ contains: [ YARDOCTAG ] }
|
||||
),
|
||||
hljs.COMMENT(
|
||||
'^=begin',
|
||||
'^=end',
|
||||
{
|
||||
contains: [ YARDOCTAG ],
|
||||
relevance: 10
|
||||
}
|
||||
),
|
||||
hljs.COMMENT('^__END__', hljs.MATCH_NOTHING_RE)
|
||||
];
|
||||
const SUBST = {
|
||||
className: 'subst',
|
||||
begin: /#\{/,
|
||||
end: /\}/,
|
||||
keywords: RUBY_KEYWORDS
|
||||
};
|
||||
const STRING = {
|
||||
className: 'string',
|
||||
contains: [
|
||||
hljs.BACKSLASH_ESCAPE,
|
||||
SUBST
|
||||
],
|
||||
variants: [
|
||||
{
|
||||
begin: /'/,
|
||||
end: /'/
|
||||
},
|
||||
{
|
||||
begin: /"/,
|
||||
end: /"/
|
||||
},
|
||||
{
|
||||
begin: /`/,
|
||||
end: /`/
|
||||
},
|
||||
{
|
||||
begin: /%[qQwWx]?\(/,
|
||||
end: /\)/
|
||||
},
|
||||
{
|
||||
begin: /%[qQwWx]?\[/,
|
||||
end: /\]/
|
||||
},
|
||||
{
|
||||
begin: /%[qQwWx]?\{/,
|
||||
end: /\}/
|
||||
},
|
||||
{
|
||||
begin: /%[qQwWx]?</,
|
||||
end: />/
|
||||
},
|
||||
{
|
||||
begin: /%[qQwWx]?\//,
|
||||
end: /\//
|
||||
},
|
||||
{
|
||||
begin: /%[qQwWx]?%/,
|
||||
end: /%/
|
||||
},
|
||||
{
|
||||
begin: /%[qQwWx]?-/,
|
||||
end: /-/
|
||||
},
|
||||
{
|
||||
begin: /%[qQwWx]?\|/,
|
||||
end: /\|/
|
||||
},
|
||||
// in the following expressions, \B in the beginning suppresses recognition of ?-sequences
|
||||
// where ? is the last character of a preceding identifier, as in: `func?4`
|
||||
{ begin: /\B\?(\\\d{1,3})/ },
|
||||
{ begin: /\B\?(\\x[A-Fa-f0-9]{1,2})/ },
|
||||
{ begin: /\B\?(\\u\{?[A-Fa-f0-9]{1,6}\}?)/ },
|
||||
{ begin: /\B\?(\\M-\\C-|\\M-\\c|\\c\\M-|\\M-|\\C-\\M-)[\x20-\x7e]/ },
|
||||
{ begin: /\B\?\\(c|C-)[\x20-\x7e]/ },
|
||||
{ begin: /\B\?\\?\S/ },
|
||||
// heredocs
|
||||
{
|
||||
// this guard makes sure that we have an entire heredoc and not a false
|
||||
// positive (auto-detect, etc.)
|
||||
begin: regex.concat(
|
||||
/<<[-~]?'?/,
|
||||
regex.lookahead(/(\w+)(?=\W)[^\n]*\n(?:[^\n]*\n)*?\s*\1\b/)
|
||||
),
|
||||
contains: [
|
||||
hljs.END_SAME_AS_BEGIN({
|
||||
begin: /(\w+)/,
|
||||
end: /(\w+)/,
|
||||
contains: [
|
||||
hljs.BACKSLASH_ESCAPE,
|
||||
SUBST
|
||||
]
|
||||
})
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// Ruby syntax is underdocumented, but this grammar seems to be accurate
|
||||
// as of version 2.7.2 (confirmed with (irb and `Ripper.sexp(...)`)
|
||||
// https://docs.ruby-lang.org/en/2.7.0/doc/syntax/literals_rdoc.html#label-Numbers
|
||||
const decimal = '[1-9](_?[0-9])*|0';
|
||||
const digits = '[0-9](_?[0-9])*';
|
||||
const NUMBER = {
|
||||
className: 'number',
|
||||
relevance: 0,
|
||||
variants: [
|
||||
// decimal integer/float, optionally exponential or rational, optionally imaginary
|
||||
{ begin: `\\b(${decimal})(\\.(${digits}))?([eE][+-]?(${digits})|r)?i?\\b` },
|
||||
|
||||
// explicit decimal/binary/octal/hexadecimal integer,
|
||||
// optionally rational and/or imaginary
|
||||
{ begin: "\\b0[dD][0-9](_?[0-9])*r?i?\\b" },
|
||||
{ begin: "\\b0[bB][0-1](_?[0-1])*r?i?\\b" },
|
||||
{ begin: "\\b0[oO][0-7](_?[0-7])*r?i?\\b" },
|
||||
{ begin: "\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\b" },
|
||||
|
||||
// 0-prefixed implicit octal integer, optionally rational and/or imaginary
|
||||
{ begin: "\\b0(_?[0-7])+r?i?\\b" }
|
||||
]
|
||||
};
|
||||
|
||||
const PARAMS = {
|
||||
variants: [
|
||||
{
|
||||
match: /\(\)/,
|
||||
},
|
||||
{
|
||||
className: 'params',
|
||||
begin: /\(/,
|
||||
end: /(?=\))/,
|
||||
excludeBegin: true,
|
||||
endsParent: true,
|
||||
keywords: RUBY_KEYWORDS,
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const INCLUDE_EXTEND = {
|
||||
match: [
|
||||
/(include|extend)\s+/,
|
||||
CLASS_NAME_WITH_NAMESPACE_RE
|
||||
],
|
||||
scope: {
|
||||
2: "title.class"
|
||||
},
|
||||
keywords: RUBY_KEYWORDS
|
||||
};
|
||||
|
||||
const CLASS_DEFINITION = {
|
||||
variants: [
|
||||
{
|
||||
match: [
|
||||
/class\s+/,
|
||||
CLASS_NAME_WITH_NAMESPACE_RE,
|
||||
/\s+<\s+/,
|
||||
CLASS_NAME_WITH_NAMESPACE_RE
|
||||
]
|
||||
},
|
||||
{
|
||||
match: [
|
||||
/\b(class|module)\s+/,
|
||||
CLASS_NAME_WITH_NAMESPACE_RE
|
||||
]
|
||||
}
|
||||
],
|
||||
scope: {
|
||||
2: "title.class",
|
||||
4: "title.class.inherited"
|
||||
},
|
||||
keywords: RUBY_KEYWORDS
|
||||
};
|
||||
|
||||
const UPPER_CASE_CONSTANT = {
|
||||
relevance: 0,
|
||||
match: /\b[A-Z][A-Z_0-9]+\b/,
|
||||
className: "variable.constant"
|
||||
};
|
||||
|
||||
const METHOD_DEFINITION = {
|
||||
match: [
|
||||
/def/, /\s+/,
|
||||
RUBY_METHOD_RE
|
||||
],
|
||||
scope: {
|
||||
1: "keyword",
|
||||
3: "title.function"
|
||||
},
|
||||
contains: [
|
||||
PARAMS
|
||||
]
|
||||
};
|
||||
|
||||
const OBJECT_CREATION = {
|
||||
relevance: 0,
|
||||
match: [
|
||||
CLASS_NAME_WITH_NAMESPACE_RE,
|
||||
/\.new[. (]/
|
||||
],
|
||||
scope: {
|
||||
1: "title.class"
|
||||
}
|
||||
};
|
||||
|
||||
// CamelCase
|
||||
const CLASS_REFERENCE = {
|
||||
relevance: 0,
|
||||
match: CLASS_NAME_RE,
|
||||
scope: "title.class"
|
||||
};
|
||||
|
||||
const RUBY_DEFAULT_CONTAINS = [
|
||||
STRING,
|
||||
CLASS_DEFINITION,
|
||||
INCLUDE_EXTEND,
|
||||
OBJECT_CREATION,
|
||||
UPPER_CASE_CONSTANT,
|
||||
CLASS_REFERENCE,
|
||||
METHOD_DEFINITION,
|
||||
{
|
||||
// swallow namespace qualifiers before symbols
|
||||
begin: hljs.IDENT_RE + '::' },
|
||||
{
|
||||
className: 'symbol',
|
||||
begin: hljs.UNDERSCORE_IDENT_RE + '(!|\\?)?:',
|
||||
relevance: 0
|
||||
},
|
||||
{
|
||||
className: 'symbol',
|
||||
begin: ':(?!\\s)',
|
||||
contains: [
|
||||
STRING,
|
||||
{ begin: RUBY_METHOD_RE }
|
||||
],
|
||||
relevance: 0
|
||||
},
|
||||
NUMBER,
|
||||
{
|
||||
// negative-look forward attempts to prevent false matches like:
|
||||
// @ident@ or $ident$ that might indicate this is not ruby at all
|
||||
className: "variable",
|
||||
begin: '(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])' + `(?![A-Za-z])(?![@$?'])`
|
||||
},
|
||||
{
|
||||
className: 'params',
|
||||
begin: /\|(?!=)/,
|
||||
end: /\|/,
|
||||
excludeBegin: true,
|
||||
excludeEnd: true,
|
||||
relevance: 0, // this could be a lot of things (in other languages) other than params
|
||||
keywords: RUBY_KEYWORDS
|
||||
},
|
||||
{ // regexp container
|
||||
begin: '(' + hljs.RE_STARTERS_RE + '|unless)\\s*',
|
||||
keywords: 'unless',
|
||||
contains: [
|
||||
{
|
||||
className: 'regexp',
|
||||
contains: [
|
||||
hljs.BACKSLASH_ESCAPE,
|
||||
SUBST
|
||||
],
|
||||
illegal: /\n/,
|
||||
variants: [
|
||||
{
|
||||
begin: '/',
|
||||
end: '/[a-z]*'
|
||||
},
|
||||
{
|
||||
begin: /%r\{/,
|
||||
end: /\}[a-z]*/
|
||||
},
|
||||
{
|
||||
begin: '%r\\(',
|
||||
end: '\\)[a-z]*'
|
||||
},
|
||||
{
|
||||
begin: '%r!',
|
||||
end: '![a-z]*'
|
||||
},
|
||||
{
|
||||
begin: '%r\\[',
|
||||
end: '\\][a-z]*'
|
||||
}
|
||||
]
|
||||
}
|
||||
].concat(IRB_OBJECT, COMMENT_MODES),
|
||||
relevance: 0
|
||||
}
|
||||
].concat(IRB_OBJECT, COMMENT_MODES);
|
||||
|
||||
SUBST.contains = RUBY_DEFAULT_CONTAINS;
|
||||
PARAMS.contains = RUBY_DEFAULT_CONTAINS;
|
||||
|
||||
// >>
|
||||
// ?>
|
||||
const SIMPLE_PROMPT = "[>?]>";
|
||||
// irb(main):001:0>
|
||||
const DEFAULT_PROMPT = "[\\w#]+\\(\\w+\\):\\d+:\\d+[>*]";
|
||||
const RVM_PROMPT = "(\\w+-)?\\d+\\.\\d+\\.\\d+(p\\d+)?[^\\d][^>]+>";
|
||||
|
||||
const IRB_DEFAULT = [
|
||||
{
|
||||
begin: /^\s*=>/,
|
||||
starts: {
|
||||
end: '$',
|
||||
contains: RUBY_DEFAULT_CONTAINS
|
||||
}
|
||||
},
|
||||
{
|
||||
className: 'meta.prompt',
|
||||
begin: '^(' + SIMPLE_PROMPT + "|" + DEFAULT_PROMPT + '|' + RVM_PROMPT + ')(?=[ ])',
|
||||
starts: {
|
||||
end: '$',
|
||||
keywords: RUBY_KEYWORDS,
|
||||
contains: RUBY_DEFAULT_CONTAINS
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
COMMENT_MODES.unshift(IRB_OBJECT);
|
||||
|
||||
return {
|
||||
name: 'Ruby',
|
||||
aliases: [
|
||||
'rb',
|
||||
'gemspec',
|
||||
'podspec',
|
||||
'thor',
|
||||
'irb'
|
||||
],
|
||||
keywords: RUBY_KEYWORDS,
|
||||
illegal: /\/\*/,
|
||||
contains: [ hljs.SHEBANG({ binary: "ruby" }) ]
|
||||
.concat(IRB_DEFAULT)
|
||||
.concat(COMMENT_MODES)
|
||||
.concat(RUBY_DEFAULT_CONTAINS)
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = ruby;
|
Reference in New Issue
Block a user