Hey Stéfano, this is totally awesome! As far as I can tell your text has exactly the amount of verbosity that is needed to introduce people to this kind of tool.
I will have very few and minor clarifications to ask for, and I suggest we put it on the GitHub Wiki page. Thank you very much Urs Am 29. Januar 2018 21:36:48 MEZ schrieb Stefano Troncaro <stefanotronc...@gmail.com>: >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" 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