~ubuntu-branches/ubuntu/natty/moin/natty-updates

« back to all changes in this revision

Viewing changes to MoinMoin/support/pygments/lexers/functional.py

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Smedegaard
  • Date: 2008-06-22 21:17:13 UTC
  • mto: This revision was merged to the branch mainline in revision 18.
  • Revision ID: james.westby@ubuntu.com-20080622211713-inlv5k4eifxckelr
ImportĀ upstreamĀ versionĀ 1.7.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- coding: utf-8 -*-
2
 
"""
3
 
    pygments.lexers.functional
4
 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~
5
 
 
6
 
    Lexers for functional languages.
7
 
 
8
 
    :copyright: Copyright 2006-2010 by the Pygments team, see AUTHORS.
9
 
    :license: BSD, see LICENSE for details.
10
 
"""
11
 
 
12
 
import re
13
 
 
14
 
from pygments.lexer import Lexer, RegexLexer, bygroups, include, do_insertions
15
 
from pygments.token import Text, Comment, Operator, Keyword, Name, \
16
 
     String, Number, Punctuation, Literal, Generic
17
 
 
18
 
 
19
 
__all__ = ['SchemeLexer', 'CommonLispLexer', 'HaskellLexer', 'LiterateHaskellLexer',
20
 
           'OcamlLexer', 'ErlangLexer', 'ErlangShellLexer']
21
 
 
22
 
 
23
 
class SchemeLexer(RegexLexer):
24
 
    """
25
 
    A Scheme lexer, parsing a stream and outputting the tokens
26
 
    needed to highlight scheme code.
27
 
    This lexer could be most probably easily subclassed to parse
28
 
    other LISP-Dialects like Common Lisp, Emacs Lisp or AutoLisp.
29
 
 
30
 
    This parser is checked with pastes from the LISP pastebin
31
 
    at http://paste.lisp.org/ to cover as much syntax as possible.
32
 
 
33
 
    It supports the full Scheme syntax as defined in R5RS.
34
 
 
35
 
    *New in Pygments 0.6.*
36
 
    """
37
 
    name = 'Scheme'
38
 
    aliases = ['scheme', 'scm']
39
 
    filenames = ['*.scm']
40
 
    mimetypes = ['text/x-scheme', 'application/x-scheme']
41
 
 
42
 
    # list of known keywords and builtins taken form vim 6.4 scheme.vim
43
 
    # syntax file.
44
 
    keywords = [
45
 
        'lambda', 'define', 'if', 'else', 'cond', 'and', 'or', 'case', 'let',
46
 
        'let*', 'letrec', 'begin', 'do', 'delay', 'set!', '=>', 'quote',
47
 
        'quasiquote', 'unquote', 'unquote-splicing', 'define-syntax',
48
 
        'let-syntax', 'letrec-syntax', 'syntax-rules'
49
 
    ]
50
 
    builtins = [
51
 
        '*', '+', '-', '/', '<', '<=', '=', '>', '>=', 'abs', 'acos', 'angle',
52
 
        'append', 'apply', 'asin', 'assoc', 'assq', 'assv', 'atan',
53
 
        'boolean?', 'caaaar', 'caaadr', 'caaar', 'caadar', 'caaddr', 'caadr',
54
 
        'caar', 'cadaar', 'cadadr', 'cadar', 'caddar', 'cadddr', 'caddr',
55
 
        'cadr', 'call-with-current-continuation', 'call-with-input-file',
56
 
        'call-with-output-file', 'call-with-values', 'call/cc', 'car',
57
 
        'cdaaar', 'cdaadr', 'cdaar', 'cdadar', 'cdaddr', 'cdadr', 'cdar',
58
 
        'cddaar', 'cddadr', 'cddar', 'cdddar', 'cddddr', 'cdddr', 'cddr',
59
 
        'cdr', 'ceiling', 'char->integer', 'char-alphabetic?', 'char-ci<=?',
60
 
        'char-ci<?', 'char-ci=?', 'char-ci>=?', 'char-ci>?', 'char-downcase',
61
 
        'char-lower-case?', 'char-numeric?', 'char-ready?', 'char-upcase',
62
 
        'char-upper-case?', 'char-whitespace?', 'char<=?', 'char<?', 'char=?',
63
 
        'char>=?', 'char>?', 'char?', 'close-input-port', 'close-output-port',
64
 
        'complex?', 'cons', 'cos', 'current-input-port', 'current-output-port',
65
 
        'denominator', 'display', 'dynamic-wind', 'eof-object?', 'eq?',
66
 
        'equal?', 'eqv?', 'eval', 'even?', 'exact->inexact', 'exact?', 'exp',
67
 
        'expt', 'floor', 'for-each', 'force', 'gcd', 'imag-part',
68
 
        'inexact->exact', 'inexact?', 'input-port?', 'integer->char',
69
 
        'integer?', 'interaction-environment', 'lcm', 'length', 'list',
70
 
        'list->string', 'list->vector', 'list-ref', 'list-tail', 'list?',
71
 
        'load', 'log', 'magnitude', 'make-polar', 'make-rectangular',
72
 
        'make-string', 'make-vector', 'map', 'max', 'member', 'memq', 'memv',
73
 
        'min', 'modulo', 'negative?', 'newline', 'not', 'null-environment',
74
 
        'null?', 'number->string', 'number?', 'numerator', 'odd?',
75
 
        'open-input-file', 'open-output-file', 'output-port?', 'pair?',
76
 
        'peek-char', 'port?', 'positive?', 'procedure?', 'quotient',
77
 
        'rational?', 'rationalize', 'read', 'read-char', 'real-part', 'real?',
78
 
        'remainder', 'reverse', 'round', 'scheme-report-environment',
79
 
        'set-car!', 'set-cdr!', 'sin', 'sqrt', 'string', 'string->list',
80
 
        'string->number', 'string->symbol', 'string-append', 'string-ci<=?',
81
 
        'string-ci<?', 'string-ci=?', 'string-ci>=?', 'string-ci>?',
82
 
        'string-copy', 'string-fill!', 'string-length', 'string-ref',
83
 
        'string-set!', 'string<=?', 'string<?', 'string=?', 'string>=?',
84
 
        'string>?', 'string?', 'substring', 'symbol->string', 'symbol?',
85
 
        'tan', 'transcript-off', 'transcript-on', 'truncate', 'values',
86
 
        'vector', 'vector->list', 'vector-fill!', 'vector-length',
87
 
        'vector-ref', 'vector-set!', 'vector?', 'with-input-from-file',
88
 
        'with-output-to-file', 'write', 'write-char', 'zero?'
89
 
    ]
