pygmentplugin.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. # ext/pygmentplugin.py
  2. # Copyright 2006-2025 the Mako authors and contributors <see AUTHORS file>
  3. #
  4. # This module is part of Mako and is released under
  5. # the MIT License: http://www.opensource.org/licenses/mit-license.php
  6. from pygments import highlight
  7. from pygments.formatters.html import HtmlFormatter
  8. from pygments.lexer import bygroups
  9. from pygments.lexer import DelegatingLexer
  10. from pygments.lexer import include
  11. from pygments.lexer import RegexLexer
  12. from pygments.lexer import using
  13. from pygments.lexers.agile import Python3Lexer
  14. from pygments.lexers.agile import PythonLexer
  15. from pygments.lexers.web import CssLexer
  16. from pygments.lexers.web import HtmlLexer
  17. from pygments.lexers.web import JavascriptLexer
  18. from pygments.lexers.web import XmlLexer
  19. from pygments.token import Comment
  20. from pygments.token import Keyword
  21. from pygments.token import Name
  22. from pygments.token import Operator
  23. from pygments.token import Other
  24. from pygments.token import String
  25. from pygments.token import Text
  26. class MakoLexer(RegexLexer):
  27. name = "Mako"
  28. aliases = ["mako"]
  29. filenames = ["*.mao"]
  30. tokens = {
  31. "root": [
  32. (
  33. r"(\s*)(\%)(\s*end(?:\w+))(\n|\Z)",
  34. bygroups(Text, Comment.Preproc, Keyword, Other),
  35. ),
  36. (
  37. r"(\s*)(\%(?!%))([^\n]*)(\n|\Z)",
  38. bygroups(Text, Comment.Preproc, using(PythonLexer), Other),
  39. ),
  40. (
  41. r"(\s*)(##[^\n]*)(\n|\Z)",
  42. bygroups(Text, Comment.Preproc, Other),
  43. ),
  44. (r"""(?s)<%doc>.*?</%doc>""", Comment.Preproc),
  45. (
  46. r"(<%)([\w\.\:]+)",
  47. bygroups(Comment.Preproc, Name.Builtin),
  48. "tag",
  49. ),
  50. (
  51. r"(</%)([\w\.\:]+)(>)",
  52. bygroups(Comment.Preproc, Name.Builtin, Comment.Preproc),
  53. ),
  54. (r"<%(?=([\w\.\:]+))", Comment.Preproc, "ondeftags"),
  55. (
  56. r"(?s)(<%(?:!?))(.*?)(%>)",
  57. bygroups(Comment.Preproc, using(PythonLexer), Comment.Preproc),
  58. ),
  59. (
  60. r"(\$\{)(.*?)(\})",
  61. bygroups(Comment.Preproc, using(PythonLexer), Comment.Preproc),
  62. ),
  63. (
  64. r"""(?sx)
  65. (.+?) # anything, followed by:
  66. (?:
  67. (?<=\n)(?=%(?!%)|\#\#) | # an eval or comment line
  68. (?=\#\*) | # multiline comment
  69. (?=</?%) | # a python block
  70. # call start or end
  71. (?=\$\{) | # a substitution
  72. (?<=\n)(?=\s*%) |
  73. # - don't consume
  74. (\\\n) | # an escaped newline
  75. \Z # end of string
  76. )
  77. """,
  78. bygroups(Other, Operator),
  79. ),
  80. (r"\s+", Text),
  81. ],
  82. "ondeftags": [
  83. (r"<%", Comment.Preproc),
  84. (r"(?<=<%)(include|inherit|namespace|page)", Name.Builtin),
  85. include("tag"),
  86. ],
  87. "tag": [
  88. (r'((?:\w+)\s*=)\s*(".*?")', bygroups(Name.Attribute, String)),
  89. (r"/?\s*>", Comment.Preproc, "#pop"),
  90. (r"\s+", Text),
  91. ],
  92. "attr": [
  93. ('".*?"', String, "#pop"),
  94. ("'.*?'", String, "#pop"),
  95. (r"[^\s>]+", String, "#pop"),
  96. ],
  97. }
  98. class MakoHtmlLexer(DelegatingLexer):
  99. name = "HTML+Mako"
  100. aliases = ["html+mako"]
  101. def __init__(self, **options):
  102. super().__init__(HtmlLexer, MakoLexer, **options)
  103. class MakoXmlLexer(DelegatingLexer):
  104. name = "XML+Mako"
  105. aliases = ["xml+mako"]
  106. def __init__(self, **options):
  107. super().__init__(XmlLexer, MakoLexer, **options)
  108. class MakoJavascriptLexer(DelegatingLexer):
  109. name = "JavaScript+Mako"
  110. aliases = ["js+mako", "javascript+mako"]
  111. def __init__(self, **options):
  112. super().__init__(JavascriptLexer, MakoLexer, **options)
  113. class MakoCssLexer(DelegatingLexer):
  114. name = "CSS+Mako"
  115. aliases = ["css+mako"]
  116. def __init__(self, **options):
  117. super().__init__(CssLexer, MakoLexer, **options)
  118. pygments_html_formatter = HtmlFormatter(
  119. cssclass="syntax-highlighted", linenos=True
  120. )
  121. def syntax_highlight(filename="", language=None):
  122. mako_lexer = MakoLexer()
  123. python_lexer = Python3Lexer()
  124. if filename.startswith("memory:") or language == "mako":
  125. return lambda string: highlight(
  126. string, mako_lexer, pygments_html_formatter
  127. )
  128. return lambda string: highlight(
  129. string, python_lexer, pygments_html_formatter
  130. )