1"""
2 pygments.lexers.javascript
3 ~~~~~~~~~~~~~~~~~~~~~~~~~~
4
5 Lexers for JavaScript and related languages.
6
7 :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8 :license: BSD, see LICENSE for details.
9"""
10
11import re
12
13from pygments.lexer import bygroups, combined, default, do_insertions, include, \
14 inherit, Lexer, RegexLexer, this, using, words, line_re
15from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
16 Number, Punctuation, Other, Generic, Whitespace
17from pygments.util import get_bool_opt
18import pygments.unistring as uni
19
20__all__ = ['JavascriptLexer', 'KalLexer', 'LiveScriptLexer', 'DartLexer',
21 'TypeScriptLexer', 'LassoLexer', 'ObjectiveJLexer',
22 'CoffeeScriptLexer', 'MaskLexer', 'EarlGreyLexer', 'JuttleLexer',
23 'NodeConsoleLexer']
24
25JS_IDENT_START = ('(?:[$_' + uni.combine('Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl') +
26 ']|\\\\u[a-fA-F0-9]{4})')
27JS_IDENT_PART = ('(?:[$' + uni.combine('Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl',
28 'Mn', 'Mc', 'Nd', 'Pc') +
29 '\u200c\u200d]|\\\\u[a-fA-F0-9]{4})')
30JS_IDENT = JS_IDENT_START + '(?:' + JS_IDENT_PART + ')*'
31
32
33class JavascriptLexer(RegexLexer):
34 """
35 For JavaScript source code.
36 """
37
38 name = 'JavaScript'
39 url = 'https://www.ecma-international.org/publications-and-standards/standards/ecma-262/'
40 aliases = ['javascript', 'js']
41 filenames = ['*.js', '*.jsm', '*.mjs', '*.cjs']
42 mimetypes = ['application/javascript', 'application/x-javascript',
43 'text/x-javascript', 'text/javascript']
44 version_added = ''
45
46 flags = re.DOTALL | re.MULTILINE
47
48 tokens = {
49 'commentsandwhitespace': [
50 (r'\s+', Whitespace),
51 (r'<!--', Comment),
52 (r'//.*?$', Comment.Single),
53 (r'/\*.*?\*/', Comment.Multiline)
54 ],
55 'slashstartsregex': [
56 include('commentsandwhitespace'),
57 (r'/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/'
58 r'([gimuysd]+\b|\B)', String.Regex, '#pop'),
59 (r'(?=/)', Text, ('#pop', 'badregex')),
60 default('#pop')
61 ],
62 'badregex': [
63 (r'\n', Whitespace, '#pop')
64 ],
65 'root': [
66 (r'\A#! ?/.*?$', Comment.Hashbang), # recognized by node.js
67 (r'^(?=\s|/|<!--)', Text, 'slashstartsregex'),
68 include('commentsandwhitespace'),
69
70 # Numeric literals
71 (r'0[bB][01]+n?', Number.Bin),
72 (r'0[oO]?[0-7]+n?', Number.Oct), # Browsers support "0o7" and "07" (< ES5) notations
73 (r'0[xX][0-9a-fA-F]+n?', Number.Hex),
74 (r'[0-9]+n', Number.Integer), # Javascript BigInt requires an "n" postfix
75 # Javascript doesn't have actual integer literals, so every other
76 # numeric literal is handled by the regex below (including "normal")
77 # integers
78 (r'(\.[0-9]+|[0-9]+\.[0-9]*|[0-9]+)([eE][-+]?[0-9]+)?', Number.Float),
79
80 (r'\.\.\.|=>', Punctuation),
81 (r'\+\+|--|~|\?\?=?|\?|:|\\(?=\n)|'
82 r'(<<|>>>?|==?|!=?|(?:\*\*|\|\||&&|[-<>+*%&|^/]))=?', Operator, 'slashstartsregex'),
83 (r'[{(\[;,]', Punctuation, 'slashstartsregex'),
84 (r'[})\].]', Punctuation),
85
86 (r'(typeof|instanceof|in|void|delete|new)\b', Operator.Word, 'slashstartsregex'),
87
88 # Match stuff like: constructor
89 (r'\b(constructor|from|as)\b', Keyword.Reserved),
90
91 (r'(for|in|while|do|break|return|continue|switch|case|default|if|else|'
92 r'throw|try|catch|finally|yield|await|async|this|of|static|export|'
93 r'import|debugger|extends|super)\b', Keyword, 'slashstartsregex'),
94 (r'(var|let|const|with|function|class)\b', Keyword.Declaration, 'slashstartsregex'),
95
96 (r'(abstract|boolean|byte|char|double|enum|final|float|goto|'
97 r'implements|int|interface|long|native|package|private|protected|'
98 r'public|short|synchronized|throws|transient|volatile)\b', Keyword.Reserved),
99 (r'(true|false|null|NaN|Infinity|undefined)\b', Keyword.Constant),
100
101 (r'(Array|Boolean|Date|BigInt|Function|Math|ArrayBuffer|'
102 r'Number|Object|RegExp|String|Promise|Proxy|decodeURI|'
103 r'decodeURIComponent|encodeURI|encodeURIComponent|'
104 r'eval|isFinite|isNaN|parseFloat|parseInt|DataView|'
105 r'document|window|globalThis|global|Symbol|Intl|'
106 r'WeakSet|WeakMap|Set|Map|Reflect|JSON|Atomics|'
107 r'Int(?:8|16|32)Array|BigInt64Array|Float32Array|Float64Array|'
108 r'Uint8ClampedArray|Uint(?:8|16|32)Array|BigUint64Array)\b', Name.Builtin),
109
110 (r'((?:Eval|Internal|Range|Reference|Syntax|Type|URI)?Error)\b', Name.Exception),
111
112 # Match stuff like: super(argument, list)
113 (r'(super)(\s*)(\([\w,?.$\s]+\s*\))',
114 bygroups(Keyword, Whitespace), 'slashstartsregex'),
115 # Match stuff like: function() {...}
116 (r'([a-zA-Z_?.$][\w?.$]*)(?=\(\) \{)', Name.Other, 'slashstartsregex'),
117
118 (JS_IDENT, Name.Other),
119 (r'"(\\\\|\\[^\\]|[^"\\])*"', String.Double),
120 (r"'(\\\\|\\[^\\]|[^'\\])*'", String.Single),
121 (r'`', String.Backtick, 'interp'),
122 # private identifier
123 (r'#[a-zA-Z_]\w*', Name),
124 ],
125 'interp': [
126 (r'`', String.Backtick, '#pop'),
127 (r'\\.', String.Backtick),
128 (r'\$\{', String.Interpol, 'interp-inside'),
129 (r'\$', String.Backtick),
130 (r'[^`\\$]+', String.Backtick),
131 ],
132 'interp-inside': [
133 # TODO: should this include single-line comments and allow nesting strings?
134 (r'\}', String.Interpol, '#pop'),
135 include('root'),
136 ],
137 }
138
139
140class TypeScriptLexer(JavascriptLexer):
141 """
142 For TypeScript source code.
143 """
144
145 name = 'TypeScript'
146 url = 'https://www.typescriptlang.org/'
147 aliases = ['typescript', 'ts']
148 filenames = ['*.ts']
149 mimetypes = ['application/x-typescript', 'text/x-typescript']
150 version_added = '1.6'
151
152 # Higher priority than the TypoScriptLexer, as TypeScript is far more
153 # common these days
154 priority = 0.5
155
156 tokens = {
157 'root': [
158 (r'(abstract|implements|private|protected|public|readonly)\b',
159 Keyword, 'slashstartsregex'),
160 (r'(enum|interface|override)\b', Keyword.Declaration, 'slashstartsregex'),
161 (r'\b(declare|type)\b', Keyword.Reserved),
162 # Match variable type keywords
163 (r'\b(string|boolean|number)\b', Keyword.Type),
164 # Match stuff like: module name {...}
165 (r'\b(module)(\s*)([\w?.$]+)(\s*)',
166 bygroups(Keyword.Reserved, Whitespace, Name.Other, Whitespace), 'slashstartsregex'),
167 # Match stuff like: (function: return type)
168 (r'([\w?.$]+)(\s*)(:)(\s*)([\w?.$]+)',
169 bygroups(Name.Other, Whitespace, Operator, Whitespace, Keyword.Type)),
170 # Match stuff like: Decorators
171 (r'@' + JS_IDENT, Keyword.Declaration),
172 inherit,
173 # private identifier
174 (r'#[a-zA-Z_]\w*', Name),
175 ],
176 }
177
178
179class KalLexer(RegexLexer):
180 """
181 For Kal source code.
182 """
183
184 name = 'Kal'
185 url = 'http://rzimmerman.github.io/kal'
186 aliases = ['kal']
187 filenames = ['*.kal']
188 mimetypes = ['text/kal', 'application/kal']
189 version_added = '2.0'
190
191 flags = re.DOTALL
192 tokens = {
193 'commentsandwhitespace': [
194 (r'\s+', Whitespace),
195 (r'###[^#].*?###', Comment.Multiline),
196 (r'(#(?!##[^#]).*?)(\n)', bygroups(Comment.Single, Whitespace)),
197 ],
198 'functiondef': [
199 (r'([$a-zA-Z_][\w$]*)(\s*)', bygroups(Name.Function, Whitespace),
200 '#pop'),
201 include('commentsandwhitespace'),
202 ],
203 'classdef': [
204 (r'\b(inherits)(\s+)(from)\b',
205 bygroups(Keyword, Whitespace, Keyword)),
206 (r'([$a-zA-Z_][\w$]*)(?=\s*\n)', Name.Class, '#pop'),
207 (r'[$a-zA-Z_][\w$]*\b', Name.Class),
208 include('commentsandwhitespace'),
209 ],
210 'listcomprehension': [
211 (r'\]', Punctuation, '#pop'),
212 (r'\b(property|value)\b', Keyword),
213 include('root'),
214 ],
215 'waitfor': [
216 (r'\n', Whitespace, '#pop'),
217 (r'\bfrom\b', Keyword),
218 include('root'),
219 ],
220 'root': [
221 include('commentsandwhitespace'),
222 (r'/(?! )(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/'
223 r'([gimuysd]+\b|\B)', String.Regex),
224 (r'\?|:|_(?=\n)|==?|!=|-(?!>)|[<>+*/-]=?',
225 Operator),
226 (r'\b(and|or|isnt|is|not|but|bitwise|mod|\^|xor|exists|'
227 r'doesnt\s+exist)\b', Operator.Word),
228 (r'(\([^()]+\))?(\s*)(>)',
229 bygroups(Name.Function, Whitespace, Punctuation)),
230 (r'[{(]', Punctuation),
231 (r'\[', Punctuation, 'listcomprehension'),
232 (r'[})\].,]', Punctuation),
233 (r'\b(function|method|task)\b', Keyword.Declaration, 'functiondef'),
234 (r'\bclass\b', Keyword.Declaration, 'classdef'),
235 (r'\b(safe(?=\s))?(\s*)(wait(?=\s))(\s+)(for)\b',
236 bygroups(Keyword, Whitespace, Keyword, Whitespace,
237 Keyword), 'waitfor'),
238 (r'\b(me|this)(\.[$a-zA-Z_][\w.$]*)?\b', Name.Variable.Instance),
239 (r'(?<![.$])(run)(\s+)(in)(\s+)(parallel)\b',
240 bygroups(Keyword, Whitespace, Keyword, Whitespace, Keyword)),
241 (r'(?<![.$])(for)(\s+)(parallel|series)?\b',
242 bygroups(Keyword, Whitespace, Keyword)),
243 (r'(?<![.$])(except)(\s+)(when)?\b',
244 bygroups(Keyword, Whitespace, Keyword)),
245 (r'(?<![.$])(fail)(\s+)(with)?\b',
246 bygroups(Keyword, Whitespace, Keyword)),
247 (r'(?<![.$])(inherits)(\s+)(from)?\b',
248 bygroups(Keyword, Whitespace, Keyword)),
249 (r'(?<![.$])(for)(\s+)(parallel|series)?\b',
250 bygroups(Keyword, Whitespace, Keyword)),
251 (words((
252 'in', 'of', 'while', 'until', 'break', 'return', 'continue',
253 'when', 'if', 'unless', 'else', 'otherwise', 'throw', 'raise',
254 'try', 'catch', 'finally', 'new', 'delete', 'typeof',
255 'instanceof', 'super'), prefix=r'(?<![.$])', suffix=r'\b'),
256 Keyword),
257 (words((
258 'true', 'false', 'yes', 'no', 'on', 'off', 'null', 'nothing',
259 'none', 'NaN', 'Infinity', 'undefined'), prefix=r'(?<![.$])',
260 suffix=r'\b'), Keyword.Constant),
261 (words((
262 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math',
263 'Number', 'Object', 'RegExp', 'String', 'decodeURI',
264 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'eval',
265 'isFinite', 'isNaN', 'isSafeInteger', 'parseFloat', 'parseInt',
266 'document', 'window', 'globalThis', 'Symbol', 'print'),
267 suffix=r'\b'), Name.Builtin),
268 (r'([$a-zA-Z_][\w.$]*)(\s*)(:|[+\-*/]?\=)?\b',
269 bygroups(Name.Variable, Whitespace, Operator)),
270 (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
271 (r'0x[0-9a-fA-F]+', Number.Hex),
272 (r'[0-9]+', Number.Integer),
273 ('"""', String, 'tdqs'),
274 ("'''", String, 'tsqs'),
275 ('"', String, 'dqs'),
276 ("'", String, 'sqs'),
277 ],
278 'strings': [
279 (r'[^#\\\'"]+', String),
280 # note that all kal strings are multi-line.
281 # hashmarks, quotes and backslashes must be parsed one at a time
282 ],
283 'interpoling_string': [
284 (r'\}', String.Interpol, "#pop"),
285 include('root')
286 ],
287 'dqs': [
288 (r'"', String, '#pop'),
289 (r'\\.|\'', String), # double-quoted string don't need ' escapes
290 (r'#\{', String.Interpol, "interpoling_string"),
291 include('strings')
292 ],
293 'sqs': [
294 (r"'", String, '#pop'),
295 (r'#|\\.|"', String), # single quoted strings don't need " escapses
296 include('strings')
297 ],
298 'tdqs': [
299 (r'"""', String, '#pop'),
300 (r'\\.|\'|"', String), # no need to escape quotes in triple-string
301 (r'#\{', String.Interpol, "interpoling_string"),
302 include('strings'),
303 ],
304 'tsqs': [
305 (r"'''", String, '#pop'),
306 (r'#|\\.|\'|"', String), # no need to escape quotes in triple-strings
307 include('strings')
308 ],
309 }
310
311
312class LiveScriptLexer(RegexLexer):
313 """
314 For LiveScript source code.
315 """
316
317 name = 'LiveScript'
318 url = 'https://livescript.net/'
319 aliases = ['livescript', 'live-script']
320 filenames = ['*.ls']
321 mimetypes = ['text/livescript']
322 version_added = '1.6'
323
324 flags = re.DOTALL
325 tokens = {
326 'commentsandwhitespace': [
327 (r'\s+', Whitespace),
328 (r'/\*.*?\*/', Comment.Multiline),
329 (r'(#.*?)(\n)', bygroups(Comment.Single, Whitespace)),
330 ],
331 'multilineregex': [
332 include('commentsandwhitespace'),
333 (r'//([gimuysd]+\b|\B)', String.Regex, '#pop'),
334 (r'/', String.Regex),
335 (r'[^/#]+', String.Regex)
336 ],
337 'slashstartsregex': [
338 include('commentsandwhitespace'),
339 (r'//', String.Regex, ('#pop', 'multilineregex')),
340 (r'/(?! )(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/'
341 r'([gimuysd]+\b|\B)', String.Regex, '#pop'),
342 (r'/', Operator, '#pop'),
343 default('#pop'),
344 ],
345 'root': [
346 (r'\A(?=\s|/)', Text, 'slashstartsregex'),
347 include('commentsandwhitespace'),
348 (r'(?:\([^()]+\))?[ ]*[~-]{1,2}>|'
349 r'(?:\(?[^()\n]+\)?)?[ ]*<[~-]{1,2}', Name.Function),
350 (r'\+\+|&&|(?<![.$])\b(?:and|x?or|is|isnt|not)\b|\?|:|=|'
351 r'\|\||\\(?=\n)|(<<|>>>?|==?|!=?|'
352 r'~(?!\~?>)|-(?!\-?>)|<(?!\[)|(?<!\])>|'
353 r'[+*`%&|^/])=?',
354 Operator, 'slashstartsregex'),
355 (r'[{(\[;,]', Punctuation, 'slashstartsregex'),
356 (r'[})\].]', Punctuation),
357 (r'(?<![.$])(for|own|in|of|while|until|loop|break|'
358 r'return|continue|switch|when|then|if|unless|else|'
359 r'throw|try|catch|finally|new|delete|typeof|instanceof|super|'
360 r'extends|this|class|by|const|var|to|til)\b', Keyword,
361 'slashstartsregex'),
362 (r'(?<![.$])(true|false|yes|no|on|off|'
363 r'null|NaN|Infinity|undefined|void)\b',
364 Keyword.Constant),
365 (r'(Array|Boolean|Date|Error|Function|Math|'
366 r'Number|Object|RegExp|String|decodeURI|'
367 r'decodeURIComponent|encodeURI|encodeURIComponent|'
368 r'eval|isFinite|isNaN|parseFloat|parseInt|document|window|'
369 r'globalThis|Symbol|Symbol|BigInt)\b', Name.Builtin),
370 (r'([$a-zA-Z_][\w.\-:$]*)(\s*)([:=])(\s+)',
371 bygroups(Name.Variable, Whitespace, Operator, Whitespace),
372 'slashstartsregex'),
373 (r'(@[$a-zA-Z_][\w.\-:$]*)(\s*)([:=])(\s+)',
374 bygroups(Name.Variable.Instance, Whitespace, Operator,
375 Whitespace),
376 'slashstartsregex'),
377 (r'@', Name.Other, 'slashstartsregex'),
378 (r'@?[$a-zA-Z_][\w-]*', Name.Other, 'slashstartsregex'),
379 (r'[0-9]+\.[0-9]+([eE][0-9]+)?[fd]?(?:[a-zA-Z_]+)?', Number.Float),
380 (r'[0-9]+(~[0-9a-z]+)?(?:[a-zA-Z_]+)?', Number.Integer),
381 ('"""', String, 'tdqs'),
382 ("'''", String, 'tsqs'),
383 ('"', String, 'dqs'),
384 ("'", String, 'sqs'),
385 (r'\\\S+', String),
386 (r'<\[.*?\]>', String),
387 ],
388 'strings': [
389 (r'[^#\\\'"]+', String),
390 # note that all coffee script strings are multi-line.
391 # hashmarks, quotes and backslashes must be parsed one at a time
392 ],
393 'interpoling_string': [
394 (r'\}', String.Interpol, "#pop"),
395 include('root')
396 ],
397 'dqs': [
398 (r'"', String, '#pop'),
399 (r'\\.|\'', String), # double-quoted string don't need ' escapes
400 (r'#\{', String.Interpol, "interpoling_string"),
401 (r'#', String),
402 include('strings')
403 ],
404 'sqs': [
405 (r"'", String, '#pop'),
406 (r'#|\\.|"', String), # single quoted strings don't need " escapses
407 include('strings')
408 ],
409 'tdqs': [
410 (r'"""', String, '#pop'),
411 (r'\\.|\'|"', String), # no need to escape quotes in triple-string
412 (r'#\{', String.Interpol, "interpoling_string"),
413 (r'#', String),
414 include('strings'),
415 ],
416 'tsqs': [
417 (r"'''", String, '#pop'),
418 (r'#|\\.|\'|"', String), # no need to escape quotes in triple-strings
419 include('strings')
420 ],
421 }
422
423
424class DartLexer(RegexLexer):
425 """
426 For Dart source code.
427 """
428
429 name = 'Dart'
430 url = 'http://dart.dev/'
431 aliases = ['dart']
432 filenames = ['*.dart']
433 mimetypes = ['text/x-dart']
434 version_added = '1.5'
435
436 flags = re.MULTILINE | re.DOTALL
437
438 tokens = {
439 'root': [
440 include('string_literal'),
441 (r'#!(.*?)$', Comment.Preproc),
442 (r'\b(import|export)\b', Keyword, 'import_decl'),
443 (r'\b(library|source|part of|part)\b', Keyword),
444 (r'[^\S\n]+', Whitespace),
445 (r'(//.*?)(\n)', bygroups(Comment.Single, Whitespace)),
446 (r'/\*.*?\*/', Comment.Multiline),
447 (r'\b(class|extension|mixin)\b(\s+)',
448 bygroups(Keyword.Declaration, Whitespace), 'class'),
449 (r'\b(as|assert|break|case|catch|const|continue|default|do|else|finally|'
450 r'for|if|in|is|new|rethrow|return|super|switch|this|throw|try|while)\b',
451 Keyword),
452 (r'\b(abstract|async|await|const|covariant|extends|external|factory|final|'
453 r'get|implements|late|native|on|operator|required|set|static|sync|typedef|'
454 r'var|with|yield)\b', Keyword.Declaration),
455 (r'\b(bool|double|dynamic|int|num|Function|Never|Null|Object|String|void)\b',
456 Keyword.Type),
457 (r'\b(false|null|true)\b', Keyword.Constant),
458 (r'[~!%^&*+=|?:<>/-]|as\b', Operator),
459 (r'@[a-zA-Z_$]\w*', Name.Decorator),
460 (r'[a-zA-Z_$]\w*:', Name.Label),
461 (r'[a-zA-Z_$]\w*', Name),
462 (r'[(){}\[\],.;]', Punctuation),
463 (r'0[xX][0-9a-fA-F]+', Number.Hex),
464 # DIGIT+ (‘.’ DIGIT*)? EXPONENT?
465 (r'\d+(\.\d*)?([eE][+-]?\d+)?', Number),
466 (r'\.\d+([eE][+-]?\d+)?', Number), # ‘.’ DIGIT+ EXPONENT?
467 (r'\n', Whitespace)
468 # pseudo-keyword negate intentionally left out
469 ],
470 'class': [
471 (r'[a-zA-Z_$]\w*', Name.Class, '#pop')
472 ],
473 'import_decl': [
474 include('string_literal'),
475 (r'\s+', Whitespace),
476 (r'\b(as|deferred|show|hide)\b', Keyword),
477 (r'[a-zA-Z_$]\w*', Name),
478 (r'\,', Punctuation),
479 (r'\;', Punctuation, '#pop')
480 ],
481 'string_literal': [
482 # Raw strings.
483 (r'r"""([\w\W]*?)"""', String.Double),
484 (r"r'''([\w\W]*?)'''", String.Single),
485 (r'r"(.*?)"', String.Double),
486 (r"r'(.*?)'", String.Single),
487 # Normal Strings.
488 (r'"""', String.Double, 'string_double_multiline'),
489 (r"'''", String.Single, 'string_single_multiline'),
490 (r'"', String.Double, 'string_double'),
491 (r"'", String.Single, 'string_single')
492 ],
493 'string_common': [
494 (r"\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|u\{[0-9A-Fa-f]*\}|[a-z'\"$\\])",
495 String.Escape),
496 (r'(\$)([a-zA-Z_]\w*)', bygroups(String.Interpol, Name)),
497 (r'(\$\{)(.*?)(\})',
498 bygroups(String.Interpol, using(this), String.Interpol))
499 ],
500 'string_double': [
501 (r'"', String.Double, '#pop'),
502 (r'[^"$\\\n]+', String.Double),
503 include('string_common'),
504 (r'\$+', String.Double)
505 ],
506 'string_double_multiline': [
507 (r'"""', String.Double, '#pop'),
508 (r'[^"$\\]+', String.Double),
509 include('string_common'),
510 (r'(\$|\")+', String.Double)
511 ],
512 'string_single': [
513 (r"'", String.Single, '#pop'),
514 (r"[^'$\\\n]+", String.Single),
515 include('string_common'),
516 (r'\$+', String.Single)
517 ],
518 'string_single_multiline': [
519 (r"'''", String.Single, '#pop'),
520 (r'[^\'$\\]+', String.Single),
521 include('string_common'),
522 (r'(\$|\')+', String.Single)
523 ]
524 }
525
526
527class LassoLexer(RegexLexer):
528 """
529 For Lasso source code, covering both Lasso 9
530 syntax and LassoScript for Lasso 8.6 and earlier. For Lasso embedded in
531 HTML, use the `LassoHtmlLexer`.
532
533 Additional options accepted:
534
535 `builtinshighlighting`
536 If given and ``True``, highlight builtin types, traits, methods, and
537 members (default: ``True``).
538 `requiredelimiters`
539 If given and ``True``, only highlight code between delimiters as Lasso
540 (default: ``False``).
541 """
542
543 name = 'Lasso'
544 aliases = ['lasso', 'lassoscript']
545 filenames = ['*.lasso', '*.lasso[89]']
546 version_added = '1.6'
547 alias_filenames = ['*.incl', '*.inc', '*.las']
548 mimetypes = ['text/x-lasso']
549 url = 'https://www.lassosoft.com'
550
551 flags = re.IGNORECASE | re.DOTALL | re.MULTILINE
552
553 tokens = {
554 'root': [
555 (r'^#![ \S]+lasso9\b', Comment.Preproc, 'lasso'),
556 (r'(?=\[|<)', Other, 'delimiters'),
557 (r'\s+', Whitespace),
558 default(('delimiters', 'lassofile')),
559 ],
560 'delimiters': [
561 (r'\[no_square_brackets\]', Comment.Preproc, 'nosquarebrackets'),
562 (r'\[noprocess\]', Comment.Preproc, 'noprocess'),
563 (r'\[', Comment.Preproc, 'squarebrackets'),
564 (r'<\?(lasso(script)?|=)', Comment.Preproc, 'anglebrackets'),
565 (r'<(!--.*?-->)?', Other),
566 (r'[^[<]+', Other),
567 ],
568 'nosquarebrackets': [
569 (r'\[noprocess\]', Comment.Preproc, 'noprocess'),
570 (r'\[', Other),
571 (r'<\?(lasso(script)?|=)', Comment.Preproc, 'anglebrackets'),
572 (r'<(!--.*?-->)?', Other),
573 (r'[^[<]+', Other),
574 ],
575 'noprocess': [
576 (r'\[/noprocess\]', Comment.Preproc, '#pop'),
577 (r'\[', Other),
578 (r'[^[]', Other),
579 ],
580 'squarebrackets': [
581 (r'\]', Comment.Preproc, '#pop'),
582 include('lasso'),
583 ],
584 'anglebrackets': [
585 (r'\?>', Comment.Preproc, '#pop'),
586 include('lasso'),
587 ],
588 'lassofile': [
589 (r'\]|\?>', Comment.Preproc, '#pop'),
590 include('lasso'),
591 ],
592 'whitespacecomments': [
593 (r'\s+', Whitespace),
594 (r'(//.*?)(\s*)$', bygroups(Comment.Single, Whitespace)),
595 (r'/\*\*!.*?\*/', String.Doc),
596 (r'/\*.*?\*/', Comment.Multiline),
597 ],
598 'lasso': [
599 # whitespace/comments
600 include('whitespacecomments'),
601
602 # literals
603 (r'\d*\.\d+(e[+-]?\d+)?', Number.Float),
604 (r'0x[\da-f]+', Number.Hex),
605 (r'\d+', Number.Integer),
606 (r'(infinity|NaN)\b', Number),
607 (r"'", String.Single, 'singlestring'),
608 (r'"', String.Double, 'doublestring'),
609 (r'`[^`]*`', String.Backtick),
610
611 # names
612 (r'\$[a-z_][\w.]*', Name.Variable),
613 (r'#([a-z_][\w.]*|\d+\b)', Name.Variable.Instance),
614 (r"(\.)(\s*)('[a-z_][\w.]*')",
615 bygroups(Name.Builtin.Pseudo, Whitespace, Name.Variable.Class)),
616 (r"(self)(\s*)(->)(\s*)('[a-z_][\w.]*')",
617 bygroups(Name.Builtin.Pseudo, Whitespace, Operator, Whitespace,
618 Name.Variable.Class)),
619 (r'(\.\.?)(\s*)([a-z_][\w.]*(=(?!=))?)',
620 bygroups(Name.Builtin.Pseudo, Whitespace, Name.Other.Member)),
621 (r'(->\\?|&)(\s*)([a-z_][\w.]*(=(?!=))?)',
622 bygroups(Operator, Whitespace, Name.Other.Member)),
623 (r'(?<!->)(self|inherited|currentcapture|givenblock)\b',
624 Name.Builtin.Pseudo),
625 (r'-(?!infinity)[a-z_][\w.]*', Name.Attribute),
626 (r'(::)(\s*)([a-z_][\w.]*)',
627 bygroups(Punctuation, Whitespace, Name.Label)),
628 (r'(error_(code|msg)_\w+|Error_AddError|Error_ColumnRestriction|'
629 r'Error_DatabaseConnectionUnavailable|Error_DatabaseTimeout|'
630 r'Error_DeleteError|Error_FieldRestriction|Error_FileNotFound|'
631 r'Error_InvalidDatabase|Error_InvalidPassword|'
632 r'Error_InvalidUsername|Error_ModuleNotFound|'
633 r'Error_NoError|Error_NoPermission|Error_OutOfMemory|'
634 r'Error_ReqColumnMissing|Error_ReqFieldMissing|'
635 r'Error_RequiredColumnMissing|Error_RequiredFieldMissing|'
636 r'Error_UpdateError)\b', Name.Exception),
637
638 # definitions
639 (r'(define)(\s+)([a-z_][\w.]*)(\s*)(=>)(\s*)(type|trait|thread)\b',
640 bygroups(Keyword.Declaration, Whitespace, Name.Class,
641 Whitespace, Operator, Whitespace, Keyword)),
642 (r'(define)(\s+)([a-z_][\w.]*)(\s*)(->)(\s*)([a-z_][\w.]*=?|[-+*/%])',
643 bygroups(Keyword.Declaration, Whitespace, Name.Class,
644 Whitespace, Operator, Whitespace, Name.Function),
645 'signature'),
646 (r'(define)(\s+)([a-z_][\w.]*)',
647 bygroups(Keyword.Declaration, Whitespace, Name.Function), 'signature'),
648 (r'(public|protected|private|provide)(\s+)(([a-z_][\w.]*=?|[-+*/%])'
649 r'(?=\s*\())', bygroups(Keyword, Whitespace, Name.Function),
650 'signature'),
651 (r'(public|protected|private|provide)(\s+)([a-z_][\w.]*)',
652 bygroups(Keyword, Whitespace, Name.Function)),
653
654 # keywords
655 (r'(true|false|none|minimal|full|all|void)\b', Keyword.Constant),
656 (r'(local|var|variable|global|data(?=\s))\b', Keyword.Declaration),
657 (r'(array|date|decimal|duration|integer|map|pair|string|tag|xml|'
658 r'null|boolean|bytes|keyword|list|locale|queue|set|stack|'
659 r'staticarray)\b', Keyword.Type),
660 (r'([a-z_][\w.]*)(\s+)(in)\b', bygroups(Name, Whitespace, Keyword)),
661 (r'(let|into)(\s+)([a-z_][\w.]*)', bygroups(Keyword, Whitespace, Name)),
662 (r'require\b', Keyword, 'requiresection'),
663 (r'(/?)(Namespace_Using)\b', bygroups(Punctuation, Keyword.Namespace)),
664 (r'(/?)(Cache|Database_Names|Database_SchemaNames|'
665 r'Database_TableNames|Define_Tag|Define_Type|Email_Batch|'
666 r'Encode_Set|HTML_Comment|Handle|Handle_Error|Header|If|Inline|'
667 r'Iterate|LJAX_Target|Link|Link_CurrentAction|Link_CurrentGroup|'
668 r'Link_CurrentRecord|Link_Detail|Link_FirstGroup|Link_FirstRecord|'
669 r'Link_LastGroup|Link_LastRecord|Link_NextGroup|Link_NextRecord|'
670 r'Link_PrevGroup|Link_PrevRecord|Log|Loop|Output_None|Portal|'
671 r'Private|Protect|Records|Referer|Referrer|Repeating|ResultSet|'
672 r'Rows|Search_Args|Search_Arguments|Select|Sort_Args|'
673 r'Sort_Arguments|Thread_Atomic|Value_List|While|Abort|Case|Else|'
674 r'Fail_If|Fail_IfNot|Fail|If_Empty|If_False|If_Null|If_True|'
675 r'Loop_Abort|Loop_Continue|Loop_Count|Params|Params_Up|Return|'
676 r'Return_Value|Run_Children|SOAP_DefineTag|SOAP_LastRequest|'
677 r'SOAP_LastResponse|Tag_Name|ascending|average|by|define|'
678 r'descending|do|equals|frozen|group|handle_failure|import|in|into|'
679 r'join|let|match|max|min|on|order|parent|protected|provide|public|'
680 r'require|returnhome|skip|split_thread|sum|take|thread|to|trait|'
681 r'type|where|with|yield|yieldhome)\b',
682 bygroups(Punctuation, Keyword)),
683
684 # other
685 (r',', Punctuation, 'commamember'),
686 (r'(and|or|not)\b', Operator.Word),
687 (r'([a-z_][\w.]*)(\s*)(::)(\s*)([a-z_][\w.]*)?(\s*=(?!=))',
688 bygroups(Name, Whitespace, Punctuation, Whitespace, Name.Label,
689 Operator)),
690 (r'(/?)([\w.]+)', bygroups(Punctuation, Name.Other)),
691 (r'(=)(n?bw|n?ew|n?cn|lte?|gte?|n?eq|n?rx|ft)\b',
692 bygroups(Operator, Operator.Word)),
693 (r':=|[-+*/%=<>&|!?\\]+', Operator),
694 (r'[{}():;,@^]', Punctuation),
695 ],
696 'singlestring': [
697 (r"'", String.Single, '#pop'),
698 (r"[^'\\]+", String.Single),
699 include('escape'),
700 (r"\\", String.Single),
701 ],
702 'doublestring': [
703 (r'"', String.Double, '#pop'),
704 (r'[^"\\]+', String.Double),
705 include('escape'),
706 (r'\\', String.Double),
707 ],
708 'escape': [
709 (r'\\(U[\da-f]{8}|u[\da-f]{4}|x[\da-f]{1,2}|[0-7]{1,3}|:[^:\n\r]+:|'
710 r'[abefnrtv?"\'\\]|$)', String.Escape),
711 ],
712 'signature': [
713 (r'=>', Operator, '#pop'),
714 (r'\)', Punctuation, '#pop'),
715 (r'[(,]', Punctuation, 'parameter'),
716 include('lasso'),
717 ],
718 'parameter': [
719 (r'\)', Punctuation, '#pop'),
720 (r'-?[a-z_][\w.]*', Name.Attribute, '#pop'),
721 (r'\.\.\.', Name.Builtin.Pseudo),
722 include('lasso'),
723 ],
724 'requiresection': [
725 (r'(([a-z_][\w.]*=?|[-+*/%])(?=\s*\())', Name, 'requiresignature'),
726 (r'(([a-z_][\w.]*=?|[-+*/%])(?=(\s*::\s*[\w.]+)?\s*,))', Name),
727 (r'[a-z_][\w.]*=?|[-+*/%]', Name, '#pop'),
728 (r'(::)(\s*)([a-z_][\w.]*)',
729 bygroups(Punctuation, Whitespace, Name.Label)),
730 (r',', Punctuation),
731 include('whitespacecomments'),
732 ],
733 'requiresignature': [
734 (r'(\)(?=(\s*::\s*[\w.]+)?\s*,))', Punctuation, '#pop'),
735 (r'\)', Punctuation, '#pop:2'),
736 (r'-?[a-z_][\w.]*', Name.Attribute),
737 (r'(::)(\s*)([a-z_][\w.]*)',
738 bygroups(Punctuation, Whitespace, Name.Label)),
739 (r'\.\.\.', Name.Builtin.Pseudo),
740 (r'[(,]', Punctuation),
741 include('whitespacecomments'),
742 ],
743 'commamember': [
744 (r'(([a-z_][\w.]*=?|[-+*/%])'
745 r'(?=\s*(\(([^()]*\([^()]*\))*[^)]*\)\s*)?(::[\w.\s]+)?=>))',
746 Name.Function, 'signature'),
747 include('whitespacecomments'),
748 default('#pop'),
749 ],
750 }
751
752 def __init__(self, **options):
753 self.builtinshighlighting = get_bool_opt(
754 options, 'builtinshighlighting', True)
755 self.requiredelimiters = get_bool_opt(
756 options, 'requiredelimiters', False)
757
758 self._builtins = set()
759 self._members = set()
760 if self.builtinshighlighting:
761 from pygments.lexers._lasso_builtins import BUILTINS, MEMBERS
762 for key, value in BUILTINS.items():
763 self._builtins.update(value)
764 for key, value in MEMBERS.items():
765 self._members.update(value)
766 RegexLexer.__init__(self, **options)
767
768 def get_tokens_unprocessed(self, text):
769 stack = ['root']
770 if self.requiredelimiters:
771 stack.append('delimiters')
772 for index, token, value in \
773 RegexLexer.get_tokens_unprocessed(self, text, stack):
774 if (token is Name.Other and value.lower() in self._builtins or
775 token is Name.Other.Member and
776 value.lower().rstrip('=') in self._members):
777 yield index, Name.Builtin, value
778 continue
779 yield index, token, value
780
781 def analyse_text(text):
782 rv = 0.0
783 if 'bin/lasso9' in text:
784 rv += 0.8
785 if re.search(r'<\?lasso', text, re.I):
786 rv += 0.4
787 if re.search(r'local\(', text, re.I):
788 rv += 0.4
789 return rv
790
791
792class ObjectiveJLexer(RegexLexer):
793 """
794 For Objective-J source code with preprocessor directives.
795 """
796
797 name = 'Objective-J'
798 aliases = ['objective-j', 'objectivej', 'obj-j', 'objj']
799 filenames = ['*.j']
800 mimetypes = ['text/x-objective-j']
801 url = 'https://www.cappuccino.dev/learn/objective-j.html'
802 version_added = '1.3'
803
804 #: optional Comment or Whitespace
805 _ws = r'(?:\s|//[^\n]*\n|/[*](?:[^*]|[*][^/])*[*]/)*'
806
807 flags = re.DOTALL | re.MULTILINE
808
809 tokens = {
810 'root': [
811 include('whitespace'),
812
813 # function definition
814 (r'^(' + _ws + r'[+-]' + _ws + r')([(a-zA-Z_].*?[^(])(' + _ws + r'\{)',
815 bygroups(using(this), using(this, state='function_signature'),
816 using(this))),
817
818 # class definition
819 (r'(@interface|@implementation)(\s+)', bygroups(Keyword, Whitespace),
820 'classname'),
821 (r'(@class|@protocol)(\s*)', bygroups(Keyword, Whitespace),
822 'forward_classname'),
823 (r'(\s*)(@end)(\s*)', bygroups(Whitespace, Keyword, Whitespace)),
824
825 include('statements'),
826 ('[{()}]', Punctuation),
827 (';', Punctuation),
828 ],
829 'whitespace': [
830 (r'(@import)(\s+)("(?:\\\\|\\"|[^"])*")',
831 bygroups(Comment.Preproc, Whitespace, String.Double)),
832 (r'(@import)(\s+)(<(?:\\\\|\\>|[^>])*>)',
833 bygroups(Comment.Preproc, Whitespace, String.Double)),
834 (r'(#(?:include|import))(\s+)("(?:\\\\|\\"|[^"])*")',
835 bygroups(Comment.Preproc, Whitespace, String.Double)),
836 (r'(#(?:include|import))(\s+)(<(?:\\\\|\\>|[^>])*>)',
837 bygroups(Comment.Preproc, Whitespace, String.Double)),
838
839 (r'#if\s+0', Comment.Preproc, 'if0'),
840 (r'#', Comment.Preproc, 'macro'),
841
842 (r'\s+', Whitespace),
843 (r'(\\)(\n)',
844 bygroups(String.Escape, Whitespace)), # line continuation
845 (r'//(\n|(.|\n)*?[^\\]\n)', Comment.Single),
846 (r'/(\\\n)?[*](.|\n)*?[*](\\\n)?/', Comment.Multiline),
847 (r'<!--', Comment),
848 ],
849 'slashstartsregex': [
850 include('whitespace'),
851 (r'/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/'
852 r'([gim]+\b|\B)', String.Regex, '#pop'),
853 (r'(?=/)', Text, ('#pop', 'badregex')),
854 default('#pop'),
855 ],
856 'badregex': [
857 (r'\n', Whitespace, '#pop'),
858 ],
859 'statements': [
860 (r'(L|@)?"', String, 'string'),
861 (r"(L|@)?'(\\.|\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|[^\\\'\n])'",
862 String.Char),
863 (r'"(\\\\|\\[^\\]|[^"\\])*"', String.Double),
864 (r"'(\\\\|\\[^\\]|[^'\\])*'", String.Single),
865 (r'(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d+[lL]?', Number.Float),
866 (r'(\d+\.\d*|\.\d+|\d+[fF])[fF]?', Number.Float),
867 (r'0x[0-9a-fA-F]+[Ll]?', Number.Hex),
868 (r'0[0-7]+[Ll]?', Number.Oct),
869 (r'\d+[Ll]?', Number.Integer),
870
871 (r'^(?=\s|/|<!--)', Text, 'slashstartsregex'),
872
873 (r'\+\+|--|~|&&|\?|:|\|\||\\(?=\n)|'
874 r'(<<|>>>?|==?|!=?|[-<>+*%&|^/])=?',
875 Operator, 'slashstartsregex'),
876 (r'[{(\[;,]', Punctuation, 'slashstartsregex'),
877 (r'[})\].]', Punctuation),
878
879 (r'(for|in|while|do|break|return|continue|switch|case|default|if|'
880 r'else|throw|try|catch|finally|new|delete|typeof|instanceof|void|'
881 r'prototype|__proto__)\b', Keyword, 'slashstartsregex'),
882
883 (r'(var|with|function)\b', Keyword.Declaration, 'slashstartsregex'),
884
885 (r'(@selector|@private|@protected|@public|@encode|'
886 r'@synchronized|@try|@throw|@catch|@finally|@end|@property|'
887 r'@synthesize|@dynamic|@for|@accessors|new)\b', Keyword),
888
889 (r'(int|long|float|short|double|char|unsigned|signed|void|'
890 r'id|BOOL|bool|boolean|IBOutlet|IBAction|SEL|@outlet|@action)\b',
891 Keyword.Type),
892
893 (r'(self|super)\b', Name.Builtin),
894
895 (r'(TRUE|YES|FALSE|NO|Nil|nil|NULL)\b', Keyword.Constant),
896 (r'(true|false|null|NaN|Infinity|undefined)\b', Keyword.Constant),
897 (r'(ABS|ASIN|ACOS|ATAN|ATAN2|SIN|COS|TAN|EXP|POW|CEIL|FLOOR|ROUND|'
898 r'MIN|MAX|RAND|SQRT|E|LN2|LN10|LOG2E|LOG10E|PI|PI2|PI_2|SQRT1_2|'
899 r'SQRT2)\b', Keyword.Constant),
900
901 (r'(Array|Boolean|Date|Error|Function|Math|'
902 r'Number|Object|RegExp|String|decodeURI|'
903 r'decodeURIComponent|encodeURI|encodeURIComponent|'
904 r'Error|eval|isFinite|isNaN|parseFloat|parseInt|document|this|'
905 r'window|globalThis|Symbol)\b', Name.Builtin),
906
907 (r'([$a-zA-Z_]\w*)(' + _ws + r')(?=\()',
908 bygroups(Name.Function, using(this))),
909
910 (r'[$a-zA-Z_]\w*', Name),
911 ],
912 'classname': [
913 # interface definition that inherits
914 (r'([a-zA-Z_]\w*)(' + _ws + r':' + _ws +
915 r')([a-zA-Z_]\w*)?',
916 bygroups(Name.Class, using(this), Name.Class), '#pop'),
917 # interface definition for a category
918 (r'([a-zA-Z_]\w*)(' + _ws + r'\()([a-zA-Z_]\w*)(\))',
919 bygroups(Name.Class, using(this), Name.Label, Text), '#pop'),
920 # simple interface / implementation
921 (r'([a-zA-Z_]\w*)', Name.Class, '#pop'),
922 ],
923 'forward_classname': [
924 (r'([a-zA-Z_]\w*)(\s*)(,)(\s*)',
925 bygroups(Name.Class, Whitespace, Text, Whitespace), '#push'),
926 (r'([a-zA-Z_]\w*)(\s*)(;?)',
927 bygroups(Name.Class, Whitespace, Text), '#pop'),
928 ],
929 'function_signature': [
930 include('whitespace'),
931
932 # start of a selector w/ parameters
933 (r'(\(' + _ws + r')' # open paren
934 r'([a-zA-Z_]\w+)' # return type
935 r'(' + _ws + r'\)' + _ws + r')' # close paren
936 r'([$a-zA-Z_]\w+' + _ws + r':)', # function name
937 bygroups(using(this), Keyword.Type, using(this),
938 Name.Function), 'function_parameters'),
939
940 # no-param function
941 (r'(\(' + _ws + r')' # open paren
942 r'([a-zA-Z_]\w+)' # return type
943 r'(' + _ws + r'\)' + _ws + r')' # close paren
944 r'([$a-zA-Z_]\w+)', # function name
945 bygroups(using(this), Keyword.Type, using(this),
946 Name.Function), "#pop"),
947
948 # no return type given, start of a selector w/ parameters
949 (r'([$a-zA-Z_]\w+' + _ws + r':)', # function name
950 bygroups(Name.Function), 'function_parameters'),
951
952 # no return type given, no-param function
953 (r'([$a-zA-Z_]\w+)', # function name
954 bygroups(Name.Function), "#pop"),
955
956 default('#pop'),
957 ],
958 'function_parameters': [
959 include('whitespace'),
960
961 # parameters
962 (r'(\(' + _ws + ')' # open paren
963 r'([^)]+)' # type
964 r'(' + _ws + r'\)' + _ws + r')' # close paren
965 r'([$a-zA-Z_]\w+)', # param name
966 bygroups(using(this), Keyword.Type, using(this), Text)),
967
968 # one piece of a selector name
969 (r'([$a-zA-Z_]\w+' + _ws + r':)', # function name
970 Name.Function),
971
972 # smallest possible selector piece
973 (r'(:)', Name.Function),
974
975 # var args
976 (r'(,' + _ws + r'\.\.\.)', using(this)),
977
978 # param name
979 (r'([$a-zA-Z_]\w+)', Text),
980 ],
981 'expression': [
982 (r'([$a-zA-Z_]\w*)(\()', bygroups(Name.Function,
983 Punctuation)),
984 (r'(\))', Punctuation, "#pop"),
985 ],
986 'string': [
987 (r'"', String, '#pop'),
988 (r'\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})', String.Escape),
989 (r'[^\\"\n]+', String), # all other characters
990 (r'(\\)(\n)', bygroups(String.Escape, Whitespace)), # line continuation
991 (r'\\', String), # stray backslash
992 ],
993 'macro': [
994 (r'[^/\n]+', Comment.Preproc),
995 (r'/[*](.|\n)*?[*]/', Comment.Multiline),
996 (r'(//.*?)(\n)', bygroups(Comment.Single, Whitespace), '#pop'),
997 (r'/', Comment.Preproc),
998 (r'(?<=\\)\n', Whitespace),
999 (r'\n', Whitespace, '#pop'),
1000 ],
1001 'if0': [
1002 (r'^\s*#if.*?(?<!\\)\n', Comment.Preproc, '#push'),
1003 (r'^\s*#endif.*?(?<!\\)\n', Comment.Preproc, '#pop'),
1004 (r'(.*?)(\n)', bygroups(Comment, Whitespace)),
1005 ]
1006 }
1007
1008 def analyse_text(text):
1009 if re.search(r'^\s*@import\s+[<"]', text, re.MULTILINE):
1010 # special directive found in most Objective-J files
1011 return True
1012 return False
1013
1014
1015class CoffeeScriptLexer(RegexLexer):
1016 """
1017 For CoffeeScript source code.
1018 """
1019
1020 name = 'CoffeeScript'
1021 url = 'http://coffeescript.org'
1022 aliases = ['coffeescript', 'coffee-script', 'coffee']
1023 filenames = ['*.coffee']
1024 mimetypes = ['text/coffeescript']
1025 version_added = '1.3'
1026
1027 _operator_re = (
1028 r'\+\+|~|&&|\band\b|\bor\b|\bis\b|\bisnt\b|\bnot\b|\?|:|'
1029 r'\|\||\\(?=\n)|'
1030 r'(<<|>>>?|==?(?!>)|!=?|=(?!>)|-(?!>)|[<>+*`%&|\^/])=?')
1031
1032 flags = re.DOTALL
1033 tokens = {
1034 'commentsandwhitespace': [
1035 (r'\s+', Whitespace),
1036 (r'###[^#].*?###', Comment.Multiline),
1037 (r'(#(?!##[^#]).*?)(\n)', bygroups(Comment.Single, Whitespace)),
1038 ],
1039 'multilineregex': [
1040 (r'[^/#]+', String.Regex),
1041 (r'///([gimuysd]+\b|\B)', String.Regex, '#pop'),
1042 (r'#\{', String.Interpol, 'interpoling_string'),
1043 (r'[/#]', String.Regex),
1044 ],
1045 'slashstartsregex': [
1046 include('commentsandwhitespace'),
1047 (r'///', String.Regex, ('#pop', 'multilineregex')),
1048 (r'/(?! )(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/'
1049 r'([gimuysd]+\b|\B)', String.Regex, '#pop'),
1050 # This isn't really guarding against mishighlighting well-formed
1051 # code, just the ability to infinite-loop between root and
1052 # slashstartsregex.
1053 (r'/', Operator, '#pop'),
1054 default('#pop'),
1055 ],
1056 'root': [
1057 include('commentsandwhitespace'),
1058 (r'\A(?=\s|/)', Text, 'slashstartsregex'),
1059 (_operator_re, Operator, 'slashstartsregex'),
1060 (r'(?:\([^()]*\))?\s*[=-]>', Name.Function, 'slashstartsregex'),
1061 (r'[{(\[;,]', Punctuation, 'slashstartsregex'),
1062 (r'[})\].]', Punctuation),
1063 (r'(?<![.$])(for|own|in|of|while|until|'
1064 r'loop|break|return|continue|'
1065 r'switch|when|then|if|unless|else|'
1066 r'throw|try|catch|finally|new|delete|typeof|instanceof|super|'
1067 r'extends|this|class|by)\b', Keyword, 'slashstartsregex'),
1068 (r'(?<![.$])(true|false|yes|no|on|off|null|'
1069 r'NaN|Infinity|undefined)\b',
1070 Keyword.Constant),
1071 (r'(Array|Boolean|Date|Error|Function|Math|'
1072 r'Number|Object|RegExp|String|decodeURI|'
1073 r'decodeURIComponent|encodeURI|encodeURIComponent|'
1074 r'eval|isFinite|isNaN|parseFloat|parseInt|document|window|globalThis|Symbol)\b',
1075 Name.Builtin),
1076 (r'([$a-zA-Z_][\w.:$]*)(\s*)([:=])(\s+)',
1077 bygroups(Name.Variable, Whitespace, Operator, Whitespace),
1078 'slashstartsregex'),
1079 (r'(@[$a-zA-Z_][\w.:$]*)(\s*)([:=])(\s+)',
1080 bygroups(Name.Variable.Instance, Whitespace, Operator, Whitespace),
1081 'slashstartsregex'),
1082 (r'@', Name.Other, 'slashstartsregex'),
1083 (r'@?[$a-zA-Z_][\w$]*', Name.Other),
1084 (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
1085 (r'0x[0-9a-fA-F]+', Number.Hex),
1086 (r'[0-9]+', Number.Integer),
1087 ('"""', String, 'tdqs'),
1088 ("'''", String, 'tsqs'),
1089 ('"', String, 'dqs'),
1090 ("'", String, 'sqs'),
1091 ],
1092 'strings': [
1093 (r'[^#\\\'"]+', String),
1094 # note that all coffee script strings are multi-line.
1095 # hashmarks, quotes and backslashes must be parsed one at a time
1096 ],
1097 'interpoling_string': [
1098 (r'\}', String.Interpol, "#pop"),
1099 include('root')
1100 ],
1101 'dqs': [
1102 (r'"', String, '#pop'),
1103 (r'\\.|\'', String), # double-quoted string don't need ' escapes
1104 (r'#\{', String.Interpol, "interpoling_string"),
1105 (r'#', String),
1106 include('strings')
1107 ],
1108 'sqs': [
1109 (r"'", String, '#pop'),
1110 (r'#|\\.|"', String), # single quoted strings don't need " escapses
1111 include('strings')
1112 ],
1113 'tdqs': [
1114 (r'"""', String, '#pop'),
1115 (r'\\.|\'|"', String), # no need to escape quotes in triple-string
1116 (r'#\{', String.Interpol, "interpoling_string"),
1117 (r'#', String),
1118 include('strings'),
1119 ],
1120 'tsqs': [
1121 (r"'''", String, '#pop'),
1122 (r'#|\\.|\'|"', String), # no need to escape quotes in triple-strings
1123 include('strings')
1124 ],
1125 }
1126
1127
1128class MaskLexer(RegexLexer):
1129 """
1130 For Mask markup.
1131 """
1132 name = 'Mask'
1133 url = 'https://github.com/atmajs/MaskJS'
1134 aliases = ['mask']
1135 filenames = ['*.mask']
1136 mimetypes = ['text/x-mask']
1137 version_added = '2.0'
1138
1139 flags = re.MULTILINE | re.IGNORECASE | re.DOTALL
1140 tokens = {
1141 'root': [
1142 (r'\s+', Whitespace),
1143 (r'(//.*?)(\n)', bygroups(Comment.Single, Whitespace)),
1144 (r'/\*.*?\*/', Comment.Multiline),
1145 (r'[{};>]', Punctuation),
1146 (r"'''", String, 'string-trpl-single'),
1147 (r'"""', String, 'string-trpl-double'),
1148 (r"'", String, 'string-single'),
1149 (r'"', String, 'string-double'),
1150 (r'([\w-]+)', Name.Tag, 'node'),
1151 (r'([^.#;{>\s]+)', Name.Class, 'node'),
1152 (r'(#[\w-]+)', Name.Function, 'node'),
1153 (r'(\.[\w-]+)', Name.Variable.Class, 'node')
1154 ],
1155 'string-base': [
1156 (r'\\.', String.Escape),
1157 (r'~\[', String.Interpol, 'interpolation'),
1158 (r'.', String.Single),
1159 ],
1160 'string-single': [
1161 (r"'", String.Single, '#pop'),
1162 include('string-base')
1163 ],
1164 'string-double': [
1165 (r'"', String.Single, '#pop'),
1166 include('string-base')
1167 ],
1168 'string-trpl-single': [
1169 (r"'''", String.Single, '#pop'),
1170 include('string-base')
1171 ],
1172 'string-trpl-double': [
1173 (r'"""', String.Single, '#pop'),
1174 include('string-base')
1175 ],
1176 'interpolation': [
1177 (r'\]', String.Interpol, '#pop'),
1178 (r'(\s*)(:)', bygroups(Whitespace, String.Interpol), 'expression'),
1179 (r'(\s*)(\w+)(:)', bygroups(Whitespace, Name.Other, Punctuation)),
1180 (r'[^\]]+', String.Interpol)
1181 ],
1182 'expression': [
1183 (r'[^\]]+', using(JavascriptLexer), '#pop')
1184 ],
1185 'node': [
1186 (r'\s+', Whitespace),
1187 (r'\.', Name.Variable.Class, 'node-class'),
1188 (r'\#', Name.Function, 'node-id'),
1189 (r'(style)([ \t]*)(=)',
1190 bygroups(Name.Attribute, Whitespace, Operator),
1191 'node-attr-style-value'),
1192 (r'([\w:-]+)([ \t]*)(=)',
1193 bygroups(Name.Attribute, Whitespace, Operator),
1194 'node-attr-value'),
1195 (r'[\w:-]+', Name.Attribute),
1196 (r'[>{;]', Punctuation, '#pop')
1197 ],
1198 'node-class': [
1199 (r'[\w-]+', Name.Variable.Class),
1200 (r'~\[', String.Interpol, 'interpolation'),
1201 default('#pop')
1202 ],
1203 'node-id': [
1204 (r'[\w-]+', Name.Function),
1205 (r'~\[', String.Interpol, 'interpolation'),
1206 default('#pop')
1207 ],
1208 'node-attr-value': [
1209 (r'\s+', Whitespace),
1210 (r'\w+', Name.Variable, '#pop'),
1211 (r"'", String, 'string-single-pop2'),
1212 (r'"', String, 'string-double-pop2'),
1213 default('#pop')
1214 ],
1215 'node-attr-style-value': [
1216 (r'\s+', Whitespace),
1217 (r"'", String.Single, 'css-single-end'),
1218 (r'"', String.Single, 'css-double-end'),
1219 include('node-attr-value')
1220 ],
1221 'css-base': [
1222 (r'\s+', Whitespace),
1223 (r";", Punctuation),
1224 (r"[\w\-]+\s*:", Name.Builtin)
1225 ],
1226 'css-single-end': [
1227 include('css-base'),
1228 (r"'", String.Single, '#pop:2'),
1229 (r"[^;']+", Name.Entity)
1230 ],
1231 'css-double-end': [
1232 include('css-base'),
1233 (r'"', String.Single, '#pop:2'),
1234 (r'[^;"]+', Name.Entity)
1235 ],
1236 'string-single-pop2': [
1237 (r"'", String.Single, '#pop:2'),
1238 include('string-base')
1239 ],
1240 'string-double-pop2': [
1241 (r'"', String.Single, '#pop:2'),
1242 include('string-base')
1243 ],
1244 }
1245
1246
1247class EarlGreyLexer(RegexLexer):
1248 """
1249 For Earl-Grey source code.
1250
1251 .. versionadded: 2.1
1252 """
1253
1254 name = 'Earl Grey'
1255 aliases = ['earl-grey', 'earlgrey', 'eg']
1256 filenames = ['*.eg']
1257 mimetypes = ['text/x-earl-grey']
1258 url = 'https://github.com/breuleux/earl-grey'
1259 version_added = ''
1260
1261 tokens = {
1262 'root': [
1263 (r'\n', Whitespace),
1264 include('control'),
1265 (r'[^\S\n]+', Text),
1266 (r'(;;.*)(\n)', bygroups(Comment, Whitespace)),
1267 (r'[\[\]{}:(),;]', Punctuation),
1268 (r'(\\)(\n)', bygroups(String.Escape, Whitespace)),
1269 (r'\\', Text),
1270 include('errors'),
1271 (words((
1272 'with', 'where', 'when', 'and', 'not', 'or', 'in',
1273 'as', 'of', 'is'),
1274 prefix=r'(?<=\s|\[)', suffix=r'(?![\w$\-])'),
1275 Operator.Word),
1276 (r'[*@]?->', Name.Function),
1277 (r'[+\-*/~^<>%&|?!@#.]*=', Operator.Word),
1278 (r'\.{2,3}', Operator.Word), # Range Operator
1279 (r'([+*/~^<>&|?!]+)|([#\-](?=\s))|@@+(?=\s)|=+', Operator),
1280 (r'(?<![\w$\-])(var|let)(?:[^\w$])', Keyword.Declaration),
1281 include('keywords'),
1282 include('builtins'),
1283 include('assignment'),
1284 (r'''(?x)
1285 (?:()([a-zA-Z$_](?:[\w$\-]*[\w$])?)|
1286 (?<=[\s{\[(])(\.)([a-zA-Z$_](?:[\w$\-]*[\w$])?))
1287 (?=.*%)''',
1288 bygroups(Punctuation, Name.Tag, Punctuation, Name.Class.Start), 'dbs'),
1289 (r'[rR]?`', String.Backtick, 'bt'),
1290 (r'[rR]?```', String.Backtick, 'tbt'),
1291 (r'(?<=[\s\[{(,;])\.([a-zA-Z$_](?:[\w$\-]*[\w$])?)'
1292 r'(?=[\s\]}),;])', String.Symbol),
1293 include('nested'),
1294 (r'(?:[rR]|[rR]\.[gmi]{1,3})?"', String, combined('stringescape', 'dqs')),
1295 (r'(?:[rR]|[rR]\.[gmi]{1,3})?\'', String, combined('stringescape', 'sqs')),
1296 (r'"""', String, combined('stringescape', 'tdqs')),
1297 include('tuple'),
1298 include('import_paths'),
1299 include('name'),
1300 include('numbers'),
1301 ],
1302 'dbs': [
1303 (r'(\.)([a-zA-Z$_](?:[\w$\-]*[\w$])?)(?=[.\[\s])',
1304 bygroups(Punctuation, Name.Class.DBS)),
1305 (r'(\[)([\^#][a-zA-Z$_](?:[\w$\-]*[\w$])?)(\])',
1306 bygroups(Punctuation, Name.Entity.DBS, Punctuation)),
1307 (r'\s+', Whitespace),
1308 (r'%', Operator.DBS, '#pop'),
1309 ],
1310 'import_paths': [
1311 (r'(?<=[\s:;,])(\.{1,3}(?:[\w\-]*/)*)(\w(?:[\w\-]*\w)*)(?=[\s;,])',
1312 bygroups(Text.Whitespace, Text)),
1313 ],
1314 'assignment': [
1315 (r'(\.)?([a-zA-Z$_](?:[\w$\-]*[\w$])?)'
1316 r'(?=\s+[+\-*/~^<>%&|?!@#.]*\=\s)',
1317 bygroups(Punctuation, Name.Variable))
1318 ],
1319 'errors': [
1320 (words(('Error', 'TypeError', 'ReferenceError'),
1321 prefix=r'(?<![\w\-$.])', suffix=r'(?![\w\-$.])'),
1322 Name.Exception),
1323 (r'''(?x)
1324 (?<![\w$])
1325 E\.[\w$](?:[\w$\-]*[\w$])?
1326 (?:\.[\w$](?:[\w$\-]*[\w$])?)*
1327 (?=[({\[?!\s])''',
1328 Name.Exception),
1329 ],
1330 'control': [
1331 (r'''(?x)
1332 ([a-zA-Z$_](?:[\w$-]*[\w$])?)
1333 (?!\n)\s+
1334 (?!and|as|each\*|each|in|is|mod|of|or|when|where|with)
1335 (?=(?:[+\-*/~^<>%&|?!@#.])?[a-zA-Z$_](?:[\w$-]*[\w$])?)''',
1336 Keyword.Control),
1337 (r'([a-zA-Z$_](?:[\w$-]*[\w$])?)(?!\n)(\s+)(?=[\'"\d{\[(])',
1338 bygroups(Keyword.Control, Whitespace)),
1339 (r'''(?x)
1340 (?:
1341 (?<=[%=])|
1342 (?<=[=\-]>)|
1343 (?<=with|each|with)|
1344 (?<=each\*|where)
1345 )(\s+)
1346 ([a-zA-Z$_](?:[\w$-]*[\w$])?)(:)''',
1347 bygroups(Whitespace, Keyword.Control, Punctuation)),
1348 (r'''(?x)
1349 (?<![+\-*/~^<>%&|?!@#.])(\s+)
1350 ([a-zA-Z$_](?:[\w$-]*[\w$])?)(:)''',
1351 bygroups(Whitespace, Keyword.Control, Punctuation)),
1352 ],
1353 'nested': [
1354 (r'''(?x)
1355 (?<=[\w$\]})])(\.)
1356 ([a-zA-Z$_](?:[\w$-]*[\w$])?)
1357 (?=\s+with(?:\s|\n))''',
1358 bygroups(Punctuation, Name.Function)),
1359 (r'''(?x)
1360 (?<!\s)(\.)
1361 ([a-zA-Z$_](?:[\w$-]*[\w$])?)
1362 (?=[}\]).,;:\s])''',
1363 bygroups(Punctuation, Name.Field)),
1364 (r'''(?x)
1365 (?<=[\w$\]})])(\.)
1366 ([a-zA-Z$_](?:[\w$-]*[\w$])?)
1367 (?=[\[{(:])''',
1368 bygroups(Punctuation, Name.Function)),
1369 ],
1370 'keywords': [
1371 (words((
1372 'each', 'each*', 'mod', 'await', 'break', 'chain',
1373 'continue', 'elif', 'expr-value', 'if', 'match',
1374 'return', 'yield', 'pass', 'else', 'require', 'var',
1375 'let', 'async', 'method', 'gen'),
1376 prefix=r'(?<![\w\-$.])', suffix=r'(?![\w\-$.])'),
1377 Keyword.Pseudo),
1378 (words(('this', 'self', '@'),
1379 prefix=r'(?<![\w\-$.])', suffix=r'(?![\w\-$])'),
1380 Keyword.Constant),
1381 (words((
1382 'Function', 'Object', 'Array', 'String', 'Number',
1383 'Boolean', 'ErrorFactory', 'ENode', 'Promise'),
1384 prefix=r'(?<![\w\-$.])', suffix=r'(?![\w\-$])'),
1385 Keyword.Type),
1386 ],
1387 'builtins': [
1388 (words((
1389 'send', 'object', 'keys', 'items', 'enumerate', 'zip',
1390 'product', 'neighbours', 'predicate', 'equal',
1391 'nequal', 'contains', 'repr', 'clone', 'range',
1392 'getChecker', 'get-checker', 'getProperty', 'get-property',
1393 'getProjector', 'get-projector', 'consume', 'take',
1394 'promisify', 'spawn', 'constructor'),
1395 prefix=r'(?<![\w\-#.])', suffix=r'(?![\w\-.])'),
1396 Name.Builtin),
1397 (words((
1398 'true', 'false', 'null', 'undefined'),
1399 prefix=r'(?<![\w\-$.])', suffix=r'(?![\w\-$.])'),
1400 Name.Constant),
1401 ],
1402 'name': [
1403 (r'@([a-zA-Z$_](?:[\w$-]*[\w$])?)', Name.Variable.Instance),
1404 (r'([a-zA-Z$_](?:[\w$-]*[\w$])?)(\+\+|\-\-)?',
1405 bygroups(Name.Symbol, Operator.Word))
1406 ],
1407 'tuple': [
1408 (r'#[a-zA-Z_][\w\-]*(?=[\s{(,;])', Name.Namespace)
1409 ],
1410 'interpoling_string': [
1411 (r'\}', String.Interpol, '#pop'),
1412 include('root')
1413 ],
1414 'stringescape': [
1415 (r'\\([\\abfnrtv"\']|\n|N\{.*?\}|u[a-fA-F0-9]{4}|'
1416 r'U[a-fA-F0-9]{8}|x[a-fA-F0-9]{2}|[0-7]{1,3})', String.Escape)
1417 ],
1418 'strings': [
1419 (r'[^\\\'"]', String),
1420 (r'[\'"\\]', String),
1421 (r'\n', String) # All strings are multiline in EG
1422 ],
1423 'dqs': [
1424 (r'"', String, '#pop'),
1425 (r'\\\\|\\"|\\\n', String.Escape),
1426 include('strings')
1427 ],
1428 'sqs': [
1429 (r"'", String, '#pop'),
1430 (r"\\\\|\\'|\\\n", String.Escape),
1431 (r'\{', String.Interpol, 'interpoling_string'),
1432 include('strings')
1433 ],
1434 'tdqs': [
1435 (r'"""', String, '#pop'),
1436 include('strings'),
1437 ],
1438 'bt': [
1439 (r'`', String.Backtick, '#pop'),
1440 (r'(?<!`)\n', String.Backtick),
1441 (r'\^=?', String.Escape),
1442 (r'.+', String.Backtick),
1443 ],
1444 'tbt': [
1445 (r'```', String.Backtick, '#pop'),
1446 (r'\n', String.Backtick),
1447 (r'\^=?', String.Escape),
1448 (r'[^`]+', String.Backtick),
1449 ],
1450 'numbers': [
1451 (r'\d+\.(?!\.)\d*([eE][+-]?[0-9]+)?', Number.Float),
1452 (r'\d+[eE][+-]?[0-9]+', Number.Float),
1453 (r'8r[0-7]+', Number.Oct),
1454 (r'2r[01]+', Number.Bin),
1455 (r'16r[a-fA-F0-9]+', Number.Hex),
1456 (r'([3-79]|[12][0-9]|3[0-6])r[a-zA-Z\d]+(\.[a-zA-Z\d]+)?',
1457 Number.Radix),
1458 (r'\d+', Number.Integer)
1459 ],
1460 }
1461
1462
1463class JuttleLexer(RegexLexer):
1464 """
1465 For Juttle source code.
1466 """
1467
1468 name = 'Juttle'
1469 url = 'http://juttle.github.io/'
1470 aliases = ['juttle']
1471 filenames = ['*.juttle']
1472 mimetypes = ['application/juttle', 'application/x-juttle',
1473 'text/x-juttle', 'text/juttle']
1474 version_added = '2.2'
1475
1476 flags = re.DOTALL | re.MULTILINE
1477
1478 tokens = {
1479 'commentsandwhitespace': [
1480 (r'\s+', Whitespace),
1481 (r'(//.*?)(\n)', bygroups(Comment.Single, Whitespace)),
1482 (r'/\*.*?\*/', Comment.Multiline)
1483 ],
1484 'slashstartsregex': [
1485 include('commentsandwhitespace'),
1486 (r'/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/'
1487 r'([gimuysd]+\b|\B)', String.Regex, '#pop'),
1488 (r'(?=/)', Text, ('#pop', 'badregex')),
1489 default('#pop')
1490 ],
1491 'badregex': [
1492 (r'\n', Text, '#pop')
1493 ],
1494 'root': [
1495 (r'^(?=\s|/)', Text, 'slashstartsregex'),
1496 include('commentsandwhitespace'),
1497 (r':\d{2}:\d{2}:\d{2}(\.\d*)?:', String.Moment),
1498 (r':(now|beginning|end|forever|yesterday|today|tomorrow|'
1499 r'(\d+(\.\d*)?|\.\d+)(ms|[smhdwMy])?):', String.Moment),
1500 (r':\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d*)?)?'
1501 r'(Z|[+-]\d{2}:\d{2}|[+-]\d{4})?:', String.Moment),
1502 (r':((\d+(\.\d*)?|\.\d+)[ ]+)?(millisecond|second|minute|hour|'
1503 r'day|week|month|year)[s]?'
1504 r'(([ ]+and[ ]+(\d+[ ]+)?(millisecond|second|minute|hour|'
1505 r'day|week|month|year)[s]?)'
1506 r'|[ ]+(ago|from[ ]+now))*:', String.Moment),
1507 (r'\+\+|--|~|&&|\?|:|\|\||\\(?=\n)|'
1508 r'(==?|!=?|[-<>+*%&|^/])=?', Operator, 'slashstartsregex'),
1509 (r'[{(\[;,]', Punctuation, 'slashstartsregex'),
1510 (r'[})\].]', Punctuation),
1511 (r'(import|return|continue|if|else)\b', Keyword, 'slashstartsregex'),
1512 (r'(var|const|function|reducer|sub|input)\b', Keyword.Declaration,
1513 'slashstartsregex'),
1514 (r'(batch|emit|filter|head|join|keep|pace|pass|put|read|reduce|remove|'
1515 r'sequence|skip|sort|split|tail|unbatch|uniq|view|write)\b',
1516 Keyword.Reserved),
1517 (r'(true|false|null|Infinity)\b', Keyword.Constant),
1518 (r'(Array|Date|Juttle|Math|Number|Object|RegExp|String)\b',
1519 Name.Builtin),
1520 (JS_IDENT, Name.Other),
1521 (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
1522 (r'[0-9]+', Number.Integer),
1523 (r'"(\\\\|\\[^\\]|[^"\\])*"', String.Double),
1524 (r"'(\\\\|\\[^\\]|[^'\\])*'", String.Single),
1525 ]
1526
1527 }
1528
1529
1530class NodeConsoleLexer(Lexer):
1531 """
1532 For parsing within an interactive Node.js REPL, such as:
1533
1534 .. sourcecode:: nodejsrepl
1535
1536 > let a = 3
1537 undefined
1538 > a
1539 3
1540 > let b = '4'
1541 undefined
1542 > b
1543 '4'
1544 > b == a
1545 false
1546
1547 .. versionadded: 2.10
1548 """
1549 name = 'Node.js REPL console session'
1550 aliases = ['nodejsrepl', ]
1551 mimetypes = ['text/x-nodejsrepl', ]
1552 url = 'https://nodejs.org'
1553 version_added = ''
1554
1555 def get_tokens_unprocessed(self, text):
1556 jslexer = JavascriptLexer(**self.options)
1557
1558 curcode = ''
1559 insertions = []
1560
1561 for match in line_re.finditer(text):
1562 line = match.group()
1563 if line.startswith('> '):
1564 insertions.append((len(curcode),
1565 [(0, Generic.Prompt, line[:1]),
1566 (1, Whitespace, line[1:2])]))
1567
1568 curcode += line[2:]
1569 elif line.startswith('...'):
1570 # node does a nested ... thing depending on depth
1571 code = line.lstrip('.')
1572 lead = len(line) - len(code)
1573
1574 insertions.append((len(curcode),
1575 [(0, Generic.Prompt, line[:lead])]))
1576
1577 curcode += code
1578 else:
1579 if curcode:
1580 yield from do_insertions(insertions,
1581 jslexer.get_tokens_unprocessed(curcode))
1582
1583 curcode = ''
1584 insertions = []
1585
1586 yield from do_insertions([],
1587 jslexer.get_tokens_unprocessed(line))
1588
1589 if curcode:
1590 yield from do_insertions(insertions,
1591 jslexer.get_tokens_unprocessed(curcode))