90
 
 
91
 
    # valid names for identifiers
92
 
    # well, names can only not consist fully of numbers
93
 
    # but this should be good enough for now
94
 
    valid_name = r'[a-zA-Z0-9!$%&*+,/:<=>?@^_~|-]+'
95
 
 
96
 
    tokens = {
97
 
        'root' : [
98
 
            # the comments - always starting with semicolon
99
 
            # and going to the end of the line
100
 
            (r';.*$', Comment.Single),
101
 
 
102
 
            # whitespaces - usually not relevant
103
 
            (r'\s+', Text),
104
 
 
105
 
            # numbers
106
 
            (r'-?\d+\.\d+', Number.Float),
107
 
            (r'-?\d+', Number.Integer),
108
 
            # support for uncommon kinds of numbers -
109
 
            # have to figure out what the characters mean
110
 
            #(r'(#e|#i|#b|#o|#d|#x)[\d.]+', Number),
111
 
 
112
 
            # strings, symbols and characters
113
 
            (r'"(\\\\|\\"|[^"])*"', String),
114
 
            (r"'" + valid_name, String.Symbol),
115
 
            (r"#\\([()/'\".'_!Ā§$%& ?=+-]{1}|[a-zA-Z0-9]+)", String.Char),
116
 
 
117
 
            # constants
118
 
            (r'(#t|#f)', Name.Constant),
119
 
 
120
 
            # special operators
121
 
            (r"('|#|`|,@|,|\.)", Operator),
122
 
 
123
 
            # highlight the keywords
124
 
            ('(%s)' % '|'.join([
125
 
                re.escape(entry) + ' ' for entry in keywords]),
126
 
                Keyword
127
 
            ),
128
 
 
129
 
            # first variable in a quoted string like
130
 
            # '(this is syntactic sugar)
131
 
            (r"(?<='\()" + valid_name, Name.Variable),
132
 
            (r"(?<=#\()" + valid_name, Name.Variable),
133
 
 
134
 
            # highlight the builtins
135
 
            ("(?<=\()(%s)" % '|'.join([
136
 
                re.escape(entry) + ' ' for entry in builtins]),
137
 
                Name.Builtin
138
 
            ),
139
 
 
140
 
            # the remaining functions
141
 
            (r'(?<=\()' + valid_name, Name.Function),
142
 
            # find the remaining variables
143
 
            (valid_name, Name.Variable),
144
 
 
145
 
            # the famous parentheses!
146
 
            (r'(\(|\))', Punctuation),
147
 
        ],
148
 
    }
149
 
 
150
 
 
151
 
class CommonLispLexer(RegexLexer):
152
 
    """
153
 
    A Common Lisp lexer.
154
 
 
155
 
    *New in Pygments 0.9.*
156
 
    """
157
 
    name = 'Common Lisp'
158
 
    aliases = ['common-lisp', 'cl']
159
 
    filenames = ['*.cl', '*.lisp', '*.el']  # use for Elisp too
160
 
    mimetypes = ['text/x-common-lisp']
161
 
 
162
 
    flags = re.IGNORECASE | re.MULTILINE
163
 
 
164
 
    ### couple of useful regexes
165
 
 
166
 
    # characters that are not macro-characters and can be used to begin a symbol
167
 
    nonmacro = r'\\.|[a-zA-Z0-9!$%&*+-/<=>?@\[\]^_{}~]'
168
 
    constituent = nonmacro + '|[#.:]'
169
 
    terminated = r'(?=[ "()\'\n,;`])' # whitespace or terminating macro characters
