Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LilyPond: slightly improve lexing #2283

Merged
merged 1 commit into from Nov 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
48 changes: 37 additions & 11 deletions pygments/lexers/lilypond.py
Expand Up @@ -23,6 +23,14 @@

__all__ = ["LilyPondLexer"]

# In LilyPond, (unquoted) name tokens only contain letters, hyphens,
# and underscores, where hyphens and underscores must not start or end
# a name token.
#
# Note that many of the entities listed as LilyPond built-in keywords
# (in file `_lilypond_builtins.py`) are only valid if surrounded by
# double quotes, for example, 'hufnagel-fa1'. This means that
# `NAME_END_RE` doesn't apply to such entities in valid LilyPond code.
NAME_END_RE = r"(?=\d|[^\w\-]|[\-_][\W\d])"

def builtin_words(names, backslash, suffix=NAME_END_RE):
Expand Down Expand Up @@ -80,10 +88,10 @@ def get_tokens_unprocessed(self, text):
# Whitespace.
(r"\s+", Token.Text.Whitespace),

# Multi-line comment. These are non-nestable.
# Multi-line comments. These are non-nestable.
(r"%\{.*?%\}", Token.Comment.Multiline),

# Simple comment.
# Simple comments.
(r"%.*?$", Token.Comment.Single),

# End of embedded LilyPond in Scheme.
Expand All @@ -105,22 +113,37 @@ def get_tokens_unprocessed(self, text):
# \override Stem.color = red,
# - comma as alternative syntax for lists: \time 3,3,2 4/4,
# - colon in tremolos: c:32,
# - double hyphen in lyrics: li -- ly -- pond,
(r"\\\\|--|[{}<>=.,:|]", Token.Punctuation),

# Pitch, with optional octavation marks, octave check,
# - double hyphen and underscore in lyrics: li -- ly -- pond __
# (which must be preceded by ASCII whitespace)
(r"""(?x)
\\\\
| (?<= \s ) (?: -- | __ )
| [{}<>=.,:|]
""", Token.Punctuation),

# Pitches, with optional octavation marks, octave check,
# and forced or cautionary accidental.
(words(pitches, suffix=r"=?[',]*!?\??" + NAME_END_RE), Token.Pitch),

# String, optionally with direction specifier.
# Strings, optionally with direction specifier.
(r'[\-_^]?"', Token.String, "string"),

# Numbers.
(r"-?\d+\.\d+", Token.Number.Float), # 5. and .5 are not allowed
(r"-?\d+/\d+", Token.Number.Fraction),
# Integer, or duration with optional augmentation dots. We have no
# way to distinguish these, so we highlight them all as numbers.
(r"-?(\d+|\\longa|\\breve)\.*", Token.Number),
# Integers, or durations with optional augmentation dots.
# We have no way to distinguish these, so we highlight
# them all as numbers.
#
# Normally, there is a space before the integer (being an
# argument to a music function), which we check here. The
# case without a space is handled below (as a fingering
# number).
lemzwerg marked this conversation as resolved.
Show resolved Hide resolved
(r"""(?x)
(?<= \s ) -\d+
| (?: (?: \d+ | \\breve | \\longa | \\maxima )
\.* )
""", Token.Number),
# Separates duration and duration multiplier highlighted as fraction.
(r"\*", Token.Number),

Expand Down Expand Up @@ -168,7 +191,10 @@ def get_tokens_unprocessed(self, text):

# Definition of a variable. Support assignments to alist keys
# (myAlist.my-key.my-nested-key = \markup \spam \eggs).
(r"([^\W\d]|-)+(?=([^\W\d]|[\-.])*\s*=)", Token.Name.Lvalue),
(r"""(?x)
(?: [^\W\d] | - )+
(?= (?: [^\W\d] | [\-.] )* \s* = )
""", Token.Name.Lvalue),

# Virtually everything can appear in markup mode, so we highlight
# as text. Try to get a complete word, or we might wrongly lex
Expand Down
5 changes: 3 additions & 2 deletions tests/examplefiles/lilypond/example.ly
Expand Up @@ -76,7 +76,8 @@ piuPiano = \markup \italic "più piano"
\key d \major
\cadenzaOn
deses'!4.~(\tweak thickness 4\( deses^\p-\signumcongruentiae_1\4
deses\longa) \myFunc { r } 4 des8 8[ <des ges>8]\)
deses\longa) \myFunc { r } 4
des8-- 8[__ \ottava -1 <des, ges>8]\) \ottava 0
\bar "||"
\cadenzaOff
\pageBreak
Expand All @@ -100,7 +101,7 @@ piuPiano = \markup \italic "più piano"
}
\addlyrics {
\set Score.melismaBusyProperties = #'()
My Lily -- Song
My Lily -- Song __
}
\chordmode {
c cis:dim3+\dim des:maj7/+e\!
Expand Down
18 changes: 15 additions & 3 deletions tests/examplefiles/lilypond/example.ly.output

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.