[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Context question
From: |
Jean Abou Samra |
Subject: |
Re: Context question |
Date: |
Sun, 11 Sep 2022 23:22:03 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.2.0 |
Le 11/09/2022 à 23:01, John Schlomann a écrit :
Can someone please explain why the following won’t work. I want get
the current moment at the end of the music expression. Is this not a
valid thing to do? Or perhaps I don’t know how to specify the context.
This code gives an unbound variable error.
\version "2.22.2"
\score {
\relative c'' {
\new Staff {
a b c d
#(display (ly:context-current-moment Staff))
}
}
}
This code tries to mix two passes of LilyPond's processing that
are separate. First, LilyPond reads the input code, and creates
music objects from it, basically those that you store in variables
when you do
violin = \relative c' { ... }
% \violin is a music expression
Now, suppose that you could do
violinPartI =
\relative c' {
...
}
violinPartII =
\relative c' {
...
#(display (ly:context-current-moment Staff))
...
}
%% What has been printed at this point?
\score {
{
\violinPartI
\violinPartII
}
}
How could this work? The current moment of the context at the point
you ask for it won't be determined until the whole score, including
the duration of violinPartI, is known. Yet you are asking it as soon
as violinPartII is read.
A music expression is just, well, an expression. At the time it is
read, nothing special happens. It's just a data structure. There are
no variables in scope ("Staff" is not defined), no execution process.
Scheme code used within a music expression is executed at the moment
the music is read. This just serves to embed a piece of Scheme-generated
music into it, like in
\version "2.22.2"
\score {
{
\new Staff {
#(make-sequential-music
(map (lambda (i)
(make-music 'NoteEvent
'duration #{ 4 #}
'pitch (ly:make-pitch 0 i 0)))
(iota 20)))
}
}
}
What I've done here is putting some Scheme expression that generates
a piece of music that you could have written as { c'4 d'4 e'4 ... }.
This is just creating a piece of music, without any ambient context
from the surrounding music, since that music has not been determined
yet.
Then, _after_ all the music expressions have been read and assembled,
LilyPond will start its "iteration" (also called "translation") process,
and only then contexts and timing start to come into play.
The way to achieve what you are after is to use the \applyContext hook,
which embeds a procedure into the music expression that will be executed
at iteration time. It's documented here:
https://lilypond.org/doc/v2.22/Documentation/extending/context-evaluation
Example:
\version "2.22.2"
\score {
\relative c'' {
\new Staff {
a b c d
\context Staff
\applyContext
#(lambda (context)
(display (ly:context-current-moment context)))
}
}
}
Maybe this will help you understand the different stages of LilyPond's
processing:
https://extending-lilypond.readthedocs.io/en/latest/intro.html#overview-of-lilypond-s-inner-workings-and-how-you-might-hook-in-them
Best,
Jean