Skip to content

Commit

Permalink
Add a lexer for Schemas for Minecraft Add-ons and 4 examples, merging…
Browse files Browse the repository at this point in the history
… lexers (#2276)
  • Loading branch information
MiemieMethod committed Nov 29, 2022
1 parent 0411c43 commit 7e2ae04
Show file tree
Hide file tree
Showing 10 changed files with 4,117 additions and 11 deletions.
5 changes: 3 additions & 2 deletions pygments/lexers/_mapping.py
Expand Up @@ -275,7 +275,8 @@
'LogosLexer': ('pygments.lexers.objective', 'Logos', ('logos',), ('*.x', '*.xi', '*.xm', '*.xmi'), ('text/x-logos',)),
'LogtalkLexer': ('pygments.lexers.prolog', 'Logtalk', ('logtalk',), ('*.lgt', '*.logtalk'), ('text/x-logtalk',)),
'LuaLexer': ('pygments.lexers.scripting', 'Lua', ('lua',), ('*.lua', '*.wlua'), ('text/x-lua', 'application/x-lua')),
'MCFunctionLexer': ('pygments.lexers.mcfunction', 'MCFunction', ('mcfunction', 'mcf'), ('*.mcfunction',), ('text/mcfunction',)),
'MCFunctionLexer': ('pygments.lexers.minecraft', 'MCFunction', ('mcfunction', 'mcf'), ('*.mcfunction',), ('text/mcfunction',)),
'MCSchemaLexer': ('pygments.lexers.minecraft', 'MCSchema', ('mcschema',), ('*.mcschema',), ('text/mcschema',)),
'MIMELexer': ('pygments.lexers.mime', 'MIME', ('mime',), (), ('multipart/mixed', 'multipart/related', 'multipart/alternative')),
'MIPSLexer': ('pygments.lexers.mips', 'MIPS', ('mips',), ('*.mips', '*.MIPS'), ()),
'MOOCodeLexer': ('pygments.lexers.scripting', 'MOOCode', ('moocode', 'moo'), ('*.moo',), ('text/x-moocode',)),
Expand Down Expand Up @@ -428,7 +429,7 @@
'SASLexer': ('pygments.lexers.sas', 'SAS', ('sas',), ('*.SAS', '*.sas'), ('text/x-sas', 'text/sas', 'application/x-sas')),
'SLexer': ('pygments.lexers.r', 'S', ('splus', 's', 'r'), ('*.S', '*.R', '.Rhistory', '.Rprofile', '.Renviron'), ('text/S-plus', 'text/S', 'text/x-r-source', 'text/x-r', 'text/x-R', 'text/x-r-history', 'text/x-r-profile')),
'SMLLexer': ('pygments.lexers.ml', 'Standard ML', ('sml',), ('*.sml', '*.sig', '*.fun'), ('text/x-standardml', 'application/x-standardml')),
'SNBTLexer': ('pygments.lexers.mcfunction', 'SNBT', ('snbt',), ('*.snbt',), ('text/snbt',)),
'SNBTLexer': ('pygments.lexers.minecraft', 'SNBT', ('snbt',), ('*.snbt',), ('text/snbt',)),
'SarlLexer': ('pygments.lexers.jvm', 'SARL', ('sarl',), ('*.sarl',), ('text/x-sarl',)),
'SassLexer': ('pygments.lexers.css', 'Sass', ('sass',), ('*.sass',), ('text/x-sass',)),
'SaviLexer': ('pygments.lexers.savi', 'Savi', ('savi',), ('*.savi',), ()),
Expand Down
104 changes: 95 additions & 9 deletions pygments/lexers/mcfunction.py → pygments/lexers/minecraft.py
@@ -1,8 +1,19 @@
"""
pygments.lexers.mcfunction
~~~~~~~~~~~~~~~~~~~~~~~~~~
Lexers for MCFunction and related languages.
pygments.lexers.minecraft
~~~~~~~~~~~~~~~~~~~~~~~~~
Lexers for Minecraft related languages.
SNBT. A data communication format used in Minecraft.
wiki: https://minecraft.fandom.com/wiki/NBT_format
MCFunction. The Function file for Minecraft Data packs and Add-ons.
official: https://learn.microsoft.com/en-us/minecraft/creator/documents/functionsintroduction
wiki: https://minecraft.fandom.com/wiki/Function
MCSchema. A kind of data Schema for Minecraft Add-on Development.
official: https://learn.microsoft.com/en-us/minecraft/creator/reference/content/schemasreference/
community example: https://www.mcbe-dev.net/addons/data-driven/manifest.html
:copyright: Copyright 2006-2022 by the Pygments team, see AUTHORS.
:license: BSD, see LICENSE for details.
Expand All @@ -12,13 +23,13 @@
from pygments.token import Comment, Keyword, Literal, Name, Number, Operator, \
Punctuation, String, Text, Whitespace

__all__ = ['SNBTLexer', 'MCFunctionLexer']
__all__ = ['SNBTLexer', 'MCFunctionLexer', 'MCSchemaLexer']


class SNBTLexer(RegexLexer):
"""Lexer for stringified NBT, a data format used in Minecraft
.. versionadded:: 2.12
.. versionadded:: 2.12.0
"""

name = "SNBT"
Expand Down Expand Up @@ -127,8 +138,8 @@ class MCFunctionLexer(RegexLexer):
include("resource-name"),
# normal command names and scoreboards
# there's no way to know the differences unfortuntely
(r"[A-Za-z_][A-Za-z0-9_.#%$]+", Keyword.Constant),
(r"[#%$][A-Za-z0-9_.#%$]+", Name.Variable.Magic),
(r"[A-Za-z_][\w.#%$]+", Keyword.Constant),
(r"[#%$][\w.#%$]+", Name.Variable.Magic),
],

"resource-name": [
Expand Down Expand Up @@ -173,7 +184,7 @@ class MCFunctionLexer(RegexLexer):
include("resource-name"),

# Scoreboard player names
(r"[#%$][A-Za-z0-9_.#%$]+", Name.Variable.Magic),
(r"[#%$][\w.#%$]+", Name.Variable.Magic),
],

"operators": [
Expand Down Expand Up @@ -306,3 +317,78 @@ class MCFunctionLexer(RegexLexer):
default("#pop"),
],
}


class MCSchemaLexer(RegexLexer):
"""Lexer for Minecraft Add-ons data Schemas, an interface structure standard used in Minecraft
.. versionadded:: 2.14.0
"""

name = 'MCSchema'
url = 'https://learn.microsoft.com/en-us/minecraft/creator/reference/content/schemasreference/'
aliases = ['mcschema']
filenames = ['*.mcschema']
mimetypes = ['text/mcschema']

tokens = {
'commentsandwhitespace': [
(r'\s+', Whitespace),
(r'//.*?$', Comment.Single),
(r'/\*.*?\*/', Comment.Multiline)
],
'slashstartsregex': [
include('commentsandwhitespace'),
(r'/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/'
r'([gimuysd]+\b|\B)', String.Regex, '#pop'),
(r'(?=/)', Text, ('#pop', 'badregex')),
default('#pop')
],
'badregex': [
(r'\n', Whitespace, '#pop')
],
'singlestring': [
(r'\\.', String.Escape),
(r"'", String.Single, '#pop'),
(r"[^\\']+", String.Single),
],
'doublestring': [
(r'\\.', String.Escape),
(r'"', String.Double, '#pop'),
(r'[^\\"]+', String.Double),
],
'root': [
(r'^(?=\s|/|<!--)', Text, 'slashstartsregex'),
include('commentsandwhitespace'),

# keywords for optional word and field types
(r'(?<=: )opt', Operator.Word),
(r'(?<=\s)[\w-]*(?=(\s+"|\n))', Keyword.Declaration),

# numeric literals
(r'0[bB][01]+', Number.Bin),
(r'0[oO]?[0-7]+', Number.Oct),
(r'0[xX][0-9a-fA-F]+', Number.Hex),
(r'\d+', Number.Integer),
(r'(\.\d+|\d+\.\d*|\d+)([eE][-+]?\d+)?', Number.Float),

# possible punctuations
(r'\.\.\.|=>', Punctuation),
(r'\+\+|--|~|\?\?=?|\?|:|\\(?=\n)|'
r'(<<|>>>?|==?|!=?|(?:\*\*|\|\||&&|[-<>+*%&|^/]))=?', Operator, 'slashstartsregex'),
(r'[{(\[;,]', Punctuation, 'slashstartsregex'),
(r'[})\].]', Punctuation),

# strings
(r"'", String.Single, 'singlestring'),
(r'"', String.Double, 'doublestring'),

# title line
(r'[\w-]*?(?=:\{?\n)', String.Symbol),
# title line with a version code, formatted
# `major.minor.patch-prerelease+buildmeta`
(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)),

(r'.*\n', Text),
]
}
145 changes: 145 additions & 0 deletions tests/examplefiles/mcschema/actor_animation.mcschema
@@ -0,0 +1,145 @@
actor_animation:1.8.0:{
version "format_version"
object "animations"
{
object "animation.<identifier>"
{
bool "loop" : opt // should this animation stop, loop, or stay on the last frame when finished (true, false, "hold_on_last_frame"
string "loop"<"hold_on_last_frame"> : opt // should this animation stop, loop, or stay on the last frame when finished (true, false, "hold_on_last_frame"
molang "start_delay" : opt // How long to wait in seconds before playing this animation. Note that this expression is evaluated once before playing, and only re-evaluated if asked to play from the beginning again. A looping animation should use 'loop_delay' if it wants a delay between loops.
molang "loop_delay" : opt // How long to wait in seconds before looping this animation. Note that this expression is evaluated after each loop and on looping animation only.
molang "anim_time_update" : opt // how does time pass when playing the animation. Defaults to "query.anim_time + query.delta_time" which means advance in seconds.
molang "blend_weight" : opt
bool "override_previous_animation" : opt // reset bones in this animation to the default pose before applying this animation
object "bones" : opt
{
object "<identifier>"
{
object "relative_to" : opt
{
string "rotation"<"entity"> : opt // if set, makes the bone rotation relative to the entity instead of the bone's parent
}
molang "position" : opt
array "position" : opt
{
molang "<any array element>"
}
object "position" : opt
{
array "<time_stamp>"[3]
{
molang "<any array element>"
}
object "<time_stamp>"
{
enumerated_value "lerp_mode"<"linear", "catmullrom"> : opt
array "pre"[3] : opt
{
molang "<any array element>"
}
array "post"[3] : opt
{
molang "<any array element>"
}
}
}
molang "rotation" : opt
array "rotation" : opt
{
molang "<any array element>"
object "<any array element>"
{
molang "[xyz]"
}
}
object "rotation" : opt
{
array "<time_stamp>"[3]
{
molang "<any array element>"
}
object "<time_stamp>"
{
enumerated_value "lerp_mode"<"linear", "catmullrom"> : opt
array "pre"[3] : opt
{
molang "<any array element>"
}
array "post"[3] : opt
{
molang "<any array element>"
}
}
}
molang "scale" : opt
array "scale" : opt
{
molang "<any array element>"
}
object "scale" : opt
{
array "<time_stamp>"[3]
{
molang "<any array element>"
}
object "<time_stamp>"
{
enumerated_value "lerp_mode"<"linear", "catmullrom"> : opt
array "pre"[3] : opt
{
molang "<any array element>"
}
array "post"[3] : opt
{
molang "<any array element>"
}
}
}
}
}
object "particle_effects" : opt
{
object "<time_stamp>" : opt
{
string "effect" // The name of a particle effect that should be played
string "locator" : opt // The name of a locator on the actor where the effect should be located
molang "pre_effect_script" : opt // A Molang script that will be run when the particle emitter is initialized
bool "bind_to_actor" : opt // Set to false to have the effect spawned in the world without being bound to an actor (by default an effect is bound to the actor).
}
array "<time_stamp>" : opt
{
object "<any array element>" : opt
{
string "effect" // The name of a particle effect that should be played
string "locator" : opt // The name of a locator on the actor where the effect should be located
molang "pre_effect_script" : opt // A Molang script that will be run when the particle emitter is initialized
bool "bind_to_actor" : opt // Set to false to have the effect spawned in the world without being bound to an actor (by default an effect is bound to the actor).
}
}
}
object "sound_effects" : opt // sound effects to trigger as this animation plays, keyed by time
{
object "<time_stamp>" : opt
{
string "effect" // Valid sound effect names should be listed in the entity's resource_definition json file.
}
array "<time_stamp>" : opt
{
object "<any array element>" : opt
{
string "effect" // Valid sound effect names should be listed in the entity's resource_definition json file.
}
}
}
object "timeline" : opt
{
string "<time_stamp>" : opt
array "<time_stamp>" : opt
{
string "<any array element>" : opt
}
}
float "animation_length" : opt // override calculated value (set as the max keyframe or event time) and set animation length in seconds.
}
}
}

0 comments on commit 7e2ae04

Please sign in to comment.