]> luflow.net public git repositories - flow-web.git/blob - static/highlight/languages/r.js
Initial commit.
[flow-web.git] / static / highlight / languages / r.js
1 /*! `r` grammar compiled for Highlight.js 11.11.1 */
2 (function(){
3 var hljsGrammar = (function () {
4 'use strict';
5
6 /*
7 Language: R
8 Description: R is a free software environment for statistical computing and graphics.
9 Author: Joe Cheng <joe@rstudio.org>
10 Contributors: Konrad Rudolph <konrad.rudolph@gmail.com>
11 Website: https://www.r-project.org
12 Category: common,scientific
13 */
14
15 /** @type LanguageFn */
16 function r(hljs) {
17 const regex = hljs.regex;
18 // Identifiers in R cannot start with `_`, but they can start with `.` if it
19 // is not immediately followed by a digit.
20 // R also supports quoted identifiers, which are near-arbitrary sequences
21 // delimited by backticks (`…`), which may contain escape sequences. These are
22 // handled in a separate mode. See `test/markup/r/names.txt` for examples.
23 // FIXME: Support Unicode identifiers.
24 const IDENT_RE = /(?:(?:[a-zA-Z]|\.[._a-zA-Z])[._a-zA-Z0-9]*)|\.(?!\d)/;
25 const NUMBER_TYPES_RE = regex.either(
26 // Special case: only hexadecimal binary powers can contain fractions
27 /0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*[pP][+-]?\d+i?/,
28 // Hexadecimal numbers without fraction and optional binary power
29 /0[xX][0-9a-fA-F]+(?:[pP][+-]?\d+)?[Li]?/,
30 // Decimal numbers
31 /(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?[Li]?/
32 );
33 const OPERATORS_RE = /[=!<>:]=|\|\||&&|:::?|<-|<<-|->>|->|\|>|[-+*\/?!$&|:<=>@^~]|\*\*/;
34 const PUNCTUATION_RE = regex.either(
35 /[()]/,
36 /[{}]/,
37 /\[\[/,
38 /[[\]]/,
39 /\\/,
40 /,/
41 );
42
43 return {
44 name: 'R',
45
46 keywords: {
47 $pattern: IDENT_RE,
48 keyword:
49 'function if in break next repeat else for while',
50 literal:
51 'NULL NA TRUE FALSE Inf NaN NA_integer_|10 NA_real_|10 '
52 + 'NA_character_|10 NA_complex_|10',
53 built_in:
54 // Builtin constants
55 'LETTERS letters month.abb month.name pi T F '
56 // Primitive functions
57 // These are all the functions in `base` that are implemented as a
58 // `.Primitive`, minus those functions that are also keywords.
59 + 'abs acos acosh all any anyNA Arg as.call as.character '
60 + 'as.complex as.double as.environment as.integer as.logical '
61 + 'as.null.default as.numeric as.raw asin asinh atan atanh attr '
62 + 'attributes baseenv browser c call ceiling class Conj cos cosh '
63 + 'cospi cummax cummin cumprod cumsum digamma dim dimnames '
64 + 'emptyenv exp expression floor forceAndCall gamma gc.time '
65 + 'globalenv Im interactive invisible is.array is.atomic is.call '
66 + 'is.character is.complex is.double is.environment is.expression '
67 + 'is.finite is.function is.infinite is.integer is.language '
68 + 'is.list is.logical is.matrix is.na is.name is.nan is.null '
69 + 'is.numeric is.object is.pairlist is.raw is.recursive is.single '
70 + 'is.symbol lazyLoadDBfetch length lgamma list log max min '
71 + 'missing Mod names nargs nzchar oldClass on.exit pos.to.env '
72 + 'proc.time prod quote range Re rep retracemem return round '
73 + 'seq_along seq_len seq.int sign signif sin sinh sinpi sqrt '
74 + 'standardGeneric substitute sum switch tan tanh tanpi tracemem '
75 + 'trigamma trunc unclass untracemem UseMethod xtfrm',
76 },
77
78 contains: [
79 // Roxygen comments
80 hljs.COMMENT(
81 /#'/,
82 /$/,
83 { contains: [
84 {
85 // Handle `@examples` separately to cause all subsequent code
86 // until the next `@`-tag on its own line to be kept as-is,
87 // preventing highlighting. This code is example R code, so nested
88 // doctags shouldn’t be treated as such. See
89 // `test/markup/r/roxygen.txt` for an example.
90 scope: 'doctag',
91 match: /@examples/,
92 starts: {
93 end: regex.lookahead(regex.either(
94 // end if another doc comment
95 /\n^#'\s*(?=@[a-zA-Z]+)/,
96 // or a line with no comment
97 /\n^(?!#')/
98 )),
99 endsParent: true
100 }
101 },
102 {
103 // Handle `@param` to highlight the parameter name following
104 // after.
105 scope: 'doctag',
106 begin: '@param',
107 end: /$/,
108 contains: [
109 {
110 scope: 'variable',
111 variants: [
112 { match: IDENT_RE },
113 { match: /`(?:\\.|[^`\\])+`/ }
114 ],
115 endsParent: true
116 }
117 ]
118 },
119 {
120 scope: 'doctag',
121 match: /@[a-zA-Z]+/
122 },
123 {
124 scope: 'keyword',
125 match: /\\[a-zA-Z]+/
126 }
127 ] }
128 ),
129
130 hljs.HASH_COMMENT_MODE,
131
132 {
133 scope: 'string',
134 contains: [ hljs.BACKSLASH_ESCAPE ],
135 variants: [
136 hljs.END_SAME_AS_BEGIN({
137 begin: /[rR]"(-*)\(/,
138 end: /\)(-*)"/
139 }),
140 hljs.END_SAME_AS_BEGIN({
141 begin: /[rR]"(-*)\{/,
142 end: /\}(-*)"/
143 }),
144 hljs.END_SAME_AS_BEGIN({
145 begin: /[rR]"(-*)\[/,
146 end: /\](-*)"/
147 }),
148 hljs.END_SAME_AS_BEGIN({
149 begin: /[rR]'(-*)\(/,
150 end: /\)(-*)'/
151 }),
152 hljs.END_SAME_AS_BEGIN({
153 begin: /[rR]'(-*)\{/,
154 end: /\}(-*)'/
155 }),
156 hljs.END_SAME_AS_BEGIN({
157 begin: /[rR]'(-*)\[/,
158 end: /\](-*)'/
159 }),
160 {
161 begin: '"',
162 end: '"',
163 relevance: 0
164 },
165 {
166 begin: "'",
167 end: "'",
168 relevance: 0
169 }
170 ],
171 },
172
173 // Matching numbers immediately following punctuation and operators is
174 // tricky since we need to look at the character ahead of a number to
175 // ensure the number is not part of an identifier, and we cannot use
176 // negative look-behind assertions. So instead we explicitly handle all
177 // possible combinations of (operator|punctuation), number.
178 // TODO: replace with negative look-behind when available
179 // { begin: /(?<![a-zA-Z0-9._])0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*[pP][+-]?\d+i?/ },
180 // { begin: /(?<![a-zA-Z0-9._])0[xX][0-9a-fA-F]+([pP][+-]?\d+)?[Li]?/ },
181 // { begin: /(?<![a-zA-Z0-9._])(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?[Li]?/ }
182 {
183 relevance: 0,
184 variants: [
185 {
186 scope: {
187 1: 'operator',
188 2: 'number'
189 },
190 match: [
191 OPERATORS_RE,
192 NUMBER_TYPES_RE
193 ]
194 },
195 {
196 scope: {
197 1: 'operator',
198 2: 'number'
199 },
200 match: [
201 /%[^%]*%/,
202 NUMBER_TYPES_RE
203 ]
204 },
205 {
206 scope: {
207 1: 'punctuation',
208 2: 'number'
209 },
210 match: [
211 PUNCTUATION_RE,
212 NUMBER_TYPES_RE
213 ]
214 },
215 {
216 scope: { 2: 'number' },
217 match: [
218 /[^a-zA-Z0-9._]|^/, // not part of an identifier, or start of document
219 NUMBER_TYPES_RE
220 ]
221 }
222 ]
223 },
224
225 // Operators/punctuation when they're not directly followed by numbers
226 {
227 // Relevance boost for the most common assignment form.
228 scope: { 3: 'operator' },
229 match: [
230 IDENT_RE,
231 /\s+/,
232 /<-/,
233 /\s+/
234 ]
235 },
236
237 {
238 scope: 'operator',
239 relevance: 0,
240 variants: [
241 { match: OPERATORS_RE },
242 { match: /%[^%]*%/ }
243 ]
244 },
245
246 {
247 scope: 'punctuation',
248 relevance: 0,
249 match: PUNCTUATION_RE
250 },
251
252 {
253 // Escaped identifier
254 begin: '`',
255 end: '`',
256 contains: [ { begin: /\\./ } ]
257 }
258 ]
259 };
260 }
261
262 return r;
263
264 })();
265
266 hljs.registerLanguage('r', hljsGrammar);
267 })();