8

Here is a short snippet of Lilypond that I think expresses the intent of what I want to do.

verseNotes = \relative c' {
    d^\markup { \verseText } d d d16 d d8 a r4 |
    cis8 cis cis cis16 cis cis8 a r4 |
}

verseSection = \relative c' {
    \repeat volta 2 {
        \verseNotes
    }
    gis,1 |
    gis4. b8~b2 |
    \repeat volta 3 {
        verseText = "Verse (repeat 2x)"
        \verseNotes
    }
}

\relative c' {
    verseText = "Verse"
    \verseSection
}

It, of course, errors out.

I think the cause is something like verseNotes being bound at the time it is parsed, and \verseText having no value at the time. I would like to re-use the verseNotes variable, but with different values of verseText.

I’m thinking I want the “dynamic” equivalent of a function of some sort, to which I pass a text param. I see various sections in the Lilypond documentation expressing stuff in Scheme, but this is likely last thing I want to be doing while entering music.

0

2 Answers 2

5

Yes, you're right - you must declare the variable before using it. Hope this helps:

verseText = "Verse"

    verseNotes = \relative c' {
        d8^\markup { \verseText } d d d16 d d8 a r4 |
        cis8 cis cis cis16 cis cis8 a r4 |
    }

    verseSection = \relative c' {
        \repeat volta 2 {
            \verseNotes
        }
        gis'1 |
        gis4. b8~b2 |
    }       

    \score { 
     \new Staff \verseSection
    }

Peter's further solution, Nov 7, 2013:

verseNotes = \relative c' {
    d8 d d d16 d d8 a r4 |
    cis8 cis cis cis16 cis cis8 a r4 |
}

verseSection = \relative c' {
    \override Score.RehearsalMark #'self-alignment-X = #LEFT
    \mark \markup { \normalsize "Verse" }
    \repeat volta 2 {
        \verseNotes
    }

    gis'1 |
    gis4. b8~b2 |
    \mark \markup { \normalsize "Verse (repeat 2x)" }
    \repeat volta 3 {
        \verseNotes
    }
}

\score {
    \new Staff \verseSection
}
0
4
I see various sections in the Lilypond documentation expressing stuff in Scheme, but this is likely last thing I want to be doing while entering music.

Better get used to it, though. At pure LilyPond level, you can only assign static music expressions. While one can introduce a bit of variation into those using \tag, it's not really a parameterization.

You usually don't need to be "expressing stuff" while entering music and vice versa: it's quite feasible to write Scheme for schemish things (namely the parameterization) and music for musicish things by employing #{...#} judiciously.

In this case, this would look (after some tiny octave, duration, and context fixes) like:

verseNotes =
#(define-music-function (parser location verseText) (markup?)
  #{
    \relative c' {
      d8^\markup { #verseText } d d d16 d d8 a r4 |
      cis8 cis cis cis16 cis cis8 a r4 |
    }
  #})

verseSection =
#(define-music-function (parser location verseText) (markup?)
  #{
     \relative c' {
       \repeat volta 2 {
          \verseNotes #verseText
       }
       gis1 |
       gis4. b8~b2 |
       \repeat volta 3 {
          \verseNotes "Verse (repeat 2x)"
       }
     }
  #})

\relative c' {
    \new Staff \verseSection "Verse"
}

As you can see, the Scheme code compresses itself into single lines that one can learn by heart easily enough and that are only moderately infuriating.

1
  • 1
    Thank you! This is really helpful and so hard to find! Jan 26, 2022 at 11:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.