def music(cls): """Musical items.""" yield from cls.find_string(cls.list) yield from cls.find_scheme(cls.list) yield r"\{", Bracket.Start, cls.musiclist('}') yield r"<<", Bracket.Start, cls.musiclist('>>') yield r"<", Delimiter.Chord.Start, cls.chord yield r"\\\\", Separator.VoiceSeparator yield r"\|", Separator.PipeSymbol yield r"\\[\[\]]", Spanner.Ligature yield r"[\[\]]", Spanner.Beam yield r"\\[()]", Spanner.Slur.Phrasing yield r"[()]", Spanner.Slur yield r"~", Spanner.Tie yield r"\\~", Spanner.PesOrFlexa yield r"\\[<>!]", Dynamic yield r"[-_^]", Direction, cls.script yield r"(\\=)\s*(?:(\d+)|({}))?".format(RE_LILYPOND_SYMBOL), \ bygroup(Spanner.Id, Number, cls.ifpitch(Name.Symbol.Invalid, Name.Symbol)) yield RE_LILYPOND_SYMBOL, findmember(TEXT, ( ('q', Pitch), (lilypond_words.rests, Rest), (lilypond_words.all_pitch_names, (Pitch, cls.pitch)), (lilypond_words.contexts, (Context, cls.list)), (lilypond_words.grobs, (Grob, cls.list)), ), (Name.Symbol, cls.list)) yield r'[.,]', Delimiter yield r'(:)\s*(8|16|32|64|128|256|512|1024|2048)?(?!\d)', bygroup( Delimiter.Tremolo, Duration.Tremolo) yield RE_FRACTION, Number.Fraction yield r'\d+\.\d+', Number.Float yield r'(\d+)(?=\s*,)', Number, cls.list yield RE_LILYPOND_DURATION, Duration, cls.duration yield r"\d+", Number, cls.list
def common(cls, pop=0): """Yield common stuff. ``pop`` can be set to -1 for one-arg mode.""" yield r"['`]|,@?", Delimiter.Scheme.Quote yield r"\(", Delimiter.OpenParen, pop, cls.list yield r"#\(", Delimiter.OpenVector, pop, cls.vector yield r'"', String, pop, cls.string yield r';', Comment, pop, cls.singleline_comment yield r'#!', Comment, pop, cls.multiline_comment yield r"#[tTfF]\b", Number.Boolean, pop yield r"#\\([a-z]+|.)", Character, pop yield RE_SCHEME_ID, cls.get_word_action(), pop _g = lambda action: bygroup(Number.Prefix, action, skip, Number.Prefix) yield r'(#[eEiI])?(#([bBoOxXdD]))(#[eEiI])?', findmember( MATCH[3], (('bB', (_g(Number.Prefix.Binary), pop, cls.number(2))), ('oO', (_g(Number.Prefix.Octal), pop, cls.number(8))), ('xX', (_g(Number.Prefix.Hexadecimal), pop, cls.number(16)))), (_g(Number.Prefix.Decimal), pop, cls.number)) yield r'#[eEiI]', Number.Prefix, pop, cls.number yield r'[-+]inf.0', Number.Infinity, pop, cls.number yield r'[-+]nan.0', Number.NaN, pop, cls.number yield r'[-+]', Operator.Sign, pop, cls.number yield r'(\.?)(\d+)', bygroup(Number.Dot, Number.Decimal), pop, cls.number if pop == 0: yield r"\.(?!\S)", Delimiter.Dot
def root(cls): yield r'\A#!.*?$', Comment.Special yield from cls.values() yield r"([^\s\\{}[\]$'();]+)(\()?", bygroup( findmember(MATCH[1], ((operators, Operator), (tcl_commands, Keyword), (tk_commands, Name.Command)), Text.Word), Delimiter), ifgroup(2, cls.index) yield r'\(\)', Delimiter
def common(cls): yield r'#', Comment, cls.comment yield fr'({_N_})(\s*)', bygroup(Escape, Whitespace) yield r'\[', Delimiter, cls.list yield r'\(', Delimiter, cls.tuple yield r'\{', Delimiter, cls.dict ## string literals yield from cls.find_string_literals() yield from cls.find_bytes_literals() ## numerical values yield '0[oO](?:_?[0-7])+', Number.Octal yield '0[bB](?:_?[01])+', Number.Binary yield '0[xX](?:_?[0-9a-fA-F])+', Number.Hexadecimal yield r'(?:\.\d(?:_?\d)*|\d(?:_?\d)*(?:\.(?:\d(?:_?\d)*)?)?)(?:[eE][-+]\d(?:_?\d)*)?[jJ]?', Number ## keywords, variables, functions yield words(python_words.keywords, prefix=r'\b', suffix=r'\b'), Keyword yield words(python_words.constants, prefix=r'\b', suffix=r'\b'), Name.Constant yield fr'\b(self|cls)\b(?:{_SN_}*([\[\(]))?', Name.Variable.Special, \ dselect(MATCH[2], {'(': cls.call, '[': cls.item}) # method, class or attribute (keywords after a . are also caught) yield fr'(\.){_SN_}*\b({_I_})\b(?:{_SN_}*([\[\(]))?', \ bygroup( Delimiter, ifmember(MATCH[2], python_words.keywords, Keyword, dselect(MATCH[3], {'(': select(call(isclassname, TEXT), Name.Method, Name.Class)}, select(call(str.isupper, TEXT), select(call(isclassname, TEXT), Name.Attribute, Name.Class), Name.Constant))), Delimiter), \ dselect(MATCH[3], {'(': cls.call, '[': cls.item}) # function, class or variable yield fr'\b({_I_})\b(?:{_SN_}*([\[\(]))?', \ bygroup( findmember(MATCH[1], ((python_words.builtins, Name.Builtin), (python_words.exceptions, Name.Exception)), select(call(str.isupper, TEXT), select(call(isclassname, TEXT), dselect(MATCH[2], {'(': Name.Function}, Name.Variable), Name.Class), Name.Constant)), Delimiter), \ dselect(MATCH[2], {'(': cls.call, '[': cls.item}) ## delimiters, operators yield r'\.\.\.', Delimiter.Special.Ellipsis yield r'(?:\*\*|//|<<|>>|[-+*/%@&|^:])?=', Operator.Assignment yield r'\*\*|//|<<|>>|[<>=!]=|[-+*/%@&|^~<>]', Operator yield r'[.;,:]', Delimiter
def drumlist(cls): """Drum music between ``{`` ... ``}`` or ``<<`` ... ``>>``.""" yield from cls.inputmode_list(cls.drumlist) yield RE_LILYPOND_SYMBOL, findmember( TEXT, ((lilypond_words.rests, Rest), (lilypond_words.drum_pitch_names, Pitch.Drum), (lilypond_words.contexts, (Context, cls.list)), (lilypond_words.grobs, (Grob, cls.list))), (Name.Symbol, cls.list)) yield from cls.music() yield from cls.common() yield from cls.commands()
def layout_context(cls): r"""Contents of ``\layout`` or ``\midi { \context { } }`` or ``\with. { }``.""" yield r'\}', Bracket.End, -1 yield RE_LILYPOND_SYMBOL, findmember(TEXT, ( (lilypond_words.rests, Rest), (lilypond_words.all_pitch_names, (Pitch, cls.pitch)), (lilypond_words.contexts, (Context, cls.list)), (lilypond_words.grobs, (Grob, cls.list)), ), (Name.Variable, cls.list)) yield from cls.music() yield from cls.common() yield from cls.commands(list_target=cls.start_list)
def root(cls): """Toplevel LilyPond document.""" yield from cls.blocks() yield RE_LILYPOND_SYMBOL, findmember(TEXT, ( (lilypond_words.rests, Rest), (lilypond_words.all_pitch_names, (Pitch, cls.pitch)), (lilypond_words.contexts, (Context, cls.list)), (lilypond_words.grobs, (Grob, cls.list)), ), (Name.Variable.Definition, cls.list)) yield from cls.find_string(cls.list) yield from cls.music() yield from cls.common() yield from cls.commands(list_target=cls.start_list)
def commands(cls, *, list_target=0): """Yield commands that can occur in all input modes. If a ``list_target`` is given, that lexicon is pushed after a Keyword, to be able to parse symbols, strings, numbers or scheme. This makes sense in e.g. lyrics mode. """ yield r"(\\with)\s*(\{)", bygroup(Keyword, Bracket.Start), cls.layout_context yield r'(' + RE_LILYPOND_COMMAND + r')(?=\s*(\.))?', ifgroup( 3, # part of a \bla.bla or \bla.1 construct, always a user command (Name.Variable, cls.identifier_ref), # no "." or "," , can be a builtin dselect( MATCH[2], { # input modes "lyricsto": (Keyword.Lyric, cls.lyricsto, cls.start_list), "addlyrics": (Keyword.Lyric, cls.lyricmode), "lyrics": (Keyword.Lyric, cls.lyricmode), "lyricmode": (Keyword.Lyric, cls.lyricmode), "chords": (Keyword, cls.chordmode), "chordmode": (Keyword, cls.chordmode), "drums": (Keyword, cls.drummode), "drummode": (Keyword, cls.drummode), "figures": (Keyword, cls.figuremode), "figuremode": (Keyword, cls.figuremode), "notemode": (Keyword, cls.notemode), # \notes doesn't exist anymore # commands that expect some symbols in all input modes "repeat": (Name.Builtin, cls.repeat), }, (findmember(MATCH[2], ( (lilypond_words.keywords, (Keyword, list_target)), (lilypond_words.all_articulations, Articulation), (lilypond_words.dynamics, Dynamic), (lilypond_words.units, Name.Builtin.Unit), (lilypond_words.music_commands, Name.Builtin), (lilypond_words.contexts, Name.Builtin.Context), (lilypond_words.modes, Name.Type), ), (Name.Variable, cls.identifier_ref))))) # seldom used, but nevertheless allowed in LilyPond: \"blabla" yield r'(\\)(?=")', Name.Variable, cls.identifier_ref
def get_symbol_action(self, text, default=Name.Symbol): """Return a proper dynamic action for the name of a symbol.""" return findmember(text, ( (lilypond_words.grobs, Grob), (lilypond_words.contexts, Context), ), default)