lisp_highlighter.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. # Flexlay - A Generic 2D Game Editor
  2. # Copyright (C) 2015 Karkus476 <karkus476@yahoo.com>
  3. #
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation, either version 3 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. from typing import Any, IO, Optional
  17. import json
  18. import re
  19. from PyQt5.QtGui import (QTextCharFormat, QFont)
  20. from PyQt5.QtCore import Qt
  21. from PyQt5.QtWidgets import QTextEdit
  22. from .highlighter import SuperTuxHighlighter, HighlightingRule
  23. class SuperTuxLispHighlighter(SuperTuxHighlighter):
  24. @staticmethod
  25. def clean_text(text: str) -> str:
  26. tiles = text.find("(tiles")
  27. while tiles != -1:
  28. close_bracket = text.find(")", tiles)
  29. assert close_bracket >= 0
  30. before_length = len(text)
  31. text = text[:tiles] + "(tiles" + text[close_bracket:]
  32. after_length = len(text)
  33. delta_length = before_length - after_length
  34. tiles = text.find("(tiles", close_bracket - delta_length)
  35. return text
  36. @staticmethod
  37. def load_tree_json(filename: Optional[str] = None) -> Any:
  38. if not filename or filename[-5:] != ".json":
  39. filename = "highlighters/patterns2.json"
  40. patterns_file = open(filename, "r")
  41. pattern_tree = json.loads(patterns_file.read())
  42. return pattern_tree
  43. @staticmethod
  44. def search_tree(tree: Any, tag_list: list[str]) -> Optional[QTextCharFormat]:
  45. '''
  46. Searches a tree to find a tag
  47. :param tag_list: ["supertux-level", "sector", "name"]
  48. :return: QTextCharFormat if possible, else None
  49. '''
  50. if tag_list[0] != "supertux-level":
  51. print("lisp_highlighter.py Line 53, tag_list is not from a supertux-level")
  52. return None
  53. tree = tree[tag_list.pop(0)]
  54. try:
  55. while len(tag_list) > 0:
  56. tree = tree["branches"][tag_list.pop(0)]
  57. except KeyError:
  58. return None
  59. colour = tree["color"]
  60. format = QTextCharFormat()
  61. if colour == "black":
  62. format.setForeground(Qt.black)
  63. elif colour == "blue":
  64. format.setForeground(Qt.blue)
  65. elif colour == "red":
  66. format.setForeground(Qt.red)
  67. elif colour == "green":
  68. format.setForeground(Qt.green)
  69. elif colour == "darkGreen":
  70. format.setForeground(Qt.darkGreen)
  71. elif colour == "darkBlue":
  72. format.setForeground(Qt.darkBlue)
  73. elif colour == "darkRed":
  74. format.setForeground(Qt.darkRed)
  75. elif colour == "magenta":
  76. format.setForeground(Qt.magenta)
  77. if tree["bold"]:
  78. format.setFontWeight(QFont.Bold)
  79. if tree["italic"]:
  80. format.setFontItalic(True)
  81. return format
  82. def __init__(self, text_edit: QTextEdit, level_file: IO[str]):
  83. super().__init__(text_edit)
  84. text = level_file.read()
  85. text = SuperTuxLispHighlighter.clean_text(text)
  86. text_edit.setText(text)
  87. self.highlighting_rules += SuperTuxHighlighter.load_patterns("highlighters/patterns.json")
  88. string_format = QTextCharFormat()
  89. string_format.setForeground(Qt.darkRed)
  90. string_pattern = '"'
  91. self.string = HighlightingRule(string_pattern, string_format, "string")
  92. # comment_format = QTextCharFormat()
  93. # comment_format.setForeground(Qt.darkRed)
  94. # comment_pattern = r';.*'
  95. # comment = HighlightingRule(comment_pattern, comment_format)
  96. #
  97. # self.highlighting_rules.append(comment)
  98. # tree_json = SuperTuxLispHighlighter.load_tree_json()
  99. # SuperTuxLispHighlighter.search_tree(tree_json,["supertux-level", "sector", "name"])
  100. def highlightBlock(self, text: str) -> None:
  101. for rule in self.highlighting_rules:
  102. search = re.search(rule.pattern, text)
  103. span = None if not search else search.span()
  104. while span:
  105. length = span[1] - span[0]
  106. self.setFormat(span[0], length, rule.format)
  107. search = re.search(rule.pattern, text[span[1]:])
  108. span = None if not search else search.span()
  109. self.setCurrentBlockState(0)
  110. # EOF #