170
 
 
171
 
    ### symbol token, reverse-engineered from hyperspec
172
 
    # Take a deep breath...
173
 
    symbol = r'(\|[^|]+\||(?:%s)(?:%s)*)' % (nonmacro, constituent)
174
 
 
175
 
    def __init__(self, **options):
176
 
        from pygments.lexers._clbuiltins import BUILTIN_FUNCTIONS, \
177
 
            SPECIAL_FORMS, MACROS, LAMBDA_LIST_KEYWORDS, DECLARATIONS, \
178
 
            BUILTIN_TYPES, BUILTIN_CLASSES
179
 
        self.builtin_function = BUILTIN_FUNCTIONS
180
 
        self.special_forms = SPECIAL_FORMS
181
 
        self.macros = MACROS
182
 
        self.lambda_list_keywords = LAMBDA_LIST_KEYWORDS
183
 
        self.declarations = DECLARATIONS
184
 
        self.builtin_types = BUILTIN_TYPES
185
 
        self.builtin_classes = BUILTIN_CLASSES
186
 
        RegexLexer.__init__(self, **options)
187
 
 
188
 
    def get_tokens_unprocessed(self, text):
189
 
        stack = ['root']
190
 
        for index, token, value in RegexLexer.get_tokens_unprocessed(self, text, stack):
191
 
            if token is Name.Variable:
192
 
                if value in self.builtin_function:
193
 
                    yield index, Name.Builtin, value
194
 
                    continue
195
 
                if value in self.special_forms:
196
 
                    yield index, Keyword, value
197
 
                    continue
198
 
                if value in self.macros:
199
 
                    yield index, Name.Builtin, value
200
 
                    continue
201
 
                if value in self.lambda_list_keywords:
202
 
                    yield index, Keyword, value
203
 
                    continue
204
 
                if value in self.declarations:
205
 
                    yield index, Keyword, value
206
 
                    continue
207
 
                if value in self.builtin_types:
208
 
                    yield index, Keyword.Type, value
209
 
                    continue
210
 
                if value in self.builtin_classes:
211
 
                    yield index, Name.Class, value
212
 
                    continue
213
 
            yield index, token, value
214
 
 
215
 
    tokens = {
216
 
        'root' : [
217
 
            ('', Text, 'body'),
218
 
        ],
219
 
        'multiline-comment' : [
220
 
            (r'#\|', Comment.Multiline, '#push'), # (cf. Hyperspec 2.4.8.19)
221
 
            (r'\|#', Comment.Multiline, '#pop'),
222
 
            (r'[^|#]+', Comment.Multiline),
223
 
            (r'[|#]', Comment.Multiline),
224
 
        ],
225
 
        'commented-form' : [
226
 
            (r'\(', Comment.Preproc, '#push'),
227
 
            (r'\)', Comment.Preproc, '#pop'),
228
 
            (r'[^()]+', Comment.Preproc),
229
 
        ],
230
 
        'body' : [
231
 
            # whitespace
232
 
            (r'\s+', Text),
233
 
 
234
 
            # single-line comment
235
 
            (r';.*$', Comment.Single),
236
 
 
237
 
            # multi-line comment
238
 
            (r'#\|', Comment.Multiline, 'multiline-comment'),
239
 
 
240
 
            # encoding comment (?)
241
 
            (r'#\d*Y.*$', Comment.Special),
242
 
 
243
 
            # strings and characters
244
 
            (r'"(\\.|[^"\\])*"', String),
245
 
            # quoting
246
 
            (r":" + symbol, String.Symbol),
247
 
            (r"'" + symbol, String.Symbol),
248
 
            (r"'", Operator),
249
 
            (r"`", Operator),
250
 
 
251
 
            # decimal numbers
252
 
            (r'[-+]?\d+\.?' + terminated, Number.Integer),
253
 
            (r'[-+]?\d+/\d+' + terminated, Number),
254
 
            (r'[-+]?(\d*\.\d+([defls][-+]?\d+)?|\d+(\.\d*)?[defls][-+]?\d+)' \
255
 
                + terminated, Number.Float),
256
 
 
257
 
            # sharpsign strings and characters
258
 
            (r"#\\." + terminated, String.Char),
259
 
            (r"#\\" + symbol, String.Char),
260
 
 
261
 
            # vector
262
 
            (r'#\(', Operator, 'body'),
263
 
 
264
 
            # bitstring
265
 
            (r'#\d*\*[01]*', Literal.Other),
266
 
 
267
 
            # uninterned symbol
268
 
            (r'#:' + symbol, String.Symbol),
269
 
 
270
 
            # read-time and load-time evaluation
271
 
            (r'#[.,]', Operator),
272
 
 
273
 
            # function shorthand
274
 
            (r'#\'', Name.Function),
275
 
 
276
 
            # binary rational
277
 
            (r'#[bB][+-]?[01]+(/[01]+)?', Number),
278
 
 
279
 
            # octal rational
280
 
            (r'#[oO][+-]?[0-7]+(/[0-7]+)?', Number.Oct),
281
 
 
282
 
            # hex rational
283
 
            (r'#[xX][+-]?[0-9a-fA-F]+(/[0-9a-fA-F]+)?', Number.Hex),
284
 
 
285
 
            # radix rational
286
 
            (r'#\d+[rR][+-]?[0-9a-zA-Z]+(/[0-9a-zA-Z]+)?', Number),
287
 
 
288
 
            # complex
289
 
            (r'(#[cC])(\()', bygroups(Number, Punctuation), 'body'),
290
 
 
291
 
            # array
292
 
            (r'(#\d+[aA])(\()', bygroups(Literal.Other, Punctuation), 'body'),
293
 
 
294
 
            # structure
295
 
            (r'(#[sS])(\()', bygroups(Literal.Other, Punctuation), 'body'),
296
 
 
297
 
            # path
298
 
            (r'#[pP]?"(\\.|[^"])*"', Literal.Other),
299
 
 
300
 
            # reference
301
 
            (r'#\d+=', Operator),
302
 
            (r'#\d+#', Operator),
303
 
 
304
 
            # read-time comment
305
 
            (r'#+nil' + terminated + '\s*\(', Comment.Preproc, 'commented-form'),
306
 
 
307
 
            # read-time conditional
308
 
            (r'#[+-]', Operator),
309
 
 
310
 
            # special operators that should have been parsed already
311
 
            (r'(,@|,|\.)', Operator),
312
 
 
313
 
            # special constants
314
 
            (r'(t|nil)' + terminated, Name.Constant),
315
 
 
316
 
            # functions and variables
317
 
            (r'\*' + symbol + '\*', Name.Variable.Global),
318
 
            (symbol, Name.Variable),
319
 
 
320
 
            # parentheses
321
 
            (r'\(', Punctuation, 'body'),
322
 
            (r'\)', Punctuation, '#pop'),
323
 
        ],
324
 
    }
