On 2019-04-03 1:01 am, Michael Gerdau wrote:
in the Snippet Repository there is under number 650
(http://lsr.di.unimi.it/LSR/Snippet?id=650) a rather neat snippet
showing splitting and converging arrows for voices. However with
increasing frequency I'm encountering timesignature changes where
these splits occur. In those cases the arrows aren't correctly
positioned.

Now the arrows are no longer nicely visible.

Is there a way to adjust the position when there is a TimeSignature at
the end of a line?

One option would be to attach the arrows to the TimeSignature instead of the BarLine. This keeps the arrows right-most, which looks better to my eye.

I have made many alterations to the LSR 650 snippet, so please review the attachment.

- The definition of arrow-at-angle was off in places. Annoyingly, \rotate only supports rotation about the center. We actually want to rotate relative to the starting point of the arrow. The solution is to use the internal ly:stencil-rotate which lets you rotate from any point. As a bonus, it lets you specify this point relative to the extent of the stencil. This saves on all of the trigonometric work. Also, the arrow head was slightly disjoint from the end of the line.

- Things like \splitStaffBarLine and \convDownStaffBarLine were changed to music functions that accept a grob name as an argument. That means it becomes \splitStaff BarLine or \convDownStaff TimeSignature. Note the space!

- The arrows looked best when directly attached to the BarLine, but I felt they needed a little padding when attached to the TimeSignature. This is done currently with a hard-coded conditional in each of the music functions.

- Lastly, I used some \tags to support conditionally altering TimeSignatures, and there is a second \score demonstrating that.

This feels a little hacking in places, but that is often the case when playing around with stencils. Especially when one is changing the stencil but lying about its dimensions. These arrows have no proper extents, which is of course why you saw the overlap in the first place.

The problem with trying to attach the arrows to the BarLine and giving them proper extents is that the lines from the StaffSymbol would extend further to the right to accommodate the wider dimensions. This does have as a side effect that the TimeSignatures would appear further to the right to prevent overlap.

If this is not a problem, then it may perhaps be another option. All you need to do to play around with this is change the \with-dimensions lines to be something more appropriate. For instance, try: \with-dimensions #'(0 . 3) #'(-2 . 2).


-- Aaron Hill
\version "2.19.82"

#(define-markup-command (arrow-at-angle layout props angle length fill)
  (number? number? boolean?)
  (ly:stencil-rotate
    (interpret-markup layout props
      (markup #:concat (#:draw-line (cons length 0)
                        #:hspace -0.1
                        #:arrow-head X RIGHT fill)))
    angle -1 0))

splitStaffMarkup = \markup
  \with-dimensions #'(0 . 0) #'(0 . 0)
  \overlay { \arrow-at-angle #45 #(sqrt 8) ##t
             \arrow-at-angle #-45 #(sqrt 8) ##t }

splitStaff = #(define-music-function (grob-name) (string?)
  #{ { \once \override Staff.$grob-name stencil =
          #(grob-transformer 'stencil (lambda (grob orig)
            (if (= LEFT (ly:item-break-dir grob))
              (ly:stencil-combine-at-edge
                orig X RIGHT
                (grob-interpret-markup grob splitStaffMarkup)
                (if (equal? "TimeSignature" grob-name) 0.5 0))
              orig)))
        \break } #} )

convDownStaff = #(define-music-function (grob-name) (string?)
  #{ { \once \override Staff.$grob-name stencil =
          #(grob-transformer 'stencil (lambda (grob orig)
            (if (= LEFT (ly:item-break-dir grob))
              (ly:stencil-combine-at-edge
                orig X RIGHT
                (grob-interpret-markup grob #{
                  \markup
                    \with-dimensions #'(0 . 0) #'(0 . 0)
                    \arrow-at-angle #-45 #(sqrt 8) ##t #})
                (if (equal? "TimeSignature" grob-name) 0.5 0))
              orig)))
        \break } #} )

convUpStaff = #(define-music-function (grob-name) (string?)
  #{ { \once \override Staff.$grob-name stencil =
          #(grob-transformer 'stencil (lambda (grob orig)
            (if (= LEFT (ly:item-break-dir grob))
              (ly:stencil-combine-at-edge
                orig X RIGHT
                (grob-interpret-markup grob #{
                  \markup
                    \with-dimensions #'(0 . 0) #'(0 . 0)
                    \arrow-at-angle #45 #(sqrt 8) ##t #})
                (if (equal? "TimeSignature" grob-name) 0.5 0))
              orig)))
        \break } #} )

