The easy way to add articulation to notes is to merge two music expressions into one context, as explained in Creating contexts. However, suppose that we want to write a music function which does this.
A $variable
inside the #{...#}
notation is like
using a regular \variable
in classical LilyPond
notation. We know that
{ \music -. -> }
will not work in LilyPond. We could avoid this problem by attaching the articulation to a fake note,
{ << \music s1*0-.-> }
but for the sake of this example, we will learn how to do this in Scheme. We begin by examining our input and desired output,
% input \displayMusic c4 ===> (make-music 'EventChord 'elements (list (make-music 'NoteEvent 'duration (ly:make-duration 2 0 1 1) 'pitch (ly:make-pitch -1 0 0)))) ===== % desired output \displayMusic c4-> ===> (make-music 'EventChord 'elements (list (make-music 'NoteEvent 'duration (ly:make-duration 2 0 1 1) 'pitch (ly:make-pitch -1 0 0)) (make-music 'ArticulationEvent 'articulation-type "marcato")))
We see that a note (c4
) is represented as an EventChord
expression, with a NoteEvent
expression in its elements list. To
add a marcato articulation, an ArticulationEvent
expression must
be added to the elements property of the EventChord
expression.
To build this function, we begin with
(define (add-marcato event-chord) "Add a marcato ArticulationEvent to the elements of ‘event-chord’, which is supposed to be an EventChord expression." (let ((result-event-chord (ly:music-deep-copy event-chord))) (set! (ly:music-property result-event-chord 'elements) (cons (make-music 'ArticulationEvent 'articulation-type "marcato") (ly:music-property result-event-chord 'elements))) result-event-chord))
The first line is the way to define a function in Scheme: the function
name is add-marcato
, and has one variable called
event-chord
. In Scheme, the type of variable is often clear
from its name. (this is good practice in other programming languages,
too!)
"Add a marcato..."
is a description of what the function does. This is not strictly necessary, but just like clear variable names, it is good practice.
(let ((result-event-chord (ly:music-deep-copy event-chord)))
`let' is used to declare local variables. Here we use one local
variable, named `result-event-chord', to which we give the value
(ly:music-deep-copy event-chord)
. `ly:music-deep-copy' is
a function specific to LilyPond, like all functions prefixed by
`ly:'. It is use to make a copy of a music
expression. Here we copy `event-chord
(the parameter of the
function). Recall that our purpose is to add a marcato to an
EventChord
expression. It is better to not modify the
EventChord
which was given as an argument, because it may be
used elsewhere.
Now we have a result-event-chord
, which is a
NoteEventChord
expression and is a copy of event-chord
. We
add the marcato to its elements list property.
(set! place new-value)
Here, what we want to set (the "place") is the "elements" property of
result-event-chord
expression
(ly:music-property result-event-chord 'elements)
ly:music-property
is the function used to access music properties
(the 'elements
, 'duration
, 'pitch
, etc, that we
see in the \displayMusic
output above). The new value is the
former elements property, with an extra item: the
MarcatoEvent
expression, which we copy from the
\displayMusic
output,
(cons (make-music 'ArticulationEvent 'articulation-type "marcato") (ly:music-property result-event-chord 'elements))
`cons' is used to add an element to a list without modifying the
original list. This is what we
want: the same list as before, plus the new ArticulationEvent
expression. The order inside the elements property is not important here.
Finally, once we have added the MarcatoEvent
to its elements
property, we can return result-event-chord
, hence the last line of
the function.
Now we transform the add-marcato
function into a music
function,
addMarcato = #(define-music-function (parser location event-chord) (ly:music?) "Add a marcato ArticulationEvent to the elements of ‘event-chord’, which is supposed to be an EventChord expression." (let ((result-event-chord (ly:music-deep-copy event-chord))) (set! (ly:music-property result-event-chord 'elements) (cons (make-music 'ArticulationEvent 'articulation-type "marcato") (ly:music-property result-event-chord 'elements))) result-event-chord))
We may verify that this music function works correctly,
\displayMusic \addMarcato c4
This page is for LilyPond-2.10.33 (stable-branch).