325
 
 
326
 
 
327
 
class HaskellLexer(RegexLexer):
328
 
    """
329
 
    A Haskell lexer based on the lexemes defined in the Haskell 98 Report.
330
 
 
331
 
    *New in Pygments 0.8.*
332
 
    """
333
 
    name = 'Haskell'
334
 
    aliases = ['haskell', 'hs']
335
 
    filenames = ['*.hs']
336
 
    mimetypes = ['text/x-haskell']
337
 
 
338
 
    reserved = ['case','class','data','default','deriving','do','else',
339
 
                'if','in','infix[lr]?','instance',
340
 
                'let','newtype','of','then','type','where','_']
341
 
    ascii = ['NUL','SOH','[SE]TX','EOT','ENQ','ACK',
342
 
             'BEL','BS','HT','LF','VT','FF','CR','S[OI]','DLE',
343
 
             'DC[1-4]','NAK','SYN','ETB','CAN',
344
 
             'EM','SUB','ESC','[FGRU]S','SP','DEL']
345
 
 
346
 
    tokens = {
347
 
        'root': [
348
 
            # Whitespace:
349
 
            (r'\s+', Text),
350
 
            #(r'--\s*|.*$', Comment.Doc),
351
 
            (r'--(?![!#$%&*+./<=>?@\^|_~]).*?$', Comment.Single),
352
 
            (r'{-', Comment.Multiline, 'comment'),
353
 
            # Lexemes:
354
 
            #  Identifiers
355
 
            (r'\bimport\b', Keyword.Reserved, 'import'),
356
 
            (r'\bmodule\b', Keyword.Reserved, 'module'),
357
 
            (r'\berror\b', Name.Exception),
358
 
            (r'\b(%s)(?!\')\b' % '|'.join(reserved), Keyword.Reserved),
359
 
            (r'^[_a-z][\w\']*', Name.Function),
360
 
            (r'[_a-z][\w\']*', Name),
361
 
            (r'[A-Z][\w\']*', Keyword.Type),
362
 
            #  Operators
363
 
            (r'\\(?![:!#$%&*+.\\/<=>?@^|~-]+)', Name.Function), # lambda operator
364
 
            (r'(<-|::|->|=>|=)(?![:!#$%&*+.\\/<=>?@^|~-]+)', Operator.Word), # specials
365
 
            (r':[:!#$%&*+.\\/<=>?@^|~-]*', Keyword.Type), # Constructor operators
366
 
            (r'[:!#$%&*+.\\/<=>?@^|~-]+', Operator), # Other operators
367
 
            #  Numbers
368
 
            (r'\d+[eE][+-]?\d+', Number.Float),
369
 
            (r'\d+\.\d+([eE][+-]?\d+)?', Number.Float),
370
 
            (r'0[oO][0-7]+', Number.Oct),
371
 
            (r'0[xX][\da-fA-F]+', Number.Hex),
372
 
            (r'\d+', Number.Integer),
373
 
            #  Character/String Literals
374
 
            (r"'", String.Char, 'character'),
375
 
            (r'"', String, 'string'),
376
 
            #  Special
377
 
            (r'\[\]', Keyword.Type),
378
 
            (r'\(\)', Name.Builtin),
379
 
            (r'[][(),;`{}]', Punctuation),
380
 
        ],
381
 
        'import': [
382
 
            # Import statements
383
 
            (r'\s+', Text),
384
 
            # after "funclist" state
385
 
            (r'\)', Punctuation, '#pop'),
386
 
            (r'qualified\b', Keyword),
387
 
            # import X as Y
388
 
            (r'([A-Z][a-zA-Z0-9_.]*)(\s+)(as)(\s+)([A-Z][a-zA-Z0-9_.]*)',
389
 
             bygroups(Name.Namespace, Text, Keyword, Text, Name), '#pop'),
390
 
            # import X hiding (functions)
391
 
            (r'([A-Z][a-zA-Z0-9_.]*)(\s+)(hiding)(\s+)(\()',
392
 
             bygroups(Name.Namespace, Text, Keyword, Text, Punctuation), 'funclist'),
393
 
            # import X (functions)
394
 
            (r'([A-Z][a-zA-Z0-9_.]*)(\s+)(\()',
395
 
             bygroups(Name.Namespace, Text, Punctuation), 'funclist'),
396
 
            # import X
397
 
            (r'[a-zA-Z0-9_.]+', Name.Namespace, '#pop'),
398
 
        ],
399
 
        'module': [
400
 
            (r'\s+', Text),
401
 
            (r'([A-Z][a-zA-Z0-9_.]*)(\s+)(\()',
402
 
             bygroups(Name.Namespace, Text, Punctuation), 'funclist'),
403
 
            (r'[A-Z][a-zA-Z0-9_.]*', Name.Namespace, '#pop'),
404
 
        ],
405
 
        'funclist': [
406
 
            (r'\s+', Text),
407
 
            (r'[A-Z][a-zA-Z0-9_]*', Keyword.Type),
408
 
            (r'[_a-z][\w\']+', Name.Function),
409
 
            (r'--.*$', Comment.Single),
410
 
            (r'{-', Comment.Multiline, 'comment'),
411
 
            (r',', Punctuation),
412
 
            (r'[:!#$%&*+.\\/<=>?@^|~-]+', Operator),
413
 
            # (HACK, but it makes sense to push two instances, believe me)
414
 
            (r'\(', Punctuation, ('funclist', 'funclist')),
415
 
            (r'\)', Punctuation, '#pop:2'),
416
 
        ],
417
 
        'comment': [
418
 
            # Multiline Comments
419
 
            (r'[^-{}]+', Comment.Multiline),
420
 
            (r'{-', Comment.Multiline, '#push'),
421
 
            (r'-}', Comment.Multiline, '#pop'),
422
 
            (r'[-{}]', Comment.Multiline),
423
 
        ],
424
 
        'character': [
425
 
            # Allows multi-chars, incorrectly.
426
 
            (r"[^\\']", String.Char),
427
 
            (r"\\", String.Escape, 'escape'),
428
 
            ("'", String.Char, '#pop'),
429
 
        ],
430
 
        'string': [
431
 
            (r'[^\\"]+', String),
432
 
            (r"\\", String.Escape, 'escape'),
433
 
            ('"', String, '#pop'),
434
 
        ],
435
 
        'escape': [
436
 
            (r'[abfnrtv"\'&\\]', String.Escape, '#pop'),
437
 
            (r'\^[][A-Z@\^_]', String.Escape, '#pop'),
438
 
            ('|'.join(ascii), String.Escape, '#pop'),
439
 
            (r'o[0-7]+', String.Escape, '#pop'),
440
 
            (r'x[\da-fA-F]+', String.Escape, '#pop'),
441
 
            (r'\d+', String.Escape, '#pop'),
442
 
            (r'\s+\\', String.Escape, '#pop'),
443
 
        ],
444
 
    }