\paper {
  ragged-right = ##t
  short-indent = 10\mm
}

separateSopranos = {
  \set Staff.instrumentName = "AI AII"
  \set Staff.shortInstrumentName = "AI AII"
  \tag #'no-time-change \splitStaff BarLine
  \tag #'time-change \splitStaff TimeSignature
  \change Staff = "up"
}
convSopranos = {
  \tag #'no-time-change \convDownStaff BarLine
  \tag #'time-change \convDownStaff TimeSignature
  \change Staff = "shared"
  \set Staff.instrumentName = "S A"
  \set Staff.shortInstrumentName = "S A"
}

sI = {
  \voiceOne
  \repeat unfold 4 f''2
  \separateSopranos
  \tag #'time-change \time 4/2
  \repeat unfold 4 g''2
  \convSopranos
  \tag #'time-change \time 4/4
  \repeat unfold 4 c''2
}
sII = {
  s1*2
  \voiceTwo
  \change Staff = "up"
  \repeat unfold 4 d''2
}
aI = {
  \voiceTwo
  \repeat unfold 4 a'2
  \voiceOne
  \repeat unfold 4 b'2
  \tag #'no-time-change \convUpStaff BarLine
  \tag #'time-change \convUpStaff TimeSignature
  \voiceTwo
  \repeat unfold 4 g'2
}
aII = {
  s1*2
  \voiceTwo
  \repeat unfold 4 g'2
}
ten = {
  \voiceOne
  \repeat unfold 4 c'2
  \repeat unfold 4 d'2
  \repeat unfold 4 c'2
}
bas = {
  \voiceTwo
  \repeat unfold 4 f2
  \repeat unfold 4 g2
  \repeat unfold 4 c2
}

\score { \keepWithTag #'(no-time-change)
  <<
    \new ChoirStaff <<
      \new Staff = up \with {
        instrumentName = "SI SII"
        shortInstrumentName = "SI SII"
      } {
        s1*4
      }

      \new Staff = shared \with {
        instrumentName = "S A"
        shortInstrumentName = "S A"
      } <<
        \new Voice = sopI \sI
        \new Voice = sopII \sII
        \new Voice = altI \aI
        \new Voice = altII \aII
      >>
      \new Lyrics \with {
        alignBelowContext = up
      }
      \lyricsto sopII { e f g h }
      \new Lyrics \lyricsto altI { a b c d e f g h i j k l }

      \new Staff = men \with {
        instrumentName = "T B"
        shortInstrumentName = "T B"
      } <<
        \clef F
        \new Voice = ten \ten
        \new Voice = bas \bas
      >>
      \new Lyrics \lyricsto bas { a b c d e f g h i j k l }
    >>
  >>
  \layout {
    \context {
      \Staff \RemoveEmptyStaves
      \override VerticalAxisGroup.remove-first = ##t
    }
  }
}

\score { \keepWithTag #'(time-change)
  <<
    \new ChoirStaff <<
      \new Staff = up \with {
        instrumentName = "SI SII"
        shortInstrumentName = "SI SII"
      } {
        s1*4
      }

      \new Staff = shared \with {
        instrumentName = "S A"
        shortInstrumentName = "S A"
      } <<
        \new Voice = sopI \sI
        \new Voice = sopII \sII
        \new Voice = altI \aI
        \new Voice = altII \aII
      >>
      \new Lyrics \with {
        alignBelowContext = up
      }
      \lyricsto sopII { e f g h }
      \new Lyrics \lyricsto altI { a b c d e f g h i j k l }

      \new Staff = men \with {
        instrumentName = "T B"
        shortInstrumentName = "T B"
      } <<
        \clef F
        \new Voice = ten \ten
        \new Voice = bas \bas
      >>
      \new Lyrics \lyricsto bas { a b c d e f g h i j k l }
    >>
  >>
  \layout {
    \context {
      \Staff \RemoveEmptyStaves
      \override VerticalAxisGroup.remove-first = ##t
    }
  }
}

Attachment: lsr650-patch.pdf
Description: Adobe PDF document

_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to