Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
lilypond.py226 linesDownload Raw Back to lexers
1"""2    pygments.lexers.lilypond3    ~~~~~~~~~~~~~~~~~~~~~~~~4 5    Lexer for LilyPond.6 7    :copyright: Copyright 2006-present by the Pygments team, see AUTHORS.8    :license: BSD, see LICENSE for details.9"""10 11import re12 13from pygments.lexer import bygroups, default, inherit, words14from pygments.lexers.lisp import SchemeLexer15from pygments.lexers._lilypond_builtins import (16    keywords, pitch_language_names, clefs, scales, repeat_types, units,17    chord_modifiers, pitches, music_functions, dynamics, articulations,18    music_commands, markup_commands, grobs, translators, contexts,19    context_properties, grob_properties, scheme_functions, paper_variables,20    header_variables21)22from pygments.token import Token23 24__all__ = ["LilyPondLexer"]25 26# In LilyPond, (unquoted) name tokens only contain letters, hyphens,27# and underscores, where hyphens and underscores must not start or end28# a name token.29#30# Note that many of the entities listed as LilyPond built-in keywords31# (in file `_lilypond_builtins.py`) are only valid if surrounded by32# double quotes, for example, 'hufnagel-fa1'. This means that33# `NAME_END_RE` doesn't apply to such entities in valid LilyPond code.34NAME_END_RE = r"(?=\d|[^\w\-]|[\-_][\W\d])"35 36def builtin_words(names, backslash, suffix=NAME_END_RE):37    prefix = r"[\-_^]?"38    if backslash == "mandatory":39        prefix += r"\\"40    elif backslash == "optional":41        prefix += r"\\?"42    else:43        assert backslash == "disallowed"44    return words(names, prefix, suffix)45 46 47class LilyPondLexer(SchemeLexer):48    """49    Lexer for input to LilyPond, a text-based music typesetter.50 51    .. important::52 53       This lexer is meant to be used in conjunction with the ``lilypond`` style.54    """55    name = 'LilyPond'56    url = 'https://lilypond.org'57    aliases = ['lilypond']58    filenames = ['*.ly']59    mimetypes = []60    version_added = '2.11'61 62    flags = re.DOTALL | re.MULTILINE63 64    # Because parsing LilyPond input is very tricky (and in fact65    # impossible without executing LilyPond when there is Scheme66    # code in the file), this lexer does not try to recognize67    # lexical modes. Instead, it catches the most frequent pieces68    # of syntax, and, above all, knows about many kinds of builtins.69 70    # In order to parse embedded Scheme, this lexer subclasses the SchemeLexer.71    # It redefines the 'root' state entirely, and adds a rule for #{ #}72    # to the 'value' state. The latter is used to parse a Scheme expression73    # after #.74 75    def get_tokens_unprocessed(self, text):76        """Highlight Scheme variables as LilyPond builtins when applicable."""77        for index, token, value in super().get_tokens_unprocessed(text):78            if token is Token.Name.Function or token is Token.Name.Variable:79                if value in scheme_functions:80                    token = Token.Name.Builtin.SchemeFunction81            elif token is Token.Name.Builtin:82                token = Token.Name.Builtin.SchemeBuiltin83            yield index, token, value84 85    tokens = {86        "root": [87            # Whitespace.88            (r"\s+", Token.Text.Whitespace),89 90            # Multi-line comments. These are non-nestable.91            (r"%\{.*?%\}", Token.Comment.Multiline),92 93            # Simple comments.94            (r"%.*?$", Token.Comment.Single),95 96            # End of embedded LilyPond in Scheme.97            (r"#\}", Token.Punctuation, "#pop"),98 99            # Embedded Scheme, starting with # ("delayed"),100            # or $ (immediate). #@ and and $@ are the lesser known101            # "list splicing operators".102            (r"[#$]@?", Token.Punctuation, "value"),103 104            # Any kind of punctuation:105            # - sequential music: { },106            # - parallel music: << >>,107            # - voice separator: << \\ >>,108            # - chord: < >,109            # - bar check: |,110            # - dot in nested properties: \revert NoteHead.color,111            # - equals sign in assignments and lists for various commands:112            #   \override Stem.color = red,113            # - comma as alternative syntax for lists: \time 3,3,2 4/4,114            # - colon in tremolos: c:32,115            # - double hyphen and underscore in lyrics: li -- ly -- pond __116            #   (which must be preceded by ASCII whitespace)117            (r"""(?x)118               \\\\119               | (?<= \s ) (?: -- | __ )120               | [{}<>=.,:|]121              """, Token.Punctuation),122 123            # Pitches, with optional octavation marks, octave check,124            # and forced or cautionary accidental.125            (words(pitches, suffix=r"=?[',]*!?\??" + NAME_END_RE), Token.Pitch),126 127            # Strings, optionally with direction specifier.128            (r'[\-_^]?"', Token.String, "string"),129 130            # Numbers.131            (r"-?\d+\.\d+", Token.Number.Float), # 5. and .5 are not allowed132            (r"-?\d+/\d+", Token.Number.Fraction),133            # Integers, or durations with optional augmentation dots.134            # We have no way to distinguish these, so we highlight135            # them all as numbers.136            #137            # Normally, there is a space before the integer (being an138            # argument to a music function), which we check here.  The139            # case without a space is handled below (as a fingering140            # number).141            (r"""(?x)142               (?<= \s ) -\d+143               | (?: (?: \d+ | \\breve | \\longa | \\maxima )144                     \.* )145              """, Token.Number),146            # Separates duration and duration multiplier highlighted as fraction.147            (r"\*", Token.Number),148 149            # Ties, slurs, manual beams.150            (r"[~()[\]]", Token.Name.Builtin.Articulation),151 152            # Predefined articulation shortcuts. A direction specifier is153            # required here.154            (r"[\-_^][>^_!.\-+]", Token.Name.Builtin.Articulation),155 156            # Fingering numbers, string numbers.157            (r"[\-_^]?\\?\d+", Token.Name.Builtin.Articulation),158 159            # Builtins.160            (builtin_words(keywords, "mandatory"), Token.Keyword),161            (builtin_words(pitch_language_names, "disallowed"), Token.Name.PitchLanguage),162            (builtin_words(clefs, "disallowed"), Token.Name.Builtin.Clef),163            (builtin_words(scales, "mandatory"), Token.Name.Builtin.Scale),164            (builtin_words(repeat_types, "disallowed"), Token.Name.Builtin.RepeatType),165            (builtin_words(units, "mandatory"), Token.Number),166            (builtin_words(chord_modifiers, "disallowed"), Token.ChordModifier),167            (builtin_words(music_functions, "mandatory"), Token.Name.Builtin.MusicFunction),168            (builtin_words(dynamics, "mandatory"), Token.Name.Builtin.Dynamic),169            # Those like slurs that don't take a backslash are covered above.170            (builtin_words(articulations, "mandatory"), Token.Name.Builtin.Articulation),171            (builtin_words(music_commands, "mandatory"), Token.Name.Builtin.MusicCommand),172            (builtin_words(markup_commands, "mandatory"), Token.Name.Builtin.MarkupCommand),173            (builtin_words(grobs, "disallowed"), Token.Name.Builtin.Grob),174            (builtin_words(translators, "disallowed"), Token.Name.Builtin.Translator),175            # Optional backslash because of \layout { \context { \Score ... } }.176            (builtin_words(contexts, "optional"), Token.Name.Builtin.Context),177            (builtin_words(context_properties, "disallowed"), Token.Name.Builtin.ContextProperty),178            (builtin_words(grob_properties, "disallowed"),179             Token.Name.Builtin.GrobProperty,180             "maybe-subproperties"),181            # Optional backslashes here because output definitions are wrappers182            # around modules.  Concretely, you can do, e.g.,183            # \paper { oddHeaderMarkup = \evenHeaderMarkup }184            (builtin_words(paper_variables, "optional"), Token.Name.Builtin.PaperVariable),185            (builtin_words(header_variables, "optional"), Token.Name.Builtin.HeaderVariable),186 187            # Other backslashed-escaped names (like dereferencing a188            # music variable), possibly with a direction specifier.189            (r"[\-_^]?\\.+?" + NAME_END_RE, Token.Name.BackslashReference),190 191            # Definition of a variable. Support assignments to alist keys192            # (myAlist.my-key.my-nested-key = \markup \spam \eggs).193            (r"""(?x)194               (?: [^\W\d] | - )+195               (?= (?: [^\W\d] | [\-.] )* \s* = )196              """, Token.Name.Lvalue),197 198            # Virtually everything can appear in markup mode, so we highlight199            # as text.  Try to get a complete word, or we might wrongly lex200            # a suffix that happens to be a builtin as a builtin (e.g., "myStaff").201            (r"([^\W\d]|-)+?" + NAME_END_RE, Token.Text),202            (r".", Token.Text),203        ],204        "string": [205            (r'"', Token.String, "#pop"),206            (r'\\.', Token.String.Escape),207            (r'[^\\"]+', Token.String),208        ],209        "value": [210            # Scan a LilyPond value, then pop back since we had a211            # complete expression.212            (r"#\{", Token.Punctuation, ("#pop", "root")),213            inherit,214        ],215        # Grob subproperties are undeclared and it would be tedious216        # to maintain them by hand. Instead, this state allows recognizing217        # everything that looks like a-known-property.foo.bar-baz as218        # one single property name.219        "maybe-subproperties": [220            (r"\s+", Token.Text.Whitespace),221            (r"(\.)((?:[^\W\d]|-)+?)" + NAME_END_RE,222             bygroups(Token.Punctuation, Token.Name.Builtin.GrobProperty)),223            default("#pop"),224        ]225    }226 
codekingpro/portable-devtools · Team Ai