445
 
 
446
 
 
447
 
line_re = re.compile('.*?\n')
448
 
bird_re = re.compile(r'(>[ \t]*)(.*\n)')
449
 
 
450
 
class LiterateHaskellLexer(Lexer):
451
 
    """
452
 
    For Literate Haskell (Bird-style or LaTeX) source.
453
 
 
454
 
    Additional options accepted:
455
 
 
456
 
    `litstyle`
457
 
        If given, must be ``"bird"`` or ``"latex"``.  If not given, the style
458
 
        is autodetected: if the first non-whitespace character in the source
459
 
        is a backslash or percent character, LaTeX is assumed, else Bird.
460
 
 
461
 
    *New in Pygments 0.9.*
462
 
    """
463
 
    name = 'Literate Haskell'
464
 
    aliases = ['lhs', 'literate-haskell']
465
 
    filenames = ['*.lhs']
466
 
    mimetypes = ['text/x-literate-haskell']
467
 
 
468
 
    def get_tokens_unprocessed(self, text):
469
 
        hslexer = HaskellLexer(**self.options)
470
 
 
471
 
        style = self.options.get('litstyle')
472
 
        if style is None:
473
 
            style = (text.lstrip()[0:1] in '%\\') and 'latex' or 'bird'
474
 
 
475
 
        code = ''
