/syntaxhighlight/pygments/lexers/templates.py
Python | 1583 lines | 1206 code | 162 blank | 215 comment | 58 complexity | 5c679c887905ece216cec7825aa53d90 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
1# -*- coding: utf-8 -*- 2""" 3 plushcms.syntaxhighlight.pygments.lexers.templates 4 ~~~~~~~~~~~~~~~~~~~~~~~~~ 5 6 Lexers for various template engines' markup. 7 8 :copyright: Copyright 2006-2010 by the Pygments team, see AUTHORS. 9 :license: BSD, see LICENSE for details. 10""" 11 12import re 13 14from plushcms.syntaxhighlight.pygments.lexers.web import \ 15 PhpLexer, HtmlLexer, XmlLexer, JavascriptLexer, CssLexer 16from plushcms.syntaxhighlight.pygments.lexers.agile import PythonLexer, PerlLexer 17from plushcms.syntaxhighlight.pygments.lexers.compiled import JavaLexer 18from plushcms.syntaxhighlight.pygments.lexer import Lexer, DelegatingLexer, RegexLexer, bygroups, \ 19 include, using, this 20from plushcms.syntaxhighlight.pygments.token import Error, Punctuation, \ 21 Text, Comment, Operator, Keyword, Name, String, Number, Other, Token 22from plushcms.syntaxhighlight.pygments.util import html_doctype_matches, looks_like_xml 23 24__all__ = ['HtmlPhpLexer', 'XmlPhpLexer', 'CssPhpLexer', 25 'JavascriptPhpLexer', 'ErbLexer', 'RhtmlLexer', 26 'XmlErbLexer', 'CssErbLexer', 'JavascriptErbLexer', 27 'SmartyLexer', 'HtmlSmartyLexer', 'XmlSmartyLexer', 28 'CssSmartyLexer', 'JavascriptSmartyLexer', 'DjangoLexer', 29 'HtmlDjangoLexer', 'CssDjangoLexer', 'XmlDjangoLexer', 30 'JavascriptDjangoLexer', 'GenshiLexer', 'HtmlGenshiLexer', 31 'GenshiTextLexer', 'CssGenshiLexer', 'JavascriptGenshiLexer', 32 'MyghtyLexer', 'MyghtyHtmlLexer', 'MyghtyXmlLexer', 33 'MyghtyCssLexer', 'MyghtyJavascriptLexer', 'MasonLexer', 'MakoLexer', 34 'MakoHtmlLexer', 'MakoXmlLexer', 'MakoJavascriptLexer', 35 'MakoCssLexer', 'JspLexer', 'CheetahLexer', 'CheetahHtmlLexer', 36 'CheetahXmlLexer', 'CheetahJavascriptLexer', 37 'EvoqueLexer', 'EvoqueHtmlLexer', 'EvoqueXmlLexer', 38 'ColdfusionLexer', 'ColdfusionHtmlLexer', 39 'VelocityLexer', 'VelocityHtmlLexer', 'VelocityXmlLexer', 40 'SspLexer'] 41 42 43class ErbLexer(Lexer): 44 """ 45 Generic `ERB <http://ruby-doc.org/core/classes/ERB.html>`_ (Ruby Templating) 46 lexer. 47 48 Just highlights ruby code between the preprocessor directives, other data 49 is left untouched by the lexer. 50 51 All options are also forwarded to the `RubyLexer`. 52 """ 53 54 name = 'ERB' 55 aliases = ['erb'] 56 mimetypes = ['application/x-ruby-templating'] 57 58 _block_re = re.compile(r'(<%%|%%>|<%=|<%#|<%-|<%|-%>|%>|^%[^%].*?$)', re.M) 59 60 def __init__(self, **options): 61 from plushcms.syntaxhighlight.pygments.lexers.agile import RubyLexer 62 self.ruby_lexer = RubyLexer(**options) 63 Lexer.__init__(self, **options) 64 65 def get_tokens_unprocessed(self, text): 66 """ 67 Since ERB doesn't allow "<%" and other tags inside of ruby 68 blocks we have to use a split approach here that fails for 69 that too. 70 """ 71 tokens = self._block_re.split(text) 72 tokens.reverse() 73 state = idx = 0 74 try: 75 while True: 76 # text 77 if state == 0: 78 val = tokens.pop() 79 yield idx, Other, val 80 idx += len(val) 81 state = 1 82 # block starts 83 elif state == 1: 84 tag = tokens.pop() 85 # literals 86 if tag in ('<%%', '%%>'): 87 yield idx, Other, tag 88 idx += 3 89 state = 0 90 # comment 91 elif tag == '<%#': 92 yield idx, Comment.Preproc, tag 93 val = tokens.pop() 94 yield idx + 3, Comment, val 95 idx += 3 + len(val) 96 state = 2 97 # blocks or output 98 elif tag in ('<%', '<%=', '<%-'): 99 yield idx, Comment.Preproc, tag 100 idx += len(tag) 101 data = tokens.pop() 102 r_idx = 0 103 for r_idx, r_token, r_value in \ 104 self.ruby_lexer.get_tokens_unprocessed(data): 105 yield r_idx + idx, r_token, r_value 106 idx += len(data) 107 state = 2 108 elif tag in ('%>', '-%>'): 109 yield idx, Error, tag 110 idx += len(tag) 111 state = 0 112 # % raw ruby statements 113 else: 114 yield idx, Comment.Preproc, tag[0] 115 r_idx = 0 116 for r_idx, r_token, r_value in \ 117 self.ruby_lexer.get_tokens_unprocessed(tag[1:]): 118 yield idx + 1 + r_idx, r_token, r_value 119 idx += len(tag) 120 state = 0 121 # block ends 122 elif state == 2: 123 tag = tokens.pop() 124 if tag not in ('%>', '-%>'): 125 yield idx, Other, tag 126 else: 127 yield idx, Comment.Preproc, tag 128 idx += len(tag) 129 state = 0 130 except IndexError: 131 return 132 133 def analyse_text(text): 134 if '<%' in text and '%>' in text: 135 return 0.4 136 137 138class SmartyLexer(RegexLexer): 139 """ 140 Generic `Smarty <http://smarty.php.net/>`_ template lexer. 141 142 Just highlights smarty code between the preprocessor directives, other 143 data is left untouched by the lexer. 144 """ 145 146 name = 'Smarty' 147 aliases = ['smarty'] 148 filenames = ['*.tpl'] 149 mimetypes = ['application/x-smarty'] 150 151 flags = re.MULTILINE | re.DOTALL 152 153 tokens = { 154 'root': [ 155 (r'[^{]+', Other), 156 (r'(\{)(\*.*?\*)(\})', 157 bygroups(Comment.Preproc, Comment, Comment.Preproc)), 158 (r'(\{php\})(.*?)(\{/php\})', 159 bygroups(Comment.Preproc, using(PhpLexer, startinline=True), 160 Comment.Preproc)), 161 (r'(\{)(/?[a-zA-Z_][a-zA-Z0-9_]*)(\s*)', 162 bygroups(Comment.Preproc, Name.Function, Text), 'smarty'), 163 (r'\{', Comment.Preproc, 'smarty') 164 ], 165 'smarty': [ 166 (r'\s+', Text), 167 (r'\}', Comment.Preproc, '#pop'), 168 (r'#[a-zA-Z_][a-zA-Z0-9_]*#', Name.Variable), 169 (r'\$[a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z0-9_]+)*', Name.Variable), 170 (r'[~!%^&*()+=|\[\]:;,.<>/?{}@-]', Operator), 171 ('(true|false|null)\b', Keyword.Constant), 172 (r"[0-9](\.[0-9]*)?(eE[+-][0-9])?[flFLdD]?|" 173 r"0[xX][0-9a-fA-F]+[Ll]?", Number), 174 (r'"(\\\\|\\"|[^"])*"', String.Double), 175 (r"'(\\\\|\\'|[^'])*'", String.Single), 176 (r'[a-zA-Z_][a-zA-Z0-9_]*', Name.Attribute) 177 ] 178 } 179 180 def analyse_text(text): 181 rv = 0.0 182 if re.search('\{if\s+.*?\}.*?\{/if\}', text): 183 rv += 0.15 184 if re.search('\{include\s+file=.*?\}', text): 185 rv += 0.15 186 if re.search('\{foreach\s+.*?\}.*?\{/foreach\}', text): 187 rv += 0.15 188 if re.search('\{\$.*?\}', text): 189 rv += 0.01 190 return rv 191 192 193class VelocityLexer(RegexLexer): 194 """ 195 Generic `Velocity <http://velocity.apache.org/>`_ template lexer. 196 197 Just highlights velocity directives and variable references, other 198 data is left untouched by the lexer. 199 """ 200 201 name = 'Velocity' 202 aliases = ['velocity'] 203 filenames = ['*.vm','*.fhtml'] 204 205 flags = re.MULTILINE | re.DOTALL 206 207 identifier = r'[a-zA-Z_][a-zA-Z0-9_]*' 208 209 tokens = { 210 'root': [ 211 (r'[^{#$]+', Other), 212 (r'(#)(\*.*?\*)(#)', 213 bygroups(Comment.Preproc, Comment, Comment.Preproc)), 214 (r'(##)(.*?$)', 215 bygroups(Comment.Preproc, Comment)), 216 (r'(#\{?)(' + identifier + r')(\}?)(\s?\()', 217 bygroups(Comment.Preproc, Name.Function, Comment.Preproc, Punctuation), 218 'directiveparams'), 219 (r'(#\{?)(' + identifier + r')(\}|\b)', 220 bygroups(Comment.Preproc, Name.Function, Comment.Preproc)), 221 (r'\$\{?', Punctuation, 'variable') 222 ], 223 'variable': [ 224 (identifier, Name.Variable), 225 (r'\(', Punctuation, 'funcparams'), 226 (r'(\.)(' + identifier + r')', bygroups(Punctuation, Name.Variable), '#push'), 227 (r'\}', Punctuation, '#pop'), 228 (r'', Other, '#pop') 229 ], 230 'directiveparams': [ 231 (r'(&&|\|\||==?|!=?|[-<>+*%&\|\^/])|\b(eq|ne|gt|lt|ge|le|not|in)\b', Operator), 232 (r'\[', Operator, 'rangeoperator'), 233 (r'\b' + identifier + r'\b', Name.Function), 234 include('funcparams') 235 ], 236 'rangeoperator': [ 237 (r'\.\.', Operator), 238 include('funcparams'), 239 (r'\]', Operator, '#pop') 240 ], 241 'funcparams': [ 242 (r'\$\{?', Punctuation, 'variable'), 243 (r'\s+', Text), 244 (r',', Punctuation), 245 (r'"(\\\\|\\"|[^"])*"', String.Double), 246 (r"'(\\\\|\\'|[^'])*'", String.Single), 247 (r"0[xX][0-9a-fA-F]+[Ll]?", Number), 248 (r"\b[0-9]+\b", Number), 249 (r'(true|false|null)\b', Keyword.Constant), 250 (r'\(', Punctuation, '#push'), 251 (r'\)', Punctuation, '#pop') 252 ] 253 } 254 255 def analyse_text(text): 256 rv = 0.0 257 if re.search(r'#\{?macro\}?\(.*?\).*?#\{?end\}?', text): 258 rv += 0.25 259 if re.search(r'#\{?if\}?\(.+?\).*?#\{?end\}?', text): 260 rv += 0.15 261 if re.search(r'#\{?foreach\}?\(.+?\).*?#\{?end\}?', text): 262 rv += 0.15 263 if re.search(r'\$\{?[a-zA-Z_][a-zA-Z0-9_]*(\([^)]*\))?(\.[a-zA-Z0-9_]+(\([^)]*\))?)*\}?', text): 264 rv += 0.01 265 return rv 266 267 268class VelocityHtmlLexer(DelegatingLexer): 269 """ 270 Subclass of the `VelocityLexer` that highlights unlexer data 271 with the `HtmlLexer`. 272 273 """ 274 275 name = 'HTML+Velocity' 276 aliases = ['html+velocity'] 277 alias_filenames = ['*.html','*.fhtml'] 278 mimetypes = ['text/html+velocity'] 279 280 def __init__(self, **options): 281 super(VelocityHtmlLexer, self).__init__(HtmlLexer, VelocityLexer, 282 **options) 283 284 285class VelocityXmlLexer(DelegatingLexer): 286 """ 287 Subclass of the `VelocityLexer` that highlights unlexer data 288 with the `XmlLexer`. 289 290 """ 291 292 name = 'XML+Velocity' 293 aliases = ['xml+velocity'] 294 alias_filenames = ['*.xml','*.vm'] 295 mimetypes = ['application/xml+velocity'] 296 297 def __init__(self, **options): 298 super(VelocityXmlLexer, self).__init__(XmlLexer, VelocityLexer, 299 **options) 300 301 def analyse_text(text): 302 rv = VelocityLexer.analyse_text(text) - 0.01 303 if looks_like_xml(text): 304 rv += 0.5 305 return rv 306 307 308class DjangoLexer(RegexLexer): 309 """ 310 Generic `django <http://www.djangoproject.com/documentation/templates/>`_ 311 and `jinja <http://wsgiarea.pocoo.org/jinja/>`_ template lexer. 312 313 It just highlights django/jinja code between the preprocessor directives, 314 other data is left untouched by the lexer. 315 """ 316 317 name = 'Django/Jinja' 318 aliases = ['django', 'jinja'] 319 mimetypes = ['application/x-django-templating', 'application/x-jinja'] 320 321 flags = re.M | re.S 322 323 tokens = { 324 'root': [ 325 (r'[^{]+', Other), 326 (r'\{\{', Comment.Preproc, 'var'), 327 # jinja/django comments 328 (r'\{[*#].*?[*#]\}', Comment), 329 # django comments 330 (r'(\{%)(-?\s*)(comment)(\s*-?)(%\})(.*?)' 331 r'(\{%)(-?\s*)(endcomment)(\s*-?)(%\})', 332 bygroups(Comment.Preproc, Text, Keyword, Text, Comment.Preproc, 333 Comment, Comment.Preproc, Text, Keyword, Text, 334 Comment.Preproc)), 335 # raw jinja blocks 336 (r'(\{%)(-?\s*)(raw)(\s*-?)(%\})(.*?)' 337 r'(\{%)(-?\s*)(endraw)(\s*-?)(%\})', 338 bygroups(Comment.Preproc, Text, Keyword, Text, Comment.Preproc, 339 Text, Comment.Preproc, Text, Keyword, Text, 340 Comment.Preproc)), 341 # filter blocks 342 (r'(\{%)(-?\s*)(filter)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)', 343 bygroups(Comment.Preproc, Text, Keyword, Text, Name.Function), 344 'block'), 345 (r'(\{%)(-?\s*)([a-zA-Z_][a-zA-Z0-9_]*)', 346 bygroups(Comment.Preproc, Text, Keyword), 'block'), 347 (r'\{', Other) 348 ], 349 'varnames': [ 350 (r'(\|)(\s*)([a-zA-Z_][a-zA-Z0-9_]*)', 351 bygroups(Operator, Text, Name.Function)), 352 (r'(is)(\s+)(not)?(\s+)?([a-zA-Z_][a-zA-Z0-9_]*)', 353 bygroups(Keyword, Text, Keyword, Text, Name.Function)), 354 (r'(_|true|false|none|True|False|None)\b', Keyword.Pseudo), 355 (r'(in|as|reversed|recursive|not|and|or|is|if|else|import|' 356 r'with(?:(?:out)?\s*context)?|scoped|ignore\s+missing)\b', 357 Keyword), 358 (r'(loop|block|super|forloop)\b', Name.Builtin), 359 (r'[a-zA-Z][a-zA-Z0-9_-]*', Name.Variable), 360 (r'\.[a-zA-Z0-9_]+', Name.Variable), 361 (r':?"(\\\\|\\"|[^"])*"', String.Double), 362 (r":?'(\\\\|\\'|[^'])*'", String.Single), 363 (r'([{}()\[\]+\-*/,:~]|[><=]=?)', Operator), 364 (r"[0-9](\.[0-9]*)?(eE[+-][0-9])?[flFLdD]?|" 365 r"0[xX][0-9a-fA-F]+[Ll]?", Number), 366 ], 367 'var': [ 368 (r'\s+', Text), 369 (r'(-?)(\}\})', bygroups(Text, Comment.Preproc), '#pop'), 370 include('varnames') 371 ], 372 'block': [ 373 (r'\s+', Text), 374 (r'(-?)(%\})', bygroups(Text, Comment.Preproc), '#pop'), 375 include('varnames'), 376 (r'.', Punctuation) 377 ] 378 } 379 380 def analyse_text(text): 381 rv = 0.0 382 if re.search(r'\{%\s*(block|extends)', text) is not None: 383 rv += 0.4 384 if re.search(r'\{%\s*if\s*.*?%\}', text) is not None: 385 rv += 0.1 386 if re.search(r'\{\{.*?\}\}', text) is not None: 387 rv += 0.1 388 return rv 389 390 391class MyghtyLexer(RegexLexer): 392 """ 393 Generic `myghty templates`_ lexer. Code that isn't Myghty 394 markup is yielded as `Token.Other`. 395 396 *New in Pygments 0.6.* 397 398 .. _myghty templates: http://www.myghty.org/ 399 """ 400 401 name = 'Myghty' 402 aliases = ['myghty'] 403 filenames = ['*.myt', 'autodelegate'] 404 mimetypes = ['application/x-myghty'] 405 406 tokens = { 407 'root': [ 408 (r'\s+', Text), 409 (r'(<%(def|method))(\s*)(.*?)(>)(.*?)(</%\2\s*>)(?s)', 410 bygroups(Name.Tag, None, Text, Name.Function, Name.Tag, 411 using(this), Name.Tag)), 412 (r'(<%(\w+))(.*?)(>)(.*?)(</%\2\s*>)(?s)', 413 bygroups(Name.Tag, None, Name.Function, Name.Tag, 414 using(PythonLexer), Name.Tag)), 415 (r'(<&[^|])(.*?)(,.*?)?(&>)', 416 bygroups(Name.Tag, Name.Function, using(PythonLexer), Name.Tag)), 417 (r'(<&\|)(.*?)(,.*?)?(&>)(?s)', 418 bygroups(Name.Tag, Name.Function, using(PythonLexer), Name.Tag)), 419 (r'</&>', Name.Tag), 420 (r'(<%!?)(.*?)(%>)(?s)', 421 bygroups(Name.Tag, using(PythonLexer), Name.Tag)), 422 (r'(?<=^)#[^\n]*(\n|\Z)', Comment), 423 (r'(?<=^)(%)([^\n]*)(\n|\Z)', 424 bygroups(Name.Tag, using(PythonLexer), Other)), 425 (r"""(?sx) 426 (.+?) # anything, followed by: 427 (?: 428 (?<=\n)(?=[%#]) | # an eval or comment line 429 (?=</?[%&]) | # a substitution or block or 430 # call start or end 431 # - don't consume 432 (\\\n) | # an escaped newline 433 \Z # end of string 434 )""", bygroups(Other, Operator)), 435 ] 436 } 437 438 439class MyghtyHtmlLexer(DelegatingLexer): 440 """ 441 Subclass of the `MyghtyLexer` that highlights unlexer data 442 with the `HtmlLexer`. 443 444 *New in Pygments 0.6.* 445 """ 446 447 name = 'HTML+Myghty' 448 aliases = ['html+myghty'] 449 mimetypes = ['text/html+myghty'] 450 451 def __init__(self, **options): 452 super(MyghtyHtmlLexer, self).__init__(HtmlLexer, MyghtyLexer, 453 **options) 454 455 456class MyghtyXmlLexer(DelegatingLexer): 457 """ 458 Subclass of the `MyghtyLexer` that highlights unlexer data 459 with the `XmlLexer`. 460 461 *New in Pygments 0.6.* 462 """ 463 464 name = 'XML+Myghty' 465 aliases = ['xml+myghty'] 466 mimetypes = ['application/xml+myghty'] 467 468 def __init__(self, **options): 469 super(MyghtyXmlLexer, self).__init__(XmlLexer, MyghtyLexer, 470 **options) 471 472 473class MyghtyJavascriptLexer(DelegatingLexer): 474 """ 475 Subclass of the `MyghtyLexer` that highlights unlexer data 476 with the `JavascriptLexer`. 477 478 *New in Pygments 0.6.* 479 """ 480 481 name = 'JavaScript+Myghty' 482 aliases = ['js+myghty', 'javascript+myghty'] 483 mimetypes = ['application/x-javascript+myghty', 484 'text/x-javascript+myghty', 485 'text/javascript+mygthy'] 486 487 def __init__(self, **options): 488 super(MyghtyJavascriptLexer, self).__init__(JavascriptLexer, 489 MyghtyLexer, **options) 490 491 492class MyghtyCssLexer(DelegatingLexer): 493 """ 494 Subclass of the `MyghtyLexer` that highlights unlexer data 495 with the `CssLexer`. 496 497 *New in Pygments 0.6.* 498 """ 499 500 name = 'CSS+Myghty' 501 aliases = ['css+myghty'] 502 mimetypes = ['text/css+myghty'] 503 504 def __init__(self, **options): 505 super(MyghtyCssLexer, self).__init__(CssLexer, MyghtyLexer, 506 **options) 507 508 509class MasonLexer(RegexLexer): 510 """ 511 Generic `mason templates`_ lexer. Stolen from Myghty lexer. Code that isn't 512 Mason markup is HTML. 513 514 .. _mason templates: http://www.masonhq.com/ 515 516 *New in Pygments 1.4.* 517 """ 518 name = 'Mason' 519 aliases = ['mason'] 520 filenames = ['*.m', '*.mhtml', '*.mc', '*.mi', 'autohandler', 'dhandler'] 521 mimetypes = ['application/x-mason'] 522 523 tokens = { 524 'root': [ 525 (r'\s+', Text), 526 (r'(<%doc>)(.*?)(</%doc>)(?s)', 527 bygroups(Name.Tag, Comment.Multiline, Name.Tag)), 528 (r'(<%(def|method))(\s*)(.*?)(>)(.*?)(</%\2\s*>)(?s)', 529 bygroups(Name.Tag, None, Text, Name.Function, Name.Tag, 530 using(this), Name.Tag)), 531 (r'(<%(\w+))(.*?)(>)(.*?)(</%\2\s*>)(?s)', 532 bygroups(Name.Tag, None, Name.Function, Name.Tag, 533 using(PerlLexer), Name.Tag)), 534 (r'(<&[^|])(.*?)(,.*?)?(&>)(?s)', 535 bygroups(Name.Tag, Name.Function, using(PerlLexer), Name.Tag)), 536 (r'(<&\|)(.*?)(,.*?)?(&>)(?s)', 537 bygroups(Name.Tag, Name.Function, using(PerlLexer), Name.Tag)), 538 (r'</&>', Name.Tag), 539 (r'(<%!?)(.*?)(%>)(?s)', 540 bygroups(Name.Tag, using(PerlLexer), Name.Tag)), 541 (r'(?<=^)#[^\n]*(\n|\Z)', Comment), 542 (r'(?<=^)(%)([^\n]*)(\n|\Z)', 543 bygroups(Name.Tag, using(PerlLexer), Other)), 544 (r"""(?sx) 545 (.+?) # anything, followed by: 546 (?: 547 (?<=\n)(?=[%#]) | # an eval or comment line 548 (?=</?[%&]) | # a substitution or block or 549 # call start or end 550 # - don't consume 551 (\\\n) | # an escaped newline 552 \Z # end of string 553 )""", bygroups(using(HtmlLexer), Operator)), 554 ] 555 } 556 557 def analyse_text(text): 558 rv = 0.0 559 if re.search('<&', text) is not None: 560 rv = 1.0 561 return rv 562 563 564class MakoLexer(RegexLexer): 565 """ 566 Generic `mako templates`_ lexer. Code that isn't Mako 567 markup is yielded as `Token.Other`. 568 569 *New in Pygments 0.7.* 570 571 .. _mako templates: http://www.makotemplates.org/ 572 """ 573 574 name = 'Mako' 575 aliases = ['mako'] 576 filenames = ['*.mao'] 577 mimetypes = ['application/x-mako'] 578 579 tokens = { 580 'root': [ 581 (r'(\s*)(%)(\s*end(?:\w+))(\n|\Z)', 582 bygroups(Text, Comment.Preproc, Keyword, Other)), 583 (r'(\s*)(%)([^\n]*)(\n|\Z)', 584 bygroups(Text, Comment.Preproc, using(PythonLexer), Other)), 585 (r'(\s*)(##[^\n]*)(\n|\Z)', 586 bygroups(Text, Comment.Preproc, Other)), 587 (r'(?s)<%doc>.*?</%doc>', Comment.Preproc), 588 (r'(<%)([\w\.\:]+)', 589 bygroups(Comment.Preproc, Name.Builtin), 'tag'), 590 (r'(</%)([\w\.\:]+)(>)', 591 bygroups(Comment.Preproc, Name.Builtin, Comment.Preproc)), 592 (r'<%(?=([\w\.\:]+))', Comment.Preproc, 'ondeftags'), 593 (r'(<%(?:!?))(.*?)(%>)(?s)', 594 bygroups(Comment.Preproc, using(PythonLexer), Comment.Preproc)), 595 (r'(\$\{)(.*?)(\})', 596 bygroups(Comment.Preproc, using(PythonLexer), Comment.Preproc)), 597 (r'''(?sx) 598 (.+?) # anything, followed by: 599 (?: 600 (?<=\n)(?=%|\#\#) | # an eval or comment line 601 (?=\#\*) | # multiline comment 602 (?=</?%) | # a python block 603 # call start or end 604 (?=\$\{) | # a substitution 605 (?<=\n)(?=\s*%) | 606 # - don't consume 607 (\\\n) | # an escaped newline 608 \Z # end of string 609 ) 610 ''', bygroups(Other, Operator)), 611 (r'\s+', Text), 612 ], 613 'ondeftags': [ 614 (r'<%', Comment.Preproc), 615 (r'(?<=<%)(include|inherit|namespace|page)', Name.Builtin), 616 include('tag'), 617 ], 618 'tag': [ 619 (r'((?:\w+)\s*=)\s*(".*?")', 620 bygroups(Name.Attribute, String)), 621 (r'/?\s*>', Comment.Preproc, '#pop'), 622 (r'\s+', Text), 623 ], 624 'attr': [ 625 ('".*?"', String, '#pop'), 626 ("'.*?'", String, '#pop'), 627 (r'[^\s>]+', String, '#pop'), 628 ], 629 } 630 631 632class MakoHtmlLexer(DelegatingLexer): 633 """ 634 Subclass of the `MakoLexer` that highlights unlexed data 635 with the `HtmlLexer`. 636 637 *New in Pygments 0.7.* 638 """ 639 640 name = 'HTML+Mako' 641 aliases = ['html+mako'] 642 mimetypes = ['text/html+mako'] 643 644 def __init__(self, **options): 645 super(MakoHtmlLexer, self).__init__(HtmlLexer, MakoLexer, 646 **options) 647 648class MakoXmlLexer(DelegatingLexer): 649 """ 650 Subclass of the `MakoLexer` that highlights unlexer data 651 with the `XmlLexer`. 652 653 *New in Pygments 0.7.* 654 """ 655 656 name = 'XML+Mako' 657 aliases = ['xml+mako'] 658 mimetypes = ['application/xml+mako'] 659 660 def __init__(self, **options): 661 super(MakoXmlLexer, self).__init__(XmlLexer, MakoLexer, 662 **options) 663 664class MakoJavascriptLexer(DelegatingLexer): 665 """ 666 Subclass of the `MakoLexer` that highlights unlexer data 667 with the `JavascriptLexer`. 668 669 *New in Pygments 0.7.* 670 """ 671 672 name = 'JavaScript+Mako' 673 aliases = ['js+mako', 'javascript+mako'] 674 mimetypes = ['application/x-javascript+mako', 675 'text/x-javascript+mako', 676 'text/javascript+mako'] 677 678 def __init__(self, **options): 679 super(MakoJavascriptLexer, self).__init__(JavascriptLexer, 680 MakoLexer, **options) 681 682class MakoCssLexer(DelegatingLexer): 683 """ 684 Subclass of the `MakoLexer` that highlights unlexer data 685 with the `CssLexer`. 686 687 *New in Pygments 0.7.* 688 """ 689 690 name = 'CSS+Mako' 691 aliases = ['css+mako'] 692 mimetypes = ['text/css+mako'] 693 694 def __init__(self, **options): 695 super(MakoCssLexer, self).__init__(CssLexer, MakoLexer, 696 **options) 697 698 699# Genshi and Cheetah lexers courtesy of Matt Good. 700 701class CheetahPythonLexer(Lexer): 702 """ 703 Lexer for handling Cheetah's special $ tokens in Python syntax. 704 """ 705 706 def get_tokens_unprocessed(self, text): 707 pylexer = PythonLexer(**self.options) 708 for pos, type_, value in pylexer.get_tokens_unprocessed(text): 709 if type_ == Token.Error and value == '$': 710 type_ = Comment.Preproc 711 yield pos, type_, value 712 713 714class CheetahLexer(RegexLexer): 715 """ 716 Generic `cheetah templates`_ lexer. Code that isn't Cheetah 717 markup is yielded as `Token.Other`. This also works for 718 `spitfire templates`_ which use the same syntax. 719 720 .. _cheetah templates: http://www.cheetahtemplate.org/ 721 .. _spitfire templates: http://code.google.com/p/spitfire/ 722 """ 723 724 name = 'Cheetah' 725 aliases = ['cheetah', 'spitfire'] 726 filenames = ['*.tmpl', '*.spt'] 727 mimetypes = ['application/x-cheetah', 'application/x-spitfire'] 728 729 tokens = { 730 'root': [ 731 (r'(##[^\n]*)$', 732 (bygroups(Comment))), 733 (r'#[*](.|\n)*?[*]#', Comment), 734 (r'#end[^#\n]*(?:#|$)', Comment.Preproc), 735 (r'#slurp$', Comment.Preproc), 736 (r'(#[a-zA-Z]+)([^#\n]*)(#|$)', 737 (bygroups(Comment.Preproc, using(CheetahPythonLexer), 738 Comment.Preproc))), 739 # TODO support other Python syntax like $foo['bar'] 740 (r'(\$)([a-zA-Z_][a-zA-Z0-9_\.]*[a-zA-Z0-9_])', 741 bygroups(Comment.Preproc, using(CheetahPythonLexer))), 742 (r'(\$\{!?)(.*?)(\})(?s)', 743 bygroups(Comment.Preproc, using(CheetahPythonLexer), 744 Comment.Preproc)), 745 (r'''(?sx) 746 (.+?) # anything, followed by: 747 (?: 748 (?=[#][#a-zA-Z]*) | # an eval comment 749 (?=\$[a-zA-Z_{]) | # a substitution 750 \Z # end of string 751 ) 752 ''', Other), 753 (r'\s+', Text), 754 ], 755 } 756 757 758class CheetahHtmlLexer(DelegatingLexer): 759 """ 760 Subclass of the `CheetahLexer` that highlights unlexer data 761 with the `HtmlLexer`. 762 """ 763 764 name = 'HTML+Cheetah' 765 aliases = ['html+cheetah', 'html+spitfire'] 766 mimetypes = ['text/html+cheetah', 'text/html+spitfire'] 767 768 def __init__(self, **options): 769 super(CheetahHtmlLexer, self).__init__(HtmlLexer, CheetahLexer, 770 **options) 771 772 773class CheetahXmlLexer(DelegatingLexer): 774 """ 775 Subclass of the `CheetahLexer` that highlights unlexer data 776 with the `XmlLexer`. 777 """ 778 779 name = 'XML+Cheetah' 780 aliases = ['xml+cheetah', 'xml+spitfire'] 781 mimetypes = ['application/xml+cheetah', 'application/xml+spitfire'] 782 783 def __init__(self, **options): 784 super(CheetahXmlLexer, self).__init__(XmlLexer, CheetahLexer, 785 **options) 786 787 788class CheetahJavascriptLexer(DelegatingLexer): 789 """ 790 Subclass of the `CheetahLexer` that highlights unlexer data 791 with the `JavascriptLexer`. 792 """ 793 794 name = 'JavaScript+Cheetah' 795 aliases = ['js+cheetah', 'javascript+cheetah', 796 'js+spitfire', 'javascript+spitfire'] 797 mimetypes = ['application/x-javascript+cheetah', 798 'text/x-javascript+cheetah', 799 'text/javascript+cheetah', 800 'application/x-javascript+spitfire', 801 'text/x-javascript+spitfire', 802 'text/javascript+spitfire'] 803 804 def __init__(self, **options): 805 super(CheetahJavascriptLexer, self).__init__(JavascriptLexer, 806 CheetahLexer, **options) 807 808 809class GenshiTextLexer(RegexLexer): 810 """ 811 A lexer that highlights `genshi <http://genshi.edgewall.org/>`_ text 812 templates. 813 """ 814 815 name = 'Genshi Text' 816 aliases = ['genshitext'] 817 mimetypes = ['application/x-genshi-text', 'text/x-genshi'] 818 819 tokens = { 820 'root': [ 821 (r'[^#\$\s]+', Other), 822 (r'^(\s*)(##.*)$', bygroups(Text, Comment)), 823 (r'^(\s*)(#)', bygroups(Text, Comment.Preproc), 'directive'), 824 include('variable'), 825 (r'[#\$\s]', Other), 826 ], 827 'directive': [ 828 (r'\n', Text, '#pop'), 829 (r'(?:def|for|if)\s+.*', using(PythonLexer), '#pop'), 830 (r'(choose|when|with)([^\S\n]+)(.*)', 831 bygroups(Keyword, Text, using(PythonLexer)), '#pop'), 832 (r'(choose|otherwise)\b', Keyword, '#pop'), 833 (r'(end\w*)([^\S\n]*)(.*)', bygroups(Keyword, Text, Comment), '#pop'), 834 ], 835 'variable': [ 836 (r'(?<!\$)(\$\{)(.+?)(\})', 837 bygroups(Comment.Preproc, using(PythonLexer), Comment.Preproc)), 838 (r'(?<!\$)(\$)([a-zA-Z_][a-zA-Z0-9_\.]*)', 839 Name.Variable), 840 ] 841 } 842 843 844class GenshiMarkupLexer(RegexLexer): 845 """ 846 Base lexer for Genshi markup, used by `HtmlGenshiLexer` and 847 `GenshiLexer`. 848 """ 849 850 flags = re.DOTALL 851 852 tokens = { 853 'root': [ 854 (r'[^<\$]+', Other), 855 (r'(<\?python)(.*?)(\?>)', 856 bygroups(Comment.Preproc, using(PythonLexer), Comment.Preproc)), 857 # yield style and script blocks as Other 858 (r'<\s*(script|style)\s*.*?>.*?<\s*/\1\s*>', Other), 859 (r'<\s*py:[a-zA-Z0-9]+', Name.Tag, 'pytag'), 860 (r'<\s*[a-zA-Z0-9:]+', Name.Tag, 'tag'), 861 include('variable'), 862 (r'[<\$]', Other), 863 ], 864 'pytag': [ 865 (r'\s+', Text), 866 (r'[a-zA-Z0-9_:-]+\s*=', Name.Attribute, 'pyattr'), 867 (r'/?\s*>', Name.Tag, '#pop'), 868 ], 869 'pyattr': [ 870 ('(")(.*?)(")', bygroups(String, using(PythonLexer), String), '#pop'), 871 ("(')(.*?)(')", bygroups(String, using(PythonLexer), String), '#pop'), 872 (r'[^\s>]+', String, '#pop'), 873 ], 874 'tag': [ 875 (r'\s+', Text), 876 (r'py:[a-zA-Z0-9_-]+\s*=', Name.Attribute, 'pyattr'), 877 (r'[a-zA-Z0-9_:-]+\s*=', Name.Attribute, 'attr'), 878 (r'/?\s*>', Name.Tag, '#pop'), 879 ], 880 'attr': [ 881 ('"', String, 'attr-dstring'), 882 ("'", String, 'attr-sstring'), 883 (r'[^\s>]*', String, '#pop') 884 ], 885 'attr-dstring': [ 886 ('"', String, '#pop'), 887 include('strings'), 888 ("'", String) 889 ], 890 'attr-sstring': [ 891 ("'", String, '#pop'), 892 include('strings'), 893 ("'", String) 894 ], 895 'strings': [ 896 ('[^"\'$]+', String), 897 include('variable') 898 ], 899 'variable': [ 900 (r'(?<!\$)(\$\{)(.+?)(\})', 901 bygroups(Comment.Preproc, using(PythonLexer), Comment.Preproc)), 902 (r'(?<!\$)(\$)([a-zA-Z_][a-zA-Z0-9_\.]*)', 903 Name.Variable), 904 ] 905 } 906 907 908class HtmlGenshiLexer(DelegatingLexer): 909 """ 910 A lexer that highlights `genshi <http://genshi.edgewall.org/>`_ and 911 `kid <http://kid-templating.org/>`_ kid HTML templates. 912 """ 913 914 name = 'HTML+Genshi' 915 aliases = ['html+genshi', 'html+kid'] 916 alias_filenames = ['*.html', '*.htm', '*.xhtml'] 917 mimetypes = ['text/html+genshi'] 918 919 def __init__(self, **options): 920 super(HtmlGenshiLexer, self).__init__(HtmlLexer, GenshiMarkupLexer, 921 **options) 922 923 def analyse_text(text): 924 rv = 0.0 925 if re.search('\$\{.*?\}', text) is not None: 926 rv += 0.2 927 if re.search('py:(.*?)=["\']', text) is not None: 928 rv += 0.2 929 return rv + HtmlLexer.analyse_text(text) - 0.01 930 931 932class GenshiLexer(DelegatingLexer): 933 """ 934 A lexer that highlights `genshi <http://genshi.edgewall.org/>`_ and 935 `kid <http://kid-templating.org/>`_ kid XML templates. 936 """ 937 938 name = 'Genshi' 939 aliases = ['genshi', 'kid', 'xml+genshi', 'xml+kid'] 940 filenames = ['*.kid'] 941 alias_filenames = ['*.xml'] 942 mimetypes = ['application/x-genshi', 'application/x-kid'] 943 944 def __init__(self, **options): 945 super(GenshiLexer, self).__init__(XmlLexer, GenshiMarkupLexer, 946 **options) 947 948 def analyse_text(text): 949 rv = 0.0 950 if re.search('\$\{.*?\}', text) is not None: 951 rv += 0.2 952 if re.search('py:(.*?)=["\']', text) is not None: 953 rv += 0.2 954 return rv + XmlLexer.analyse_text(text) - 0.01 955 956 957class JavascriptGenshiLexer(DelegatingLexer): 958 """ 959 A lexer that highlights javascript code in genshi text templates. 960 """ 961 962 name = 'JavaScript+Genshi Text' 963 aliases = ['js+genshitext', 'js+genshi', 'javascript+genshitext', 964 'javascript+genshi'] 965 alias_filenames = ['*.js'] 966 mimetypes = ['application/x-javascript+genshi', 967 'text/x-javascript+genshi', 968 'text/javascript+genshi'] 969 970 def __init__(self, **options): 971 super(JavascriptGenshiLexer, self).__init__(JavascriptLexer, 972 GenshiTextLexer, 973 **options) 974 975 def analyse_text(text): 976 return GenshiLexer.analyse_text(text) - 0.05 977 978 979class CssGenshiLexer(DelegatingLexer): 980 """ 981 A lexer that highlights CSS definitions in genshi text templates. 982 """ 983 984 name = 'CSS+Genshi Text' 985 aliases = ['css+genshitext', 'css+genshi'] 986 alias_filenames = ['*.css'] 987 mimetypes = ['text/css+genshi'] 988 989 def __init__(self, **options): 990 super(CssGenshiLexer, self).__init__(CssLexer, GenshiTextLexer, 991 **options) 992 993 def analyse_text(text): 994 return GenshiLexer.analyse_text(text) - 0.05 995 996 997class RhtmlLexer(DelegatingLexer): 998 """ 999 Subclass of the ERB lexer that highlights the unlexed data with the 1000 html lexer. 1001 1002 Nested Javascript and CSS is highlighted too. 1003 """ 1004 1005 name = 'RHTML' 1006 aliases = ['rhtml', 'html+erb', 'html+ruby'] 1007 filenames = ['*.rhtml'] 1008 alias_filenames = ['*.html', '*.htm', '*.xhtml'] 1009 mimetypes = ['text/html+ruby'] 1010 1011 def __init__(self, **options): 1012 super(RhtmlLexer, self).__init__(HtmlLexer, ErbLexer, **options) 1013 1014 def analyse_text(text): 1015 rv = ErbLexer.analyse_text(text) - 0.01 1016 if html_doctype_matches(text): 1017 # one more than the XmlErbLexer returns 1018 rv += 0.5 1019 return rv 1020 1021 1022class XmlErbLexer(DelegatingLexer): 1023 """ 1024 Subclass of `ErbLexer` which highlights data outside preprocessor 1025 directives with the `XmlLexer`. 1026 """ 1027 1028 name = 'XML+Ruby' 1029 aliases = ['xml+erb', 'xml+ruby'] 1030 alias_filenames = ['*.xml'] 1031 mimetypes = ['application/xml+ruby'] 1032 1033 def __init__(self, **options): 1034 super(XmlErbLexer, self).__init__(XmlLexer, ErbLexer, **options) 1035 1036 def analyse_text(text): 1037 rv = ErbLexer.analyse_text(text) - 0.01 1038 if looks_like_xml(text): 1039 rv += 0.4 1040 return rv 1041 1042 1043class CssErbLexer(DelegatingLexer): 1044 """ 1045 Subclass of `ErbLexer` which highlights unlexed data with the `CssLexer`. 1046 """ 1047 1048 name = 'CSS+Ruby' 1049 aliases = ['css+erb', 'css+ruby'] 1050 alias_filenames = ['*.css'] 1051 mimetypes = ['text/css+ruby'] 1052 1053 def __init__(self, **options): 1054 super(CssErbLexer, self).__init__(CssLexer, ErbLexer, **options) 1055 1056 def analyse_text(text): 1057 return ErbLexer.analyse_text(text) - 0.05 1058 1059 1060class JavascriptErbLexer(DelegatingLexer): 1061 """ 1062 Subclass of `ErbLexer` which highlights unlexed data with the 1063 `JavascriptLexer`. 1064 """ 1065 1066 name = 'JavaScript+Ruby' 1067 aliases = ['js+erb', 'javascript+erb', 'js+ruby', 'javascript+ruby'] 1068 alias_filenames = ['*.js'] 1069 mimetypes = ['application/x-javascript+ruby', 1070 'text/x-javascript+ruby', 1071 'text/javascript+ruby'] 1072 1073 def __init__(self, **options): 1074 super(JavascriptErbLexer, self).__init__(JavascriptLexer, ErbLexer, 1075 **options) 1076 1077 def analyse_text(text): 1078 return ErbLexer.analyse_text(text) - 0.05 1079 1080 1081class HtmlPhpLexer(DelegatingLexer): 1082 """ 1083 Subclass of `PhpLexer` that highlights unhandled data with the `HtmlLexer`. 1084 1085 Nested Javascript and CSS is highlighted too. 1086 """ 1087 1088 name = 'HTML+PHP' 1089 aliases = ['html+php'] 1090 filenames = ['*.phtml'] 1091 alias_filenames = ['*.php', '*.html', '*.htm', '*.xhtml', 1092 '*.php[345]'] 1093 mimetypes = ['application/x-php', 1094 'application/x-httpd-php', 'application/x-httpd-php3', 1095 'application/x-httpd-php4', 'application/x-httpd-php5'] 1096 1097 def __init__(self, **options): 1098 super(HtmlPhpLexer, self).__init__(HtmlLexer, PhpLexer, **options) 1099 1100 def analyse_text(text): 1101 rv = PhpLexer.analyse_text(text) - 0.01 1102 if html_doctype_matches(text): 1103 rv += 0.5 1104 return rv 1105 1106 1107class XmlPhpLexer(DelegatingLexer): 1108 """ 1109 Subclass of `PhpLexer` that higlights unhandled data with the `XmlLexer`. 1110 """ 1111 1112 name = 'XML+PHP' 1113 aliases = ['xml+php'] 1114 alias_filenames = ['*.xml', '*.php', '*.php[345]'] 1115 mimetypes = ['application/xml+php'] 1116 1117 def __init__(self, **options): 1118 super(XmlPhpLexer, self).__init__(XmlLexer, PhpLexer, **options) 1119 1120 def analyse_text(text): 1121 rv = PhpLexer.analyse_text(text) - 0.01 1122 if looks_like_xml(text): 1123 rv += 0.4 1124 return rv 1125 1126 1127class CssPhpLexer(DelegatingLexer): 1128 """ 1129 Subclass of `PhpLexer` which highlights unmatched data with the `CssLexer`. 1130 """ 1131 1132 name = 'CSS+PHP' 1133 aliases = ['css+php'] 1134 alias_filenames = ['*.css'] 1135 mimetypes = ['text/css+php'] 1136 1137 def __init__(self, **options): 1138 super(CssPhpLexer, self).__init__(CssLexer, PhpLexer, **options) 1139 1140 def analyse_text(text): 1141 return PhpLexer.analyse_text(text) - 0.05 1142 1143 1144class JavascriptPhpLexer(DelegatingLexer): 1145 """ 1146 Subclass of `PhpLexer` which highlights unmatched data with the 1147 `JavascriptLexer`. 1148 """ 1149 1150 name = 'JavaScript+PHP' 1151 aliases = ['js+php', 'javascript+php'] 1152 alias_filenames = ['*.js'] 1153 mimetypes = ['application/x-javascript+php', 1154 'text/x-javascript+php', 1155 'text/javascript+php'] 1156 1157 def __init__(self, **options): 1158 super(JavascriptPhpLexer, self).__init__(JavascriptLexer, PhpLexer, 1159 **options) 1160 1161 def analyse_text(text): 1162 return PhpLexer.analyse_text(text) 1163 1164 1165class HtmlSmartyLexer(DelegatingLexer): 1166 """ 1167 Subclass of the `SmartyLexer` that highighlights unlexed data with the 1168 `HtmlLexer`. 1169 1170 Nested Javascript and CSS is highlighted too. 1171 """ 1172 1173 name = 'HTML+Smarty' 1174 aliases = ['html+smarty'] 1175 alias_filenames = ['*.html', '*.htm', '*.xhtml', '*.tpl'] 1176 mimetypes = ['text/html+smarty'] 1177 1178 def __init__(self, **options): 1179 super(HtmlSmartyLexer, self).__init__(HtmlLexer, SmartyLexer, **options) 1180 1181 def analyse_text(text): 1182 rv = SmartyLexer.analyse_text(text) - 0.01 1183 if html_doctype_matches(text): 1184 rv += 0.5 1185 return rv 1186 1187 1188class XmlSmartyLexer(DelegatingLexer): 1189 """ 1190 Subclass of the `SmartyLexer` that highlights unlexed data with the 1191 `XmlLexer`. 1192 """ 1193 1194 name = 'XML+Smarty' 1195 aliases = ['xml+smarty'] 1196 alias_filenames = ['*.xml', '*.tpl'] 1197 mimetypes = ['application/xml+smarty'] 1198 1199 def __init__(self, **options): 1200 super(XmlSmartyLexer, self).__init__(XmlLexer, SmartyLexer, **options) 1201 1202 def analyse_text(text): 1203 rv = SmartyLexer.analyse_text(text) - 0.01 1204 if looks_like_xml(text): 1205 rv += 0.4 1206 return rv 1207 1208 1209class CssSmartyLexer(DelegatingLexer): 1210 """ 1211 Subclass of the `SmartyLexer` that highlights unlexed data with the 1212 `CssLexer`. 1213 """ 1214 1215 name = 'CSS+Smarty' 1216 aliases = ['css+smarty'] 1217 alias_filenames = ['*.css', '*.tpl'] 1218 mimetypes = ['text/css+smarty'] 1219 1220 def __init__(self, **options): 1221 super(CssSmartyLexer, self).__init__(CssLexer, SmartyLexer, **options) 1222 1223 def analyse_text(text): 1224 return SmartyLexer.analyse_text(text) - 0.05 1225 1226 1227class JavascriptSmartyLexer(DelegatingLexer): 1228 """ 1229 Subclass of the `SmartyLexer` that highlights unlexed data with the 1230 `JavascriptLexer`. 1231 """ 1232 1233 name = 'JavaScript+Smarty' 1234 aliases = ['js+smarty', 'javascript+smarty'] 1235 alias_filenames = ['*.js', '*.tpl'] 1236 mimetypes = ['application/x-javascript+smarty', 1237 'text/x-javascript+smarty', 1238 'text/javascript+smarty'] 1239 1240 def __init__(self, **options): 1241 super(JavascriptSmartyLexer, self).__init__(JavascriptLexer, SmartyLexer, 1242 **options) 1243 1244 def analyse_text(text): 1245 return SmartyLexer.analyse_text(text) - 0.05 1246 1247 1248class HtmlDjangoLexer(DelegatingLexer): 1249 """ 1250 Subclass of the `DjangoLexer` that highighlights unlexed data with the 1251 `HtmlLexer`. 1252 1253 Nested Javascript and CSS is highlighted too. 1254 """ 1255 1256 name = 'HTML+Django/Jinja' 1257 aliases = ['html+django', 'html+jinja'] 1258 alias_filenames = ['*.html', '*.htm', '*.xhtml'] 1259 mimetypes = ['text/html+django', 'text/html+jinja'] 1260 1261 def __init__(self, **options): 1262 super(HtmlDjangoLexer, self).__init__(HtmlLexer, DjangoLexer, **options) 1263 1264 def analyse_text(text): 1265 rv = DjangoLexer.analyse_text(text) - 0.01 1266 if html_doctype_matches(text): 1267 rv += 0.5 1268 return rv 1269 1270 1271class XmlDjangoLexer(DelegatingLexer): 1272 """ 1273 Subclass of the `DjangoLexer` that highlights unlexed data with the 1274 `XmlLexer`. 1275 """ 1276 1277 name = 'XML+Django/Jinja' 1278 aliases = ['xml+django', 'xml+jinja'] 1279 alias_filenames = ['*.xml'] 1280 mimetypes = ['application/xml+django', 'application/xml+jinja'] 1281 1282 def __init__(self, **options): 1283 super(XmlDjangoLexer, self).__init__(XmlLexer, DjangoLexer, **options) 1284 1285 def analyse_text(text): 1286 rv = DjangoLexer.analyse_text(text) - 0.01 1287 if looks_like_xml(text): 1288 rv += 0.4 1289 return rv 1290 1291 1292class CssDjangoLexer(DelegatingLexer): 1293 """ 1294 Subclass of the `DjangoLexer` that highlights unlexed data with the 1295 `CssLexer`. 1296 """ 1297 1298 name = 'CSS+Django/Jinja' 1299 aliases = ['css+django', 'css+jinja'] 1300 alias_filenames = ['*.css'] 1301 mimetypes = ['text/css+django', 'text/css+jinja'] 1302 1303 def __init__(self, **options): 1304 super(CssDjangoLexer, self).__init__(CssLexer, DjangoLexer, **options) 1305 1306 def analyse_text(text): 1307 return DjangoLexer.analyse_text(text) - 0.05 1308 1309 1310class JavascriptDjangoLexer(DelegatingLexer): 1311 """ 1312 Subclass of the `DjangoLexer` that highlights unlexed data with the 1313 `JavascriptLexer`. 1314 """ 1315 1316 name = 'JavaScript+Django/Jinja' 1317 aliases = ['js+django', 'javascript+django', 1318 'js+jinja', 'javascript+jinja'] 1319 alias_filenames = ['*.js'] 1320 mimetypes = ['application/x-javascript+django', 1321 'application/x-javascript+jinja', 1322 'text/x-javascript+django', 1323 'text/x-javascript+jinja', 1324 'text/javascript+django', 1325 'text/javascript+jinja'] 1326 1327 def __init__(self, **options): 1328 super(JavascriptDjangoLexer, self).__init__(JavascriptLexer, DjangoLexer, 1329 **options) 1330 1331 def analyse_text(text): 1332 return DjangoLexer.analyse_text(text) - 0.05 1333 1334 1335class JspRootLexer(RegexLexer): 1336 """ 1337 Base for the `JspLexer`. Yields `Token.Other` for area outside of 1338 JSP tags. 1339 1340 *New in Pygments 0.7.* 1341 """ 1342 1343 tokens = { 1344 'root': [ 1345 (r'<%\S?', Keyword, 'sec'), 1346 # FIXME: I want to make these keywords but still parse attributes. 1347 (r'</?jsp:(forward|getProperty|include|plugin|setProperty|useBean).*?>', 1348 Keyword), 1349 (r'[^<]+', Other), 1350 (r'<', Other), 1351 ], 1352 'sec': [ 1353 (r'%>', Keyword, '#pop'), 1354 # note: '\w\W' != '.' without DOTALL. 1355 (r'[\w\W]+?(?=%>|\Z)', using(JavaLexer)), 1356 ], 1357 } 1358 1359 1360class JspLexer(DelegatingLexer): 1361 """ 1362 Lexer for Java Server Pages. 1363 1364 *New in Pygments 0.7.* 1365 """ 1366 name = 'Java Server Page' 1367 aliases = ['jsp'] 1368 filenames = ['*.jsp'] 1369 mimetypes = ['application/x-jsp'] 1370 1371 def __init__(self, **options): 1372 super(JspLexer, self).__init__(XmlLexer, JspRootLexer, **options) 1373 1374 def analyse_text(text): 1375 rv = JavaLexer.analyse_text(text) - 0.01 1376 if looks_like_xml(text): 1377 rv += 0.4 1378 if '<%' in text and '%>' in text: 1379 rv += 0.1 1380 return rv 1381 1382 1383class EvoqueLexer(RegexLexer): 1384 """ 1385 For files using the Evoque templating system. 1386 1387 *New in Pygments 1.1.* 1388 """ 1389 name = 'Evoque' 1390 aliases = ['evoque'] 1391 filenames = ['*.evoque'] 1392 mimetypes = ['application/x-evoque'] 1393 1394 flags = re.DOTALL 1395 1396 tokens = { 1397 'root': [ 1398 (r'[^#$]+', Other), 1399 (r'#\[', Comment.Multiline, 'comment'), 1400 (r'\$\$', Other), 1401 # svn keywords 1402 (r'\$\w+:[^$\n]*\$', Comment.Multiline), 1403 # directives: begin, end 1404 (r'(\$)(begin|end)(\{(%)?)(.*?)((?(4)%)\})', 1405 bygroups(Punctuation, Name.Builtin, Punctuation, None, 1406 String, Punctuation, None)), 1407 # directives: evoque, overlay 1408 # see doc for handling first name arg: /directives/evoque/ 1409 #+ minor inconsistency: the "name" in e.g. $overlay{name=site_base} 1410 # should be using(PythonLexer), not passed out as String 1411 (r'(\$)(evoque|overlay)(\{(%)?)(\s*[#\w\-"\'.]+[^=,%}]+?)?' 1412 r'(.*?)((?(4)%)\})', 1413 bygroups(Punctuation, Name.Builtin, Punctuation, None, 1414 String, using(PythonLexer), Punctuation, None)), 1415 # directives: if, for, prefer, test 1416 (r'(\$)(\w+)(\{(%)?)(.*?)((?(4)%)\})', 1417 bygroups(Punctuation, Name.Builtin, Punctuation, None, 1418 using(PythonLexer), Punctuation, None)), 1419 # directive clauses (no {} expression) 1420 (r'(\$)(else|rof|fi)', bygroups(Punctuation, Name.Builtin)), 1421 # expressions 1422 (r'(\$\{(%)?)(.*?)((!)(.*?))?((?(2)%)\})', 1423 bygroups(Punctuation, None, using(PythonLexer), 1424 Name.Builtin, None, None, Punctuation, None)), 1425 (r'#', Other), 1426 ], 1427 'comment': [ 1428 (r'[^\]#]', Comment.Multiline), 1429 (r'#\[', Comment.Multiline, '#push'), 1430 (r'\]#', Comment.Multiline, '#pop'), 1431 (r'[\]#]', Comment.Multiline) 1432 ], 1433 } 1434 1435class EvoqueHtmlLexer(DelegatingLexer): 1436 """ 1437 Subclass of the `EvoqueLexer` that highlights unlexed data with the 1438 `HtmlLexer`. 1439 1440 *New in Pygments 1.1.* 1441 """ 1442 name = 'HTML+Evoque' 1443 aliases = ['html+evoque'] 1444 filenames = ['*.html'] 1445 mimetypes = ['text/html+evoque'] 1446 1447 def __init__(self, **options): 1448 super(EvoqueHtmlLexer, self).__init__(HtmlLexer, EvoqueLexer, 1449 **options) 1450 1451class EvoqueXmlLexer(DelegatingLexer): 1452 """ 1453 Subclass of the `EvoqueLexer` that highlights unlexed data with the 1454 `XmlLexer`. 1455 1456 *New in Pygments 1.1.* 1457 """ 1458 name = 'XML+Evoque' 1459 aliases = ['xml+evoque'] 1460 filenames = ['*.xml'] 1461 mimetypes = ['application/xml+evoque'] 1462 1463 def __init__(self, **options): 1464 super(EvoqueXmlLexer, self).__init__(XmlLexer, EvoqueLexer, 1465 **options) 1466 1467class ColdfusionLexer(RegexLexer): 1468 """ 1469 Coldfusion statements 1470 """ 1471 name = 'cfstatement' 1472 aliases = ['cfs'] 1473 filenames = [] 1474 mimetypes = [] 1475 flags = re.IGNORECASE | re.MULTILINE 1476 1477 tokens = { 1478 'root': [ 1479 (r'//.*', Comment), 1480 (r'\+\+|--', Operator), 1481 (r'[-+*/^&=!]', Operator), 1482 (r'<=|>=|<|>', Operator), 1483 (r'mod\b', Operator), 1484 (r'(eq|lt|gt|lte|gte|not|is|and|or)\b', Operator), 1485 (r'\|\||&&', Operator), 1486 (r'"', String.Double, 'string'), 1487 # There is a special rule for allowing html in single quoted 1488 # strings, evidently. 1489 (r"'.*?'", String.Single), 1490 (r'\d+', Number), 1491 (r'(if|else|len|var|case|default|break|switch)\b', Keyword), 1492 (r'([A-Za-z_$][A-Za-z0-9_.]*)\s*(\()', bygroups(Name.Function, Punctuation)), 1493 (r'[A-Za-z_$][A-Za-z0-9_.]*', Name.Variable), 1494 (r'[()\[\]{};:,.\\]', Punctuation), 1495 (r'\s+', Text), 1496 ], 1497 'string': [ 1498 (r'""', String.Double), 1499 (r'#.+?#', String.Interp), 1500 (r'[^"#]+', String.Double), 1501 (r'#', String.Double), 1502 (r'"', String.Double, '#pop'), 1503 ], 1504 } 1505 1506class ColdfusionMarkupLexer(RegexLexer): 1507 """ 1508 Coldfusion markup only 1509 """ 1510 name = 'Coldfusion' 1511 aliases = ['cf'] 1512 filenames = [] 1513 mimetypes = [] 1514 1515 tokens = { 1516 'root': [ 1517 (r'[^<]+', Other), 1518 include('tags'), 1519 (r'<[^<>]*', Other), 1520 ], 1521 'tags': [ 1522 (r'(?s)<!---.*?--->', Comment.Multiline), 1523 (r'(?s)<!--.*?-->', Comment), 1524 (r'<cfoutput.*?>', Name.Builtin, 'cfoutput'), 1525 (r'(?s)(<cfscript.*?>)(.+?)(</cfscript.*?>)', 1526 bygroups(Name.Builtin, using(ColdfusionLexer), Name.Builtin)), 1527 # neg…
Large files files are truncated, but you can click here to view the full file