lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re:Wrong alternative numbering when some are empty


From: Flaming Hakama by Elaine
Subject: Re:Wrong alternative numbering when some are empty
Date: Wed, 5 Oct 2016 17:46:35 -0700


    > This seems like a bug to me but perhaps someone can explain it.  I have
    > a piece where the verse repeats nine times with verses 3 and 6 followed
    > by an alternative.
    >
    >   \mark \markup \italic "repeat 9 times"
    >   \repeat volta 9 {
    >     \BassVerseA
    >   }
    >   \alternative {
    >     { }
    >     { }
    >     { \BassBridge }
    >     { }
    >     { }
    >     { \BassVerseB }
    >     { }
    >     { }
    >     { }
    >   }
    >
    >   \BassVerseC
    >
    > So I expect that it will show 3 for the bridge and 6 for verse B but it
    > shows 1 for the bridge and 4 for verse B.
    >
    > I understand that I could move the last bar of the verse into the start
    > of each alternative but that just makes the chart messy.
    >
    > Oddly enough it plays correctly.
    >
    > --
    > D'Arcy J.M. Cain
    > Big Smoke Music
    > http://BigSmokeMusic.com/ IM:address@hidden

I would suggest not using endings to try to notate a song form.
The notation you are suggesting is unclear.

The clearest approach would be to just write out the actual form.
Here are three ways of doing that.


\version "2.19.15"

bassVerseA = \relative c { g1 1 1 1  c 1 g 1  d' c g d' }
bassBridge = \relative c { d1 1 1 1 }
bassVerseB = \relative c { c1 1 1 1 }
bassVerseC = \relative c { g1\fermata }

\layout {
    \context {
        \Score
        \override RehearsalMark.self-alignment-X = #LEFT
    }
}

\score {
    {
        \clef bass
        \mark "3X"
        \repeat volta 3 { \bassVerseA }
        \mark "Bridge"
        \bassBridge \break
        \mark "3X"
        \repeat volta 3 { \bassVerseA }
        \mark "Verse B"
        \bassVerseB \break
        \mark "3X"
        \repeat volta 3 { \bassVerseA }
        \mark "Verse C"
        \bassVerseC
    }
    \header {
        piece = "Clear"
    }
}

%  If you are concerned about the length of the chart,
%  here are two other approaches.

%  If \bassVerseA is the kind of lick that you expect someone to memorize quickly,
%  you could save space and write a modified multi-measure rest
%  and write instructions to repeat the first section.

#(define (white-under grob) (grob-interpret-markup grob
  (markup #:vcenter #:whiteout #:pad-x 1 (ly:grob-property grob 'text))))

inlineMMRN = {
  \once \override MultiMeasureRest.layer = #-2
  \once \override MultiMeasureRestNumber.layer = #-1
  \once \override MultiMeasureRestNumber.Y-offset = #0
  \once \override MultiMeasureRestNumber.stencil = #white-under
}

\score {
    {
        \clef bass
        \compressFullBarRests
        \override MultiMeasureRest #'minimum-length = #20

        \mark \markup { \box "Verse A" "3X" }
        \repeat volta 3 { \bassVerseA }

        \mark \markup { \box "Bridge" }
        \bassBridge \break

        \mark \markup { \box "Verse A" "3X" }
        \repeat volta 3 { \inlineMMRN R1*12 }

        \mark \markup { \box "Verse B" }
        \bassVerseB \break

        \mark \markup { \box "Verse A" "3X" }
        \repeat volta 3 { \inlineMMRN R1*12 }

        \mark \markup { \box "Verse C" }
        \bassVerseC
    }
    \header {
        piece = "Concise but incomplete"
    }
}

%  To use standard notation with a small footprint you can use two codas.
%  This requires some fiddling with layout of simultaneous marks
%  These next functions come from http://lsr.di.unimi.it/LSR/Snippet?id=977

#(define-public (string-or-markup-or-boolean? e)
  (or (string? e) (markup? e) (boolean? e)))