476
 
        insertions = []
477
 
        if style == 'bird':
478
 
            # bird-style
479
 
            for match in line_re.finditer(text):
480
 
                line = match.group()
481
 
                m = bird_re.match(line)
482
 
                if m:
483
 
                    insertions.append((len(code),
484
 
                                       [(0, Comment.Special, m.group(1))]))
485
 
                    code += m.group(2)
486
 
                else:
487
 
                    insertions.append((len(code), [(0, Text, line)]))
488
 
        else:
489
 
            # latex-style
490
 
            from pygments.lexers.text import TexLexer
491
 
            lxlexer = TexLexer(**self.options)
492
 
 
493
 
            codelines = 0
494
 
            latex = ''
495
 
            for match in line_re.finditer(text):
496
 
                line = match.group()
497
 
                if codelines:
498
 
                    if line.lstrip().startswith('\\end{code}'):
499
 
                        codelines = 0
500
 
                        latex += line
501
 
                    else:
502
 
                        code += line
503
 
                elif line.lstrip().startswith('\\begin{code}'):
504
 
                    codelines = 1
505
 
                    latex += line
506
 
                    insertions.append((len(code),
507
 
                                       list(lxlexer.get_tokens_unprocessed(latex))))
508
 
                    latex = ''
509
 
                else:
510
 
                    latex += line
511
 
            insertions.append((len(code),
512
 
                               list(lxlexer.get_tokens_unprocessed(latex))))
513
 
        for item in do_insertions(insertions, hslexer.get_tokens_unprocessed(code)):
514
 
            yield item
515
 
 
516
 
 
517
 
class OcamlLexer(RegexLexer):
518
 
    """
519
 
    For the OCaml language.
520
 
 
521
 
    *New in Pygments 0.7.*
522
 
    """
523
 
 
524
 
    name = 'OCaml'
525
 
    aliases = ['ocaml']
526
 
    filenames = ['*.ml', '*.mli', '*.mll', '*.mly']
527
 
    mimetypes = ['text/x-ocaml']
528
 
 
529
 
    keywords = [
530
 
      'as', 'assert', 'begin', 'class', 'constraint', 'do', 'done',
531
 
      'downto', 'else', 'end', 'exception', 'external', 'false',
532
 
      'for', 'fun', 'function', 'functor', 'if', 'in', 'include',
533
 
      'inherit', 'initializer', 'lazy', 'let', 'match', 'method',
534
 
      'module', 'mutable', 'new', 'object', 'of', 'open', 'private',
535
 
      'raise', 'rec', 'sig', 'struct', 'then', 'to', 'true', 'try',
536
 
      'type', 'val', 'virtual', 'when', 'while', 'with'
537
 
    ]
538
 
    keyopts = [
539
 
      '!=','#','&','&&','\(','\)','\*','\+',',','-',
540
 
      '-\.','->','\.','\.\.',':','::',':=',':>',';',';;','<',
541
 
      '<-','=','>','>]','>}','\?','\?\?','\[','\[<','\[>','\[\|',
542
 
      ']','_','`','{','{<','\|','\|]','}','~'
543
 
    ]
544
 
 
545
 
    operators = r'[!$%&*+\./:<=>?@^|~-]'
546
 
    word_operators = ['and', 'asr', 'land', 'lor', 'lsl', 'lxor', 'mod', 'or']
547
 
    prefix_syms = r'[!?~]'
548
 
    infix_syms = r'[=<>@^|&+\*/$%-]'
549
 
    primitives = ['unit', 'int', 'float', 'bool', 'string', 'char', 'list', 'array']
