minecraft.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. """
  2. pygments.lexers.minecraft
  3. ~~~~~~~~~~~~~~~~~~~~~~~~~
  4. Lexers for Minecraft related languages.
  5. SNBT. A data communication format used in Minecraft.
  6. wiki: https://minecraft.wiki/w/NBT_format
  7. MCFunction. The Function file for Minecraft Data packs and Add-ons.
  8. official: https://learn.microsoft.com/en-us/minecraft/creator/documents/functionsintroduction
  9. wiki: https://minecraft.wiki/w/Function
  10. MCSchema. A kind of data Schema for Minecraft Add-on Development.
  11. official: https://learn.microsoft.com/en-us/minecraft/creator/reference/content/schemasreference/
  12. community example: https://www.mcbe-dev.net/addons/data-driven/manifest.html
  13. :copyright: Copyright 2006-2023 by the Pygments team, see AUTHORS.
  14. :license: BSD, see LICENSE for details.
  15. """
  16. from pygments.lexer import RegexLexer, default, include, bygroups
  17. from pygments.token import Comment, Keyword, Literal, Name, Number, Operator, \
  18. Punctuation, String, Text, Whitespace
  19. __all__ = ['SNBTLexer', 'MCFunctionLexer', 'MCSchemaLexer']
  20. class SNBTLexer(RegexLexer):
  21. """Lexer for stringified NBT, a data format used in Minecraft
  22. .. versionadded:: 2.12.0
  23. """
  24. name = "SNBT"
  25. url = "https://minecraft.wiki/w/NBT_format"
  26. aliases = ["snbt"]
  27. filenames = ["*.snbt"]
  28. mimetypes = ["text/snbt"]
  29. tokens = {
  30. "root": [
  31. # We only look for the open bracket here since square bracket
  32. # is only valid in NBT pathing (which is a mcfunction idea).
  33. (r"\{", Punctuation, "compound"),
  34. (r"[^\{]+", Text),
  35. ],
  36. "whitespace": [
  37. (r"\s+", Whitespace),
  38. ],
  39. "operators": [
  40. (r"[,:;]", Punctuation),
  41. ],
  42. "literals": [
  43. (r"(true|false)", Keyword.Constant),
  44. (r"-?\d+[eE]-?\d+", Number.Float),
  45. (r"-?\d*\.\d+[fFdD]?", Number.Float),
  46. (r"-?\d+[bBsSlLfFdD]?", Number.Integer),
  47. # Separate states for both types of strings so they don't entangle
  48. (r'"', String.Double, "literals.string_double"),
  49. (r"'", String.Single, "literals.string_single"),
  50. ],
  51. "literals.string_double": [
  52. (r"\\.", String.Escape),
  53. (r'[^\\"\n]+', String.Double),
  54. (r'"', String.Double, "#pop"),
  55. ],
  56. "literals.string_single": [
  57. (r"\\.", String.Escape),
  58. (r"[^\\'\n]+", String.Single),
  59. (r"'", String.Single, "#pop"),
  60. ],
  61. "compound": [
  62. # this handles the unquoted snbt keys
  63. # note: stringified keys still work
  64. (r"[A-Z_a-z]+", Name.Attribute),
  65. include("operators"),
  66. include("whitespace"),
  67. include("literals"),
  68. (r"\{", Punctuation, "#push"),
  69. (r"\[", Punctuation, "list"),
  70. (r"\}", Punctuation, "#pop"),
  71. ],
  72. "list": [
  73. (r"[A-Z_a-z]+", Name.Attribute),
  74. include("literals"),
  75. include("operators"),
  76. include("whitespace"),
  77. (r"\[", Punctuation, "#push"),
  78. (r"\{", Punctuation, "compound"),
  79. (r"\]", Punctuation, "#pop"),
  80. ],
  81. }
  82. class MCFunctionLexer(RegexLexer):
  83. """Lexer for the mcfunction scripting language used in Minecraft
  84. Modelled somewhat after the `GitHub mcfunction grammar <https://github.com/Arcensoth/language-mcfunction>`_.
  85. .. versionadded:: 2.12.0
  86. """
  87. name = "MCFunction"
  88. url = "https://minecraft.wiki/w/Commands"
  89. aliases = ["mcfunction", "mcf"]
  90. filenames = ["*.mcfunction"]
  91. mimetypes = ["text/mcfunction"]
  92. # Used to denotate the start of a block comment, borrowed from Github's mcfunction
  93. _block_comment_prefix = "[>!]"
  94. tokens = {
  95. "root": [
  96. include("names"),
  97. include("comments"),
  98. include("literals"),
  99. include("whitespace"),
  100. include("property"),
  101. include("operators"),
  102. include("selectors"),
  103. ],
  104. "names": [
  105. # The start of a command (either beginning of line OR after the run keyword)
  106. # We don't encode a list of keywords since mods, plugins, or even pre-processors
  107. # may add new commands, so we have a 'close-enough' regex which catches them.
  108. (r"^(\s*)([a-z_]+)", bygroups(Whitespace, Name.Builtin)),
  109. (r"(?<=run)\s+[a-z_]+", Name.Builtin),
  110. # UUID
  111. (r"\b[0-9a-fA-F]+(?:-[0-9a-fA-F]+){4}\b", Name.Variable),
  112. include("resource-name"),
  113. # normal command names and scoreboards
  114. # there's no way to know the differences unfortuntely
  115. (r"[A-Za-z_][\w.#%$]+", Keyword.Constant),
  116. (r"[#%$][\w.#%$]+", Name.Variable.Magic),
  117. ],
  118. "resource-name": [
  119. # resource names have to be lowercase
  120. (r"#?[a-z_][a-z_.-]*:[a-z0-9_./-]+", Name.Function),
  121. # similar to above except optional `:``
  122. # a `/` must be present "somewhere"
  123. (r"#?[a-z0-9_\.\-]+\/[a-z0-9_\.\-\/]+", Name.Function),
  124. ],
  125. "whitespace": [
  126. (r"\s+", Whitespace),
  127. ],
  128. "comments": [
  129. (rf"^\s*(#{_block_comment_prefix})", Comment.Multiline,
  130. ("comments.block", "comments.block.emphasized")),
  131. (r"#.*$", Comment.Single),
  132. ],
  133. "comments.block": [
  134. (rf"^\s*#{_block_comment_prefix}", Comment.Multiline,
  135. "comments.block.emphasized"),
  136. (r"^\s*#", Comment.Multiline, "comments.block.normal"),
  137. default("#pop"),
  138. ],
  139. "comments.block.normal": [
  140. include("comments.block.special"),
  141. (r"\S+", Comment.Multiline),
  142. (r"\n", Text, "#pop"),
  143. include("whitespace"),
  144. ],
  145. "comments.block.emphasized": [
  146. include("comments.block.special"),
  147. (r"\S+", String.Doc),
  148. (r"\n", Text, "#pop"),
  149. include("whitespace"),
  150. ],
  151. "comments.block.special": [
  152. # Params
  153. (r"@\S+", Name.Decorator),
  154. include("resource-name"),
  155. # Scoreboard player names
  156. (r"[#%$][\w.#%$]+", Name.Variable.Magic),
  157. ],
  158. "operators": [
  159. (r"[\-~%^?!+*<>\\/|&=.]", Operator),
  160. ],
  161. "literals": [
  162. (r"\.\.", Literal),
  163. (r"(true|false)", Keyword.Pseudo),
  164. # these are like unquoted strings and appear in many places
  165. (r"[A-Za-z_]+", Name.Variable.Class),
  166. (r"[0-7]b", Number.Byte),
  167. (r"[+-]?\d*\.?\d+([eE]?[+-]?\d+)?[df]?\b", Number.Float),
  168. (r"[+-]?\d+\b", Number.Integer),
  169. (r'"', String.Double, "literals.string-double"),
  170. (r"'", String.Single, "literals.string-single"),
  171. ],
  172. "literals.string-double": [
  173. (r"\\.", String.Escape),
  174. (r'[^\\"\n]+', String.Double),
  175. (r'"', String.Double, "#pop"),
  176. ],
  177. "literals.string-single": [
  178. (r"\\.", String.Escape),
  179. (r"[^\\'\n]+", String.Single),
  180. (r"'", String.Single, "#pop"),
  181. ],
  182. "selectors": [
  183. (r"@[a-z]", Name.Variable),
  184. ],
  185. ## Generic Property Container
  186. # There are several, differing instances where the language accepts
  187. # specific contained keys or contained key, value pairings.
  188. #
  189. # Property Maps:
  190. # - Starts with either `[` or `{`
  191. # - Key separated by `:` or `=`
  192. # - Deliminated by `,`
  193. #
  194. # Property Lists:
  195. # - Starts with `[`
  196. # - Deliminated by `,`
  197. #
  198. # For simplicity, these patterns match a generic, nestable structure
  199. # which follow a key, value pattern. For normal lists, there's only keys.
  200. # This allow some "illegal" structures, but we'll accept those for
  201. # sake of simplicity
  202. #
  203. # Examples:
  204. # - `[facing=up, powered=true]` (blockstate)
  205. # - `[name="hello world", nbt={key: 1b}]` (selector + nbt)
  206. # - `[{"text": "value"}, "literal"]` (json)
  207. ##
  208. "property": [
  209. # This state gets included in root and also several substates
  210. # We do this to shortcut the starting of new properties
  211. # within other properties. Lists can have sublists and compounds
  212. # and values can start a new property (see the `difficult_1.txt`
  213. # snippet).
  214. (r"\{", Punctuation, ("property.curly", "property.key")),
  215. (r"\[", Punctuation, ("property.square", "property.key")),
  216. ],
  217. "property.curly": [
  218. include("whitespace"),
  219. include("property"),
  220. (r"\}", Punctuation, "#pop"),
  221. ],
  222. "property.square": [
  223. include("whitespace"),
  224. include("property"),
  225. (r"\]", Punctuation, "#pop"),
  226. # lists can have sequences of items
  227. (r",", Punctuation),
  228. ],
  229. "property.key": [
  230. include("whitespace"),
  231. # resource names (for advancements)
  232. # can omit `:` to default `minecraft:`
  233. # must check if there is a future equals sign if `:` is in the name
  234. (r"#?[a-z_][a-z_\.\-]*\:[a-z0-9_\.\-/]+(?=\s*\=)", Name.Attribute, "property.delimiter"),
  235. (r"#?[a-z_][a-z0-9_\.\-/]+", Name.Attribute, "property.delimiter"),
  236. # unquoted NBT key
  237. (r"[A-Za-z_\-\+]+", Name.Attribute, "property.delimiter"),
  238. # quoted JSON or NBT key
  239. (r'"', Name.Attribute, "property.delimiter", "literals.string-double"),
  240. (r"'", Name.Attribute, "property.delimiter", "literals.string-single"),
  241. # index for a list
  242. (r"-?\d+", Number.Integer, "property.delimiter"),
  243. default("#pop"),
  244. ],
  245. "property.key.string-double": [
  246. (r"\\.", String.Escape),
  247. (r'[^\\"\n]+', Name.Attribute),
  248. (r'"', Name.Attribute, "#pop"),
  249. ],
  250. "property.key.string-single": [
  251. (r"\\.", String.Escape),
  252. (r"[^\\'\n]+", Name.Attribute),
  253. (r"'", Name.Attribute, "#pop"),
  254. ],
  255. "property.delimiter": [
  256. include("whitespace"),
  257. (r"[:=]!?", Punctuation, "property.value"),
  258. (r",", Punctuation),
  259. default("#pop"),
  260. ],
  261. "property.value": [
  262. include("whitespace"),
  263. # unquoted resource names are valid literals here
  264. (r"#?[a-z_][a-z_\.\-]*\:[a-z0-9_\.\-/]+", Name.Tag),
  265. (r"#?[a-z_][a-z0-9_\.\-/]+", Name.Tag),
  266. include("literals"),
  267. include("property"),
  268. default("#pop"),
  269. ],
  270. }
  271. class MCSchemaLexer(RegexLexer):
  272. """Lexer for Minecraft Add-ons data Schemas, an interface structure standard used in Minecraft
  273. .. versionadded:: 2.14.0
  274. """
  275. name = 'MCSchema'
  276. url = 'https://learn.microsoft.com/en-us/minecraft/creator/reference/content/schemasreference/'
  277. aliases = ['mcschema']
  278. filenames = ['*.mcschema']
  279. mimetypes = ['text/mcschema']
  280. tokens = {
  281. 'commentsandwhitespace': [
  282. (r'\s+', Whitespace),
  283. (r'//.*?$', Comment.Single),
  284. (r'/\*.*?\*/', Comment.Multiline)
  285. ],
  286. 'slashstartsregex': [
  287. include('commentsandwhitespace'),
  288. (r'/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/'
  289. r'([gimuysd]+\b|\B)', String.Regex, '#pop'),
  290. (r'(?=/)', Text, ('#pop', 'badregex')),
  291. default('#pop')
  292. ],
  293. 'badregex': [
  294. (r'\n', Whitespace, '#pop')
  295. ],
  296. 'singlestring': [
  297. (r'\\.', String.Escape),
  298. (r"'", String.Single, '#pop'),
  299. (r"[^\\']+", String.Single),
  300. ],
  301. 'doublestring': [
  302. (r'\\.', String.Escape),
  303. (r'"', String.Double, '#pop'),
  304. (r'[^\\"]+', String.Double),
  305. ],
  306. 'root': [
  307. (r'^(?=\s|/|<!--)', Text, 'slashstartsregex'),
  308. include('commentsandwhitespace'),
  309. # keywords for optional word and field types
  310. (r'(?<=: )opt', Operator.Word),
  311. (r'(?<=\s)[\w-]*(?=(\s+"|\n))', Keyword.Declaration),
  312. # numeric literals
  313. (r'0[bB][01]+', Number.Bin),
  314. (r'0[oO]?[0-7]+', Number.Oct),
  315. (r'0[xX][0-9a-fA-F]+', Number.Hex),
  316. (r'\d+', Number.Integer),
  317. (r'(\.\d+|\d+\.\d*|\d+)([eE][-+]?\d+)?', Number.Float),
  318. # possible punctuations
  319. (r'\.\.\.|=>', Punctuation),
  320. (r'\+\+|--|~|\?\?=?|\?|:|\\(?=\n)|'
  321. r'(<<|>>>?|==?|!=?|(?:\*\*|\|\||&&|[-<>+*%&|^/]))=?', Operator, 'slashstartsregex'),
  322. (r'[{(\[;,]', Punctuation, 'slashstartsregex'),
  323. (r'[})\].]', Punctuation),
  324. # strings
  325. (r"'", String.Single, 'singlestring'),
  326. (r'"', String.Double, 'doublestring'),
  327. # title line
  328. (r'[\w-]*?(?=:\{?\n)', String.Symbol),
  329. # title line with a version code, formatted
  330. # `major.minor.patch-prerelease+buildmeta`
  331. (r'([\w-]*?)(:)(\d+)(?:(\.)(\d+)(?:(\.)(\d+)(?:(\-)((?:[^\W_]|-)*(?:\.(?:[^\W_]|-)*)*))?(?:(\+)((?:[^\W_]|-)+(?:\.(?:[^\W_]|-)+)*))?)?)?(?=:\{?\n)', bygroups(String.Symbol, Operator, Number.Integer, Operator, Number.Integer, Operator, Number.Integer, Operator, String, Operator, String)),
  332. (r'.*\n', Text),
  333. ]
  334. }