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