550
 
 
551
 
    tokens = {
552
 
        'escape-sequence': [
553
 
            (r'\\[\"\'ntbr]', String.Escape),
554
 
            (r'\\[0-9]{3}', String.Escape),
555
 
            (r'\\x[0-9a-fA-F]{2}', String.Escape),
556
 
        ],
557
 
        'root': [
558
 
            (r'\s+', Text),
559
 
            (r'false|true|\(\)|\[\]', Name.Builtin.Pseudo),
560
 
            (r'\b([A-Z][A-Za-z0-9_\']*)(?=\s*\.)',
561
 
             Name.Namespace, 'dotted'),
562
 
            (r'\b([A-Z][A-Za-z0-9_\']*)', Name.Class),
563
 
            (r'\(\*', Comment, 'comment'),
564
 
            (r'\b(%s)\b' % '|'.join(keywords), Keyword),
565
 
            (r'(%s)' % '|'.join(keyopts), Operator),
566
 
            (r'(%s|%s)?%s' % (infix_syms, prefix_syms, operators), Operator),
567
 
            (r'\b(%s)\b' % '|'.join(word_operators), Operator.Word),
568
 
            (r'\b(%s)\b' % '|'.join(primitives), Keyword.Type),
569
 
 
570
 
            (r"[^\W\d][\w']*", Name),
571
 
 
572
 
            (r'\d[\d_]*', Number.Integer),
573
 
            (r'0[xX][\da-fA-F][\da-fA-F_]*', Number.Hex),
574
 
            (r'0[oO][0-7][0-7_]*', Number.Oct),
575
 
            (r'0[bB][01][01_]*', Number.Binary),
576
 
            (r'-?\d[\d_]*(.[\d_]*)?([eE][+\-]?\d[\d_]*)', Number.Float),
577
 
 
578
 
            (r"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2}))'",
579
 
             String.Char),
580
 
            (r"'.'", String.Char),
581
 
            (r"'", Keyword), # a stray quote is another syntax element
582
 
 
583
 
            (r'"', String.Double, 'string'),
584
 
 
585
 
            (r'[~?][a-z][\w\']*:', Name.Variable),
586
 
        ],
587
 
        'comment': [
588
 
            (r'[^(*)]+', Comment),
589
 
            (r'\(\*', Comment, '#push'),
590
 
            (r'\*\)', Comment, '#pop'),
591
 
            (r'[(*)]', Comment),
592
 
        ],
593
 
        'string': [
594
 
            (r'[^\\"]+', String.Double),
595
 
            include('escape-sequence'),
596
 
            (r'\\\n', String.Double),
597
 
            (r'"', String.Double, '#pop'),
598
 
        ],
599
 
        'dotted': [
600
 
            (r'\s+', Text),
601
 
            (r'\.', Punctuation),
602
 
            (r'[A-Z][A-Za-z0-9_\']*(?=\s*\.)', Name.Namespace),
603
 
            (r'[A-Z][A-Za-z0-9_\']*', Name.Class, '#pop'),
604
 
            (r'[a-z][a-z0-9_\']*', Name, '#pop'),
605
 
        ],
606
 
    }
607
 
 
608
 
 
609
 
class ErlangLexer(RegexLexer):
610
 
    """
611
 
    For the Erlang functional programming language.
612
 
 
613
 
    Blame Jeremy Thurgood (http://jerith.za.net/).
614
 
 
615
 
    *New in Pygments 0.9.*
616
 
    """
617
 
 
618
 
    name = 'Erlang'
619
 
    aliases = ['erlang']
620
 
    filenames = ['*.erl', '*.hrl']
621
 
    mimetypes = ['text/x-erlang']
622
 
 
623
 
    keywords = [
624
 
        'after', 'begin', 'case', 'catch', 'cond', 'end', 'fun', 'if',
625
 
        'let', 'of', 'query', 'receive', 'try', 'when',
626
 
        ]
627
 
 
628
 
    builtins = [ # See erlang(3) man page
629
 
        'abs', 'append_element', 'apply', 'atom_to_list', 'binary_to_list',
630
 
        'bitstring_to_list', 'binary_to_term', 'bit_size', 'bump_reductions',
631
 
        'byte_size', 'cancel_timer', 'check_process_code', 'delete_module',
632
 
        'demonitor', 'disconnect_node', 'display', 'element', 'erase', 'exit',
633
 
        'float', 'float_to_list', 'fun_info', 'fun_to_list',
634
 
        'function_exported', 'garbage_collect', 'get', 'get_keys',
635
 
        'group_leader', 'hash', 'hd', 'integer_to_list', 'iolist_to_binary',
636
 
        'iolist_size', 'is_atom', 'is_binary', 'is_bitstring', 'is_boolean',
637
 
        'is_builtin', 'is_float', 'is_function', 'is_integer', 'is_list',
638
 
        'is_number', 'is_pid', 'is_port', 'is_process_alive', 'is_record',
639
 
        'is_reference', 'is_tuple', 'length', 'link', 'list_to_atom',
640
 
        'list_to_binary', 'list_to_bitstring', 'list_to_existing_atom',
641
 
        'list_to_float', 'list_to_integer', 'list_to_pid', 'list_to_tuple',
642
 
        'load_module', 'localtime_to_universaltime', 'make_tuple', 'md5',
643
 
        'md5_final', 'md5_update', 'memory', 'module_loaded', 'monitor',
644
 
        'monitor_node', 'node', 'nodes', 'open_port', 'phash', 'phash2',
645
 
        'pid_to_list', 'port_close', 'port_command', 'port_connect',
646
 
        'port_control', 'port_call', 'port_info', 'port_to_list',
647
 
        'process_display', 'process_flag', 'process_info', 'purge_module',
648
 
        'put', 'read_timer', 'ref_to_list', 'register', 'resume_process',
649
 
        'round', 'send', 'send_after', 'send_nosuspend', 'set_cookie',
650
 
        'setelement', 'size', 'spawn', 'spawn_link', 'spawn_monitor',
651
 
        'spawn_opt', 'split_binary', 'start_timer', 'statistics',
652
 
        'suspend_process', 'system_flag', 'system_info', 'system_monitor',
653
 
        'system_profile', 'term_to_binary', 'tl', 'trace', 'trace_delivered',
654
 
        'trace_info', 'trace_pattern', 'trunc', 'tuple_size', 'tuple_to_list',
655
 
        'universaltime_to_localtime', 'unlink', 'unregister', 'whereis'
656
 
        ]