#(define (music-property-description symbol type? description)
  (if (not (equal? #f (object-property symbol 'music-doc)))
      (ly:error (_ "symbol ~S redefined") symbol))
  (set-object-property! symbol 'music-type? type?)
  (set-object-property! symbol 'music-doc description)
  symbol)

#(for-each
  (lambda (x)
    (apply music-property-description x))
    `((left-label
       ,string-or-markup-or-boolean?
       "set the left part of a RehearsalMark")
      (right-label
       ,string-or-markup-or-boolean?
       "set the right part of a RehearsalMark")
       ))

#(define (double-rehearsalmark-stencil grob)
  (let*
   ((grobs-event (ly:grob-property grob 'cause '()))
    (left-label (ly:event-property grobs-event 'left-label))
    (right-label (ly:event-property grobs-event 'right-label))
    (gap (ly:grob-property grob 'gap 1.4)))
   (if (not (or (null? left-label) (null? right-label)))
    (case (ly:item-break-dir grob)
     ((-1)
      (if (boolean? left-label) empty-stencil
       (grob-interpret-markup grob
        (make-right-align-markup left-label))))
     ((1)
      (if (boolean? right-label) empty-stencil
       (grob-interpret-markup grob
        (make-left-align-markup right-label))))
     (else
      (if (boolean? left-label)
       (grob-interpret-markup grob
        (if left-label
         (make-center-align-markup right-label)
         (make-left-align-markup right-label)))
       (if (boolean? right-label)
        (grob-interpret-markup grob
         (if right-label
          (make-center-align-markup left-label)
          (make-right-align-markup left-label)))
        (ly:stencil-add
         (ly:stencil-translate
          (grob-interpret-markup grob
           (make-right-align-markup left-label))
          (cons (* -0.5 gap) 0.0))
         (ly:stencil-translate
          (grob-interpret-markup grob
           (make-left-align-markup right-label))
          (cons (* 0.5 gap) 0.0)))))))
    (begin
     (ly:warning "\"doubleMark stencil\" did not find \"doubleMark texts\".")
     (ly:warning "fallback to using \"ly:text-interface::print\".")
     (ly:text-interface::print grob)))))

doubleMark =
#(define-music-function
  (parser location left-string right-string)
  (string-or-markup-or-boolean? string-or-markup-or-boolean?)
  (if (and (boolean? left-string) (boolean? right-string))
   (ly:warning "~a \\doubleMark - at least one string or markup required" location))
  (make-music 'SequentialMusic
   'elements (list
    (make-music 'ContextSpeccedMusic
     'context-type 'Score
     'element
      (make-music 'OverrideProperty
       'symbol 'RehearsalMark
       'grob-value double-rehearsalmark-stencil
       'grob-property-path (list 'stencil)
       'pop-first #t
       'once #t))
    (make-music 'ContextSpeccedMusic
     'context-type 'Score
     'element
      (make-music 'OverrideProperty
       'symbol 'RehearsalMark
       'grob-value #f
       'grob-property-path (list 'self-alignment-X)
       'pop-first #t
       'once #t))
    (make-music 'ContextSpeccedMusic
     'context-type 'Score
     'element
      (make-music 'OverrideProperty
       'symbol 'RehearsalMark
       'grob-value `#(,(not (boolean? left-string))
                      #t
                      ,(not (boolean? right-string)))
       'grob-property-path (list 'break-visibility)
       'pop-first #t
       'once #t))
    (make-music 'MarkEvent
     'label #f
     'left-label (if (string? left-string)
                  (make-simple-markup left-string)
                  left-string)
     'right-label (if (string? right-string)
                   (make-simple-markup right-string)
                   right-string)
     'origin location))))

set-mark-y-dir =
#(define-music-function (parser location ls)(list?)
"
 Sets 'direction of RehearsalMark. Depending on their break-dir.
 
address@hidden is supposed to be an alist with entries like
  (<break-dir of the item> . <Y-direction>)
 A full list is not needed. An empty list is possible, too, will default to all
 items UP.
 
 Example:
 `( (,left . ,DOWN) (,center . ,DOWN) (,right . ,UP) )
 Ofcourse this is the same as:
 '((-1 . -1)(0 . -1)(1 . 1))
 "
#{
  \override Score.RehearsalMark.before-line-breaking =
    #(lambda (grob)
       (let* ((get-break-dir (ly:item-break-dir grob))
              (left-y-dir (or (assoc-get left ls) 1))
              (right-y-dir (or (assoc-get right ls) 1))
              (center-y-dir (or (assoc-get center ls) 1)))
        
         (ly:grob-set-property! grob 'direction
           (case get-break-dir
            ((-1) left-y-dir)
            ((1) right-y-dir)
            ((0) center-y-dir)
            ;; better be paranoiac
            (else 1)))))
#})
    

%  And now back to our example.

toCodaOne = \markup \tiny { \musicglyph #"scripts.coda" }
toCodaTwo = \markup \tiny { \musicglyph #"scripts.coda" \musicglyph #"scripts.coda" }
dcOne = \markup \teeny { \lower #0.5 "D.C. al " \musicglyph #"scripts.coda" }
dcTwo = \markup \teeny { \lower #0.5 "D.C. al " \musicglyph #"scripts.coda" \musicglyph #"scripts.coda" }

\score {
    {
        \clef bass

        \mark "3X"
        \repeat volta 3 {
            \bassVerseA
            %  I'm not happy with the alignment of this mark,
            %  it would work better centered over the barline.
            %  but the following override isn't working like I'd expect.
            \once \override RehearsalMark.self-alignment-X = #CENTER
            \mark \markup { \center-column { \toCodaOne \toCodaTwo } "Bridge" }
        }

        \bassBridge \break

        \set-mark-y-dir #`( (,left . ,DOWN) (,center . ,DOWN) (,right . ,UP) )
        \doubleMark
            \markup \teeny \center-column { \dcOne "with repeats" }
            \markup { \musicglyph #"scripts.coda" "Verse B" } \bar "||"
        \bassVerseB

        \set-mark-y-dir #`( (,left . ,DOWN) (,center . ,DOWN) (,right . ,UP) )
        \doubleMark
            \markup \teeny \center-column { \dcTwo "with repeats" }
            \markup { \musicglyph #"scripts.coda" \musicglyph #"scripts.coda" "Verse C" } \bar "||" \break

        \bassVerseC
    }
    \header {
        piece = "Concise and complete"
    }
}


HTH,

David Elaine Alt
415 . 341 .4954                                           "Confusion is highly underrated"
address@hidden
self-immolation.info
skype: flaming_hakama
Producer ~ Composer ~ Instrumentalist
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-


reply via email to

[Prev in Thread] Current Thread [Next in Thread]