ThirdParty/Pygments/pygments/lexers/text.py

changeset 4172
4f20dba37ab6
parent 3145
a9de05d4a22f
child 4697
c2e9bf425554
equal deleted inserted replaced
4170:8bc578136279 4172:4f20dba37ab6
3 pygments.lexers.text 3 pygments.lexers.text
4 ~~~~~~~~~~~~~~~~~~~~ 4 ~~~~~~~~~~~~~~~~~~~~
5 5
6 Lexers for non-source code file types. 6 Lexers for non-source code file types.
7 7
8 :copyright: Copyright 2006-2013 by the Pygments team, see AUTHORS. 8 :copyright: Copyright 2006-2014 by the Pygments team, see AUTHORS.
9 :license: BSD, see LICENSE for details. 9 :license: BSD, see LICENSE for details.
10 """ 10 """
11 11
12 from __future__ import unicode_literals 12 from pygments.lexers.configs import ApacheConfLexer, NginxConfLexer, \
13 SquidConfLexer, LighttpdConfLexer, IniLexer, RegeditLexer, PropertiesLexer
14 from pygments.lexers.console import PyPyLogLexer
15 from pygments.lexers.textedit import VimLexer
16 from pygments.lexers.markup import BBCodeLexer, MoinWikiLexer, RstLexer, \
17 TexLexer, GroffLexer
18 from pygments.lexers.installers import DebianControlLexer, SourcesListLexer
19 from pygments.lexers.make import MakefileLexer, BaseMakefileLexer, CMakeLexer
20 from pygments.lexers.haxe import HxmlLexer
21 from pygments.lexers.diff import DiffLexer, DarcsPatchLexer
22 from pygments.lexers.data import YamlLexer
23 from pygments.lexers.textfmts import IrcLogsLexer, GettextLexer, HttpLexer
13 24
14 import re 25 __all__ = []
15 from bisect import bisect
16
17 from pygments.lexer import Lexer, LexerContext, RegexLexer, ExtendedRegexLexer, \
18 bygroups, include, using, this, do_insertions
19 from pygments.token import Punctuation, Text, Comment, Keyword, Name, String, \
20 Generic, Operator, Number, Whitespace, Literal
21 from pygments.util import get_bool_opt, ClassNotFound
22 from pygments.lexers.other import BashLexer
23
24 __all__ = ['IniLexer', 'PropertiesLexer', 'SourcesListLexer', 'BaseMakefileLexer',
25 'MakefileLexer', 'DiffLexer', 'IrcLogsLexer', 'TexLexer',
26 'GroffLexer', 'ApacheConfLexer', 'BBCodeLexer', 'MoinWikiLexer',
27 'RstLexer', 'VimLexer', 'GettextLexer', 'SquidConfLexer',
28 'DebianControlLexer', 'DarcsPatchLexer', 'YamlLexer',
29 'LighttpdConfLexer', 'NginxConfLexer', 'CMakeLexer', 'HttpLexer',
30 'PyPyLogLexer', 'RegeditLexer', 'HxmlLexer']
31
32
33 class IniLexer(RegexLexer):
34 """
35 Lexer for configuration files in INI style.
36 """
37
38 name = 'INI'
39 aliases = ['ini', 'cfg']
40 filenames = ['*.ini', '*.cfg']
41 mimetypes = ['text/x-ini']
42
43 tokens = {
44 'root': [
45 (r'\s+', Text),
46 (r'[;#].*', Comment.Single),
47 (r'\[.*?\]$', Keyword),
48 (r'(.*?)([ \t]*)(=)([ \t]*)(.*(?:\n[ \t].+)*)',
49 bygroups(Name.Attribute, Text, Operator, Text, String))
50 ]
51 }
52
53 def analyse_text(text):
54 npos = text.find('\n')
55 if npos < 3:
56 return False
57 return text[0] == '[' and text[npos-1] == ']'
58
59
60 class RegeditLexer(RegexLexer):
61 """
62 Lexer for `Windows Registry
63 <http://en.wikipedia.org/wiki/Windows_Registry#.REG_files>`_ files produced
64 by regedit.
65
66 *New in Pygments 1.6.*
67 """
68
69 name = 'reg'
70 aliases = ['registry']
71 filenames = ['*.reg']
72 mimetypes = ['text/x-windows-registry']
73
74 tokens = {
75 'root': [
76 (r'Windows Registry Editor.*', Text),
77 (r'\s+', Text),
78 (r'[;#].*', Comment.Single),
79 (r'(\[)(-?)(HKEY_[A-Z_]+)(.*?\])$',
80 bygroups(Keyword, Operator, Name.Builtin, Keyword)),
81 # String keys, which obey somewhat normal escaping
82 (r'("(?:\\"|\\\\|[^"])+")([ \t]*)(=)([ \t]*)',
83 bygroups(Name.Attribute, Text, Operator, Text),
84 'value'),
85 # Bare keys (includes @)
86 (r'(.*?)([ \t]*)(=)([ \t]*)',
87 bygroups(Name.Attribute, Text, Operator, Text),
88 'value'),
89 ],
90 'value': [
91 (r'-', Operator, '#pop'), # delete value
92 (r'(dword|hex(?:\([0-9a-fA-F]\))?)(:)([0-9a-fA-F,]+)',
93 bygroups(Name.Variable, Punctuation, Number), '#pop'),
94 # As far as I know, .reg files do not support line continuation.
95 (r'.*', String, '#pop'),
96 ]
97 }
98
99 def analyse_text(text):
100 return text.startswith('Windows Registry Editor')
101
102
103 class PropertiesLexer(RegexLexer):
104 """
105 Lexer for configuration files in Java's properties format.
106
107 *New in Pygments 1.4.*
108 """
109
110 name = 'Properties'
111 aliases = ['properties']
112 filenames = ['*.properties']
113 mimetypes = ['text/x-java-properties']
114
115 tokens = {
116 'root': [
117 (r'\s+', Text),
118 (r'(?:[;#]|//).*$', Comment),
119 (r'(.*?)([ \t]*)([=:])([ \t]*)(.*(?:(?<=\\)\n.*)*)',
120 bygroups(Name.Attribute, Text, Operator, Text, String)),
121 ],
122 }
123
124
125 class SourcesListLexer(RegexLexer):
126 """
127 Lexer that highlights debian sources.list files.
128
129 *New in Pygments 0.7.*
130 """
131
132 name = 'Debian Sourcelist'
133 aliases = ['sourceslist', 'sources.list']
134 filenames = ['sources.list']
135 mimetype = ['application/x-debian-sourceslist']
136
137 tokens = {
138 'root': [
139 (r'\s+', Text),
140 (r'#.*?$', Comment),
141 (r'^(deb(?:-src)?)(\s+)',
142 bygroups(Keyword, Text), 'distribution')
143 ],
144 'distribution': [
145 (r'#.*?$', Comment, '#pop'),
146 (r'\$\(ARCH\)', Name.Variable),
147 (r'[^\s$[]+', String),
148 (r'\[', String.Other, 'escaped-distribution'),
149 (r'\$', String),
150 (r'\s+', Text, 'components')
151 ],
152 'escaped-distribution': [
153 (r'\]', String.Other, '#pop'),
154 (r'\$\(ARCH\)', Name.Variable),
155 (r'[^\]$]+', String.Other),
156 (r'\$', String.Other)
157 ],
158 'components': [
159 (r'#.*?$', Comment, '#pop:2'),
160 (r'$', Text, '#pop:2'),
161 (r'\s+', Text),
162 (r'\S+', Keyword.Pseudo),
163 ]
164 }
165
166 def analyse_text(text):
167 for line in text.split('\n'):
168 line = line.strip()
169 if not (line.startswith('#') or line.startswith('deb ') or
170 line.startswith('deb-src ') or not line):
171 return False
172 return True
173
174
175 class MakefileLexer(Lexer):
176 """
177 Lexer for BSD and GNU make extensions (lenient enough to handle both in
178 the same file even).
179
180 *Rewritten in Pygments 0.10.*
181 """
182
183 name = 'Makefile'
184 aliases = ['make', 'makefile', 'mf', 'bsdmake']
185 filenames = ['*.mak', 'Makefile', 'makefile', 'Makefile.*', 'GNUmakefile']
186 mimetypes = ['text/x-makefile']
187
188 r_special = re.compile(r'^(?:'
189 # BSD Make
190 r'\.\s*(include|undef|error|warning|if|else|elif|endif|for|endfor)|'
191 # GNU Make
192 r'\s*(ifeq|ifneq|ifdef|ifndef|else|endif|-?include|define|endef|:))(?=\s)')
193 r_comment = re.compile(r'^\s*@?#')
194
195 def get_tokens_unprocessed(self, text):
196 ins = []
197 lines = text.splitlines(True)
198 done = ''
199 lex = BaseMakefileLexer(**self.options)
200 backslashflag = False
201 for line in lines:
202 if self.r_special.match(line) or backslashflag:
203 ins.append((len(done), [(0, Comment.Preproc, line)]))
204 backslashflag = line.strip().endswith('\\')
205 elif self.r_comment.match(line):
206 ins.append((len(done), [(0, Comment, line)]))
207 else:
208 done += line
209 for item in do_insertions(ins, lex.get_tokens_unprocessed(done)):
210 yield item
211
212
213 class BaseMakefileLexer(RegexLexer):
214 """
215 Lexer for simple Makefiles (no preprocessing).
216
217 *New in Pygments 0.10.*
218 """
219
220 name = 'Base Makefile'
221 aliases = ['basemake']
222 filenames = []
223 mimetypes = []
224
225 tokens = {
226 'root': [
227 (r'^(?:[\t ]+.*\n|\n)+', using(BashLexer)),
228 (r'\$\((?:.*\\\n|.*\n)+', using(BashLexer)),
229 (r'\s+', Text),
230 (r'#.*?\n', Comment),
231 (r'(export)(\s+)(?=[a-zA-Z0-9_${}\t -]+\n)',
232 bygroups(Keyword, Text), 'export'),
233 (r'export\s+', Keyword),
234 # assignment
235 (r'([a-zA-Z0-9_${}.-]+)(\s*)([!?:+]?=)([ \t]*)((?:.*\\\n)+|.*\n)',
236 bygroups(Name.Variable, Text, Operator, Text, using(BashLexer))),
237 # strings
238 (r'(?s)"(\\\\|\\.|[^"\\])*"', String.Double),
239 (r"(?s)'(\\\\|\\.|[^'\\])*'", String.Single),
240 # targets
241 (r'([^\n:]+)(:+)([ \t]*)', bygroups(Name.Function, Operator, Text),
242 'block-header'),
243 # TODO: add paren handling (grr)
244 ],
245 'export': [
246 (r'[a-zA-Z0-9_${}-]+', Name.Variable),
247 (r'\n', Text, '#pop'),
248 (r'\s+', Text),
249 ],
250 'block-header': [
251 (r'[^,\\\n#]+', Number),
252 (r',', Punctuation),
253 (r'#.*?\n', Comment),
254 (r'\\\n', Text), # line continuation
255 (r'\\.', Text),
256 (r'(?:[\t ]+.*\n|\n)+', using(BashLexer), '#pop'),
257 ],
258 }
259
260
261 class DiffLexer(RegexLexer):
262 """
263 Lexer for unified or context-style diffs or patches.
264 """
265
266 name = 'Diff'
267 aliases = ['diff', 'udiff']
268 filenames = ['*.diff', '*.patch']
269 mimetypes = ['text/x-diff', 'text/x-patch']
270
271 tokens = {
272 'root': [
273 (r' .*\n', Text),
274 (r'\+.*\n', Generic.Inserted),
275 (r'-.*\n', Generic.Deleted),
276 (r'!.*\n', Generic.Strong),
277 (r'@.*\n', Generic.Subheading),
278 (r'([Ii]ndex|diff).*\n', Generic.Heading),
279 (r'=.*\n', Generic.Heading),
280 (r'.*\n', Text),
281 ]
282 }
283
284 def analyse_text(text):
285 if text[:7] == 'Index: ':
286 return True
287 if text[:5] == 'diff ':
288 return True
289 if text[:4] == '--- ':
290 return 0.9
291
292
293 DPATCH_KEYWORDS = ['hunk', 'addfile', 'adddir', 'rmfile', 'rmdir', 'move',
294 'replace']
295
296 class DarcsPatchLexer(RegexLexer):
297 """
298 DarcsPatchLexer is a lexer for the various versions of the darcs patch
299 format. Examples of this format are derived by commands such as
300 ``darcs annotate --patch`` and ``darcs send``.
301
302 *New in Pygments 0.10.*
303 """
304 name = 'Darcs Patch'
305 aliases = ['dpatch']
306 filenames = ['*.dpatch', '*.darcspatch']
307
308 tokens = {
309 'root': [
310 (r'<', Operator),
311 (r'>', Operator),
312 (r'{', Operator),
313 (r'}', Operator),
314 (r'(\[)((?:TAG )?)(.*)(\n)(.*)(\*\*)(\d+)(\s?)(\])',
315 bygroups(Operator, Keyword, Name, Text, Name, Operator,
316 Literal.Date, Text, Operator)),
317 (r'(\[)((?:TAG )?)(.*)(\n)(.*)(\*\*)(\d+)(\s?)',
318 bygroups(Operator, Keyword, Name, Text, Name, Operator,
319 Literal.Date, Text), 'comment'),
320 (r'New patches:', Generic.Heading),
321 (r'Context:', Generic.Heading),
322 (r'Patch bundle hash:', Generic.Heading),
323 (r'(\s*)(%s)(.*\n)' % '|'.join(DPATCH_KEYWORDS),
324 bygroups(Text, Keyword, Text)),
325 (r'\+', Generic.Inserted, "insert"),
326 (r'-', Generic.Deleted, "delete"),
327 (r'.*\n', Text),
328 ],
329 'comment': [
330 (r'[^\]].*\n', Comment),
331 (r'\]', Operator, "#pop"),
332 ],
333 'specialText': [ # darcs add [_CODE_] special operators for clarity
334 (r'\n', Text, "#pop"), # line-based
335 (r'\[_[^_]*_]', Operator),
336 ],
337 'insert': [
338 include('specialText'),
339 (r'\[', Generic.Inserted),
340 (r'[^\n\[]+', Generic.Inserted),
341 ],
342 'delete': [
343 include('specialText'),
344 (r'\[', Generic.Deleted),
345 (r'[^\n\[]+', Generic.Deleted),
346 ],
347 }
348
349
350 class IrcLogsLexer(RegexLexer):
351 """
352 Lexer for IRC logs in *irssi*, *xchat* or *weechat* style.
353 """
354
355 name = 'IRC logs'
356 aliases = ['irc']
357 filenames = ['*.weechatlog']
358 mimetypes = ['text/x-irclog']
359
360 flags = re.VERBOSE | re.MULTILINE
361 timestamp = r"""
362 (
363 # irssi / xchat and others
364 (?: \[|\()? # Opening bracket or paren for the timestamp
365 (?: # Timestamp
366 (?: (?:\d{1,4} [-/]?)+ # Date as - or /-separated groups of digits
367 [T ])? # Date/time separator: T or space
368 (?: \d?\d [:.]?)+ # Time as :/.-separated groups of 1 or 2 digits
369 )
370 (?: \]|\))?\s+ # Closing bracket or paren for the timestamp
371 |
372 # weechat
373 \d{4}\s\w{3}\s\d{2}\s # Date
374 \d{2}:\d{2}:\d{2}\s+ # Time + Whitespace
375 |
376 # xchat
377 \w{3}\s\d{2}\s # Date
378 \d{2}:\d{2}:\d{2}\s+ # Time + Whitespace
379 )?
380 """
381 tokens = {
382 'root': [
383 # log start/end
384 (r'^\*\*\*\*(.*)\*\*\*\*$', Comment),
385 # hack
386 ("^" + timestamp + r'(\s*<[^>]*>\s*)$', bygroups(Comment.Preproc, Name.Tag)),
387 # normal msgs
388 ("^" + timestamp + r"""
389 (\s*<.*?>\s*) # Nick """,
390 bygroups(Comment.Preproc, Name.Tag), 'msg'),
391 # /me msgs
392 ("^" + timestamp + r"""
393 (\s*[*]\s+) # Star
394 (\S+\s+.*?\n) # Nick + rest of message """,
395 bygroups(Comment.Preproc, Keyword, Generic.Inserted)),
396 # join/part msgs
397 ("^" + timestamp + r"""
398 (\s*(?:\*{3}|<?-[!@=P]?->?)\s*) # Star(s) or symbols
399 (\S+\s+) # Nick + Space
400 (.*?\n) # Rest of message """,
401 bygroups(Comment.Preproc, Keyword, String, Comment)),
402 (r"^.*?\n", Text),
403 ],
404 'msg': [
405 (r"\S+:(?!//)", Name.Attribute), # Prefix
406 (r".*\n", Text, '#pop'),
407 ],
408 }
409
410
411 class BBCodeLexer(RegexLexer):
412 """
413 A lexer that highlights BBCode(-like) syntax.
414
415 *New in Pygments 0.6.*
416 """
417
418 name = 'BBCode'
419 aliases = ['bbcode']
420 mimetypes = ['text/x-bbcode']
421
422 tokens = {
423 'root': [
424 (r'[^[]+', Text),
425 # tag/end tag begin
426 (r'\[/?\w+', Keyword, 'tag'),
427 # stray bracket
428 (r'\[', Text),
429 ],
430 'tag': [
431 (r'\s+', Text),
432 # attribute with value
433 (r'(\w+)(=)("?[^\s"\]]+"?)',
434 bygroups(Name.Attribute, Operator, String)),
435 # tag argument (a la [color=green])
436 (r'(=)("?[^\s"\]]+"?)',
437 bygroups(Operator, String)),
438 # tag end
439 (r'\]', Keyword, '#pop'),
440 ],
441 }
442
443
444 class TexLexer(RegexLexer):
445 """
446 Lexer for the TeX and LaTeX typesetting languages.
447 """
448
449 name = 'TeX'
450 aliases = ['tex', 'latex']
451 filenames = ['*.tex', '*.aux', '*.toc']
452 mimetypes = ['text/x-tex', 'text/x-latex']
453
454 tokens = {
455 'general': [
456 (r'%.*?\n', Comment),
457 (r'[{}]', Name.Builtin),
458 (r'[&_^]', Name.Builtin),
459 ],
460 'root': [
461 (r'\\\[', String.Backtick, 'displaymath'),
462 (r'\\\(', String, 'inlinemath'),
463 (r'\$\$', String.Backtick, 'displaymath'),
464 (r'\$', String, 'inlinemath'),
465 (r'\\([a-zA-Z]+|.)', Keyword, 'command'),
466 include('general'),
467 (r'[^\\$%&_^{}]+', Text),
468 ],
469 'math': [
470 (r'\\([a-zA-Z]+|.)', Name.Variable),
471 include('general'),
472 (r'[0-9]+', Number),
473 (r'[-=!+*/()\[\]]', Operator),
474 (r'[^=!+*/()\[\]\\$%&_^{}0-9-]+', Name.Builtin),
475 ],
476 'inlinemath': [
477 (r'\\\)', String, '#pop'),
478 (r'\$', String, '#pop'),
479 include('math'),
480 ],
481 'displaymath': [
482 (r'\\\]', String, '#pop'),
483 (r'\$\$', String, '#pop'),
484 (r'\$', Name.Builtin),
485 include('math'),
486 ],
487 'command': [
488 (r'\[.*?\]', Name.Attribute),
489 (r'\*', Keyword),
490 (r'', Text, '#pop'),
491 ],
492 }
493
494 def analyse_text(text):
495 for start in ("\\documentclass", "\\input", "\\documentstyle",
496 "\\relax"):
497 if text[:len(start)] == start:
498 return True
499
500
501 class GroffLexer(RegexLexer):
502 """
503 Lexer for the (g)roff typesetting language, supporting groff
504 extensions. Mainly useful for highlighting manpage sources.
505
506 *New in Pygments 0.6.*
507 """
508
509 name = 'Groff'
510 aliases = ['groff', 'nroff', 'man']
511 filenames = ['*.[1234567]', '*.man']
512 mimetypes = ['application/x-troff', 'text/troff']
513
514 tokens = {
515 'root': [
516 (r'(\.)(\w+)', bygroups(Text, Keyword), 'request'),
517 (r'\.', Punctuation, 'request'),
518 # Regular characters, slurp till we find a backslash or newline
519 (r'[^\\\n]*', Text, 'textline'),
520 ],
521 'textline': [
522 include('escapes'),
523 (r'[^\\\n]+', Text),
524 (r'\n', Text, '#pop'),
525 ],
526 'escapes': [
527 # groff has many ways to write escapes.
528 (r'\\"[^\n]*', Comment),
529 (r'\\[fn]\w', String.Escape),
530 (r'\\\(.{2}', String.Escape),
531 (r'\\.\[.*\]', String.Escape),
532 (r'\\.', String.Escape),
533 (r'\\\n', Text, 'request'),
534 ],
535 'request': [
536 (r'\n', Text, '#pop'),
537 include('escapes'),
538 (r'"[^\n"]+"', String.Double),
539 (r'\d+', Number),
540 (r'\S+', String),
541 (r'\s+', Text),
542 ],
543 }
544
545 def analyse_text(text):
546 if text[:1] != '.':
547 return False
548 if text[:3] == '.\\"':
549 return True
550 if text[:4] == '.TH ':
551 return True
552 if text[1:3].isalnum() and text[3].isspace():
553 return 0.9
554
555
556 class ApacheConfLexer(RegexLexer):
557 """
558 Lexer for configuration files following the Apache config file
559 format.
560
561 *New in Pygments 0.6.*
562 """
563
564 name = 'ApacheConf'
565 aliases = ['apacheconf', 'aconf', 'apache']
566 filenames = ['.htaccess', 'apache.conf', 'apache2.conf']
567 mimetypes = ['text/x-apacheconf']
568 flags = re.MULTILINE | re.IGNORECASE
569
570 tokens = {
571 'root': [
572 (r'\s+', Text),
573 (r'(#.*?)$', Comment),
574 (r'(<[^\s>]+)(?:(\s+)(.*?))?(>)',
575 bygroups(Name.Tag, Text, String, Name.Tag)),
576 (r'([a-zA-Z][a-zA-Z0-9_]*)(\s+)',
577 bygroups(Name.Builtin, Text), 'value'),
578 (r'\.+', Text),
579 ],
580 'value': [
581 (r'$', Text, '#pop'),
582 (r'[^\S\n]+', Text),
583 (r'\d+\.\d+\.\d+\.\d+(?:/\d+)?', Number),
584 (r'\d+', Number),
585 (r'/([a-zA-Z0-9][a-zA-Z0-9_./-]+)', String.Other),
586 (r'(on|off|none|any|all|double|email|dns|min|minimal|'
587 r'os|productonly|full|emerg|alert|crit|error|warn|'
588 r'notice|info|debug|registry|script|inetd|standalone|'
589 r'user|group)\b', Keyword),
590 (r'"([^"\\]*(?:\\.[^"\\]*)*)"', String.Double),
591 (r'[^\s"]+', Text)
592 ]
593 }
594
595
596 class MoinWikiLexer(RegexLexer):
597 """
598 For MoinMoin (and Trac) Wiki markup.
599
600 *New in Pygments 0.7.*
601 """
602
603 name = 'MoinMoin/Trac Wiki markup'
604 aliases = ['trac-wiki', 'moin']
605 filenames = []
606 mimetypes = ['text/x-trac-wiki']
607 flags = re.MULTILINE | re.IGNORECASE
608
609 tokens = {
610 'root': [
611 (r'^#.*$', Comment),
612 (r'(!)(\S+)', bygroups(Keyword, Text)), # Ignore-next
613 # Titles
614 (r'^(=+)([^=]+)(=+)(\s*#.+)?$',
615 bygroups(Generic.Heading, using(this), Generic.Heading, String)),
616 # Literal code blocks, with optional shebang
617 (r'({{{)(\n#!.+)?', bygroups(Name.Builtin, Name.Namespace), 'codeblock'),
618 (r'(\'\'\'?|\|\||`|__|~~|\^|,,|::)', Comment), # Formatting
619 # Lists
620 (r'^( +)([.*-])( )', bygroups(Text, Name.Builtin, Text)),
621 (r'^( +)([a-z]{1,5}\.)( )', bygroups(Text, Name.Builtin, Text)),
622 # Other Formatting
623 (r'\[\[\w+.*?\]\]', Keyword), # Macro
624 (r'(\[[^\s\]]+)(\s+[^\]]+?)?(\])',
625 bygroups(Keyword, String, Keyword)), # Link
626 (r'^----+$', Keyword), # Horizontal rules
627 (r'[^\n\'\[{!_~^,|]+', Text),
628 (r'\n', Text),
629 (r'.', Text),
630 ],
631 'codeblock': [
632 (r'}}}', Name.Builtin, '#pop'),
633 # these blocks are allowed to be nested in Trac, but not MoinMoin
634 (r'{{{', Text, '#push'),
635 (r'[^{}]+', Comment.Preproc), # slurp boring text
636 (r'.', Comment.Preproc), # allow loose { or }
637 ],
638 }
639
640
641 class RstLexer(RegexLexer):
642 """
643 For `reStructuredText <http://docutils.sf.net/rst.html>`_ markup.
644
645 *New in Pygments 0.7.*
646
647 Additional options accepted:
648
649 `handlecodeblocks`
650 Highlight the contents of ``.. sourcecode:: langauge`` and
651 ``.. code:: language`` directives with a lexer for the given
652 language (default: ``True``). *New in Pygments 0.8.*
653 """
654 name = 'reStructuredText'
655 aliases = ['rst', 'rest', 'restructuredtext']
656 filenames = ['*.rst', '*.rest']
657 mimetypes = ["text/x-rst", "text/prs.fallenstein.rst"]
658 flags = re.MULTILINE
659
660 def _handle_sourcecode(self, match):
661 from pygments.lexers import get_lexer_by_name
662
663 # section header
664 yield match.start(1), Punctuation, match.group(1)
665 yield match.start(2), Text, match.group(2)
666 yield match.start(3), Operator.Word, match.group(3)
667 yield match.start(4), Punctuation, match.group(4)
668 yield match.start(5), Text, match.group(5)
669 yield match.start(6), Keyword, match.group(6)
670 yield match.start(7), Text, match.group(7)
671
672 # lookup lexer if wanted and existing
673 lexer = None
674 if self.handlecodeblocks:
675 try:
676 lexer = get_lexer_by_name(match.group(6).strip())
677 except ClassNotFound:
678 pass
679 indention = match.group(8)
680 indention_size = len(indention)
681 code = (indention + match.group(9) + match.group(10) + match.group(11))
682
683 # no lexer for this language. handle it like it was a code block
684 if lexer is None:
685 yield match.start(8), String, code
686 return
687
688 # highlight the lines with the lexer.
689 ins = []
690 codelines = code.splitlines(True)
691 code = ''
692 for line in codelines:
693 if len(line) > indention_size:
694 ins.append((len(code), [(0, Text, line[:indention_size])]))
695 code += line[indention_size:]
696 else:
697 code += line
698 for item in do_insertions(ins, lexer.get_tokens_unprocessed(code)):
699 yield item
700
701 # from docutils.parsers.rst.states
702 closers = '\'")]}>\u2019\u201d\xbb!?'
703 unicode_delimiters = '\u2010\u2011\u2012\u2013\u2014\u00a0'
704 end_string_suffix = (r'((?=$)|(?=[-/:.,; \n\x00%s%s]))'
705 % (re.escape(unicode_delimiters),
706 re.escape(closers)))
707
708 tokens = {
709 'root': [
710 # Heading with overline
711 (r'^(=+|-+|`+|:+|\.+|\'+|"+|~+|\^+|_+|\*+|\++|#+)([ \t]*\n)'
712 r'(.+)(\n)(\1)(\n)',
713 bygroups(Generic.Heading, Text, Generic.Heading,
714 Text, Generic.Heading, Text)),
715 # Plain heading
716 (r'^(\S.*)(\n)(={3,}|-{3,}|`{3,}|:{3,}|\.{3,}|\'{3,}|"{3,}|'
717 r'~{3,}|\^{3,}|_{3,}|\*{3,}|\+{3,}|#{3,})(\n)',
718 bygroups(Generic.Heading, Text, Generic.Heading, Text)),
719 # Bulleted lists
720 (r'^(\s*)([-*+])( .+\n(?:\1 .+\n)*)',
721 bygroups(Text, Number, using(this, state='inline'))),
722 # Numbered lists
723 (r'^(\s*)([0-9#ivxlcmIVXLCM]+\.)( .+\n(?:\1 .+\n)*)',
724 bygroups(Text, Number, using(this, state='inline'))),
725 (r'^(\s*)(\(?[0-9#ivxlcmIVXLCM]+\))( .+\n(?:\1 .+\n)*)',
726 bygroups(Text, Number, using(this, state='inline'))),
727 # Numbered, but keep words at BOL from becoming lists
728 (r'^(\s*)([A-Z]+\.)( .+\n(?:\1 .+\n)+)',
729 bygroups(Text, Number, using(this, state='inline'))),
730 (r'^(\s*)(\(?[A-Za-z]+\))( .+\n(?:\1 .+\n)+)',
731 bygroups(Text, Number, using(this, state='inline'))),
732 # Line blocks
733 (r'^(\s*)(\|)( .+\n(?:\| .+\n)*)',
734 bygroups(Text, Operator, using(this, state='inline'))),
735 # Sourcecode directives
736 (r'^( *\.\.)(\s*)((?:source)?code)(::)([ \t]*)([^\n]+)'
737 r'(\n[ \t]*\n)([ \t]+)(.*)(\n)((?:(?:\8.*|)\n)+)',
738 _handle_sourcecode),
739 # A directive
740 (r'^( *\.\.)(\s*)([\w:-]+?)(::)(?:([ \t]*)(.*))',
741 bygroups(Punctuation, Text, Operator.Word, Punctuation, Text,
742 using(this, state='inline'))),
743 # A reference target
744 (r'^( *\.\.)(\s*)(_(?:[^:\\]|\\.)+:)(.*?)$',
745 bygroups(Punctuation, Text, Name.Tag, using(this, state='inline'))),
746 # A footnote/citation target
747 (r'^( *\.\.)(\s*)(\[.+\])(.*?)$',
748 bygroups(Punctuation, Text, Name.Tag, using(this, state='inline'))),
749 # A substitution def
750 (r'^( *\.\.)(\s*)(\|.+\|)(\s*)([\w:-]+?)(::)(?:([ \t]*)(.*))',
751 bygroups(Punctuation, Text, Name.Tag, Text, Operator.Word,
752 Punctuation, Text, using(this, state='inline'))),
753 # Comments
754 (r'^ *\.\..*(\n( +.*\n|\n)+)?', Comment.Preproc),
755 # Field list
756 (r'^( *)(:[a-zA-Z-]+:)(\s*)$', bygroups(Text, Name.Class, Text)),
757 (r'^( *)(:.*?:)([ \t]+)(.*?)$',
758 bygroups(Text, Name.Class, Text, Name.Function)),
759 # Definition list
760 (r'^([^ ].*(?<!::)\n)((?:(?: +.*)\n)+)',
761 bygroups(using(this, state='inline'), using(this, state='inline'))),
762 # Code blocks
763 (r'(::)(\n[ \t]*\n)([ \t]+)(.*)(\n)((?:(?:\3.*|)\n)+)',
764 bygroups(String.Escape, Text, String, String, Text, String)),
765 include('inline'),
766 ],
767 'inline': [
768 (r'\\.', Text), # escape
769 (r'``', String, 'literal'), # code
770 (r'(`.+?)(<.+?>)(`__?)', # reference with inline target
771 bygroups(String, String.Interpol, String)),
772 (r'`.+?`__?', String), # reference
773 (r'(`.+?`)(:[a-zA-Z0-9:-]+?:)?',
774 bygroups(Name.Variable, Name.Attribute)), # role
775 (r'(:[a-zA-Z0-9:-]+?:)(`.+?`)',
776 bygroups(Name.Attribute, Name.Variable)), # role (content first)
777 (r'\*\*.+?\*\*', Generic.Strong), # Strong emphasis
778 (r'\*.+?\*', Generic.Emph), # Emphasis
779 (r'\[.*?\]_', String), # Footnote or citation
780 (r'<.+?>', Name.Tag), # Hyperlink
781 (r'[^\\\n\[*`:]+', Text),
782 (r'.', Text),
783 ],
784 'literal': [
785 (r'[^`]+', String),
786 (r'``' + end_string_suffix, String, '#pop'),
787 (r'`', String),
788 ]
789 }
790
791 def __init__(self, **options):
792 self.handlecodeblocks = get_bool_opt(options, 'handlecodeblocks', True)
793 RegexLexer.__init__(self, **options)
794
795 def analyse_text(text):
796 if text[:2] == '..' and text[2:3] != '.':
797 return 0.3
798 p1 = text.find("\n")
799 p2 = text.find("\n", p1 + 1)
800 if (p2 > -1 and # has two lines
801 p1 * 2 + 1 == p2 and # they are the same length
802 text[p1+1] in '-=' and # the next line both starts and ends with
803 text[p1+1] == text[p2-1]): # ...a sufficiently high header
804 return 0.5
805
806
807 class VimLexer(RegexLexer):
808 """
809 Lexer for VimL script files.
810
811 *New in Pygments 0.8.*
812 """
813 name = 'VimL'
814 aliases = ['vim']
815 filenames = ['*.vim', '.vimrc', '.exrc', '.gvimrc',
816 '_vimrc', '_exrc', '_gvimrc', 'vimrc', 'gvimrc']
817 mimetypes = ['text/x-vim']
818 flags = re.MULTILINE
819
820 tokens = {
821 'root': [
822 (r'^\s*".*', Comment),
823
824 (r'[ \t]+', Text),
825 # TODO: regexes can have other delims
826 (r'/(\\\\|\\/|[^\n/])*/', String.Regex),
827 (r'"(\\\\|\\"|[^\n"])*"', String.Double),
828 (r"'(\\\\|\\'|[^\n'])*'", String.Single),
829
830 # Who decided that doublequote was a good comment character??
831 (r'(?<=\s)"[^\-:.%#=*].*', Comment),
832 (r'-?\d+', Number),
833 (r'#[0-9a-f]{6}', Number.Hex),
834 (r'^:', Punctuation),
835 (r'[()<>+=!|,~-]', Punctuation), # Inexact list. Looks decent.
836 (r'\b(let|if|else|endif|elseif|fun|function|endfunction)\b',
837 Keyword),
838 (r'\b(NONE|bold|italic|underline|dark|light)\b', Name.Builtin),
839 (r'\b\w+\b', Name.Other), # These are postprocessed below
840 (r'.', Text),
841 ],
842 }
843 def __init__(self, **options):
844 from pygments.lexers._vimbuiltins import command, option, auto
845 self._cmd = command
846 self._opt = option
847 self._aut = auto
848
849 RegexLexer.__init__(self, **options)
850
851 def is_in(self, w, mapping):
852 r"""
853 It's kind of difficult to decide if something might be a keyword
854 in VimL because it allows you to abbreviate them. In fact,
855 'ab[breviate]' is a good example. :ab, :abbre, or :abbreviate are
856 valid ways to call it so rather than making really awful regexps
857 like::
858
859 \bab(?:b(?:r(?:e(?:v(?:i(?:a(?:t(?:e)?)?)?)?)?)?)?)?\b
860
861 we match `\b\w+\b` and then call is_in() on those tokens. See
862 `scripts/get_vimkw.py` for how the lists are extracted.
863 """
864 p = bisect(mapping, (w,))
865 if p > 0:
866 if mapping[p-1][0] == w[:len(mapping[p-1][0])] and \
867 mapping[p-1][1][:len(w)] == w: return True
868 if p < len(mapping):
869 return mapping[p][0] == w[:len(mapping[p][0])] and \
870 mapping[p][1][:len(w)] == w
871 return False
872
873 def get_tokens_unprocessed(self, text):
874 # TODO: builtins are only subsequent tokens on lines
875 # and 'keywords' only happen at the beginning except
876 # for :au ones
877 for index, token, value in \
878 RegexLexer.get_tokens_unprocessed(self, text):
879 if token is Name.Other:
880 if self.is_in(value, self._cmd):
881 yield index, Keyword, value
882 elif self.is_in(value, self._opt) or \
883 self.is_in(value, self._aut):
884 yield index, Name.Builtin, value
885 else:
886 yield index, Text, value
887 else:
888 yield index, token, value
889
890
891 class GettextLexer(RegexLexer):
892 """
893 Lexer for Gettext catalog files.
894
895 *New in Pygments 0.9.*
896 """
897 name = 'Gettext Catalog'
898 aliases = ['pot', 'po']
899 filenames = ['*.pot', '*.po']
900 mimetypes = ['application/x-gettext', 'text/x-gettext', 'text/gettext']
901
902 tokens = {
903 'root': [
904 (r'^#,\s.*?$', Keyword.Type),
905 (r'^#:\s.*?$', Keyword.Declaration),
906 #(r'^#$', Comment),
907 (r'^(#|#\.\s|#\|\s|#~\s|#\s).*$', Comment.Single),
908 (r'^(")([A-Za-z-]+:)(.*")$',
909 bygroups(String, Name.Property, String)),
910 (r'^".*"$', String),
911 (r'^(msgid|msgid_plural|msgstr)(\s+)(".*")$',
912 bygroups(Name.Variable, Text, String)),
913 (r'^(msgstr\[)(\d)(\])(\s+)(".*")$',
914 bygroups(Name.Variable, Number.Integer, Name.Variable, Text, String)),
915 ]
916 }
917
918
919 class SquidConfLexer(RegexLexer):
920 """
921 Lexer for `squid <http://www.squid-cache.org/>`_ configuration files.
922
923 *New in Pygments 0.9.*
924 """
925
926 name = 'SquidConf'
927 aliases = ['squidconf', 'squid.conf', 'squid']
928 filenames = ['squid.conf']
929 mimetypes = ['text/x-squidconf']
930 flags = re.IGNORECASE
931
932 keywords = [
933 "access_log", "acl", "always_direct", "announce_host",
934 "announce_period", "announce_port", "announce_to", "anonymize_headers",
935 "append_domain", "as_whois_server", "auth_param_basic",
936 "authenticate_children", "authenticate_program", "authenticate_ttl",
937 "broken_posts", "buffered_logs", "cache_access_log", "cache_announce",
938 "cache_dir", "cache_dns_program", "cache_effective_group",
939 "cache_effective_user", "cache_host", "cache_host_acl",
940 "cache_host_domain", "cache_log", "cache_mem", "cache_mem_high",
941 "cache_mem_low", "cache_mgr", "cachemgr_passwd", "cache_peer",
942 "cache_peer_access", "cahce_replacement_policy", "cache_stoplist",
943 "cache_stoplist_pattern", "cache_store_log", "cache_swap",
944 "cache_swap_high", "cache_swap_log", "cache_swap_low", "client_db",
945 "client_lifetime", "client_netmask", "connect_timeout", "coredump_dir",
946 "dead_peer_timeout", "debug_options", "delay_access", "delay_class",
947 "delay_initial_bucket_level", "delay_parameters", "delay_pools",
948 "deny_info", "dns_children", "dns_defnames", "dns_nameservers",
949 "dns_testnames", "emulate_httpd_log", "err_html_text",
950 "fake_user_agent", "firewall_ip", "forwarded_for", "forward_snmpd_port",
951 "fqdncache_size", "ftpget_options", "ftpget_program", "ftp_list_width",
952 "ftp_passive", "ftp_user", "half_closed_clients", "header_access",
953 "header_replace", "hierarchy_stoplist", "high_response_time_warning",
954 "high_page_fault_warning", "hosts_file", "htcp_port", "http_access",
955 "http_anonymizer", "httpd_accel", "httpd_accel_host",
956 "httpd_accel_port", "httpd_accel_uses_host_header",
957 "httpd_accel_with_proxy", "http_port", "http_reply_access",
958 "icp_access", "icp_hit_stale", "icp_port", "icp_query_timeout",
959 "ident_lookup", "ident_lookup_access", "ident_timeout",
960 "incoming_http_average", "incoming_icp_average", "inside_firewall",
961 "ipcache_high", "ipcache_low", "ipcache_size", "local_domain",
962 "local_ip", "logfile_rotate", "log_fqdn", "log_icp_queries",
963 "log_mime_hdrs", "maximum_object_size", "maximum_single_addr_tries",
964 "mcast_groups", "mcast_icp_query_timeout", "mcast_miss_addr",
965 "mcast_miss_encode_key", "mcast_miss_port", "memory_pools",
966 "memory_pools_limit", "memory_replacement_policy", "mime_table",
967 "min_http_poll_cnt", "min_icp_poll_cnt", "minimum_direct_hops",
968 "minimum_object_size", "minimum_retry_timeout", "miss_access",
969 "negative_dns_ttl", "negative_ttl", "neighbor_timeout",
970 "neighbor_type_domain", "netdb_high", "netdb_low", "netdb_ping_period",
971 "netdb_ping_rate", "never_direct", "no_cache", "passthrough_proxy",
972 "pconn_timeout", "pid_filename", "pinger_program", "positive_dns_ttl",
973 "prefer_direct", "proxy_auth", "proxy_auth_realm", "query_icmp",
974 "quick_abort", "quick_abort", "quick_abort_max", "quick_abort_min",
975 "quick_abort_pct", "range_offset_limit", "read_timeout",
976 "redirect_children", "redirect_program",
977 "redirect_rewrites_host_header", "reference_age", "reference_age",
978 "refresh_pattern", "reload_into_ims", "request_body_max_size",
979 "request_size", "request_timeout", "shutdown_lifetime",
980 "single_parent_bypass", "siteselect_timeout", "snmp_access",
981 "snmp_incoming_address", "snmp_port", "source_ping", "ssl_proxy",
982 "store_avg_object_size", "store_objects_per_bucket",
983 "strip_query_terms", "swap_level1_dirs", "swap_level2_dirs",
984 "tcp_incoming_address", "tcp_outgoing_address", "tcp_recv_bufsize",
985 "test_reachability", "udp_hit_obj", "udp_hit_obj_size",
986 "udp_incoming_address", "udp_outgoing_address", "unique_hostname",
987 "unlinkd_program", "uri_whitespace", "useragent_log",
988 "visible_hostname", "wais_relay", "wais_relay_host", "wais_relay_port",
989 ]
990
991 opts = [
992 "proxy-only", "weight", "ttl", "no-query", "default", "round-robin",
993 "multicast-responder", "on", "off", "all", "deny", "allow", "via",
994 "parent", "no-digest", "heap", "lru", "realm", "children", "q1", "q2",
995 "credentialsttl", "none", "disable", "offline_toggle", "diskd",
996 ]
997
998 actions = [
999 "shutdown", "info", "parameter", "server_list", "client_list",
1000 r'squid\.conf',
1001 ]
1002
1003 actions_stats = [
1004 "objects", "vm_objects", "utilization", "ipcache", "fqdncache", "dns",
1005 "redirector", "io", "reply_headers", "filedescriptors", "netdb",
1006 ]
1007
1008 actions_log = ["status", "enable", "disable", "clear"]
1009
1010 acls = [
1011 "url_regex", "urlpath_regex", "referer_regex", "port", "proto",
1012 "req_mime_type", "rep_mime_type", "method", "browser", "user", "src",
1013 "dst", "time", "dstdomain", "ident", "snmp_community",
1014 ]
1015
1016 ip_re = (
1017 r'(?:(?:(?:[3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}|0x0*[0-9a-f]{1,2}|'
1018 r'0+[1-3]?[0-7]{0,2})(?:\.(?:[3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}|'
1019 r'0x0*[0-9a-f]{1,2}|0+[1-3]?[0-7]{0,2})){3})|(?!.*::.*::)(?:(?!:)|'
1020 r':(?=:))(?:[0-9a-f]{0,4}(?:(?<=::)|(?<!::):)){6}(?:[0-9a-f]{0,4}'
1021 r'(?:(?<=::)|(?<!::):)[0-9a-f]{0,4}(?:(?<=::)|(?<!:)|(?<=:)(?<!::):)|'
1022 r'(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|'
1023 r'[1-9]?\d)){3}))'
1024 )
1025
1026 def makelistre(list):
1027 return r'\b(?:' + '|'.join(list) + r')\b'
1028
1029 tokens = {
1030 'root': [
1031 (r'\s+', Whitespace),
1032 (r'#', Comment, 'comment'),
1033 (makelistre(keywords), Keyword),
1034 (makelistre(opts), Name.Constant),
1035 # Actions
1036 (makelistre(actions), String),
1037 (r'stats/'+makelistre(actions), String),
1038 (r'log/'+makelistre(actions)+r'=', String),
1039 (makelistre(acls), Keyword),
1040 (ip_re + r'(?:/(?:' + ip_re + r'|\b\d+\b))?', Number.Float),
1041 (r'(?:\b\d+\b(?:-\b\d+|%)?)', Number),
1042 (r'\S+', Text),
1043 ],
1044 'comment': [
1045 (r'\s*TAG:.*', String.Escape, '#pop'),
1046 (r'.*', Comment, '#pop'),
1047 ],
1048 }
1049
1050
1051 class DebianControlLexer(RegexLexer):
1052 """
1053 Lexer for Debian ``control`` files and ``apt-cache show <pkg>`` outputs.
1054
1055 *New in Pygments 0.9.*
1056 """
1057 name = 'Debian Control file'
1058 aliases = ['control']
1059 filenames = ['control']
1060
1061 tokens = {
1062 'root': [
1063 (r'^(Description)', Keyword, 'description'),
1064 (r'^(Maintainer)(:\s*)', bygroups(Keyword, Text), 'maintainer'),
1065 (r'^((Build-)?Depends)', Keyword, 'depends'),
1066 (r'^((?:Python-)?Version)(:\s*)(\S+)$',
1067 bygroups(Keyword, Text, Number)),
1068 (r'^((?:Installed-)?Size)(:\s*)(\S+)$',
1069 bygroups(Keyword, Text, Number)),
1070 (r'^(MD5Sum|SHA1|SHA256)(:\s*)(\S+)$',
1071 bygroups(Keyword, Text, Number)),
1072 (r'^([a-zA-Z\-0-9\.]*?)(:\s*)(.*?)$',
1073 bygroups(Keyword, Whitespace, String)),
1074 ],
1075 'maintainer': [
1076 (r'<[^>]+>', Generic.Strong),
1077 (r'<[^>]+>$', Generic.Strong, '#pop'),
1078 (r',\n?', Text),
1079 (r'.', Text),
1080 ],
1081 'description': [
1082 (r'(.*)(Homepage)(: )(\S+)',
1083 bygroups(Text, String, Name, Name.Class)),
1084 (r':.*\n', Generic.Strong),
1085 (r' .*\n', Text),
1086 ('', Text, '#pop'),
1087 ],
1088 'depends': [
1089 (r':\s*', Text),
1090 (r'(\$)(\{)(\w+\s*:\s*\w+)', bygroups(Operator, Text, Name.Entity)),
1091 (r'\(', Text, 'depend_vers'),
1092 (r',', Text),
1093 (r'\|', Operator),
1094 (r'[\s]+', Text),
1095 (r'[}\)]\s*$', Text, '#pop'),
1096 (r'}', Text),
1097 (r'[^,]$', Name.Function, '#pop'),
1098 (r'([\+\.a-zA-Z0-9-])(\s*)', bygroups(Name.Function, Text)),
1099 (r'\[.*?\]', Name.Entity),
1100 ],
1101 'depend_vers': [
1102 (r'\),', Text, '#pop'),
1103 (r'\)[^,]', Text, '#pop:2'),
1104 (r'([><=]+)(\s*)([^\)]+)', bygroups(Operator, Text, Number))
1105 ]
1106 }
1107
1108
1109 class YamlLexerContext(LexerContext):
1110 """Indentation context for the YAML lexer."""
1111
1112 def __init__(self, *args, **kwds):
1113 super(YamlLexerContext, self).__init__(*args, **kwds)
1114 self.indent_stack = []
1115 self.indent = -1
1116 self.next_indent = 0
1117 self.block_scalar_indent = None
1118
1119
1120 class YamlLexer(ExtendedRegexLexer):
1121 """
1122 Lexer for `YAML <http://yaml.org/>`_, a human-friendly data serialization
1123 language.
1124
1125 *New in Pygments 0.11.*
1126 """
1127
1128 name = 'YAML'
1129 aliases = ['yaml']
1130 filenames = ['*.yaml', '*.yml']
1131 mimetypes = ['text/x-yaml']
1132
1133
1134 def something(token_class):
1135 """Do not produce empty tokens."""
1136 def callback(lexer, match, context):
1137 text = match.group()
1138 if not text:
1139 return
1140 yield match.start(), token_class, text
1141 context.pos = match.end()
1142 return callback
1143
1144 def reset_indent(token_class):
1145 """Reset the indentation levels."""
1146 def callback(lexer, match, context):
1147 text = match.group()
1148 context.indent_stack = []
1149 context.indent = -1
1150 context.next_indent = 0
1151 context.block_scalar_indent = None
1152 yield match.start(), token_class, text
1153 context.pos = match.end()
1154 return callback
1155
1156 def save_indent(token_class, start=False):
1157 """Save a possible indentation level."""
1158 def callback(lexer, match, context):
1159 text = match.group()
1160 extra = ''
1161 if start:
1162 context.next_indent = len(text)
1163 if context.next_indent < context.indent:
1164 while context.next_indent < context.indent:
1165 context.indent = context.indent_stack.pop()
1166 if context.next_indent > context.indent:
1167 extra = text[context.indent:]
1168 text = text[:context.indent]
1169 else:
1170 context.next_indent += len(text)
1171 if text:
1172 yield match.start(), token_class, text
1173 if extra:
1174 yield match.start()+len(text), token_class.Error, extra
1175 context.pos = match.end()
1176 return callback
1177
1178 def set_indent(token_class, implicit=False):
1179 """Set the previously saved indentation level."""
1180 def callback(lexer, match, context):
1181 text = match.group()
1182 if context.indent < context.next_indent:
1183 context.indent_stack.append(context.indent)
1184 context.indent = context.next_indent
1185 if not implicit:
1186 context.next_indent += len(text)
1187 yield match.start(), token_class, text
1188 context.pos = match.end()
1189 return callback
1190
1191 def set_block_scalar_indent(token_class):
1192 """Set an explicit indentation level for a block scalar."""
1193 def callback(lexer, match, context):
1194 text = match.group()
1195 context.block_scalar_indent = None
1196 if not text:
1197 return
1198 increment = match.group(1)
1199 if increment:
1200 current_indent = max(context.indent, 0)
1201 increment = int(increment)
1202 context.block_scalar_indent = current_indent + increment
1203 if text:
1204 yield match.start(), token_class, text
1205 context.pos = match.end()
1206 return callback
1207
1208 def parse_block_scalar_empty_line(indent_token_class, content_token_class):
1209 """Process an empty line in a block scalar."""
1210 def callback(lexer, match, context):
1211 text = match.group()
1212 if (context.block_scalar_indent is None or
1213 len(text) <= context.block_scalar_indent):
1214 if text:
1215 yield match.start(), indent_token_class, text
1216 else:
1217 indentation = text[:context.block_scalar_indent]
1218 content = text[context.block_scalar_indent:]
1219 yield match.start(), indent_token_class, indentation
1220 yield (match.start()+context.block_scalar_indent,
1221 content_token_class, content)
1222 context.pos = match.end()
1223 return callback
1224
1225 def parse_block_scalar_indent(token_class):
1226 """Process indentation spaces in a block scalar."""
1227 def callback(lexer, match, context):
1228 text = match.group()
1229 if context.block_scalar_indent is None:
1230 if len(text) <= max(context.indent, 0):
1231 context.stack.pop()
1232 context.stack.pop()
1233 return
1234 context.block_scalar_indent = len(text)
1235 else:
1236 if len(text) < context.block_scalar_indent:
1237 context.stack.pop()
1238 context.stack.pop()
1239 return
1240 if text:
1241 yield match.start(), token_class, text
1242 context.pos = match.end()
1243 return callback
1244
1245 def parse_plain_scalar_indent(token_class):
1246 """Process indentation spaces in a plain scalar."""
1247 def callback(lexer, match, context):
1248 text = match.group()
1249 if len(text) <= context.indent:
1250 context.stack.pop()
1251 context.stack.pop()
1252 return
1253 if text:
1254 yield match.start(), token_class, text
1255 context.pos = match.end()
1256 return callback
1257
1258
1259
1260 tokens = {
1261 # the root rules
1262 'root': [
1263 # ignored whitespaces
1264 (r'[ ]+(?=#|$)', Text),
1265 # line breaks
1266 (r'\n+', Text),
1267 # a comment
1268 (r'#[^\n]*', Comment.Single),
1269 # the '%YAML' directive
1270 (r'^%YAML(?=[ ]|$)', reset_indent(Name.Tag), 'yaml-directive'),
1271 # the %TAG directive
1272 (r'^%TAG(?=[ ]|$)', reset_indent(Name.Tag), 'tag-directive'),
1273 # document start and document end indicators
1274 (r'^(?:---|\.\.\.)(?=[ ]|$)', reset_indent(Name.Namespace),
1275 'block-line'),
1276 # indentation spaces
1277 (r'[ ]*(?![ \t\n\r\f\v]|$)', save_indent(Text, start=True),
1278 ('block-line', 'indentation')),
1279 ],
1280
1281 # trailing whitespaces after directives or a block scalar indicator
1282 'ignored-line': [
1283 # ignored whitespaces
1284 (r'[ ]+(?=#|$)', Text),
1285 # a comment
1286 (r'#[^\n]*', Comment.Single),
1287 # line break
1288 (r'\n', Text, '#pop:2'),
1289 ],
1290
1291 # the %YAML directive
1292 'yaml-directive': [
1293 # the version number
1294 (r'([ ]+)([0-9]+\.[0-9]+)',
1295 bygroups(Text, Number), 'ignored-line'),
1296 ],
1297
1298 # the %YAG directive
1299 'tag-directive': [
1300 # a tag handle and the corresponding prefix
1301 (r'([ ]+)(!|![0-9A-Za-z_-]*!)'
1302 r'([ ]+)(!|!?[0-9A-Za-z;/?:@&=+$,_.!~*\'()\[\]%-]+)',
1303 bygroups(Text, Keyword.Type, Text, Keyword.Type),
1304 'ignored-line'),
1305 ],
1306
1307 # block scalar indicators and indentation spaces
1308 'indentation': [
1309 # trailing whitespaces are ignored
1310 (r'[ ]*$', something(Text), '#pop:2'),
1311 # whitespaces preceeding block collection indicators
1312 (r'[ ]+(?=[?:-](?:[ ]|$))', save_indent(Text)),
1313 # block collection indicators
1314 (r'[?:-](?=[ ]|$)', set_indent(Punctuation.Indicator)),
1315 # the beginning a block line
1316 (r'[ ]*', save_indent(Text), '#pop'),
1317 ],
1318
1319 # an indented line in the block context
1320 'block-line': [
1321 # the line end
1322 (r'[ ]*(?=#|$)', something(Text), '#pop'),
1323 # whitespaces separating tokens
1324 (r'[ ]+', Text),
1325 # tags, anchors and aliases,
1326 include('descriptors'),
1327 # block collections and scalars
1328 include('block-nodes'),
1329 # flow collections and quoted scalars
1330 include('flow-nodes'),
1331 # a plain scalar
1332 (r'(?=[^ \t\n\r\f\v?:,\[\]{}#&*!|>\'"%@`-]|[?:-][^ \t\n\r\f\v])',
1333 something(Name.Variable),
1334 'plain-scalar-in-block-context'),
1335 ],
1336
1337 # tags, anchors, aliases
1338 'descriptors' : [
1339 # a full-form tag
1340 (r'!<[0-9A-Za-z;/?:@&=+$,_.!~*\'()\[\]%-]+>', Keyword.Type),
1341 # a tag in the form '!', '!suffix' or '!handle!suffix'
1342 (r'!(?:[0-9A-Za-z_-]+)?'
1343 r'(?:![0-9A-Za-z;/?:@&=+$,_.!~*\'()\[\]%-]+)?', Keyword.Type),
1344 # an anchor
1345 (r'&[0-9A-Za-z_-]+', Name.Label),
1346 # an alias
1347 (r'\*[0-9A-Za-z_-]+', Name.Variable),
1348 ],
1349
1350 # block collections and scalars
1351 'block-nodes': [
1352 # implicit key
1353 (r':(?=[ ]|$)', set_indent(Punctuation.Indicator, implicit=True)),
1354 # literal and folded scalars
1355 (r'[|>]', Punctuation.Indicator,
1356 ('block-scalar-content', 'block-scalar-header')),
1357 ],
1358
1359 # flow collections and quoted scalars
1360 'flow-nodes': [
1361 # a flow sequence
1362 (r'\[', Punctuation.Indicator, 'flow-sequence'),
1363 # a flow mapping
1364 (r'\{', Punctuation.Indicator, 'flow-mapping'),
1365 # a single-quoted scalar
1366 (r'\'', String, 'single-quoted-scalar'),
1367 # a double-quoted scalar
1368 (r'\"', String, 'double-quoted-scalar'),
1369 ],
1370
1371 # the content of a flow collection
1372 'flow-collection': [
1373 # whitespaces
1374 (r'[ ]+', Text),
1375 # line breaks
1376 (r'\n+', Text),
1377 # a comment
1378 (r'#[^\n]*', Comment.Single),
1379 # simple indicators
1380 (r'[?:,]', Punctuation.Indicator),
1381 # tags, anchors and aliases
1382 include('descriptors'),
1383 # nested collections and quoted scalars
1384 include('flow-nodes'),
1385 # a plain scalar
1386 (r'(?=[^ \t\n\r\f\v?:,\[\]{}#&*!|>\'"%@`])',
1387 something(Name.Variable),
1388 'plain-scalar-in-flow-context'),
1389 ],
1390
1391 # a flow sequence indicated by '[' and ']'
1392 'flow-sequence': [
1393 # include flow collection rules
1394 include('flow-collection'),
1395 # the closing indicator
1396 (r'\]', Punctuation.Indicator, '#pop'),
1397 ],
1398
1399 # a flow mapping indicated by '{' and '}'
1400 'flow-mapping': [
1401 # include flow collection rules
1402 include('flow-collection'),
1403 # the closing indicator
1404 (r'\}', Punctuation.Indicator, '#pop'),
1405 ],
1406
1407 # block scalar lines
1408 'block-scalar-content': [
1409 # line break
1410 (r'\n', Text),
1411 # empty line
1412 (r'^[ ]+$',
1413 parse_block_scalar_empty_line(Text, Name.Constant)),
1414 # indentation spaces (we may leave the state here)
1415 (r'^[ ]*', parse_block_scalar_indent(Text)),
1416 # line content
1417 (r'[^\n\r\f\v]+', Name.Constant),
1418 ],
1419
1420 # the content of a literal or folded scalar
1421 'block-scalar-header': [
1422 # indentation indicator followed by chomping flag
1423 (r'([1-9])?[+-]?(?=[ ]|$)',
1424 set_block_scalar_indent(Punctuation.Indicator),
1425 'ignored-line'),
1426 # chomping flag followed by indentation indicator
1427 (r'[+-]?([1-9])?(?=[ ]|$)',
1428 set_block_scalar_indent(Punctuation.Indicator),
1429 'ignored-line'),
1430 ],
1431
1432 # ignored and regular whitespaces in quoted scalars
1433 'quoted-scalar-whitespaces': [
1434 # leading and trailing whitespaces are ignored
1435 (r'^[ ]+', Text),
1436 (r'[ ]+$', Text),
1437 # line breaks are ignored
1438 (r'\n+', Text),
1439 # other whitespaces are a part of the value
1440 (r'[ ]+', Name.Variable),
1441 ],
1442
1443 # single-quoted scalars
1444 'single-quoted-scalar': [
1445 # include whitespace and line break rules
1446 include('quoted-scalar-whitespaces'),
1447 # escaping of the quote character
1448 (r'\'\'', String.Escape),
1449 # regular non-whitespace characters
1450 (r'[^ \t\n\r\f\v\']+', String),
1451 # the closing quote
1452 (r'\'', String, '#pop'),
1453 ],
1454
1455 # double-quoted scalars
1456 'double-quoted-scalar': [
1457 # include whitespace and line break rules
1458 include('quoted-scalar-whitespaces'),
1459 # escaping of special characters
1460 (r'\\[0abt\tn\nvfre "\\N_LP]', String),
1461 # escape codes
1462 (r'\\(?:x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})',
1463 String.Escape),
1464 # regular non-whitespace characters
1465 (r'[^ \t\n\r\f\v\"\\]+', String),
1466 # the closing quote
1467 (r'"', String, '#pop'),
1468 ],
1469
1470 # the beginning of a new line while scanning a plain scalar
1471 'plain-scalar-in-block-context-new-line': [
1472 # empty lines
1473 (r'^[ ]+$', Text),
1474 # line breaks
1475 (r'\n+', Text),
1476 # document start and document end indicators
1477 (r'^(?=---|\.\.\.)', something(Name.Namespace), '#pop:3'),
1478 # indentation spaces (we may leave the block line state here)
1479 (r'^[ ]*', parse_plain_scalar_indent(Text), '#pop'),
1480 ],
1481
1482 # a plain scalar in the block context
1483 'plain-scalar-in-block-context': [
1484 # the scalar ends with the ':' indicator
1485 (r'[ ]*(?=:[ ]|:$)', something(Text), '#pop'),
1486 # the scalar ends with whitespaces followed by a comment
1487 (r'[ ]+(?=#)', Text, '#pop'),
1488 # trailing whitespaces are ignored
1489 (r'[ ]+$', Text),
1490 # line breaks are ignored
1491 (r'\n+', Text, 'plain-scalar-in-block-context-new-line'),
1492 # other whitespaces are a part of the value
1493 (r'[ ]+', Literal.Scalar.Plain),
1494 # regular non-whitespace characters
1495 (r'(?::(?![ \t\n\r\f\v])|[^ \t\n\r\f\v:])+', Literal.Scalar.Plain),
1496 ],
1497
1498 # a plain scalar is the flow context
1499 'plain-scalar-in-flow-context': [
1500 # the scalar ends with an indicator character
1501 (r'[ ]*(?=[,:?\[\]{}])', something(Text), '#pop'),
1502 # the scalar ends with a comment
1503 (r'[ ]+(?=#)', Text, '#pop'),
1504 # leading and trailing whitespaces are ignored
1505 (r'^[ ]+', Text),
1506 (r'[ ]+$', Text),
1507 # line breaks are ignored
1508 (r'\n+', Text),
1509 # other whitespaces are a part of the value
1510 (r'[ ]+', Name.Variable),
1511 # regular non-whitespace characters
1512 (r'[^ \t\n\r\f\v,:?\[\]{}]+', Name.Variable),
1513 ],
1514
1515 }
1516
1517 def get_tokens_unprocessed(self, text=None, context=None):
1518 if context is None:
1519 context = YamlLexerContext(text, 0)
1520 return super(YamlLexer, self).get_tokens_unprocessed(text, context)
1521
1522
1523 class LighttpdConfLexer(RegexLexer):
1524 """
1525 Lexer for `Lighttpd <http://lighttpd.net/>`_ configuration files.
1526
1527 *New in Pygments 0.11.*
1528 """
1529 name = 'Lighttpd configuration file'
1530 aliases = ['lighty', 'lighttpd']
1531 filenames = []
1532 mimetypes = ['text/x-lighttpd-conf']
1533
1534 tokens = {
1535 'root': [
1536 (r'#.*\n', Comment.Single),
1537 (r'/\S*', Name), # pathname
1538 (r'[a-zA-Z._-]+', Keyword),
1539 (r'\d+\.\d+\.\d+\.\d+(?:/\d+)?', Number),
1540 (r'[0-9]+', Number),
1541 (r'=>|=~|\+=|==|=|\+', Operator),
1542 (r'\$[A-Z]+', Name.Builtin),
1543 (r'[(){}\[\],]', Punctuation),
1544 (r'"([^"\\]*(?:\\.[^"\\]*)*)"', String.Double),
1545 (r'\s+', Text),
1546 ],
1547
1548 }
1549
1550
1551 class NginxConfLexer(RegexLexer):
1552 """
1553 Lexer for `Nginx <http://nginx.net/>`_ configuration files.
1554
1555 *New in Pygments 0.11.*
1556 """
1557 name = 'Nginx configuration file'
1558 aliases = ['nginx']
1559 filenames = []
1560 mimetypes = ['text/x-nginx-conf']
1561
1562 tokens = {
1563 'root': [
1564 (r'(include)(\s+)([^\s;]+)', bygroups(Keyword, Text, Name)),
1565 (r'[^\s;#]+', Keyword, 'stmt'),
1566 include('base'),
1567 ],
1568 'block': [
1569 (r'}', Punctuation, '#pop:2'),
1570 (r'[^\s;#]+', Keyword.Namespace, 'stmt'),
1571 include('base'),
1572 ],
1573 'stmt': [
1574 (r'{', Punctuation, 'block'),
1575 (r';', Punctuation, '#pop'),
1576 include('base'),
1577 ],
1578 'base': [
1579 (r'#.*\n', Comment.Single),
1580 (r'on|off', Name.Constant),
1581 (r'\$[^\s;#()]+', Name.Variable),
1582 (r'([a-z0-9.-]+)(:)([0-9]+)',
1583 bygroups(Name, Punctuation, Number.Integer)),
1584 (r'[a-z-]+/[a-z-+]+', String), # mimetype
1585 #(r'[a-zA-Z._-]+', Keyword),
1586 (r'[0-9]+[km]?\b', Number.Integer),
1587 (r'(~)(\s*)([^\s{]+)', bygroups(Punctuation, Text, String.Regex)),
1588 (r'[:=~]', Punctuation),
1589 (r'[^\s;#{}$]+', String), # catch all
1590 (r'/[^\s;#]*', Name), # pathname
1591 (r'\s+', Text),
1592 (r'[$;]', Text), # leftover characters
1593 ],
1594 }
1595
1596
1597 class CMakeLexer(RegexLexer):
1598 """
1599 Lexer for `CMake <http://cmake.org/Wiki/CMake>`_ files.
1600
1601 *New in Pygments 1.2.*
1602 """
1603 name = 'CMake'
1604 aliases = ['cmake']
1605 filenames = ['*.cmake', 'CMakeLists.txt']
1606 mimetypes = ['text/x-cmake']
1607
1608 tokens = {
1609 'root': [
1610 #(r'(ADD_CUSTOM_COMMAND|ADD_CUSTOM_TARGET|ADD_DEFINITIONS|'
1611 # r'ADD_DEPENDENCIES|ADD_EXECUTABLE|ADD_LIBRARY|ADD_SUBDIRECTORY|'
1612 # r'ADD_TEST|AUX_SOURCE_DIRECTORY|BUILD_COMMAND|BUILD_NAME|'
1613 # r'CMAKE_MINIMUM_REQUIRED|CONFIGURE_FILE|CREATE_TEST_SOURCELIST|'
1614 # r'ELSE|ELSEIF|ENABLE_LANGUAGE|ENABLE_TESTING|ENDFOREACH|'
1615 # r'ENDFUNCTION|ENDIF|ENDMACRO|ENDWHILE|EXEC_PROGRAM|'
1616 # r'EXECUTE_PROCESS|EXPORT_LIBRARY_DEPENDENCIES|FILE|FIND_FILE|'
1617 # r'FIND_LIBRARY|FIND_PACKAGE|FIND_PATH|FIND_PROGRAM|FLTK_WRAP_UI|'
1618 # r'FOREACH|FUNCTION|GET_CMAKE_PROPERTY|GET_DIRECTORY_PROPERTY|'
1619 # r'GET_FILENAME_COMPONENT|GET_SOURCE_FILE_PROPERTY|'
1620 # r'GET_TARGET_PROPERTY|GET_TEST_PROPERTY|IF|INCLUDE|'
1621 # r'INCLUDE_DIRECTORIES|INCLUDE_EXTERNAL_MSPROJECT|'
1622 # r'INCLUDE_REGULAR_EXPRESSION|INSTALL|INSTALL_FILES|'
1623 # r'INSTALL_PROGRAMS|INSTALL_TARGETS|LINK_DIRECTORIES|'
1624 # r'LINK_LIBRARIES|LIST|LOAD_CACHE|LOAD_COMMAND|MACRO|'
1625 # r'MAKE_DIRECTORY|MARK_AS_ADVANCED|MATH|MESSAGE|OPTION|'
1626 # r'OUTPUT_REQUIRED_FILES|PROJECT|QT_WRAP_CPP|QT_WRAP_UI|REMOVE|'
1627 # r'REMOVE_DEFINITIONS|SEPARATE_ARGUMENTS|SET|'
1628 # r'SET_DIRECTORY_PROPERTIES|SET_SOURCE_FILES_PROPERTIES|'
1629 # r'SET_TARGET_PROPERTIES|SET_TESTS_PROPERTIES|SITE_NAME|'
1630 # r'SOURCE_GROUP|STRING|SUBDIR_DEPENDS|SUBDIRS|'
1631 # r'TARGET_LINK_LIBRARIES|TRY_COMPILE|TRY_RUN|UNSET|'
1632 # r'USE_MANGLED_MESA|UTILITY_SOURCE|VARIABLE_REQUIRES|'
1633 # r'VTK_MAKE_INSTANTIATOR|VTK_WRAP_JAVA|VTK_WRAP_PYTHON|'
1634 # r'VTK_WRAP_TCL|WHILE|WRITE_FILE|'
1635 # r'COUNTARGS)\b', Name.Builtin, 'args'),
1636 (r'\b([A-Za-z_]+)([ \t]*)(\()', bygroups(Name.Builtin, Text,
1637 Punctuation), 'args'),
1638 include('keywords'),
1639 include('ws')
1640 ],
1641 'args': [
1642 (r'\(', Punctuation, '#push'),
1643 (r'\)', Punctuation, '#pop'),
1644 (r'(\${)(.+?)(})', bygroups(Operator, Name.Variable, Operator)),
1645 (r'(?s)".*?"', String.Double),
1646 (r'\\\S+', String),
1647 (r'[^\)$"# \t\n]+', String),
1648 (r'\n', Text), # explicitly legal
1649 include('keywords'),
1650 include('ws')
1651 ],
1652 'string': [
1653
1654 ],
1655 'keywords': [
1656 (r'\b(WIN32|UNIX|APPLE|CYGWIN|BORLAND|MINGW|MSVC|MSVC_IDE|MSVC60|'
1657 r'MSVC70|MSVC71|MSVC80|MSVC90)\b', Keyword),
1658 ],
1659 'ws': [
1660 (r'[ \t]+', Text),
1661 (r'#.+\n', Comment),
1662 ]
1663 }
1664
1665
1666 class HttpLexer(RegexLexer):
1667 """
1668 Lexer for HTTP sessions.
1669
1670 *New in Pygments 1.5.*
1671 """
1672
1673 name = 'HTTP'
1674 aliases = ['http']
1675
1676 flags = re.DOTALL
1677
1678 def header_callback(self, match):
1679 if match.group(1).lower() == 'content-type':
1680 content_type = match.group(5).strip()
1681 if ';' in content_type:
1682 content_type = content_type[:content_type.find(';')].strip()
1683 self.content_type = content_type
1684 yield match.start(1), Name.Attribute, match.group(1)
1685 yield match.start(2), Text, match.group(2)
1686 yield match.start(3), Operator, match.group(3)
1687 yield match.start(4), Text, match.group(4)
1688 yield match.start(5), Literal, match.group(5)
1689 yield match.start(6), Text, match.group(6)
1690
1691 def continuous_header_callback(self, match):
1692 yield match.start(1), Text, match.group(1)
1693 yield match.start(2), Literal, match.group(2)
1694 yield match.start(3), Text, match.group(3)
1695
1696 def content_callback(self, match):
1697 content_type = getattr(self, 'content_type', None)
1698 content = match.group()
1699 offset = match.start()
1700 if content_type:
1701 from pygments.lexers import get_lexer_for_mimetype
1702 try:
1703 lexer = get_lexer_for_mimetype(content_type)
1704 except ClassNotFound:
1705 pass
1706 else:
1707 for idx, token, value in lexer.get_tokens_unprocessed(content):
1708 yield offset + idx, token, value
1709 return
1710 yield offset, Text, content
1711
1712 tokens = {
1713 'root': [
1714 (r'(GET|POST|PUT|DELETE|HEAD|OPTIONS|TRACE)( +)([^ ]+)( +)'
1715 r'(HTTPS?)(/)(1\.[01])(\r?\n|$)',
1716 bygroups(Name.Function, Text, Name.Namespace, Text,
1717 Keyword.Reserved, Operator, Number, Text),
1718 'headers'),
1719 (r'(HTTPS?)(/)(1\.[01])( +)(\d{3})( +)([^\r\n]+)(\r?\n|$)',
1720 bygroups(Keyword.Reserved, Operator, Number, Text, Number,
1721 Text, Name.Exception, Text),
1722 'headers'),
1723 ],
1724 'headers': [
1725 (r'([^\s:]+)( *)(:)( *)([^\r\n]+)(\r?\n|$)', header_callback),
1726 (r'([\t ]+)([^\r\n]+)(\r?\n|$)', continuous_header_callback),
1727 (r'\r?\n', Text, 'content')
1728 ],
1729 'content': [
1730 (r'.+', content_callback)
1731 ]
1732 }
1733
1734
1735 class PyPyLogLexer(RegexLexer):
1736 """
1737 Lexer for PyPy log files.
1738
1739 *New in Pygments 1.5.*
1740 """
1741 name = "PyPy Log"
1742 aliases = ["pypylog", "pypy"]
1743 filenames = ["*.pypylog"]
1744 mimetypes = ['application/x-pypylog']
1745
1746 tokens = {
1747 "root": [
1748 (r"\[\w+\] {jit-log-.*?$", Keyword, "jit-log"),
1749 (r"\[\w+\] {jit-backend-counts$", Keyword, "jit-backend-counts"),
1750 include("extra-stuff"),
1751 ],
1752 "jit-log": [
1753 (r"\[\w+\] jit-log-.*?}$", Keyword, "#pop"),
1754 (r"^\+\d+: ", Comment),
1755 (r"--end of the loop--", Comment),
1756 (r"[ifp]\d+", Name),
1757 (r"ptr\d+", Name),
1758 (r"(\()(\w+(?:\.\w+)?)(\))",
1759 bygroups(Punctuation, Name.Builtin, Punctuation)),
1760 (r"[\[\]=,()]", Punctuation),
1761 (r"(\d+\.\d+|inf|-inf)", Number.Float),
1762 (r"-?\d+", Number.Integer),
1763 (r"'.*'", String),
1764 (r"(None|descr|ConstClass|ConstPtr|TargetToken)", Name),
1765 (r"<.*?>+", Name.Builtin),
1766 (r"(label|debug_merge_point|jump|finish)", Name.Class),
1767 (r"(int_add_ovf|int_add|int_sub_ovf|int_sub|int_mul_ovf|int_mul|"
1768 r"int_floordiv|int_mod|int_lshift|int_rshift|int_and|int_or|"
1769 r"int_xor|int_eq|int_ne|int_ge|int_gt|int_le|int_lt|int_is_zero|"
1770 r"int_is_true|"
1771 r"uint_floordiv|uint_ge|uint_lt|"
1772 r"float_add|float_sub|float_mul|float_truediv|float_neg|"
1773 r"float_eq|float_ne|float_ge|float_gt|float_le|float_lt|float_abs|"
1774 r"ptr_eq|ptr_ne|instance_ptr_eq|instance_ptr_ne|"
1775 r"cast_int_to_float|cast_float_to_int|"
1776 r"force_token|quasiimmut_field|same_as|virtual_ref_finish|"
1777 r"virtual_ref|mark_opaque_ptr|"
1778 r"call_may_force|call_assembler|call_loopinvariant|"
1779 r"call_release_gil|call_pure|call|"
1780 r"new_with_vtable|new_array|newstr|newunicode|new|"
1781 r"arraylen_gc|"
1782 r"getarrayitem_gc_pure|getarrayitem_gc|setarrayitem_gc|"
1783 r"getarrayitem_raw|setarrayitem_raw|getfield_gc_pure|"
1784 r"getfield_gc|getinteriorfield_gc|setinteriorfield_gc|"
1785 r"getfield_raw|setfield_gc|setfield_raw|"
1786 r"strgetitem|strsetitem|strlen|copystrcontent|"
1787 r"unicodegetitem|unicodesetitem|unicodelen|"
1788 r"guard_true|guard_false|guard_value|guard_isnull|"
1789 r"guard_nonnull_class|guard_nonnull|guard_class|guard_no_overflow|"
1790 r"guard_not_forced|guard_no_exception|guard_not_invalidated)",
1791 Name.Builtin),
1792 include("extra-stuff"),
1793 ],
1794 "jit-backend-counts": [
1795 (r"\[\w+\] jit-backend-counts}$", Keyword, "#pop"),
1796 (r":", Punctuation),
1797 (r"\d+", Number),
1798 include("extra-stuff"),
1799 ],
1800 "extra-stuff": [
1801 (r"\s+", Text),
1802 (r"#.*?$", Comment),
1803 ],
1804 }
1805
1806
1807 class HxmlLexer(RegexLexer):
1808 """
1809 Lexer for `haXe build <http://haxe.org/doc/compiler>`_ files.
1810
1811 *New in Pygments 1.6.*
1812 """
1813 name = 'Hxml'
1814 aliases = ['haxeml', 'hxml']
1815 filenames = ['*.hxml']
1816
1817 tokens = {
1818 'root': [
1819 # Seperator
1820 (r'(--)(next)', bygroups(Punctuation, Generic.Heading)),
1821 # Compiler switches with one dash
1822 (r'(-)(prompt|debug|v)', bygroups(Punctuation, Keyword.Keyword)),
1823 # Compilerswitches with two dashes
1824 (r'(--)(neko-source|flash-strict|flash-use-stage|no-opt|no-traces|'
1825 r'no-inline|times|no-output)', bygroups(Punctuation, Keyword)),
1826 # Targets and other options that take an argument
1827 (r'(-)(cpp|js|neko|x|as3|swf9?|swf-lib|php|xml|main|lib|D|resource|'
1828 r'cp|cmd)( +)(.+)',
1829 bygroups(Punctuation, Keyword, Whitespace, String)),
1830 # Options that take only numerical arguments
1831 (r'(-)(swf-version)( +)(\d+)',
1832 bygroups(Punctuation, Keyword, Number.Integer)),
1833 # An Option that defines the size, the fps and the background
1834 # color of an flash movie
1835 (r'(-)(swf-header)( +)(\d+)(:)(\d+)(:)(\d+)(:)([A-Fa-f0-9]{6})',
1836 bygroups(Punctuation, Keyword, Whitespace, Number.Integer,
1837 Punctuation, Number.Integer, Punctuation, Number.Integer,
1838 Punctuation, Number.Hex)),
1839 # options with two dashes that takes arguments
1840 (r'(--)(js-namespace|php-front|php-lib|remap|gen-hx-classes)( +)'
1841 r'(.+)', bygroups(Punctuation, Keyword, Whitespace, String)),
1842 # Single line comment, multiline ones are not allowed.
1843 (r'#.*', Comment.Single)
1844 ]
1845 }

eric ide

mercurial