Notes about ly.music
Pages 24
Clone this wiki locally
Note that ly.music is still very much in development. But it creates a tree structure of the music, scheme and markup structures in LilyPond document, using the tokens provided by ly.lex.
The tree structure can be traversed in every possible direction and so the music can be understood. Many music commands and functions are understood correctly and converted to a node on their own, with some meaningful methods. Nodes that denote music have a length() method that returns the length of the music. This counts with tuples, \times, \scaleDurations, repeats, grace notes, sequential and simultaneous music etc.
The tree structure is able to traverse assignments to variables and search in included files.
The nodes preserve the tokens that generated them in instance attributes. So it is possible to edit the document based on manipulations of the music tree, or to show a note in the text while playing it (because every token knows its position).
This should provide the basis of:
- auto-insert and check bar checks
- display measure position of cursor, show length of selected music
- extract certain events and add them to skips in a new expression, with all lengths correctly calculated
- understand position in MIDI file, highlight notes in text and PDF as they are played without LilyPond adding information to the MIDI
- play music (from cursor, or even convert the whole document to MIDI without running LilyPond)
- much more robust export to MusicXML (that understands variables, scores, contexts etc etc etc)
Other nice future possibilities:
- convert Markup to HTML
- basic scheme evaluation. Simple values are already understood (numeric, string, pair of ints)
- detailed document statistics
So please dive into ly.music!
Here is some hint to get you started:
python
>>> import ly.document, ly.music
>>> d=ly.document.Document("""\\relative c' {\n \\time 4/4\n c4 d e f\n | g2\n}\n""")
>>> print d.plaintext()
\relative c' {
\time 4/4
c4 d e f
| g2
}
>>> t=ly.music.document(d)
>>> print t.dump()
<Document>
<Relative u'\\relative'>
<Note u'c'>
<MusicList u'{'>
<TimeSignature u'\\time'>
<Note u'c'>
<Note u'd'>
<Note u'e'>
<Note u'f'>
<PipeSymbol u'|'>
<Note u'g'>
>>> t[0]
<Relative u'\\relative'>
>>> t[0].length()
Fraction(3, 2)
>>>