|
""" |
|
pygments.lexers.lilypond |
|
~~~~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
Lexer for LilyPond. |
|
|
|
:copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS. |
|
:license: BSD, see LICENSE for details. |
|
""" |
|
|
|
import re |
|
|
|
from pygments.lexer import bygroups, default, inherit, words |
|
from pygments.lexers.lisp import SchemeLexer |
|
from pygments.lexers._lilypond_builtins import ( |
|
keywords, pitch_language_names, clefs, scales, repeat_types, units, |
|
chord_modifiers, pitches, music_functions, dynamics, articulations, |
|
music_commands, markup_commands, grobs, translators, contexts, |
|
context_properties, grob_properties, scheme_functions, paper_variables, |
|
header_variables |
|
) |
|
from pygments.token import Token |
|
|
|
__all__ = ["LilyPondLexer"] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NAME_END_RE = r"(?=\d|[^\w\-]|[\-_][\W\d])" |
|
|
|
def builtin_words(names, backslash, suffix=NAME_END_RE): |
|
prefix = r"[\-_^]?" |
|
if backslash == "mandatory": |
|
prefix += r"\\" |
|
elif backslash == "optional": |
|
prefix += r"\\?" |
|
else: |
|
assert backslash == "disallowed" |
|
return words(names, prefix, suffix) |
|
|
|
|
|
class LilyPondLexer(SchemeLexer): |
|
""" |
|
Lexer for input to LilyPond, a text-based music typesetter. |
|
|
|
.. important:: |
|
|
|
This lexer is meant to be used in conjunction with the ``lilypond`` style. |
|
""" |
|
name = 'LilyPond' |
|
url = 'https://lilypond.org' |
|
aliases = ['lilypond'] |
|
filenames = ['*.ly'] |
|
mimetypes = [] |
|
version_added = '2.11' |
|
|
|
flags = re.DOTALL | re.MULTILINE |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_tokens_unprocessed(self, text): |
|
"""Highlight Scheme variables as LilyPond builtins when applicable.""" |
|
for index, token, value in super().get_tokens_unprocessed(text): |
|
if token is Token.Name.Function or token is Token.Name.Variable: |
|
if value in scheme_functions: |
|
token = Token.Name.Builtin.SchemeFunction |
|
elif token is Token.Name.Builtin: |
|
token = Token.Name.Builtin.SchemeBuiltin |
|
yield index, token, value |
|
|
|
tokens = { |
|
"root": [ |
|
|
|
(r"\s+", Token.Text.Whitespace), |
|
|
|
|
|
(r"%\{.*?%\}", Token.Comment.Multiline), |
|
|
|
|
|
(r"%.*?$", Token.Comment.Single), |
|
|
|
|
|
(r"#\}", Token.Punctuation, "#pop"), |
|
|
|
|
|
|
|
|
|
(r"[#$]@?", Token.Punctuation, "value"), |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(r"""(?x) |
|
\\\\ |
|
| (?<= \s ) (?: -- | __ ) |
|
| [{}<>=.,:|] |
|
""", Token.Punctuation), |
|
|
|
|
|
|
|
(words(pitches, suffix=r"=?[',]*!?\??" + NAME_END_RE), Token.Pitch), |
|
|
|
|
|
(r'[\-_^]?"', Token.String, "string"), |
|
|
|
|
|
(r"-?\d+\.\d+", Token.Number.Float), |
|
(r"-?\d+/\d+", Token.Number.Fraction), |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(r"""(?x) |
|
(?<= \s ) -\d+ |
|
| (?: (?: \d+ | \\breve | \\longa | \\maxima ) |
|
\.* ) |
|
""", Token.Number), |
|
|
|
(r"\*", Token.Number), |
|
|
|
|
|
(r"[~()[\]]", Token.Name.Builtin.Articulation), |
|
|
|
|
|
|
|
(r"[\-_^][>^_!.\-+]", Token.Name.Builtin.Articulation), |
|
|
|
|
|
(r"[\-_^]?\\?\d+", Token.Name.Builtin.Articulation), |
|
|
|
|
|
(builtin_words(keywords, "mandatory"), Token.Keyword), |
|
(builtin_words(pitch_language_names, "disallowed"), Token.Name.PitchLanguage), |
|
(builtin_words(clefs, "disallowed"), Token.Name.Builtin.Clef), |
|
(builtin_words(scales, "mandatory"), Token.Name.Builtin.Scale), |
|
(builtin_words(repeat_types, "disallowed"), Token.Name.Builtin.RepeatType), |
|
(builtin_words(units, "mandatory"), Token.Number), |
|
(builtin_words(chord_modifiers, "disallowed"), Token.ChordModifier), |
|
(builtin_words(music_functions, "mandatory"), Token.Name.Builtin.MusicFunction), |
|
(builtin_words(dynamics, "mandatory"), Token.Name.Builtin.Dynamic), |
|
|
|
(builtin_words(articulations, "mandatory"), Token.Name.Builtin.Articulation), |
|
(builtin_words(music_commands, "mandatory"), Token.Name.Builtin.MusicCommand), |
|
(builtin_words(markup_commands, "mandatory"), Token.Name.Builtin.MarkupCommand), |
|
(builtin_words(grobs, "disallowed"), Token.Name.Builtin.Grob), |
|
(builtin_words(translators, "disallowed"), Token.Name.Builtin.Translator), |
|
|
|
(builtin_words(contexts, "optional"), Token.Name.Builtin.Context), |
|
(builtin_words(context_properties, "disallowed"), Token.Name.Builtin.ContextProperty), |
|
(builtin_words(grob_properties, "disallowed"), |
|
Token.Name.Builtin.GrobProperty, |
|
"maybe-subproperties"), |
|
|
|
|
|
|
|
(builtin_words(paper_variables, "optional"), Token.Name.Builtin.PaperVariable), |
|
(builtin_words(header_variables, "optional"), Token.Name.Builtin.HeaderVariable), |
|
|
|
|
|
|
|
(r"[\-_^]?\\.+?" + NAME_END_RE, Token.Name.BackslashReference), |
|
|
|
|
|
|
|
(r"""(?x) |
|
(?: [^\W\d] | - )+ |
|
(?= (?: [^\W\d] | [\-.] )* \s* = ) |
|
""", Token.Name.Lvalue), |
|
|
|
|
|
|
|
|
|
(r"([^\W\d]|-)+?" + NAME_END_RE, Token.Text), |
|
(r".", Token.Text), |
|
], |
|
"string": [ |
|
(r'"', Token.String, "#pop"), |
|
(r'\\.', Token.String.Escape), |
|
(r'[^\\"]+', Token.String), |
|
], |
|
"value": [ |
|
|
|
|
|
(r"#\{", Token.Punctuation, ("#pop", "root")), |
|
inherit, |
|
], |
|
|
|
|
|
|
|
|
|
"maybe-subproperties": [ |
|
(r"\s+", Token.Text.Whitespace), |
|
(r"(\.)((?:[^\W\d]|-)+?)" + NAME_END_RE, |
|
bygroups(Token.Punctuation, Token.Name.Builtin.GrobProperty)), |
|
default("#pop"), |
|
] |
|
} |
|
|