Thank you very much, Stefano!
This is very helpful and shall be, like Urs said, added to the Wiki.
Best
Jan-Peter
Am 29.01.2018 um 21:36 schrieb Stefano Troncaro:
Hello again everyone!
In a recent thread I was asked to write a little bit depicting how I
would have liked to learn about using the Edition Engraver. I share it
here so that others can give their insights. Hopefully we can make a
"quick start guide" kind of thing to help future users.
I'll say it ended up being longer than I anticipated. I formatted it a
little to improve readability. Here it goes:
*My quick rundown of how to use OpenLilyLib's Edition Engraver
*(OR I wish I could have read this instead of having to learn by poking
example code with a stick)
What is it?
In a nutshell, the Edition Engraver provides a convenient way of storing
a tweaks, overrides and other objects that can later be applied to some
musical content.
Why use it?
To keep the "musical source" of a project free from tweaks, temporary
overrides, and tagged material that needs to be filtered later. This
serves to generate code that is clean, reusable and has clarity of
purpose, meaning it's fast to read and understand.
How is it used?
In summary, by following this four logical steps:
1. Load the Edition Engraver into the project.
2. Create an edition (a container to store the edits)
3. Fill the edition with content.
4. Consist the contents of the edition to the musical contexts to which
they apply.
Each step explained:
1) Loading the Edition Engraver:
Assuming OpenLilyLib is already installed on your working environment,
include it's core functionality:
\include "oll-core/package.ily"
Then, load the Edition Engraver itself:
\loadPackage edition-engraver
2) Creating an edition
Just use the /\addEdition/ command. Like this:
\addEdition edition-name
3) Filling the edition with content
The most basic way to do this is by using the /\editionMod/ command. It
is used as follows:
\editionMod edition measure position context content
Breaking it apart:
* /edition/ specifies in what edition the content is stored.
* /measure/ specifies in what measure of the music the content is to
be placed.
* /position/ specifies where where exactly in that measure the content
is to be placed.
* /context/ specifies in what context the content belongs.
* /content/ specifies, finally, what should be placed there.
So, this means that
\editionMod my-edition 5 0/4 Score \break
will store in /my-edition/ that a /\break/ needs to be placed in the
/Score/ context, in measure /5/, specifically at /0/4/, which is its
first beat.
3.1) About the position value
The way I understand it is that this is the amount of musical time that
is counted from the start of the given measure. A few useful examples:
* /0/4/ will not add anything, so it references the first beat of the
measure.
* /3/8/ will count three 8th notes / quavers from the start of the
measure. In 4/4 time this would reference the second half of the
second beat.
* /1/24/ will count one 16th note / semiquaver of a 16th note triplet.
If the measure starts with 16th note triplets, this will point to
the second note of the measure. The fraction is expressed like this
because there are 24 "tripleted 16th notes" in a whole note.
3.2) About referencing contexts
Precise control can be achieved by giving IDs to contexts. This is done
with the /\editionID/ command:
\new Staff \with { \editionID my-staff } {
\new Voice { c4 d e f }
}
This ID can be used like this:
\editionMod test 1 2/4 my-staff.Staff \accidentalStyle dodecaphonic
\editionMod test 1 3/4 my-staff.Voice.A \override NoteHead.color = #red
Notice that even though the ID /my-staff/ points to a specific /Staff/,
/\editionMod/ still needs to know specifically where you need to inject
the content. So, /my-staff.Staff/ puts it in the /Staff/ context, while
/my-staff.Voice.A/ puts it in the first /Voice/ inside the /Staff/.
Voices are listed in the order they are created, starting with the
symbol /A/, and each /Staff/ keeps a separate count. The Edition
Engraver produces a ".edition.log" file listing all the contexts it
finds along with their names. This is useful to work with music that
requires spontaneous creation of Voices, such as piano music, where
naming them provides a straightforward way of finding how to reference them.
Say you have an "example.ly <http://example.ly>" file with the following
music:
\new Staff \with { \editionID my-staff } {
\new Voice = "main-voice" \relative c'' {
c4 d e f
<< { \voiceOne e d c2 }
\new Voice = "spontaneous-voice" { \voiceTwo g2 e } >>
}
}
This will produce an "example.edition.log" file that, among other
things, will have the following:
(my-staff Voice A) "main-voice"
(my-staff Voice B) "spontaneous-voice"
While the /Score/ context can't be instantiated, an ID can be given to a
/\score/ block in it's /\layout/ block, like this:
\score {
... nice music goes here ...
\layout {
\context {
\Score
\editionID my-score
}
}
}
This very useful when you need specific edits for parts that you want to
keep out of the full score.
And while references can grow long pretty quickly, fortunately they can
be stored in variables:
referenceOne = my-score.my-staff.Voice.A
referenceTwo = my-other-score.my-staff.Voice.B
And then used like this:
\editionMod test 1 3/4 \referenceOne ->
3.2.1) A warning
Keep bottom level content to bottom level contexts. See this example:
\version "2.19.80"
\include "oll-core/package.ily"
\loadPackage edition-engraver
\addEdition example
\editionMod example 1 0/4 good-staff.Voice.A \once \override
NoteHead.color = #red
\editionMod example 1 0/4 bad-staff.Voice.A \once \override
NoteHead.color = #red
\consistToContexts #edition-engraver Staff.Voice
\score {
\new StaffGroup <<
\new Staff \with { \editionID good-staff } {
\new Voice { \clef C c' d' e' f' }
}
\new Staff \with { \editionID bad-staff } {
\clef C \new Voice { c' d' e' f' }
}
>>
}
Running this shows that /good-staff/ has a red first note, while
/bad-staff/ doesn't. This is because on the second /Staff/ the /\clef/
command is tacitly in a /Voice/ that has no length. This kind of tacit
Voice creation produces strange results. This is easily avoided by
moving the /\clef/ command inside the Voice that has actual music, like
/good-staff/ shows.
4) Consisting to contexts
This is done with the /\consistToContexts/ command, like this:
\consistToContexts #edition-engraver contexts.separated.by.dots
The contexts absent from the dot-separated list will not be modified.
So, for instance:
\editionMod test 1 0/4 my-score.Score \tempo "Adagio."
\editionMod test 1 0/4 my-other-score.my-staff.Staff \tempo "Adagio."
\consistToContexts #edition-engraver Staff.Voice
Will create a /TempoChangeEvent/ in /my-other-score/, since the
instruction is to create it in the /Staff/ context, but leave /my-score/
untouched.
Hopefully this will be enough to get anyone started. There is more
functionality than this, as far as I know the only way to get a look
into it is by examining the `usage-examples` folder in the Edition
Engraver repository.
I'll be waiting for your input!
Stéfano
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user