657
 
 
658
 
    operators = r'(\+|-|\*|/|<|>|=|==|/=|=:=|=/=|=<|>=|\+\+|--|<-|!)'
659
 
    word_operators = [
660
 
        'and', 'andalso', 'band', 'bnot', 'bor', 'bsl', 'bsr', 'bxor',
661
 
        'div', 'not', 'or', 'orelse', 'rem', 'xor'
662
 
        ]
663
 
 
664
 
    atom_re = r"(?:[a-z][a-zA-Z0-9_]*|'[^\n']*[^\\]')"
665
 
 
666
 
    variable_re = r'(?:[A-Z_][a-zA-Z0-9_]*)'
667
 
 
668
 
    escape_re = r'(?:\\(?:[bdefnrstv\'"\\/]|[0-7][0-7]?[0-7]?|\^[a-zA-Z]))'
669
 
 
670
 
    macro_re = r'(?:'+variable_re+r'|'+atom_re+r')'
671
 
 
672
 
    base_re = r'(?:[2-9]|[12][0-9]|3[0-6])'
673
 
 
674
 
    tokens = {
675
 
        'root': [
676
 
            (r'\s+', Text),
677
 
            (r'%.*\n', Comment),
678
 
            ('(' + '|'.join(keywords) + r')\b', Keyword),
679
 
            ('(' + '|'.join(builtins) + r')\b', Name.Builtin),
680
 
            ('(' + '|'.join(word_operators) + r')\b', Operator.Word),
681
 
            (r'^-', Punctuation, 'directive'),
682
 
            (operators, Operator),
683
 
            (r'"', String, 'string'),
684
 
            (r'<<', Name.Label),
685
 
            (r'>>', Name.Label),
686
 
            (r'('+atom_re+')(:)', bygroups(Name.Namespace, Punctuation)),
687
 
            (r'^('+atom_re+r')(\s*)(\()', bygroups(Name.Function, Text, Punctuation)),
688
 
            (r'[+-]?'+base_re+r'#[0-9a-zA-Z]+', Number.Integer),
689
 
            (r'[+-]?\d+', Number.Integer),
690
 
            (r'[+-]?\d+.\d+', Number.Float),
691
 
            (r'[][:_@\".{}()|;,]', Punctuation),
692
 
            (variable_re, Name.Variable),
693
 
            (atom_re, Name),
694
 
            (r'\?'+macro_re, Name.Constant),
695
 
            (r'\$(?:'+escape_re+r'|\\[ %]|[^\\])', String.Char),
696
 
            (r'#'+atom_re+r'(:?\.'+atom_re+r')?', Name.Label),
697
 
            ],
698
 
        'string': [
699
 
            (escape_re, String.Escape),
700
 
            (r'"', String, '#pop'),
701
 
            (r'~[0-9.*]*[~#+bBcdefginpPswWxX]', String.Interpol),
702
 
            (r'[^"\\~]+', String),
703
 
            (r'~', String),
704
 
            ],
705
 
        'directive': [
706
 
            (r'(define)(\s*)(\()('+macro_re+r')',
707
 
             bygroups(Name.Entity, Text, Punctuation, Name.Constant), '#pop'),
708
 
            (r'(record)(\s*)(\()('+macro_re+r')',
709
 
             bygroups(Name.Entity, Text, Punctuation, Name.Label), '#pop'),
710
 
            (atom_re, Name.Entity, '#pop'),
711
 
            ],
712
 
        }
713
 
 
714
 
 
715
 
class ErlangShellLexer(Lexer):
716
 
    """
717
 
    Shell sessions in erl (for Erlang code).
718
 
 
719
 
    *New in Pygments 1.1.*
720
 
    """
721
 
    name = 'Erlang erl session'
722
 
    aliases = ['erl']
723
 
    filenames = ['*.erl-sh']
724
 
    mimetypes = ['text/x-erl-shellsession']
725
 
 
726
 
    _prompt_re = re.compile(r'\d+>(?=\s|\Z)')
727
 
 
728
 
    def get_tokens_unprocessed(self, text):
729
 
        erlexer = ErlangLexer(**self.options)
730
 
 
731
 
        curcode = ''
732
 
        insertions = []
733
 
        for match in line_re.finditer(text):
734
 
            line = match.group()
735
 
            m = self._prompt_re.match(line)
736
 
            if m is not None:
737
 
                end = m.end()
738
 
                insertions.append((len(curcode),
739
 
                                   [(0, Generic.Prompt, line[:end])]))
740
 
                curcode += line[end:]
741
 
            else:
742
 
                if curcode:
743
 
                    for item in do_insertions(insertions,
744
 
                                    erlexer.get_tokens_unprocessed(curcode)):
745
 
                        yield item
746
 
                    curcode = ''
747
 
                    insertions = []
748
 
                if line.startswith('*'):
749
 
                    yield match.start(), Generic.Traceback, line
750
 
                else:
751
 
                    yield match.start(), Generic.Output, line
752
 
        if curcode:
753
 
            for item in do_insertions(insertions,
754
 
                                      erlexer.get_tokens_unprocessed(curcode)):
755
 
                yield item
756