Pygments

generic syntax highlighter


root/pygments/lexers/agile.py

Revision 1061:867193cd8aed, 79.1 kB (checked in by Georg Brandl <georg@…>, 11 days ago)

#517: "type" is not a builtin in ruby.

Line 
1# -*- coding: utf-8 -*-
2"""
3    pygments.lexers.agile
4    ~~~~~~~~~~~~~~~~~~~~~
5
6    Lexers for agile languages.
7
8    :copyright: Copyright 2006-2010 by the Pygments team, see AUTHORS.
9    :license: BSD, see LICENSE for details.
10"""
11
12import re
13
14from pygments.lexer import Lexer, RegexLexer, ExtendedRegexLexer, \
15     LexerContext, include, combined, do_insertions, bygroups, using
16from pygments.token import Error, Text, Other, \
17     Comment, Operator, Keyword, Name, String, Number, Generic, Punctuation
18from pygments.util import get_bool_opt, get_list_opt, shebang_matches
19from pygments import unistring as uni
20
21
22__all__ = ['PythonLexer', 'PythonConsoleLexer', 'PythonTracebackLexer',
23           'RubyLexer', 'RubyConsoleLexer', 'PerlLexer', 'LuaLexer',
24           'MiniDLexer', 'IoLexer', 'TclLexer', 'ClojureLexer',
25           'Python3Lexer', 'Python3TracebackLexer', 'FactorLexer', 'IokeLexer']
26
27# b/w compatibility
28from pygments.lexers.functional import SchemeLexer
29
30line_re  = re.compile('.*?\n')
31
32
33class PythonLexer(RegexLexer):
34    """
35    For `Python <http://www.python.org>`_ source code.
36    """
37
38    name = 'Python'
39    aliases = ['python', 'py']
40    filenames = ['*.py', '*.pyw', '*.sc', 'SConstruct', 'SConscript', '*.tac']
41    mimetypes = ['text/x-python', 'application/x-python']
42
43    tokens = {
44        'root': [
45            (r'\n', Text),
46            (r'^(\s*)([rRuU]{,2}"""(?:.|\n)*?""")', bygroups(Text, String.Doc)),
47            (r"^(\s*)([rRuU]{,2}'''(?:.|\n)*?''')", bygroups(Text, String.Doc)),
48            (r'[^\S\n]+', Text),
49            (r'#.*$', Comment),
50            (r'[]{}:(),;[]', Punctuation),
51            (r'\\\n', Text),
52            (r'\\', Text),
53            (r'(in|is|and|or|not)\b', Operator.Word),
54            (r'!=|==|<<|>>|[-~+/*%=<>&^|.]', Operator),
55            include('keywords'),
56            (r'(def)((?:\s|\\\s)+)', bygroups(Keyword, Text), 'funcname'),
57            (r'(class)((?:\s|\\\s)+)', bygroups(Keyword, Text), 'classname'),
58            (r'(from)((?:\s|\\\s)+)', bygroups(Keyword.Namespace, Text), 'fromimport'),
59            (r'(import)((?:\s|\\\s)+)', bygroups(Keyword.Namespace, Text), 'import'),
60            include('builtins'),
61            include('backtick'),
62            ('(?:[rR]|[uU][rR]|[rR][uU])"""', String, 'tdqs'),
63            ("(?:[rR]|[uU][rR]|[rR][uU])'''", String, 'tsqs'),
64            ('(?:[rR]|[uU][rR]|[rR][uU])"', String, 'dqs'),
65            ("(?:[rR]|[uU][rR]|[rR][uU])'", String, 'sqs'),
66            ('[uU]?"""', String, combined('stringescape', 'tdqs')),
67            ("[uU]?'''", String, combined('stringescape', 'tsqs')),
68            ('[uU]?"', String, combined('stringescape', 'dqs')),
69            ("[uU]?'", String, combined('stringescape', 'sqs')),
70            include('name'),
71            include('numbers'),
72        ],
73        'keywords': [
74            (r'(assert|break|continue|del|elif|else|except|exec|'
75             r'finally|for|global|if|lambda|pass|print|raise|'
76             r'return|try|while|yield|as|with)\b', Keyword),
77        ],
78        'builtins': [
79            (r'(?<!\.)(__import__|abs|all|any|apply|basestring|bin|bool|buffer|'
80             r'bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|'
81             r'complex|delattr|dict|dir|divmod|enumerate|eval|execfile|exit|'
82             r'file|filter|float|frozenset|getattr|globals|hasattr|hash|hex|id|'
83             r'input|int|intern|isinstance|issubclass|iter|len|list|locals|'
84             r'long|map|max|min|next|object|oct|open|ord|pow|property|range|'
85             r'raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|'
86             r'sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|'
87             r'vars|xrange|zip)\b', Name.Builtin),
88            (r'(?<!\.)(self|None|Ellipsis|NotImplemented|False|True'
89             r')\b', Name.Builtin.Pseudo),
90            (r'(?<!\.)(ArithmeticError|AssertionError|AttributeError|'
91             r'BaseException|DeprecationWarning|EOFError|EnvironmentError|'
92             r'Exception|FloatingPointError|FutureWarning|GeneratorExit|IOError|'
93             r'ImportError|ImportWarning|IndentationError|IndexError|KeyError|'
94             r'KeyboardInterrupt|LookupError|MemoryError|NameError|'
95             r'NotImplemented|NotImplementedError|OSError|OverflowError|'
96             r'OverflowWarning|PendingDeprecationWarning|ReferenceError|'
97             r'RuntimeError|RuntimeWarning|StandardError|StopIteration|'
98             r'SyntaxError|SyntaxWarning|SystemError|SystemExit|TabError|'
99             r'TypeError|UnboundLocalError|UnicodeDecodeError|'
100             r'UnicodeEncodeError|UnicodeError|UnicodeTranslateError|'
101             r'UnicodeWarning|UserWarning|ValueError|VMSError|Warning|'
102             r'WindowsError|ZeroDivisionError)\b', Name.Exception),
103        ],
104        'numbers': [
105            (r'(\d+\.\d*|\d*\.\d+)([eE][+-]?[0-9]+)?', Number.Float),
106            (r'\d+[eE][+-]?[0-9]+', Number.Float),
107            (r'0\d+', Number.Oct),
108            (r'0[xX][a-fA-F0-9]+', Number.Hex),
109            (r'\d+L', Number.Integer.Long),
110            (r'\d+', Number.Integer)
111        ],
112        'backtick': [
113            ('`.*?`', String.Backtick),
114        ],
115        'name': [
116            (r'@[a-zA-Z0-9_.]+', Name.Decorator),
117            ('[a-zA-Z_][a-zA-Z0-9_]*', Name),
118        ],
119        'funcname': [
120            ('[a-zA-Z_][a-zA-Z0-9_]*', Name.Function, '#pop')
121        ],
122        'classname': [
123            ('[a-zA-Z_][a-zA-Z0-9_]*', Name.Class, '#pop')
124        ],
125        'import': [
126            (r'((?:\s|\\\s)+)(as)((?:\s|\\\s)+)',
127             bygroups(Text, Keyword.Namespace, Text)),
128            (r'[a-zA-Z_][a-zA-Z0-9_.]*', Name.Namespace),
129            (r'(\s*)(,)(\s*)', bygroups(Text, Operator, Text)),
130            (r'', Text, '#pop') # all else: go back
131        ],
132        'fromimport': [
133            (r'((?:\s|\\\s)+)(import)\b', bygroups(Text, Keyword.Namespace), '#pop'),
134            (r'[a-zA-Z_.][a-zA-Z0-9_.]*', Name.Namespace),
135        ],
136        'stringescape': [
137            (r'\\([\\abfnrtv"\']|\n|N{.*?}|u[a-fA-F0-9]{4}|'
138             r'U[a-fA-F0-9]{8}|x[a-fA-F0-9]{2}|[0-7]{1,3})', String.Escape)
139        ],
140        'strings': [
141            (r'%(\([a-zA-Z0-9_]+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?'
142             '[hlL]?[diouxXeEfFgGcrs%]', String.Interpol),
143            (r'[^\\\'"%\n]+', String),
144            # quotes, percents and backslashes must be parsed one at a time
145            (r'[\'"\\]', String),
146            # unhandled string formatting sign
147            (r'%', String)
148            # newlines are an error (use "nl" state)
149        ],
150        'nl': [
151            (r'\n', String)
152        ],
153        'dqs': [
154            (r'"', String, '#pop'),
155            (r'\\\\|\\"|\\\n', String.Escape), # included here again for raw strings
156            include('strings')
157        ],
158        'sqs': [
159            (r"'", String, '#pop'),
160            (r"\\\\|\\'|\\\n", String.Escape), # included here again for raw strings
161            include('strings')
162        ],
163        'tdqs': [
164            (r'"""', String, '#pop'),
165            include('strings'),
166            include('nl')
167        ],
168        'tsqs': [
169            (r"'''", String, '#pop'),
170            include('strings'),
171            include('nl')
172        ],
173    }
174
175    def analyse_text(text):
176        return shebang_matches(text, r'pythonw?(2\.\d)?')
177
178
179class Python3Lexer(RegexLexer):
180    """
181    For `Python <http://www.python.org>`_ source code (version 3.0).
182
183    *New in Pygments 0.10.*
184    """
185
186    name = 'Python 3'
187    aliases = ['python3', 'py3']
188    filenames = []  # Nothing until Python 3 gets widespread
189    mimetypes = ['text/x-python3', 'application/x-python3']
190
191    flags = re.MULTILINE | re.UNICODE
192
193    uni_name = "[%s][%s]*" % (uni.xid_start, uni.xid_continue)
194
195    tokens = PythonLexer.tokens.copy()
196    tokens['keywords'] = [
197        (r'(assert|break|continue|del|elif|else|except|'
198         r'finally|for|global|if|lambda|pass|raise|'
199         r'return|try|while|yield|as|with|True|False|None)\b', Keyword),
200    ]
201    tokens['builtins'] = [
202        (r'(?<!\.)(__import__|abs|all|any|bin|bool|bytearray|bytes|'
203         r'chr|classmethod|cmp|compile|complex|delattr|dict|dir|'
204         r'divmod|enumerate|eval|filter|float|format|frozenset|getattr|'
205         r'globals|hasattr|hash|hex|id|input|int|isinstance|issubclass|'
206         r'iter|len|list|locals|map|max|memoryview|min|next|object|oct|'
207         r'open|ord|pow|print|property|range|repr|reversed|round|'
208         r'set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|'
209         r'vars|zip)\b', Name.Builtin),
210        (r'(?<!\.)(self|Ellipsis|NotImplemented)\b', Name.Builtin.Pseudo),
211        (r'(?<!\.)(ArithmeticError|AssertionError|AttributeError|'
212         r'BaseException|BufferError|BytesWarning|DeprecationWarning|'
213         r'EOFError|EnvironmentError|Exception|FloatingPointError|'
214         r'FutureWarning|GeneratorExit|IOError|ImportError|'
215         r'ImportWarning|IndentationError|IndexError|KeyError|'
216         r'KeyboardInterrupt|LookupError|MemoryError|NameError|'
217         r'NotImplementedError|OSError|OverflowError|'
218         r'PendingDeprecationWarning|ReferenceError|'
219         r'RuntimeError|RuntimeWarning|StopIteration|'
220         r'SyntaxError|SyntaxWarning|SystemError|SystemExit|TabError|'
221         r'TypeError|UnboundLocalError|UnicodeDecodeError|'
222         r'UnicodeEncodeError|UnicodeError|UnicodeTranslateError|'
223         r'UnicodeWarning|UserWarning|ValueError|VMSError|Warning|'
224         r'WindowsError|ZeroDivisionError)\b', Name.Exception),
225    ]
226    tokens['numbers'] = [
227        (r'(\d+\.\d*|\d*\.\d+)([eE][+-]?[0-9]+)?', Number.Float),
228        (r'0[oO][0-7]+', Number.Oct),
229        (r'0[bB][01]+', Number.Bin),
230        (r'0[xX][a-fA-F0-9]+', Number.Hex),
231        (r'\d+', Number.Integer)
232    ]
233    tokens['backtick'] = []
234    tokens['name'] = [
235        (r'@[a-zA-Z0-9_]+', Name.Decorator),
236        (uni_name, Name),
237    ]
238    tokens['funcname'] = [
239        (uni_name, Name.Function, '#pop')
240    ]
241    tokens['classname'] = [
242        (uni_name, Name.Class, '#pop')
243    ]
244    tokens['import'] = [
245        (r'(\s+)(as)(\s+)', bygroups(Text, Keyword, Text)),
246        (r'\.', Name.Namespace),
247        (uni_name, Name.Namespace),
248        (r'(\s*)(,)(\s*)', bygroups(Text, Operator, Text)),
249        (r'', Text, '#pop') # all else: go back
250    ]
251    tokens['fromimport'] = [
252        (r'(\s+)(import)\b', bygroups(Text, Keyword), '#pop'),
253        (r'\.', Name.Namespace),
254        (uni_name, Name.Namespace),
255    ]
256    # don't highlight "%s" substitutions
257    tokens['strings'] = [
258        (r'[^\\\'"%\n]+', String),
259        # quotes, percents and backslashes must be parsed one at a time
260        (r'[\'"\\]', String),
261        # unhandled string formatting sign
262        (r'%', String)
263        # newlines are an error (use "nl" state)
264    ]
265
266    def analyse_text(text):
267        return shebang_matches(text, r'pythonw?3(\.\d)?')
268
269
270class PythonConsoleLexer(Lexer):
271    """
272    For Python console output or doctests, such as:
273
274    .. sourcecode:: pycon
275
276        >>> a = 'foo'
277        >>> print a
278        foo
279        >>> 1 / 0
280        Traceback (most recent call last):
281          File "<stdin>", line 1, in <module>
282        ZeroDivisionError: integer division or modulo by zero
283
284    Additional options:
285
286    `python3`
287        Use Python 3 lexer for code.  Default is ``False``.
288        *New in Pygments 1.0.*
289    """
290    name = 'Python console session'
291    aliases = ['pycon']
292    mimetypes = ['text/x-python-doctest']
293
294    def __init__(self, **options):
295        self.python3 = get_bool_opt(options, 'python3', False)
296        Lexer.__init__(self, **options)
297
298    def get_tokens_unprocessed(self, text):
299        if self.python3:
300            pylexer = Python3Lexer(**self.options)
301            tblexer = Python3TracebackLexer(**self.options)
302        else:
303            pylexer = PythonLexer(**self.options)
304            tblexer = PythonTracebackLexer(**self.options)
305
306        curcode = ''
307        insertions = []
308        curtb = ''
309        tbindex = 0
310        tb = 0
311        for match in line_re.finditer(text):
312            line = match.group()
313            if line.startswith('>>> ') or line.startswith('... '):
314                tb = 0
315                insertions.append((len(curcode),
316                                   [(0, Generic.Prompt, line[:4])]))
317                curcode += line[4:]
318            elif line.rstrip() == '...' and not tb:
319                # only a new >>> prompt can end an exception block
320                # otherwise an ellipsis in place of the traceback frames
321                # will be mishandled
322                insertions.append((len(curcode),
323                                   [(0, Generic.Prompt, '...')]))
324                curcode += line[3:]
325            else:
326                if curcode:
327                    for item in do_insertions(insertions,
328                                    pylexer.get_tokens_unprocessed(curcode)):
329                        yield item
330                    curcode = ''
331                    insertions = []
332                if (line.startswith('Traceback (most recent call last):') or
333                    re.match(r'  File "[^"]+", line \d+\n$', line)):
334                    tb = 1
335                    curtb = line
336                    tbindex = match.start()
337                elif line == 'KeyboardInterrupt\n':
338                    yield match.start(), Name.Class, line
339                elif tb:
340                    curtb += line
341                    if not (line.startswith(' ') or line.strip() == '...'):
342                        tb = 0
343                        for i, t, v in tblexer.get_tokens_unprocessed(curtb):
344                            yield tbindex+i, t, v
345                else:
346                    yield match.start(), Generic.Output, line
347        if curcode:
348            for item in do_insertions(insertions,
349                                      pylexer.get_tokens_unprocessed(curcode)):
350                yield item
351
352
353class PythonTracebackLexer(RegexLexer):
354    """
355    For Python tracebacks.
356
357    *New in Pygments 0.7.*
358    """
359
360    name = 'Python Traceback'
361    aliases = ['pytb']
362    filenames = ['*.pytb']
363    mimetypes = ['text/x-python-traceback']
364
365    tokens = {
366        'root': [
367            (r'^Traceback \(most recent call last\):\n', Generic.Traceback, 'intb'),
368            # SyntaxError starts with this.
369            (r'^(?=  File "[^"]+", line \d+)', Generic.Traceback, 'intb'),
370            (r'^.*\n', Other),
371        ],
372        'intb': [
373            (r'^(  File )("[^"]+")(, line )(\d+)(, in )(.+)(\n)',
374             bygroups(Text, Name.Builtin, Text, Number, Text, Name.Identifier, Text)),
375            (r'^(  File )("[^"]+")(, line )(\d+)(\n)',
376             bygroups(Text, Name.Builtin, Text, Number, Text)),
377            (r'^(    )(.+)(\n)',
378             bygroups(Text, using(PythonLexer), Text)),
379            (r'^([ \t]*)(...)(\n)',
380             bygroups(Text, Comment, Text)), # for doctests...
381            (r'^(.+)(: )(.+)(\n)',
382             bygroups(Name.Class, Text, Name.Identifier, Text), '#pop'),
383            (r'^([a-zA-Z_][a-zA-Z0-9_]*)(:?\n)',
384             bygroups(Name.Class, Text), '#pop')
385        ],
386    }
387
388
389class Python3TracebackLexer(RegexLexer):
390    """
391    For Python 3.0 tracebacks, with support for chained exceptions.
392
393    *New in Pygments 1.0.*
394    """
395
396    name = 'Python 3.0 Traceback'
397    aliases = ['py3tb']
398    filenames = ['*.py3tb']
399    mimetypes = ['text/x-python3-traceback']
400
401    tokens = {
402        'root': [
403            (r'\n', Text),
404            (r'^Traceback \(most recent call last\):\n', Generic.Traceback, 'intb'),
405            (r'^During handling of the above exception, another '
406             r'exception occurred:\n\n', Generic.Traceback),
407            (r'^The above exception was the direct cause of the '
408             r'following exception:\n\n', Generic.Traceback),
409        ],
410        'intb': [
411            (r'^(  File )("[^"]+")(, line )(\d+)(, in )(.+)(\n)',
412             bygroups(Text, Name.Builtin, Text, Number, Text, Name.Identifier, Text)),
413            (r'^(    )(.+)(\n)',
414             bygroups(Text, using(Python3Lexer), Text)),
415            (r'^([ \t]*)(...)(\n)',
416             bygroups(Text, Comment, Text)), # for doctests...
417            (r'^(.+)(: )(.+)(\n)',
418             bygroups(Name.Class, Text, Name.Identifier, Text), '#pop'),
419            (r'^([a-zA-Z_][a-zA-Z0-9_]*)(:?\n)',
420             bygroups(Name.Class, Text), '#pop')
421        ],
422    }
423
424
425class RubyLexer(ExtendedRegexLexer):
426    """
427    For `Ruby <http://www.ruby-lang.org>`_ source code.
428    """
429
430    name = 'Ruby'
431    aliases = ['rb', 'ruby', 'duby']
432    filenames = ['*.rb', '*.rbw', 'Rakefile', '*.rake', '*.gemspec',
433                 '*.rbx', '*.duby']
434    mimetypes = ['text/x-ruby', 'application/x-ruby']
435
436    flags = re.DOTALL | re.MULTILINE
437
438    def heredoc_callback(self, match, ctx):
439        # okay, this is the hardest part of parsing Ruby...
440        # match: 1 = <<-?, 2 = quote? 3 = name 4 = quote? 5 = rest of line
441
442        start = match.start(1)
443        yield start, Operator, match.group(1)        # <<-?
444        yield match.start(2), String.Heredoc, match.group(2)  # quote ", ', `
445        yield match.start(3), Name.Constant, match.group(3)   # heredoc name
446        yield match.start(4), String.Heredoc, match.group(4)  # quote again
447
448        heredocstack = ctx.__dict__.setdefault('heredocstack', [])
449        outermost = not bool(heredocstack)
450        heredocstack.append((match.group(1) == '<<-', match.group(3)))
451
452        ctx.pos = match.start(5)
453        ctx.end = match.end(5)
454        # this may find other heredocs
455        for i, t, v in self.get_tokens_unprocessed(context=ctx):
456            yield i, t, v
457        ctx.pos = match.end()
458
459        if outermost:
460            # this is the outer heredoc again, now we can process them all
461            for tolerant, hdname in heredocstack:
462                lines = []
463                for match in line_re.finditer(ctx.text, ctx.pos):
464                    if tolerant:
465                        check = match.group().strip()
466                    else:
467                        check = match.group().rstrip()
468                    if check == hdname:
469                        for amatch in lines:
470                            yield amatch.start(), String.Heredoc, amatch.group()
471                        yield match.start(), Name.Constant, match.group()
472                        ctx.pos = match.end()
473                        break
474                    else:
475                        lines.append(match)
476                else:
477                    # end of heredoc not found -- error!
478                    for amatch in lines:
479                        yield amatch.start(), Error, amatch.group()
480            ctx.end = len(ctx.text)
481            del heredocstack[:]
482
483
484    def gen_rubystrings_rules():
485        def intp_regex_callback(self, match, ctx):
486            yield match.start(1), String.Regex, match.group(1)    # begin
487            nctx = LexerContext(match.group(3), 0, ['interpolated-regex'])
488            for i, t, v in self.get_tokens_unprocessed(context=nctx):
489                yield match.start(3)+i, t, v
490            yield match.start(4), String.Regex, match.group(4)    # end[mixounse]*
491            ctx.pos = match.end()
492
493        def intp_string_callback(self, match, ctx):
494            yield match.start(1), String.Other, match.group(1)
495            nctx = LexerContext(match.group(3), 0, ['interpolated-string'])
496            for i, t, v in self.get_tokens_unprocessed(context=nctx):
497                yield match.start(3)+i, t, v
498            yield match.start(4), String.Other, match.group(4)    # end
499            ctx.pos = match.end()
500
501        states = {}
502        states['strings'] = [
503            # easy ones
504            (r'\:([a-zA-Z_][\w_]*[\!\?]?|\*\*?|[-+]@?|'
505             r'[/%&|^`~]|\[\]=?|<<|>>|<=?>|>=?|===?)', String.Symbol),
506            (r":'(\\\\|\\'|[^'])*'", String.Symbol),
507            (r"'(\\\\|\\'|[^'])*'", String.Single),
508            (r':"', String.Symbol, 'simple-sym'),
509            (r'"', String.Double, 'simple-string'),
510            (r'(?<!\.)`', String.Backtick, 'simple-backtick'),
511        ]
512
513        # double-quoted string and symbol
514        for name, ttype, end in ('string', String.Double, '"'), \
515                                ('sym', String.Symbol, '"'), \
516                                ('backtick', String.Backtick, '`'):
517            states['simple-'+name] = [
518                include('string-intp-escaped'),
519                (r'[^\\%s#]+' % end, ttype),
520                (r'[\\#]', ttype),
521                (end, ttype, '#pop'),
522            ]
523
524        # braced quoted strings
525        for lbrace, rbrace, name in ('\\{', '\\}', 'cb'), \
526                                    ('\\[', '\\]', 'sb'), \
527                                    ('\\(', '\\)', 'pa'), \
528                                    ('<', '>', 'ab'):
529            states[name+'-intp-string'] = [
530                (r'\\[\\' + lbrace + rbrace + ']', String.Other),
531                (r'(?<!\\)' + lbrace, String.Other, '#push'),
532                (r'(?<!\\)' + rbrace, String.Other, '#pop'),
533                include('string-intp-escaped'),
534                (r'[\\#' + lbrace + rbrace + ']', String.Other),
535                (r'[^\\#' + lbrace + rbrace + ']+', String.Other),
536            ]
537            states['strings'].append((r'%[QWx]?' + lbrace, String.Other,
538                                      name+'-intp-string'))
539            states[name+'-string'] = [
540                (r'\\[\\' + lbrace + rbrace + ']', String.Other),
541                (r'(?<!\\)' + lbrace, String.Other, '#push'),
542                (r'(?<!\\)' + rbrace, String.Other, '#pop'),
543                (r'[\\#' + lbrace + rbrace + ']', String.Other),
544                (r'[^\\#' + lbrace + rbrace + ']+', String.Other),
545            ]
546            states['strings'].append((r'%[qsw]' + lbrace, String.Other,
547                                      name+'-string'))
548            states[name+'-regex'] = [
549                (r'\\[\\' + lbrace + rbrace + ']', String.Regex),
550                (r'(?<!\\)' + lbrace, String.Regex, '#push'),
551                (r'(?<!\\)' + rbrace + '[mixounse]*', String.Regex, '#pop'),
552                include('string-intp'),
553                (r'[\\#' + lbrace + rbrace + ']', String.Regex),
554                (r'[^\\#' + lbrace + rbrace + ']+', String.Regex),
555            ]
556            states['strings'].append((r'%r' + lbrace, String.Regex,
557                                      name+'-regex'))
558
559        # these must come after %<brace>!
560        states['strings'] += [
561            # %r regex
562            (r'(%r([^a-zA-Z0-9]))((?:\\\2|(?!\2).)*)(\2[mixounse]*)',
563             intp_regex_callback),
564            # regular fancy strings with qsw
565            (r'%[qsw]([^a-zA-Z0-9])((?:\\\1|(?!\1).)*)\1', String.Other),
566            (r'(%[QWx]([^a-zA-Z0-9]))((?:\\\2|(?!\2).)*)(\2)',
567             intp_string_callback),
568            # special forms of fancy strings after operators or
569            # in method calls with braces
570            (r'(?<=[-+/*%=<>&!^|~,(])(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)',
571             bygroups(Text, String.Other, None)),
572            # and because of fixed width lookbehinds the whole thing a
573            # second time for line startings...
574            (r'^(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)',
575             bygroups(Text, String.Other, None)),
576            # all regular fancy strings without qsw
577            (r'(%([^a-zA-Z0-9\s]))((?:\\\2|(?!\2).)*)(\2)',
578             intp_string_callback),
579        ]
580
581        return states
582
583    tokens = {
584        'root': [
585            (r'#.*?$', Comment.Single),
586            (r'=begin\s.*?\n=end', Comment.Multiline),
587            # keywords
588            (r'(BEGIN|END|alias|begin|break|case|defined\?|'
589             r'do|else|elsif|end|ensure|for|if|in|next|redo|'
590             r'rescue|raise|retry|return|super|then|undef|unless|until|when|'
591             r'while|yield)\b', Keyword),
592            # start of function, class and module names
593            (r'(module)(\s+)([a-zA-Z_][a-zA-Z0-9_]*(::[a-zA-Z_][a-zA-Z0-9_]*)*)',
594             bygroups(Keyword, Text, Name.Namespace)),
595            (r'(def)(\s+)', bygroups(Keyword, Text), 'funcname'),
596            (r'def(?=[*%&^`~+-/\[<>=])', Keyword, 'funcname'),
597            (r'(class)(\s+)', bygroups(Keyword, Text), 'classname'),
598            # special methods
599            (r'(initialize|new|loop|include|extend|raise|attr_reader|'
600             r'attr_writer|attr_accessor|attr|catch|throw|private|'
601             r'module_function|public|protected|true|false|nil)\b', Keyword.Pseudo),
602            (r'(not|and|or)\b', Operator.Word),
603            (r'(autoload|block_given|const_defined|eql|equal|frozen|include|'
604             r'instance_of|is_a|iterator|kind_of|method_defined|nil|'
605             r'private_method_defined|protected_method_defined|'
606             r'public_method_defined|respond_to|tainted)\?', Name.Builtin),
607            (r'(chomp|chop|exit|gsub|sub)!', Name.Builtin),
608            (r'(?<!\.)(Array|Float|Integer|String|__id__|__send__|abort|ancestors|'
609             r'at_exit|autoload|binding|callcc|caller|'
610             r'catch|chomp|chop|class_eval|class_variables|'
611             r'clone|const_defined\?|const_get|const_missing|const_set|constants|'
612             r'display|dup|eval|exec|exit|extend|fail|fork|'
613             r'format|freeze|getc|gets|global_variables|gsub|'
614             r'hash|id|included_modules|inspect|instance_eval|'
615             r'instance_method|instance_methods|'
616             r'instance_variable_get|instance_variable_set|instance_variables|'
617             r'lambda|load|local_variables|loop|'
618             r'method|method_missing|methods|module_eval|name|'
619             r'object_id|open|p|print|printf|private_class_method|'
620             r'private_instance_methods|'
621             r'private_methods|proc|protected_instance_methods|'
622             r'protected_methods|public_class_method|'
623             r'public_instance_methods|public_methods|'
624             r'putc|puts|raise|rand|readline|readlines|require|'
625             r'scan|select|self|send|set_trace_func|singleton_methods|sleep|'
626             r'split|sprintf|srand|sub|syscall|system|taint|'
627             r'test|throw|to_a|to_s|trace_var|trap|untaint|untrace_var|'
628             r'warn)\b', Name.Builtin),
629            (r'__(FILE|LINE)__\b', Name.Builtin.Pseudo),
630            # normal heredocs
631            (r'(?<!\w)(<<-?)(["`\']?)([a-zA-Z_]\w*)(\2)(.*?\n)', heredoc_callback),
632            # empty string heredocs
633            (r'(<<-?)("|\')()(\2)(.*?\n)', heredoc_callback),
634            (r'__END__', Comment.Preproc, 'end-part'),
635            # multiline regex (after keywords or assignments)
636            (r'(?:^|(?<=[=<>~!])|'
637                 r'(?<=(?:\s|;)when\s)|'
638                 r'(?<=(?:\s|;)or\s)|'
639                 r'(?<=(?:\s|;)and\s)|'
640                 r'(?<=(?:\s|;|\.)index\s)|'
641                 r'(?<=(?:\s|;|\.)scan\s)|'
642                 r'(?<=(?:\s|;|\.)sub\s)|'
643                 r'(?<=(?:\s|;|\.)sub!\s)|'
644                 r'(?<=(?:\s|;|\.)gsub\s)|'
645                 r'(?<=(?:\s|;|\.)gsub!\s)|'
646                 r'(?<=(?:\s|;|\.)match\s)|'
647                 r'(?<=(?:\s|;)if\s)|'
648                 r'(?<=(?:\s|;)elsif\s)|'
649                 r'(?<=^when\s)|'
650                 r'(?<=^index\s)|'
651                 r'(?<=^scan\s)|'
652                 r'(?<=^sub\s)|'
653                 r'(?<=^gsub\s)|'
654                 r'(?<=^sub!\s)|'
655                 r'(?<=^gsub!\s)|'
656                 r'(?<=^match\s)|'
657                 r'(?<=^if\s)|'
658                 r'(?<=^elsif\s)'
659             r')(\s*)(/)', bygroups(Text, String.Regex), 'multiline-regex'),
660            # multiline regex (in method calls)
661            (r'(?<=\(|,)/', String.Regex, 'multiline-regex'),
662            # multiline regex (this time the funny no whitespace rule)
663            (r'(\s+)(/[^\s=])', String.Regex, 'multiline-regex'),
664            # lex numbers and ignore following regular expressions which
665            # are division operators in fact (grrrr. i hate that. any
666            # better ideas?)
667            # since pygments 0.7 we also eat a "?" operator after numbers
668            # so that the char operator does not work. Chars are not allowed
669            # there so that you can use the ternary operator.
670            # stupid example:
671            #   x>=0?n[x]:""
672            (r'(0_?[0-7]+(?:_[0-7]+)*)(\s*)([/?])?',
673             bygroups(Number.Oct, Text, Operator)),
674            (r'(0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*)(\s*)([/?])?',
675             bygroups(Number.Hex, Text, Operator)),
676            (r'(0b[01]+(?:_[01]+)*)(\s*)([/?])?',
677             bygroups(Number.Bin, Text, Operator)),
678            (r'([\d]+(?:_\d+)*)(\s*)([/?])?',
679             bygroups(Number.Integer, Text, Operator)),
680            # Names
681            (r'@@[a-zA-Z_][a-zA-Z0-9_]*', Name.Variable.Class),
682            (r'@[a-zA-Z_][a-zA-Z0-9_]*', Name.Variable.Instance),
683            (r'\$[a-zA-Z0-9_]+', Name.Variable.Global),
684            (r'\$[!@&`\'+~=/\\,;.<>_*$?:"]', Name.Variable.Global),
685            (r'\$-[0adFiIlpvw]', Name.Variable.Global),
686            (r'::', Operator),
687            include('strings'),
688            # chars
689            (r'\?(\\[MC]-)*' # modifiers
690             r'(\\([\\abefnrstv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})|\S)'
691             r'(?!\w)',
692             String.Char),
693            (r'[A-Z][a-zA-Z0-9_]+', Name.Constant),
694            # this is needed because ruby attributes can look
695            # like keywords (class) or like this: ` ?!?
696            (r'(\.|::)([a-zA-Z_]\w*[\!\?]?|[*%&^`~+-/\[<>=])',
697             bygroups(Operator, Name)),
698            (r'[a-zA-Z_][\w_]*[\!\?]?', Name),
699            (r'(\[|\]|\*\*|<<?|>>?|>=|<=|<=>|=~|={3}|'
700             r'!~|&&?|\|\||\.{1,3})', Operator),
701            (r'[-+/*%=<>&!^|~]=?', Operator),
702            (r'[(){};,/?:\\]', Punctuation),
703            (r'\s+', Text)
704        ],
705        'funcname': [
706            (r'\(', Punctuation, 'defexpr'),
707            (r'(?:([a-zA-Z_][a-zA-Z0-9_]*)(\.))?'
708             r'([a-zA-Z_][\w_]*[\!\?]?|\*\*?|[-+]@?|'
709             r'[/%&|^`~]|\[\]=?|<<|>>|<=?>|>=?|===?)',
710             bygroups(Name.Class, Operator, Name.Function), '#pop'),
711            (r'', Text, '#pop')
712        ],
713        'classname': [
714            (r'\(', Punctuation, 'defexpr'),
715            (r'<<', Operator, '#pop'),
716            (r'[A-Z_][\w_]*', Name.Class, '#pop'),
717            (r'', Text, '#pop')
718        ],
719        'defexpr': [
720            (r'(\))(\.|::)?', bygroups(Punctuation, Operator), '#pop'),
721            (r'\(', Operator, '#push'),
722            include('root')
723        ],
724        'in-intp': [
725            ('}', String.Interpol, '#pop'),
726            include('root'),
727        ],
728        'string-intp': [
729            (r'#{', String.Interpol, 'in-intp'),
730            (r'#@@?[a-zA-Z_][a-zA-Z0-9_]*', String.Interpol),
731            (r'#\$[a-zA-Z_][a-zA-Z0-9_]*', String.Interpol)
732        ],
733        'string-intp-escaped': [
734            include('string-intp'),
735            (r'\\([\\abefnrstv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})', String.Escape)
736        ],
737        'interpolated-regex': [
738            include('string-intp'),
739            (r'[\\#]', String.Regex),
740            (r'[^\\#]+', String.Regex),
741        ],
742        'interpolated-string': [
743            include('string-intp'),
744            (r'[\\#]', String.Other),
745            (r'[^\\#]+', String.Other),
746        ],
747        'multiline-regex': [
748            include('string-intp'),
749            (r'\\\\', String.Regex),
750            (r'\\/', String.Regex),
751            (r'[\\#]', String.Regex),
752            (r'[^\\/#]+', String.Regex),
753            (r'/[mixounse]*', String.Regex, '#pop'),
754        ],
755        'end-part': [
756            (r'.+', Comment.Preproc, '#pop')
757        ]
758    }
759    tokens.update(gen_rubystrings_rules())
760
761    def analyse_text(text):
762        return shebang_matches(text, r'ruby(1\.\d)?')
763
764
765class RubyConsoleLexer(Lexer):
766    """
767    For Ruby interactive console (**irb**) output like:
768
769    .. sourcecode:: rbcon
770
771        irb(main):001:0> a = 1
772        => 1
773        irb(main):002:0> puts a
774        1
775        => nil
776    """
777    name = 'Ruby irb session'
778    aliases = ['rbcon', 'irb']
779    mimetypes = ['text/x-ruby-shellsession']
780
781    _prompt_re = re.compile('irb\([a-zA-Z_][a-zA-Z0-9_]*\):\d{3}:\d+[>*"\'] '
782                            '|>> |\?> ')
783
784    def get_tokens_unprocessed(self, text):
785        rblexer = RubyLexer(**self.options)
786
787        curcode = ''
788        insertions = []
789        for match in line_re.finditer(text):
790            line = match.group()
791            m = self._prompt_re.match(line)
792            if m is not None:
793                end = m.end()
794                insertions.append((len(curcode),
795                                   [(0, Generic.Prompt, line[:end])]))
796                curcode += line[end:]
797            else:
798                if curcode:
799                    for item in do_insertions(insertions,
800                                    rblexer.get_tokens_unprocessed(curcode)):
801                        yield item
802                    curcode = ''
803                    insertions = []
804                yield match.start(), Generic.Output, line
805        if curcode:
806            for item in do_insertions(insertions,
807                                      rblexer.get_tokens_unprocessed(curcode)):
808                yield item
809
810
811class PerlLexer(RegexLexer):
812    """
813    For `Perl <http://www.perl.org>`_ source code.
814    """
815
816    name = 'Perl'
817    aliases = ['perl', 'pl']
818    filenames = ['*.pl', '*.pm']
819    mimetypes = ['text/x-perl', 'application/x-perl']
820
821    flags = re.DOTALL | re.MULTILINE
822    # TODO: give this a perl guy who knows how to parse perl...
823    tokens = {
824        'balanced-regex': [
825            (r'/(\\\\|\\/|[^/])*/[egimosx]*', String.Regex, '#pop'),
826            (r'!(\\\\|\\!|[^!])*![egimosx]*', String.Regex, '#pop'),
827            (r'\\(\\\\|[^\\])*\\[egimosx]*', String.Regex, '#pop'),
828            (r'{(\\\\|\\}|[^}])*}[egimosx]*', String.Regex, '#pop'),
829            (r'<(\\\\|\\>|[^>])*>[egimosx]*', String.Regex, '#pop'),
830            (r'\[(\\\\|\\\]|[^\]])*\][egimosx]*', String.Regex, '#pop'),
831            (r'\((\\\\|\\\)|[^\)])*\)[egimosx]*', String.Regex, '#pop'),
832            (r'@(\\\\|\\\@|[^\@])*@[egimosx]*', String.Regex, '#pop'),
833            (r'%(\\\\|\\\%|[^\%])*%[egimosx]*', String.Regex, '#pop'),
834            (r'\$(\\\\|\\\$|[^\$])*\$[egimosx]*', String.Regex, '#pop'),
835        ],
836        'root': [
837            (r'\#.*?$', Comment.Single),
838            (r'^=[a-zA-Z0-9]+\s+.*?\n=cut', Comment.Multiline),
839            (r'(case|continue|do|else|elsif|for|foreach|if|last|my|'
840             r'next|our|redo|reset|then|unless|until|while|use|'
841             r'print|new|BEGIN|CHECK|INIT|END|return)\b', Keyword),
842            (r'(format)(\s+)([a-zA-Z0-9_]+)(\s*)(=)(\s*\n)',
843             bygroups(Keyword, Text, Name, Text, Punctuation, Text), 'format'),
844            (r'(eq|lt|gt|le|ge|ne|not|and|or|cmp)\b', Operator.Word),
845            # common delimiters
846            (r's/(\\\\|\\/|[^/])*/(\\\\|\\/|[^/])*/[egimosx]*', String.Regex),
847            (r's!(\\\\|\\!|[^!])*!(\\\\|\\!|[^!])*![egimosx]*', String.Regex),
848            (r's\\(\\\\|[^\\])*\\(\\\\|[^\\])*\\[egimosx]*', String.Regex),
849            (r's@(\\\\|\\@|[^@])*@(\\\\|\\@|[^@])*@[egimosx]*', String.Regex),
850            (r's%(\\\\|\\%|[^%])*%(\\\\|\\%|[^%])*%[egimosx]*', String.Regex),
851            # balanced delimiters
852            (r's{(\\\\|\\}|[^}])*}\s*', String.Regex, 'balanced-regex'),
853            (r's<(\\\\|\\>|[^>])*>\s*', String.Regex, 'balanced-regex'),
854            (r's\[(\\\\|\\\]|[^\]])*\]\s*', String.Regex, 'balanced-regex'),
855            (r's\((\\\\|\\\)|[^\)])*\)\s*', String.Regex, 'balanced-regex'),
856
857            (r'm?/(\\\\|\\/|[^/\n])*/[gcimosx]*', String.Regex),
858            (r'm(?=[/!\\{<\[\(@%\$])', String.Regex, 'balanced-regex'),
859            (r'((?<==~)|(?<=\())\s*/(\\\\|\\/|[^/])*/[gcimosx]*', String.Regex),
860            (r'\s+', Text),
861            (r'(abs|accept|alarm|atan2|bind|binmode|bless|caller|chdir|'
862             r'chmod|chomp|chop|chown|chr|chroot|close|closedir|connect|'
863             r'continue|cos|crypt|dbmclose|dbmopen|defined|delete|die|'
864             r'dump|each|endgrent|endhostent|endnetent|endprotoent|'
865             r'endpwent|endservent|eof|eval|exec|exists|exit|exp|fcntl|'
866             r'fileno|flock|fork|format|formline|getc|getgrent|getgrgid|'
867             r'getgrnam|gethostbyaddr|gethostbyname|gethostent|getlogin|'
868             r'getnetbyaddr|getnetbyname|getnetent|getpeername|getpgrp|'
869             r'getppid|getpriority|getprotobyname|getprotobynumber|'
870             r'getprotoent|getpwent|getpwnam|getpwuid|getservbyname|'
871             r'getservbyport|getservent|getsockname|getsockopt|glob|gmtime|'
872             r'goto|grep|hex|import|index|int|ioctl|join|keys|kill|last|'
873             r'lc|lcfirst|length|link|listen|local|localtime|log|lstat|'
874             r'map|mkdir|msgctl|msgget|msgrcv|msgsnd|my|next|no|oct|open|'
875             r'opendir|ord|our|pack|package|pipe|pop|pos|printf|'
876             r'prototype|push|quotemeta|rand|read|readdir|'
877             r'readline|readlink|readpipe|recv|redo|ref|rename|require|'
878             r'reverse|rewinddir|rindex|rmdir|scalar|seek|seekdir|'
879             r'select|semctl|semget|semop|send|setgrent|sethostent|setnetent|'
880             r'setpgrp|setpriority|setprotoent|setpwent|setservent|'
881             r'setsockopt|shift|shmctl|shmget|shmread|shmwrite|shutdown|'
882             r'sin|sleep|socket|socketpair|sort|splice|split|sprintf|sqrt|'
883             r'srand|stat|study|substr|symlink|syscall|sysopen|sysread|'
884             r'sysseek|system|syswrite|tell|telldir|tie|tied|time|times|tr|'
885             r'truncate|uc|ucfirst|umask|undef|unlink|unpack|unshift|untie|'
886             r'utime|values|vec|wait|waitpid|wantarray|warn|write'
887             r')\b', Name.Builtin),
888            (r'((__(DATA|DIE|WARN)__)|(STD(IN|OUT|ERR)))\b', Name.Builtin.Pseudo),
889            (r'<<([\'"]?)([a-zA-Z_][a-zA-Z0-9_]*)\1;?\n.*?\n\2\n', String),
890            (r'__END__', Comment.Preproc, 'end-part'),
891            (r'\$\^[ADEFHILMOPSTWX]', Name.Variable.Global),
892            (r"\$[\\\"\[\]'&`+*.,;=%~?@$!<>(^|/-](?!\w)", Name.Variable.Global),
893            (r'[$@%#]+', Name.Variable, 'varname'),
894            (r'0_?[0-7]+(_[0-7]+)*', Number.Oct),
895            (r'0x[0-9A-Fa-f]+(_[0-9A-Fa-f]+)*', Number.Hex),
896            (r'0b[01]+(_[01]+)*', Number.Bin),
897            (r'(?i)(\d*(_\d*)*\.\d+(_\d*)*|\d+(_\d*)*\.\d+(_\d*)*)(e[+-]?\d+)?',
898             Number.Float),
899            (r'(?i)\d+(_\d*)*e[+-]?\d+(_\d*)*', Number.Float),
900            (r'\d+(_\d+)*', Number.Integer),
901            (r"'(\\\\|\\'|[^'])*'", String),
902            (r'"(\\\\|\\"|[^"])*"', String),
903            (r'`(\\\\|\\`|[^`])*`', String.Backtick),
904            (r'<([^\s>]+)>', String.Regexp),
905            (r'(q|qq|qw|qr|qx)\{', String.Other, 'cb-string'),
906            (r'(q|qq|qw|qr|qx)\(', String.Other, 'rb-string'),
907            (r'(q|qq|qw|qr|qx)\[', String.Other, 'sb-string'),
908            (r'(q|qq|qw|qr|qx)\<', String.Other, 'lt-string'),
909            (r'(q|qq|qw|qr|qx)([^a-zA-Z0-9])(.|\n)*?\2', String.Other),
910            (r'package\s+', Keyword, 'modulename'),
911            (r'sub\s+', Keyword, 'funcname'),
912            (r'(\[\]|\*\*|::|<<|>>|>=|<=|<=>|={3}|!=|=~|'
913             r'!~|&&?|\|\||\.{1,3})', Operator),
914            (r'[-+/*%=<>&^|!\\~]=?', Operator),
915            (r'[\(\)\[\]:;,<>/\?\{\}]', Punctuation), # yes, there's no shortage
916                                                      # of punctuation in Perl!
917            (r'(?=\w)', Name, 'name'),
918        ],
919        'format': [
920            (r'\.\n', String.Interpol, '#pop'),
921            (r'[^\n]*\n', String.Interpol),
922        ],
923        'varname': [
924            (r'\s+', Text),
925            (r'\{', Punctuation, '#pop'), # hash syntax?
926            (r'\)|,', Punctuation, '#pop'), # argument specifier
927            (r'[a-zA-Z0-9_]+::', Name.Namespace),
928            (r'[a-zA-Z0-9_:]+', Name.Variable, '#pop'),
929        ],
930        'name': [
931            (r'[a-zA-Z0-9_]+::', Name.Namespace),
932            (r'[a-zA-Z0-9_:]+', Name, '#pop'),
933            (r'[A-Z_]+(?=[^a-zA-Z0-9_])', Name.Constant, '#pop'),
934            (r'(?=[^a-zA-Z0-9_])', Text, '#pop'),
935        ],
936        'modulename': [
937            (r'[a-zA-Z_][\w_]*', Name.Namespace, '#pop')
938        ],
939        'funcname': [
940            (r'[a-zA-Z_][\w_]*[\!\?]?', Name.Function),
941            (r'\s+', Text),
942            # argument declaration
943            (r'(\([$@%]*\))(\s*)', bygroups(Punctuation, Text)),
944            (r'.*?{', Punctuation, '#pop'),
945            (r';', Punctuation, '#pop'),
946        ],
947        'cb-string': [
948            (r'\\[\{\}\\]', String.Other),
949            (r'\\', String.Other),
950            (r'\{', String.Other, 'cb-string'),
951            (r'\}', String.Other, '#pop'),
952            (r'[^\{\}\\]+', String.Other)
953        ],
954        'rb-string': [
955            (r'\\[\(\)\\]', String.Other),
956            (r'\\', String.Other),
957            (r'\(', String.Other, 'rb-string'),
958            (r'\)', String.Other, '#pop'),
959            (r'[^\(\)]+', String.Other)
960        ],
961        'sb-string': [
962            (r'\\[\[\]\\]', String.Other),
963            (r'\\', String.Other),
964            (r'\[', String.Other, 'sb-string'),
965            (r'\]', String.Other, '#pop'),
966            (r'[^\[\]]+', String.Other)
967        ],
968        'lt-string': [
969            (r'\\[\<\>\\]', String.Other),
970            (r'\\', String.Other),
971            (r'\<', String.Other, 'lt-string'),
972            (r'\>', String.Other, '#pop'),
973            (r'[^\<\>]+', String.Other)
974        ],
975        'end-part': [
976            (r'.+', Comment.Preproc, '#pop')
977        ]
978    }
979
980    def analyse_text(text):
981        if shebang_matches(text, r'perl'):
982            return True
983        if 'my $' in text:
984            return 0.9
985        return 0.1 # who knows, might still be perl!
986
987
988class LuaLexer(RegexLexer):
989    """
990    For `Lua <http://www.lua.org>`_ source code.
991
992    Additional options accepted:
993
994    `func_name_highlighting`
995        If given and ``True``, highlight builtin function names
996        (default: ``True``).
997    `disabled_modules`
998        If given, must be a list of module names whose function names
999        should not be highlighted. By default all modules are highlighted.
1000
1001        To get a list of allowed modules have a look into the
1002        `_luabuiltins` module:
1003
1004        .. sourcecode:: pycon
1005
1006            >>> from pygments.lexers._luabuiltins import MODULES
1007            >>> MODULES.keys()
1008            ['string', 'coroutine', 'modules', 'io', 'basic', ...]
1009    """
1010
1011    name = 'Lua'
1012    aliases = ['lua']
1013    filenames = ['*.lua', '*.wlua']
1014    mimetypes = ['text/x-lua', 'application/x-lua']
1015
1016    tokens = {
1017        'root': [
1018            # lua allows a file to start with a shebang
1019            (r'#!(.*?)$', Comment.Preproc),
1020            (r'', Text, 'base'),
1021        ],
1022        'base': [
1023            (r'(?s)--\[(=*)\[.*?\]\1\]', Comment.Multiline),
1024            ('--.*$', Comment.Single),
1025
1026            (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number.Float),
1027            (r'(?i)\d+e[+-]?\d+', Number.Float),
1028            ('(?i)0x[0-9a-f]*', Number.Hex),
1029            (r'\d+', Number.Integer),
1030
1031            (r'\n', Text),
1032            (r'[^\S\n]', Text),
1033            # multiline strings
1034            (r'(?s)\[(=*)\[.*?\]\1\]', String),
1035
1036            (r'(==|~=|<=|>=|\.\.|\.\.\.|[=+\-*/%^<>#])', Operator),
1037            (r'[\[\]\{\}\(\)\.,:;]', Punctuation),
1038            (r'(and|or|not)\b', Operator.Word),
1039
1040            ('(break|do|else|elseif|end|for|if|in|repeat|return|then|until|'
1041             r'while)\b', Keyword),
1042            (r'(local)\b', Keyword.Declaration),
1043            (r'(true|false|nil)\b', Keyword.Constant),
1044
1045            (r'(function)(\s+)', bygroups(Keyword, Text), 'funcname'),
1046            (r'(class)(\s+)', bygroups(Keyword, Text), 'classname'),
1047
1048            (r'[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)?', Name),
1049
1050            ("'", String.Single, combined('stringescape', 'sqs')),
1051            ('"', String.Double, combined('stringescape', 'dqs'))
1052        ],
1053
1054        'funcname': [
1055            ('(?:([A-Za-z_][A-Za-z0-9_]*)(\.))?([A-Za-z_][A-Za-z0-9_]*)',
1056             bygroups(Name.Class, Punctuation, Name.Function), '#pop'),
1057            # inline function
1058            ('\(', Punctuation, '#pop'),
1059        ],
1060
1061        'classname': [
1062            ('[A-Za-z_][A-Za-z0-9_]*', Name.Class, '#pop')
1063        ],
1064
1065        # if I understand correctly, every character is valid in a lua string,
1066        # so this state is only for later corrections
1067        'string': [
1068            ('.', String)
1069        ],
1070
1071        'stringescape': [
1072            (r'''\\([abfnrtv\\"']|\d{1,3})''', String.Escape)
1073        ],
1074
1075        'sqs': [
1076            ("'", String, '#pop'),
1077            include('string')
1078        ],
1079
1080        'dqs': [
1081            ('"', String, '#pop'),
1082            include('string')
1083        ]
1084    }
1085
1086    def __init__(self, **options):
1087        self.func_name_highlighting = get_bool_opt(
1088            options, 'func_name_highlighting', True)
1089        self.disabled_modules = get_list_opt(options, 'disabled_modules', [])
1090
1091        self._functions = set()
1092        if self.func_name_highlighting:
1093            from pygments.lexers._luabuiltins import MODULES
1094            for mod, func in MODULES.iteritems():
1095                if mod not in self.disabled_modules:
1096                    self._functions.update(func)
1097        RegexLexer.__init__(self, **options)
1098
1099    def get_tokens_unprocessed(self, text):
1100        for index, token, value in \
1101            RegexLexer.get_tokens_unprocessed(self, text):
1102            if token is Name:
1103                if value in self._functions:
1104                    yield index, Name.Builtin, value
1105                    continue
1106                elif '.' in value:
1107                    a, b = value.split('.')
1108                    yield index, Name, a
1109                    yield index + len(a), Punctuation, u'.'
1110                    yield index + len(a) + 1, Name, b
1111                    continue
1112            yield index, token, value
1113
1114
1115class MiniDLexer(RegexLexer):
1116    """
1117    For `MiniD <http://www.dsource.org/projects/minid>`_ (a D-like scripting
1118    language) source.
1119    """
1120    name = 'MiniD'
1121    filenames = ['*.md']
1122    aliases = ['minid']
1123    mimetypes = ['text/x-minidsrc']
1124
1125    tokens = {
1126        'root': [
1127            (r'\n', Text),
1128            (r'\s+', Text),
1129            # Comments
1130            (r'//(.*?)\n', Comment.Single),
1131            (r'/(\\\n)?[*](.|\n)*?[*](\\\n)?/', Comment.Multiline),
1132            (r'/\+', Comment.Multiline, 'nestedcomment'),
1133            # Keywords
1134            (r'(as|assert|break|case|catch|class|continue|coroutine|default'
1135             r'|do|else|finally|for|foreach|function|global|namespace'
1136             r'|if|import|in|is|local|module|return|super|switch'
1137             r'|this|throw|try|vararg|while|with|yield)\b', Keyword),
1138            (r'(false|true|null)\b', Keyword.Constant),
1139            # FloatLiteral
1140            (r'([0-9][0-9_]*)?\.[0-9_]+([eE][+\-]?[0-9_]+)?', Number.Float),
1141            # IntegerLiteral
1142            # -- Binary
1143            (r'0[Bb][01_]+', Number),
1144            # -- Octal
1145            (r'0[Cc][0-7_]+', Number.Oct),
1146            # -- Hexadecimal
1147            (r'0[xX][0-9a-fA-F_]+', Number.Hex),
1148            # -- Decimal
1149            (r'(0|[1-9][0-9_]*)', Number.Integer),
1150            # CharacterLiteral
1151            (r"""'(\\['"?\\abfnrtv]|\\x[0-9a-fA-F]{2}|\\[0-9]{1,3}"""
1152             r"""|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|.)'""",
1153             String.Char
1154            ),
1155            # StringLiteral
1156            # -- WysiwygString
1157            (r'@"(""|.)*"', String),
1158            # -- AlternateWysiwygString
1159            (r'`(``|.)*`', String),
1160            # -- DoubleQuotedString
1161            (r'"(\\\\|\\"|[^"])*"', String),
1162            # Tokens
1163            (
1164             r'(~=|\^=|%=|\*=|==|!=|>>>=|>>>|>>=|>>|>=|<=>|\?=|-\>'
1165             r'|<<=|<<|<=|\+\+|\+=|--|-=|\|\||\|=|&&|&=|\.\.|/=)'
1166             r'|[-/.&$@|\+<>!()\[\]{}?,;:=*%^~#\\]', Punctuation
1167            ),
1168            # Identifier
1169            (r'[a-zA-Z_]\w*', Name),
1170        ],
1171        'nestedcomment': [
1172            (r'[^+/]+', Comment.Multiline),
1173            (r'/\+', Comment.Multiline, '#push'),
1174            (r'\+/', Comment.Multiline, '#pop'),
1175            (r'[+/]', Comment.Multiline),
1176        ],
1177    }
1178
1179
1180class IoLexer(RegexLexer):
1181    """
1182    For `Io <http://iolanguage.com/>`_ (a small, prototype-based
1183    programming language) source.
1184
1185    *New in Pygments 0.10.*
1186    """
1187    name = 'Io'
1188    filenames = ['*.io']
1189    aliases = ['io']
1190    mimetypes = ['text/x-iosrc']
1191    tokens = {
1192        'root': [
1193            (r'\n', Text),
1194            (r'\s+', Text),
1195            # Comments
1196            (r'//(.*?)\n', Comment.Single),
1197            (r'#(.*?)\n', Comment.Single),
1198            (r'/(\\\n)?[*](.|\n)*?[*](\\\n)?/', Comment.Multiline),
1199            (r'/\+', Comment.Multiline, 'nestedcomment'),
1200            # DoubleQuotedString
1201            (r'"(\\\\|\\"|[^"])*"', String),
1202            # Operators
1203            (r'::=|:=|=|\(|\)|;|,|\*|-|\+|>|<|@|!|/|\||\^|\.|%|&|\[|\]|\{|\}',
1204             Operator),
1205            # keywords
1206            (r'(clone|do|doFile|doString|method|for|if|else|elseif|then)\b',
1207             Keyword),
1208            # constants
1209            (r'(nil|false|true)\b', Name.Constant),
1210            # names
1211            ('(Object|list|List|Map|args|Sequence|Coroutine|File)\b',
1212             Name.Builtin),
1213            ('[a-zA-Z_][a-zA-Z0-9_]*', Name),
1214            # numbers
1215            (r'(\d+\.?\d*|\d*\.\d+)([eE][+-]?[0-9]+)?', Number.Float),
1216            (r'\d+', Number.Integer)
1217        ],
1218        'nestedcomment': [
1219            (r'[^+/]+', Comment.Multiline),
1220            (r'/\+', Comment.Multiline, '#push'),
1221            (r'\+/', Comment.Multiline, '#pop'),
1222            (r'[+/]', Comment.Multiline),
1223        ]
1224    }
1225
1226
1227class TclLexer(RegexLexer):
1228    """
1229    For Tcl source code.
1230
1231    *New in Pygments 0.10.*
1232    """
1233
1234    keyword_cmds_re = (
1235        r'\b(after|apply|array|break|catch|continue|elseif|else|error|'
1236        r'eval|expr|for|foreach|global|if|namespace|proc|rename|return|'
1237        r'set|switch|then|trace|unset|update|uplevel|upvar|variable|'
1238        r'vwait|while)\b'
1239        )
1240
1241    builtin_cmds_re = (
1242        r'\b(append|bgerror|binary|cd|chan|clock|close|concat|dde|dict|'
1243        r'encoding|eof|exec|exit|fblocked|fconfigure|fcopy|file|'
1244        r'fileevent|flush|format|gets|glob|history|http|incr|info|interp|'
1245        r'join|lappend|lassign|lindex|linsert|list|llength|load|loadTk|'
1246        r'lrange|lrepeat|lreplace|lreverse|lsearch|lset|lsort|mathfunc|'
1247        r'mathop|memory|msgcat|open|package|pid|pkg::create|pkg_mkIndex|'
1248        r'platform|platform::shell|puts|pwd|re_syntax|read|refchan|'
1249        r'regexp|registry|regsub|scan|seek|socket|source|split|string|'
1250        r'subst|tell|time|tm|unknown|unload)\b'
1251        )
1252
1253    name = 'Tcl'
1254    aliases = ['tcl']
1255    filenames = ['*.tcl']
1256    mimetypes = ['text/x-tcl', 'text/x-script.tcl', 'application/x-tcl']
1257
1258    def _gen_command_rules(keyword_cmds_re, builtin_cmds_re, context=""):
1259        return [
1260            (keyword_cmds_re, Keyword, 'params' + context),
1261            (builtin_cmds_re, Name.Builtin, 'params' + context),
1262            (r'([\w\.\-]+)', Name.Variable, 'params' + context),
1263            (r'#', Comment, 'comment'),
1264        ]
1265
1266    tokens = {
1267        'root': [
1268            include('command'),
1269            include('basic'),
1270            include('data'),
1271            (r'}', Keyword),  # HACK: somehow we miscounted our braces
1272        ],
1273        'command': _gen_command_rules(keyword_cmds_re, builtin_cmds_re),
1274        'command-in-brace': _gen_command_rules(keyword_cmds_re,
1275                                               builtin_cmds_re,
1276                                               "-in-brace"),
1277        'command-in-bracket': _gen_command_rules(keyword_cmds_re,
1278                                                 builtin_cmds_re,
1279                                                 "-in-bracket"),
1280        'command-in-paren': _gen_command_rules(keyword_cmds_re,
1281                                               builtin_cmds_re,
1282                                               "-in-paren"),
1283        'basic': [
1284            (r'\(', Keyword, 'paren'),
1285            (r'\[', Keyword, 'bracket'),
1286            (r'\{', Keyword, 'brace'),
1287            (r'"', String.Double, 'string'),
1288            (r'(eq|ne|in|ni)\b', Operator.Word),
1289            (r'!=|==|<<|>>|<=|>=|&&|\|\||\*\*|[-+~!*/%<>&^|?:]', Operator),
1290        ],
1291        'data': [
1292            (r'\s+', Text),
1293            (r'0x[a-fA-F0-9]+', Number.Hex),
1294            (r'0[0-7]+', Number.Oct),
1295            (r'\d+\.\d+', Number.Float),
1296            (r'\d+', Number.Integer),
1297            (r'\$([\w\.\-\:]+)', Name.Variable),
1298            (r'([\w\.\-\:]+)', Text),
1299        ],
1300        'params': [
1301            (r';', Keyword, '#pop'),
1302            (r'\n', Text, '#pop'),
1303            (r'(else|elseif|then)', Keyword),
1304            include('basic'),
1305            include('data'),
1306        ],
1307        'params-in-brace': [
1308            (r'}', Keyword, ('#pop', '#pop')),
1309            include('params')
1310        ],
1311        'params-in-paren': [
1312            (r'\)', Keyword, ('#pop', '#pop')),
1313            include('params')
1314        ],
1315        'params-in-bracket': [
1316            (r'\]', Keyword, ('#pop', '#pop')),
1317            include('params')
1318        ],
1319        'string': [
1320            (r'\[', String.Double, 'string-square'),
1321            (r'(?s)(\\\\|\\[0-7]+|\\.|[^"\\])', String.Double),
1322            (r'"', String.Double, '#pop')
1323        ],
1324        'string-square': [
1325            (r'\[', String.Double, 'string-square'),
1326            (r'(?s)(\\\\|\\[0-7]+|\\.|\\\n|[^\]\\])', String.Double),
1327            (r'\]', String.Double, '#pop')
1328        ],
1329        'brace': [
1330            (r'}', Keyword, '#pop'),
1331            include('command-in-brace'),
1332            include('basic'),
1333            include('data'),
1334        ],
1335        'paren': [
1336            (r'\)', Keyword, '#pop'),
1337            include('command-in-paren'),
1338            include('basic'),
1339            include('data'),
1340        ],
1341        'bracket': [
1342            (r'\]', Keyword, '#pop'),
1343            include('command-in-bracket'),
1344            include('basic'),
1345            include('data'),
1346        ],
1347        'comment': [
1348            (r'.*[^\\]\n', Comment, '#pop'),
1349            (r'.*\\\n', Comment),
1350        ],
1351    }
1352
1353    def analyse_text(text):
1354        return shebang_matches(text, r'(tcl)')
1355
1356
1357class ClojureLexer(RegexLexer):
1358    """
1359    Lexer for `Clojure <http://clojure.org/>`_ source code.
1360
1361    *New in Pygments 0.11.*
1362    """
1363    name = 'Clojure'
1364    aliases = ['clojure', 'clj']
1365    filenames = ['*.clj']
1366    mimetypes = ['text/x-clojure', 'application/x-clojure']
1367
1368    keywords = [
1369        'fn', 'def', 'defn', 'defmacro', 'defmethod', 'defmulti', 'defn-',
1370        'defstruct',
1371        'if', 'cond',
1372        'let', 'for'
1373    ]
1374    builtins = [
1375        '.', '..',
1376        '*', '+', '-', '->', '..', '/', '<', '<=', '=', '==', '>', '>=',
1377        'accessor', 'agent', 'agent-errors', 'aget', 'alength', 'all-ns',
1378        'alter', 'and', 'append-child', 'apply', 'array-map', 'aset',
1379        'aset-boolean', 'aset-byte', 'aset-char', 'aset-double', 'aset-float',
1380        'aset-int', 'aset-long', 'aset-short', 'assert', 'assoc', 'await',
1381        'await-for', 'bean', 'binding', 'bit-and', 'bit-not', 'bit-or',
1382        'bit-shift-left', 'bit-shift-right', 'bit-xor', 'boolean', 'branch?',
1383        'butlast', 'byte', 'cast', 'char', 'children', 'class',
1384        'clear-agent-errors', 'comment', 'commute', 'comp', 'comparator',
1385        'complement', 'concat', 'conj', 'cons', 'constantly',
1386        'construct-proxy', 'contains?', 'count', 'create-ns', 'create-struct',
1387        'cycle', 'dec',  'deref', 'difference', 'disj', 'dissoc', 'distinct',
1388        'doall', 'doc', 'dorun', 'doseq', 'dosync', 'dotimes', 'doto',
1389        'double', 'down', 'drop', 'drop-while', 'edit', 'end?', 'ensure',
1390        'eval', 'every?', 'false?', 'ffirst', 'file-seq', 'filter', 'find',
1391        'find-doc', 'find-ns', 'find-var', 'first', 'float', 'flush',
1392        'fnseq', 'frest', 'gensym', 'get', 'get-proxy-class',
1393        'hash-map', 'hash-set', 'identical?', 'identity', 'if-let', 'import',
1394        'in-ns', 'inc', 'index', 'insert-child', 'insert-left', 'insert-right',
1395        'inspect-table', 'inspect-tree', 'instance?', 'int', 'interleave',
1396        'intersection', 'into', 'into-array', 'iterate', 'join', 'key', 'keys',
1397        'keyword', 'keyword?', 'last', 'lazy-cat', 'lazy-cons', 'left',
1398        'lefts', 'line-seq', 'list', 'list*', 'load', 'load-file',
1399        'locking', 'long', 'loop', 'macroexpand', 'macroexpand-1',
1400        'make-array', 'make-node', 'map', 'map-invert', 'map?', 'mapcat',
1401        'max', 'max-key', 'memfn', 'merge', 'merge-with', 'meta', 'min',
1402        'min-key', 'name', 'namespace', 'neg?', 'new', 'newline', 'next',
1403        'nil?', 'node', 'not', 'not-any?', 'not-every?', 'not=', 'ns-imports',
1404        'ns-interns', 'ns-map', 'ns-name', 'ns-publics', 'ns-refers',
1405        'ns-resolve', 'ns-unmap', 'nth', 'nthrest', 'or', 'parse', 'partial',
1406        'path', 'peek', 'pop', 'pos?', 'pr', 'pr-str', 'print', 'print-str',
1407        'println', 'println-str', 'prn', 'prn-str', 'project', 'proxy',
1408        'proxy-mappings', 'quot', 'rand', 'rand-int', 'range', 're-find',
1409        're-groups', 're-matcher', 're-matches', 're-pattern', 're-seq',
1410        'read', 'read-line', 'reduce', 'ref', 'ref-set', 'refer', 'rem',
1411        'remove', 'remove-method', 'remove-ns', 'rename', 'rename-keys',
1412        'repeat', 'replace', 'replicate', 'resolve', 'rest', 'resultset-seq',
1413        'reverse', 'rfirst', 'right', 'rights', 'root', 'rrest', 'rseq',
1414        'second', 'select', 'select-keys', 'send', 'send-off', 'seq',
1415        'seq-zip', 'seq?', 'set', 'short', 'slurp', 'some', 'sort',
1416        'sort-by', 'sorted-map', 'sorted-map-by', 'sorted-set',
1417        'special-symbol?', 'split-at', 'split-with', 'str', 'string?',
1418        'struct', 'struct-map', 'subs', 'subvec', 'symbol', 'symbol?',
1419        'sync', 'take', 'take-nth', 'take-while', 'test', 'time', 'to-array',
1420        'to-array-2d', 'tree-seq', 'true?', 'union', 'up', 'update-proxy',
1421        'val', 'vals', 'var-get', 'var-set', 'var?', 'vector', 'vector-zip',
1422        'vector?', 'when', 'when-first', 'when-let', 'when-not',
1423        'with-local-vars', 'with-meta', 'with-open', 'with-out-str',
1424        'xml-seq', 'xml-zip', 'zero?', 'zipmap', 'zipper']
1425
1426    # valid names for identifiers
1427    # well, names can only not consist fully of numbers
1428    # but this should be good enough for now
1429    valid_name = r'[a-zA-Z0-9!$%&*+,/:<=>?@^_~-]+'
1430
1431    tokens = {
1432        'root' : [
1433            # the comments - always starting with semicolon
1434            # and going to the end of the line
1435            (r';.*$', Comment.Single),
1436
1437            # whitespaces - usually not relevant
1438            (r'\s+', Text),
1439
1440            # numbers
1441            (r'-?\d+\.\d+', Number.Float),
1442            (r'-?\d+', Number.Integer),
1443            # support for uncommon kinds of numbers -
1444            # have to figure out what the characters mean
1445            #(r'(#e|#i|#b|#o|#d|#x)[\d.]+', Number),
1446
1447            # strings, symbols and characters
1448            (r'"(\\\\|\\"|[^"])*"', String),
1449            (r"'" + valid_name, String.Symbol),
1450            (r"\\([()/'\".'_!§$%& ?;=#+-]{1}|[a-zA-Z0-9]+)", String.Char),
1451
1452            # constants
1453            (r'(#t|#f)', Name.Constant),
1454
1455            # special operators
1456            (r"('|#|`|,@|,|\.)", Operator),
1457
1458            # highlight the keywords
1459            ('(%s)' % '|'.join([
1460                re.escape(entry) + ' ' for entry in keywords]),
1461                Keyword
1462            ),
1463
1464            # first variable in a quoted string like
1465            # '(this is syntactic sugar)
1466            (r"(?<='\()" + valid_name, Name.Variable),
1467            (r"(?<=#\()" + valid_name, Name.Variable),
1468
1469            # highlight the builtins
1470            ("(?<=\()(%s)" % '|'.join([
1471                re.escape(entry) + ' ' for entry in builtins]),
1472                Name.Builtin
1473            ),
1474
1475            # the remaining functions
1476            (r'(?<=\()' + valid_name, Name.Function),
1477            # find the remaining variables
1478            (valid_name, Name.Variable),
1479
1480            # Clojure accepts vector notation
1481            (r'(\[|\])', Punctuation),
1482
1483            # Clojure accepts map notation
1484            (r'(\{|\})', Punctuation),
1485
1486            # the famous parentheses!
1487            (r'(\(|\))', Punctuation),
1488        ],
1489    }
1490
1491
1492class FactorLexer(RegexLexer):
1493    """
1494    Lexer for the `Factor <http://factorcode.org>`_ language.
1495
1496    *New in Pygments 1.4.*
1497    """
1498    name = 'Factor'
1499    aliases = ['factor']
1500    filenames = ['*.factor']
1501    mimetypes = ['text/x-factor']
1502
1503    flags = re.MULTILINE | re.UNICODE
1504
1505    builtin_kernel = (
1506        r'(?:or|2bi|2tri|while|wrapper|nip|4dip|wrapper\\?|bi\\*|'
1507        r'callstack>array|both\\?|hashcode|die|dupd|callstack|'
1508        r'callstack\\?|3dup|tri@|pick|curry|build|\\?execute|3bi|'
1509        r'prepose|>boolean|\\?if|clone|eq\\?|tri\\*|\\?|=|swapd|'
1510        r'2over|2keep|3keep|clear|2dup|when|not|tuple\\?|dup|2bi\\*|'
1511        r'2tri\\*|call|tri-curry|object|bi@|do|unless\\*|if\\*|loop|'
1512        r'bi-curry\\*|drop|when\\*|assert=|retainstack|assert\\?|-rot|'
1513        r'execute|2bi@|2tri@|boa|with|either\\?|3drop|bi|curry\\?|'
1514        r'datastack|until|3dip|over|3curry|tri-curry\\*|tri-curry@|swap|'
1515        r'and|2nip|throw|bi-curry|\\(clone\\)|hashcode\\*|compose|2dip|if|3tri|'
1516        r'unless|compose\\?|tuple|keep|2curry|equal\\?|assert|tri|2drop|'
1517        r'most|<wrapper>|boolean\\?|identity-hashcode|identity-tuple\\?|'
1518        r'null|new|dip|bi-curry@|rot|xor|identity-tuple|boolean)\s'
1519        )
1520
1521    builtin_assocs = (
1522        r'(?:\\?at|assoc\\?|assoc-clone-like|assoc=|delete-at\\*|'
1523        r'assoc-partition|extract-keys|new-assoc|value\\?|assoc-size|'
1524        r'map>assoc|push-at|assoc-like|key\\?|assoc-intersect|'
1525        r'assoc-refine|update|assoc-union|assoc-combine|at\\*|'
1526        r'assoc-empty\\?|at\\+|set-at|assoc-all\\?|assoc-subset\\?|'
1527        r'assoc-hashcode|change-at|assoc-each|assoc-diff|zip|values|'
1528        r'value-at|rename-at|inc-at|enum\\?|at|cache|assoc>map|<enum>|'
1529        r'assoc|assoc-map|enum|value-at\\*|assoc-map-as|>alist|'
1530        r'assoc-filter-as|clear-assoc|assoc-stack|maybe-set-at|'
1531        r'substitute|assoc-filter|2cache|delete-at|assoc-find|keys|'
1532        r'assoc-any\\?|unzip)\s'
1533        )
1534
1535    builtin_combinators = (
1536        r'(?:case|execute-effect|no-cond|no-case\\?|3cleave>quot|2cleave|'
1537        r'cond>quot|wrong-values\\?|no-cond\\?|cleave>quot|no-case|'
1538        r'case>quot|3cleave|wrong-values|to-fixed-point|alist>quot|'
1539        r'case-find|cond|cleave|call-effect|2cleave>quot|recursive-hashcode|'
1540        r'linear-case-quot|spread|spread>quot)\s'
1541        )
1542
1543    builtin_math = (
1544        r'(?:number=|if-zero|next-power-of-2|each-integer|\\?1\\+|'
1545        r'fp-special\\?|imaginary-part|unless-zero|float>bits|number\\?|'
1546        r'fp-infinity\\?|bignum\\?|fp-snan\\?|denominator|fp-bitwise=|\\*|'
1547        r'\\+|power-of-2\\?|-|u>=|/|>=|bitand|log2-expects-positive|<|'
1548        r'log2|>|integer\\?|number|bits>double|2/|zero\\?|(find-integer)|'
1549        r'bits>float|float\\?|shift|ratio\\?|even\\?|ratio|fp-sign|bitnot|'
1550        r'>fixnum|complex\\?|/i|/f|byte-array>bignum|when-zero|sgn|>bignum|'
1551        r'next-float|u<|u>|mod|recip|rational|find-last-integer|>float|'
1552        r'(all-integers\\?)|2^|times|integer|fixnum\\?|neg|fixnum|sq|'
1553        r'bignum|(each-integer)|bit\\?|fp-qnan\\?|find-integer|complex|'
1554        r'<fp-nan>|real|double>bits|bitor|rem|fp-nan-payload|all-integers\\?|'
1555        r'real-part|log2-expects-positive\\?|prev-float|align|unordered\\?|'
1556        r'float|fp-nan\\?|abs|bitxor|u<=|odd\\?|<=|/mod|rational\\?|>integer|'
1557        r'real\\?|numerator)\s'
1558        )
1559
1560    builtin_sequences = (
1561        r'(?:member-eq\\?|append|assert-sequence=|find-last-from|trim-head-slice|'
1562        r'clone-like|3sequence|assert-sequence\\?|map-as|last-index-from|'
1563        r'reversed|index-from|cut\\*|pad-tail|remove-eq!|concat-as|'
1564        r'but-last|snip|trim-tail|nths|nth|2selector|sequence|slice\\?|'
1565        r'<slice>|partition|remove-nth|tail-slice|empty\\?|tail\\*|'
1566        r'if-empty|find-from|virtual-sequence\\?|member\\?|set-length|'
1567        r'drop-prefix|unclip|unclip-last-slice|iota|map-sum|'
1568        r'bounds-error\\?|sequence-hashcode-step|selector-for|'
1569        r'accumulate-as|map|start|midpoint@|\\(accumulate\\)|rest-slice|'
1570        r'prepend|fourth|sift|accumulate!|new-sequence|follow|map!|'
1571        r'like|first4|1sequence|reverse|slice|unless-empty|padding|'
1572        r'virtual@|repetition\\?|set-last|index|4sequence|max-length|'
1573        r'set-second|immutable-sequence|first2|first3|replicate-as|'
1574        r'reduce-index|unclip-slice|supremum|suffix!|insert-nth|'
1575        r'trim-tail-slice|tail|3append|short|count|suffix|concat|'
1576        r'flip|filter|sum|immutable\\?|reverse!|2sequence|map-integers|'
1577        r'delete-all|start\\*|indices|snip-slice|check-slice|sequence\\?|'
1578        r'head|map-find|filter!|append-as|reduce|sequence=|halves|'
1579        r'collapse-slice|interleave|2map|filter-as|binary-reduce|'
1580        r'slice-error\\?|product|bounds-check\\?|bounds-check|harvest|'
1581        r'immutable|virtual-exemplar|find|produce|remove|pad-head|last|'
1582        r'replicate|set-fourth|remove-eq|shorten|reversed\\?|'
1583        r'map-find-last|3map-as|2unclip-slice|shorter\\?|3map|find-last|'
1584        r'head-slice|pop\\*|2map-as|tail-slice\\*|but-last-slice|'
1585        r'2map-reduce|iota\\?|collector-for|accumulate|each|selector|'
1586        r'append!|new-resizable|cut-slice|each-index|head-slice\\*|'
1587        r'2reverse-each|sequence-hashcode|pop|set-nth|\\?nth|'
1588        r'<flat-slice>|second|join|when-empty|collector|'
1589        r'immutable-sequence\\?|<reversed>|all\\?|3append-as|'
1590        r'virtual-sequence|subseq\\?|remove-nth!|push-either|new-like|'
1591        r'length|last-index|push-if|2all\\?|lengthen|assert-sequence|'
1592        r'copy|map-reduce|move|third|first|3each|tail\\?|set-first|'
1593        r'prefix|bounds-error|any\\?|<repetition>|trim-slice|exchange|'
1594        r'surround|2reduce|cut|change-nth|min-length|set-third|produce-as|'
1595        r'push-all|head\\?|delete-slice|rest|sum-lengths|2each|head\\*|'
1596        r'infimum|remove!|glue|slice-error|subseq|trim|replace-slice|'
1597        r'push|repetition|map-index|trim-head|unclip-last|mismatch)\s'
1598        )
1599
1600    builtin_namespaces = (
1601        r'(?:global|\\+@|change|set-namestack|change-global|init-namespaces|'
1602        r'on|off|set-global|namespace|set|with-scope|bind|with-variable|'
1603        r'inc|dec|counter|initialize|namestack|get|get-global|make-assoc)\s'
1604        )
1605
1606    builtin_arrays = (
1607        r'(?:<array>|2array|3array|pair|>array|1array|4array|pair\\?|'
1608        r'array|resize-array|array\\?)\s'
1609        )
1610
1611    builtin_io = (
1612        r'(?:\\+character\\+|bad-seek-type\\?|readln|each-morsel|stream-seek|'
1613        r'read|print|with-output-stream|contents|write1|stream-write1|'
1614        r'stream-copy|stream-element-type|with-input-stream|'
1615        r'stream-print|stream-read|stream-contents|stream-tell|'
1616        r'tell-output|bl|seek-output|bad-seek-type|nl|stream-nl|write|'
1617        r'flush|stream-lines|\\+byte\\+|stream-flush|read1|'
1618        r'seek-absolute\\?|stream-read1|lines|stream-readln|'
1619        r'stream-read-until|each-line|seek-end|with-output-stream\\*|'
1620        r'seek-absolute|with-streams|seek-input|seek-relative\\?|'
1621        r'input-stream|stream-write|read-partial|seek-end\\?|'
1622        r'seek-relative|error-stream|read-until|with-input-stream\\*|'
1623        r'with-streams\\*|tell-input|each-block|output-stream|'
1624        r'stream-read-partial|each-stream-block|each-stream-line)\s'
1625        )
1626
1627    builtin_strings = (
1628        r'(?:resize-string|>string|<string>|1string|string|string\\?)\s'
1629        )
1630
1631    builtin_vectors = (
1632        r'(?:vector\\?|<vector>|\\?push|vector|>vector|1vector)\s'
1633        )
1634
1635    builtin_continuations = (
1636        r'(?:with-return|restarts|return-continuation|with-datastack|'
1637        r'recover|rethrow-restarts|<restart>|ifcc|set-catchstack|'
1638        r'>continuation<|cleanup|ignore-errors|restart\\?|'
1639        r'compute-restarts|attempt-all-error|error-thread|continue|'
1640        r'<continuation>|attempt-all-error\\?|condition\\?|'
1641        r'<condition>|throw-restarts|error|catchstack|continue-with|'
1642        r'thread-error-hook|continuation|rethrow|callcc1|'
1643        r'error-continuation|callcc0|attempt-all|condition|'
1644        r'continuation\\?|restart|return)\s'
1645        )
1646
1647    tokens = {
1648        'root': [
1649            # TODO: (( inputs -- outputs ))
1650            # TODO: << ... >>
1651
1652            # defining words
1653            (r'(\s*)(:|::|MACRO:|MEMO:)(\s+)(\S+)',
1654                bygroups(Text, Keyword, Text, Name.Function)),
1655            (r'(\s*)(M:)(\s+)(\S+)(\s+)(\S+)',
1656                bygroups(Text, Keyword, Text, Name.Class, Text, Name.Function)),
1657            (r'(\s*)(GENERIC:)(\s+)(\S+)',
1658                bygroups(Text, Keyword, Text, Name.Function)),
1659            (r'(\s*)(HOOK:|GENERIC#)(\s+)(\S+)(\s+)(\S+)',
1660                bygroups(Text, Keyword, Text, Name.Function, Text, Name.Function)),
1661            (r'(\()(\s+)', bygroups(Name.Function, Text), 'stackeffect'),
1662            (r'\;\s', Keyword),
1663
1664            # imports and namespaces
1665            (r'(USING:)((?:\s|\\\s)+)', bygroups(Keyword.Namespace, Text), 'import'),
1666            (r'(USE:)(\s+)(\S+)', bygroups(Keyword.Namespace, Text, Name.Namespace)),
1667            (r'(UNUSE:)(\s+)(\S+)', bygroups(Keyword.Namespace, Text, Name.Namespace)),
1668            (r'(QUALIFIED:)(\s+)(\S+)',
1669                bygroups(Keyword.Namespace, Text, Name.Namespace)),
1670            (r'(QUALIFIED-WITH:)(\s+)(\S+)',
1671                bygroups(Keyword.Namespace, Text, Name.Namespace)),
1672            (r'(FROM:|EXCLUDE:)(\s+)(\S+)(\s+)(=>)',
1673                bygroups(Keyword.Namespace, Text, Name.Namespace, Text, Text)),
1674            (r'(IN:)(\s+)(\S+)', bygroups(Keyword.Namespace, Text, Name.Namespace)),
1675            (r'(?:ALIAS|DEFER|FORGET|POSTPONE):', Keyword.Namespace),
1676
1677            # tuples and classes
1678            (r'(TUPLE:)(\s+)(\S+)(\s+<\s+)(\S+)',
1679                bygroups(Keyword, Text, Name.Class, Text, Name.Class), 'slots'),
1680            (r'(TUPLE:)(\s+)(\S+)', bygroups(Keyword, Text, Name.Class), 'slots'),
1681            (r'(UNION:)(\s+)(\S+)', bygroups(Keyword, Text, Name.Class)),
1682            (r'(INTERSECTION:)(\s+)(\S+)', bygroups(Keyword, Text, Name.Class)),
1683            (r'(PREDICATE:)(\s+)(\S+)(\s+<\s+)(\S+)',
1684                bygroups(Keyword, Text, Name.Class, Text, Name.Class)),
1685            (r'(C:)(\s+)(\S+)(\s+)(\S+)',
1686                bygroups(Keyword, Text, Name.Function, Text, Name.Class)),
1687            (r'INSTANCE:', Keyword),
1688            (r'SLOT:', Keyword),
1689            (r'MIXIN:', Keyword),
1690            (r'(?:SINGLETON|SINGLETONS):', Keyword),
1691
1692            # other syntax
1693            (r'CONSTANT:', Keyword),
1694            (r'(?:SYMBOL|SYMBOLS):', Keyword),
1695            (r'ERROR:', Keyword),
1696            (r'SYNTAX:', Keyword),
1697            (r'(HELP:)(\s+)(\S+)', bygroups(Keyword, Text, Name.Function)),
1698            (r'(MAIN:)(\s+)(\S+)', bygroups(Keyword.Namespace, Text, Name.Function)),
1699            (r'(?:ALIEN|TYPEDEF|FUNCTION|STRUCT):', Keyword),
1700
1701            # vocab.private
1702            # TODO: words inside vocab.private should have red names?
1703            (r'(?:<PRIVATE|PRIVATE>)', Keyword.Namespace),
1704
1705            # strings
1706            (r'"""\s+(?:.|\n)*?\s+"""', String),
1707            (r'"(?:\\\\|\\"|[^"])*"', String),
1708            (r'CHAR:\s+(\\[\\abfnrstv]*|\S)\s', String.Char),
1709
1710            # comments
1711            (r'\!\s+.*$', Comment),
1712            (r'#\!\s+.*$', Comment),
1713
1714            # boolean constants
1715            (r'(t|f)\s', Name.Constant),
1716
1717            # numbers
1718            (r'-?\d+\.\d+\s', Number.Float),
1719            (r'-?\d+\s', Number.Integer),
1720            (r'HEX:\s+[a-fA-F\d]+\s', Number.Hex),
1721            (r'BIN:\s+[01]+\s', Number.Integer),
1722            (r'OCT:\s+[0-7]+\s', Number.Oct),
1723
1724            # operators
1725            (r'[-+/*=<>^]\s', Operator),
1726
1727            # keywords
1728            (r'(?:deprecated|final|foldable|flushable|inline|recursive)\s', Keyword),
1729
1730            # builtins
1731            (builtin_kernel, Name.Builtin),
1732            (builtin_assocs, Name.Builtin),
1733            (builtin_combinators, Name.Builtin),
1734            (builtin_math, Name.Builtin),
1735            (builtin_sequences, Name.Builtin),
1736            (builtin_namespaces, Name.Builtin),
1737            (builtin_arrays, Name.Builtin),
1738            (builtin_io, Name.Builtin),
1739            (builtin_strings, Name.Builtin),
1740            (builtin_vectors, Name.Builtin),
1741            (builtin_continuations, Name.Builtin),
1742
1743            # whitespaces - usually not relevant
1744            (r'\s+', Text),
1745
1746            # everything else is text
1747            (r'\S+', Text),
1748        ],
1749
1750        'stackeffect': [
1751            (r'\s*\(', Name.Function, 'stackeffect'),
1752            (r'\)', Name.Function, '#pop'),
1753            (r'\-\-', Name.Function),
1754            (r'\s+', Text),
1755            (r'\S+', Name.Variable),
1756        ],
1757
1758        'slots': [
1759            (r'\s+', Text),
1760            (r';\s', Keyword, '#pop'),
1761            (r'\S+', Name.Variable),
1762        ],
1763
1764        'import': [
1765            (r';', Keyword, '#pop'),
1766            (r'\S+', Name.Namespace),
1767            (r'\s+', Text),
1768        ],
1769    }
1770
1771
1772class IokeLexer(RegexLexer):
1773    """
1774    For `Ioke <http://ioke.org/>`_ (a strongly typed, dynamic,
1775    prototype based programming language) source.
1776
1777    *New in Pygments 1.4.*
1778    """
1779    name = 'Ioke'
1780    filenames = ['*.ik']
1781    aliases = ['ioke', 'ik']
1782    mimetypes = ['text/x-iokesrc']
1783    tokens = {
1784        'interpolatableText': [
1785            (r'(\\b|\\e|\\t|\\n|\\f|\\r|\\"|\\\\|\\#|\\\Z|\\u[0-9a-fA-F]{1,4}'
1786             r'|\\[0-3]?[0-7]?[0-7])', String.Escape),
1787            (r'#{', Punctuation, 'textInterpolationRoot')
1788            ],
1789
1790        'text': [
1791            (r'(?<!\\)"', String, '#pop'),
1792            include('interpolatableText'),
1793            (r'[^"]', String)
1794            ],
1795
1796        'documentation': [
1797            (r'(?<!\\)"', String.Doc, '#pop'),
1798            include('interpolatableText'),
1799            (r'[^"]', String.Doc)
1800            ],
1801
1802        'textInterpolationRoot': [
1803            (r'}', Punctuation, '#pop'),
1804            include('root')
1805            ],
1806
1807        'slashRegexp': [
1808            (r'(?<!\\)/[oxpniums]*', String.Regex, '#pop'),
1809            include('interpolatableText'),
1810            (r'\\/', String.Regex),
1811            (r'[^/]', String.Regex)
1812            ],
1813
1814        'squareRegexp': [
1815            (r'(?<!\\)][oxpniums]*', String.Regex, '#pop'),
1816            include('interpolatableText'),
1817            (r'\\]', String.Regex),
1818            (r'[^\]]', String.Regex)
1819            ],
1820
1821        'squareText': [
1822            (r'(?<!\\)]', String, '#pop'),
1823            include('interpolatableText'),
1824            (r'[^\]]', String)
1825            ],
1826
1827        'root': [
1828            (r'\n', Text),
1829            (r'\s+', Text),
1830
1831            # Comments
1832            (r';(.*?)\n', Comment),
1833            (r'\A#!(.*?)\n', Comment),
1834
1835            #Regexps
1836            (r'#/', String.Regex, 'slashRegexp'),
1837            (r'#r\[', String.Regex, 'squareRegexp'),
1838
1839            #Symbols
1840            (r':[a-zA-Z0-9_!:?]+', String.Symbol),
1841            (r'[a-zA-Z0-9_!:?]+:(?![a-zA-Z0-9_!?])', String.Other),
1842            (r':"(\\\\|\\"|[^"])*"', String.Symbol),
1843
1844            #Documentation
1845            (r'((?<=fn\()|(?<=fnx\()|(?<=method\()|(?<=macro\()|(?<=lecro\()'
1846             r'|(?<=syntax\()|(?<=dmacro\()|(?<=dlecro\()|(?<=dlecrox\()'
1847             r'|(?<=dsyntax\())[\s\n\r]*"', String.Doc, 'documentation'),
1848
1849            #Text
1850            (r'"', String, 'text'),
1851            (r'#\[', String, 'squareText'),
1852
1853            #Mimic
1854            (r'[a-zA-Z0-9_][a-zA-Z0-9!?_:]+(?=\s*=.*mimic\s)', Name.Entity),
1855
1856            #Assignment
1857            (r'[a-zA-Z_][a-zA-Z0-9_!:?]*(?=[\s]*[+*/-]?=[^=].*($|\.))', Name.Variable),
1858
1859            # keywords
1860            (r'(break|cond|continue|do|ensure|for|for:dict|for:set|if|let|'
1861             r'loop|p:for|p:for:dict|p:for:set|return|unless|until|while|'
1862             r'with)(?![a-zA-Z0-9!:_?])', Keyword.Reserved),
1863
1864            # Origin
1865            (r'(eval|mimic|print|println)(?![a-zA-Z0-9!:_?])', Keyword),
1866
1867            # Base
1868            (r'(cell\?|cellNames|cellOwner\?|cellOwner|cells|cell|'
1869             r'documentation|hash|identity|mimic|removeCell\!|undefineCell\!)'
1870             r'(?![a-zA-Z0-9!:_?])', Keyword),
1871
1872            # Ground
1873            (r'(stackTraceAsText)(?![a-zA-Z0-9!:_?])', Keyword),
1874
1875            #DefaultBehaviour Literals
1876            (r'(dict|list|message|set)(?![a-zA-Z0-9!:_?])', Keyword.Reserved),
1877
1878            #DefaultBehaviour Case
1879            (r'(case|case:and|case:else|case:nand|case:nor|case:not|case:or|'
1880             r'case:otherwise|case:xor)(?![a-zA-Z0-9!:_?])', Keyword.Reserved),
1881
1882            #DefaultBehaviour Reflection
1883            (r'(asText|become\!|derive|freeze\!|frozen\?|in\?|is\?|kind\?|'
1884             r'mimic\!|mimics|mimics\?|prependMimic\!|removeAllMimics\!|'
1885             r'removeMimic\!|same\?|send|thaw\!|uniqueHexId)'
1886             r'(?![a-zA-Z0-9!:_?])', Keyword),
1887
1888            #DefaultBehaviour Aspects
1889            (r'(after|around|before)(?![a-zA-Z0-9!:_?])', Keyword.Reserved),
1890
1891            # DefaultBehaviour
1892            (r'(kind|cellDescriptionDict|cellSummary|genSym|inspect|notice)'
1893             r'(?![a-zA-Z0-9!:_?])', Keyword),
1894            (r'(use|destructuring)', Keyword.Reserved),
1895
1896            #DefaultBehavior BaseBehavior
1897            (r'(cell\?|cellOwner\?|cellOwner|cellNames|cells|cell|'
1898             r'documentation|identity|removeCell!|undefineCell)'
1899             r'(?![a-zA-Z0-9!:_?])', Keyword),
1900
1901            #DefaultBehavior Internal
1902            (r'(internal:compositeRegexp|internal:concatenateText|'
1903             r'internal:createDecimal|internal:createNumber|'
1904             r'internal:createRegexp|internal:createText)'
1905             r'(?![a-zA-Z0-9!:_?])', Keyword.Reserved),
1906
1907            #DefaultBehaviour Conditions
1908            (r'(availableRestarts|bind|error\!|findRestart|handle|'
1909             r'invokeRestart|rescue|restart|signal\!|warn\!)'
1910             r'(?![a-zA-Z0-9!:_?])', Keyword.Reserved),
1911
1912            # constants
1913            (r'(nil|false|true)(?![a-zA-Z0-9!:_?])', Name.Constant),
1914
1915            # names
1916            (r'(Arity|Base|Call|Condition|DateTime|Aspects|Pointcut|'
1917             r'Assignment|BaseBehavior|Boolean|Case|AndCombiner|Else|'
1918             r'NAndCombiner|NOrCombiner|NotCombiner|OrCombiner|XOrCombiner|'
1919             r'Conditions|Definitions|FlowControl|Internal|Literals|'
1920             r'Reflection|DefaultMacro|DefaultMethod|DefaultSyntax|Dict|'
1921             r'FileSystem|Ground|Handler|Hook|IO|IokeGround|Struct|'
1922             r'LexicalBlock|LexicalMacro|List|Message|Method|Mixins|'
1923             r'NativeMethod|Number|Origin|Pair|Range|Reflector|Regexp Match|'
1924             r'Regexp|Rescue|Restart|Runtime|Sequence|Set|Symbol|'
1925             r'System|Text|Tuple)(?![a-zA-Z0-9!:_?])', Name.Builtin),
1926
1927            # functions
1928            (ur'(generateMatchMethod|aliasMethod|\u03bb|\u028E|fnx|fn|method|'
1929             ur'dmacro|dlecro|syntax|macro|dlecrox|lecrox|lecro|syntax)'
1930             ur'(?![a-zA-Z0-9!:_?])', Name.Function),
1931
1932            # Numbers
1933            (r'-?0[xX][0-9a-fA-F]+', Number.Hex),
1934            (r'-?(\d+\.?\d*|\d*\.\d+)([eE][+-]?[0-9]+)?', Number.Float),
1935            (r'-?\d+', Number.Integer),
1936
1937            (r'#\(', Punctuation),
1938
1939             # Operators
1940            (ur'(&&>>|\|\|>>|\*\*>>|:::|::|\.\.\.|===|\*\*>|\*\*=|&&>|&&=|'
1941             ur'\|\|>|\|\|=|\->>|\+>>|!>>|<>>>|<>>|&>>|%>>|#>>|@>>|/>>|\*>>|'
1942             ur'\?>>|\|>>|\^>>|~>>|\$>>|=>>|<<=|>>=|<=>|<\->|=~|!~|=>|\+\+|'
1943             ur'\-\-|<=|>=|==|!=|&&|\.\.|\+=|\-=|\*=|\/=|%=|&=|\^=|\|=|<\-|'
1944             ur'\+>|!>|<>|&>|%>|#>|\@>|\/>|\*>|\?>|\|>|\^>|~>|\$>|<\->|\->|'
1945             ur'<<|>>|\*\*|\?\||\?&|\|\||>|<|\*|\/|%|\+|\-|&|\^|\||=|\$|!|~|'
1946             ur'\?|#|\u2260|\u2218|\u2208|\u2209)', Operator),
1947            (r'(and|nand|or|xor|nor|return|import)(?![a-zA-Z0-9_!?])',
1948             Operator),
1949
1950            # Punctuation
1951            (r'(\`\`|\`|\'\'|\'|\.|\,|@|@@|\[|\]|\(|\)|{|})', Punctuation),
1952
1953            #kinds
1954            (r'[A-Z][a-zA-Z0-9_!:?]*', Name.Class),
1955
1956            #default cellnames
1957            (r'[a-z_][a-zA-Z0-9_!:?]*', Name)
1958        ]
1959    }
Note: See TracBrowser for help on using the browser.