Hi David,

David Nalesnik wrote:
Hi Paul,

On Mon, Apr 9, 2012 at 9:50 PM, Paul Morris <p...@paulwmorris.com <mailto:p...@paulwmorris.com>> wrote:

    Thanks David and Nick!  More below...

    David Nalesnik wrote:
    Hi Paul,

    On Mon, Apr 9, 2012 at 4:47 PM, Nick Payne
    <nick.pa...@internode.on.net
    <mailto:nick.pa...@internode.on.net>> wrote:

        On 10/04/12 06:56, Paul Morris wrote:
        Thank you!  This works, but unfortunately (like the Hydra's
        heads) it introduces two other problems, one with horizontal
        spacing collisions and one with ledger lines.

        1. Because the spacing engine does not take into account
        this low-level tweak, the tweaked notes sometimes collide
        with bar/measure lines and sometimes with other adjacent
        notes.  Is there a way to use Scheme to also increase the
        horizontal space given to the chord?  (I am still a beginner
        at Scheme.)

        Can't help with the second problem, but for the first you
        could add additional horizontal space to either the barline
        or stem to increase their separation:

        \version "2.15.36"

        barspace = #(define-music-function (parser location extent)
        (pair?) #{
            \once \override Staff.BarLine #'extra-spacing-width = #extent
        #})

        stemspace = #(define-music-function (parser location extent)
        (pair?) #{
            \once \override Staff.Stem #'X-extent = #extent
        #})

        \relative c'' {
            c2 c c c \barspace #'(0 . 2)
            c c
            \stemspace #'(-2 . 0) c c
        }

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


    This seems to do the trick as far as horizontal spacing is concerned:

    \version "2.15.36"

    #(define ((shift offsets) grob)
      (let ((note-heads (ly:grob-array->list (ly:grob-object grob
    'note-heads))))
        (map
          (lambda (p q) (set! (ly:grob-property p 'X-offset) q))
          note-heads offsets)))

    displaceHeads =
    #(define-music-function (parser location offsets) (list?)
      #{
        \once \override NoteColumn #'before-line-breaking = #(shift
    offsets)
      #}
    )

    {
      \displaceHeads #'(0 1.2 0)
    <c' e' g'>4
      \displaceHeads #'(0 1.2 1.2)
    <d' f' a'>
    }

    Hope this helps!
    -David

    Actually, David's approach appears to fix both problems!  Ledger
    lines are extended and appear twice as wide, just like with other
    chords that have notes on both sides of the stem.  The horizontal
    spacing seems to be working with standard noteheads.  (Looks like
    a good candidate for the LSR.)


    Unfortunately a function I'm using to substitute custom stencils
    for NoteHead grobs seems to disrupt the horizontal spacing in some
    instances (particularly noticeable with bar lines).  I haven't
    figured out the pattern yet.  But worst case, that's something I
    can fix manually using the tweaks Nick suggested.  Or maybe there
    is a way to expand David's function to access the Stem from the
    NoteColumn and automatically give it an X-offset too?

    A stripped down version of my code is below, if anyone is
    curious.  It is still a bit long.

    Again, thanks so much!  I really appreciate it, as it would take
    me forever to try and figure this stuff out on my own.

    -Paul


    \version "2.15.32"

    %Begin TwinNote scripts
    %Customizing note head stencils based on pitch
    %Defining stencils

    upTriangle =
    #(ly:make-stencil
        (list 'embedded-ps
        "gsave
          currentpoint translate
          newpath
          -.1875 -.5 moveto
          .65625 .5 lineto
          1.5 -.5 lineto
          closepath
          fill
          grestore" )
        (cons -.1875 1.5)
        (cons -.5 .5)
    )

    downTriangle =
    #(ly:make-stencil
        (list 'embedded-ps
        "gsave
          currentpoint translate

          newpath
          .08 .34 moveto
          .65625 -.4 lineto
          1.2325 .34 lineto
          closepath
          0.12 setlinewidth
          stroke

          newpath
          -.0775 .43 moveto
          .65625 -.43 lineto
          1.39 .43 lineto
          closepath
          0.1 setlinewidth
          stroke

          newpath
          -.1675 .48 moveto
          .65625 -.48 lineto
          1.48 .48 lineto
          closepath
          0.04 setlinewidth
          stroke

          grestore" )
        (cons -.1875 1.5)
        (cons -.5 .5)
    )

    %Based on the pitch's semitone, which note head
    #(define (semitone-to-stencil semitone)
            (if (= (remainder semitone 2) 0) downTriangle upTriangle)
    )

    %Get the pitch from the grob, convert to semitone
    #(define (stencil-notehead grob)
       (semitone-to-stencil
         (ly:pitch-semitones (ly:event-property (event-cause grob)
    'pitch))))

    %End TwinNote scripts


    #(define ((shift offsets) grob)
      (let ((note-heads (ly:grob-array->list (ly:grob-object grob
    'note-heads))))
        (map
          (lambda (p q) (set! (ly:grob-property p 'X-offset) q))
          note-heads offsets)))

    displaceHeads =
    #(define-music-function (parser location offsets) (list?)
      #{
        \once \override NoteColumn #'before-line-breaking = #(shift
    offsets)
      #}
    )

    theMusic = {
    \displaceHeads #'(0 0 1.45)
    <c' e' g' >4

    \displaceHeads #'(0 1.45 1.45)
    <d' f' a'>

    \displaceHeads #'(0 1.45 1.45)
    <d' f' a'>

    \displaceHeads #'(0 0 1.45)
    < c' e' g'>

    \displaceHeads #'(-1.45 -1.45 0)
    < c'' e'' g''>

    \displaceHeads #'(-1.45 -1.45 0)
    < c''' e''' g'''>

    \displaceHeads #'(0 0 1.45)
    < c e g>

    \displaceHeads #'(0 -1.45 0)
    < c'' e'' g''>

    \displaceHeads #'(0 0 -1.45)
    < c'' e'' g''>
    }

    %TwinNote staff
    \new Staff \with {
        staffLineLayoutFunction = #(lambda (p) (floor (/ (+
    (ly:pitch-semitones p) 1) 2)))
        \override StaffSymbol #'line-positions = #'( 4 2 -2 -4 )

        % this override is messing up horizontal spacing:
        \override NoteHead #'stencil = #stencil-notehead
    }
    {
        \theMusic
    }

    % Regular staff
    \new Staff {
        \theMusic
    }


If you treat this new situation as I did earlier, by setting the stencil within an override of 'before-line-breaking, the new shapes are accommodated:

\new Staff \with {
staffLineLayoutFunction = #(lambda (p) (floor (/ (+ (ly:pitch-semitones p) 1) 2)))
    \override StaffSymbol #'line-positions = #'( 4 2 -2 -4 )
    % this override is messing up horizontal spacing:
    %\override NoteHead #'stencil = #stencil-notehead
    \override NoteHead #'before-line-breaking = #(lambda (grob)
      (set! (ly:grob-property grob 'stencil) (stencil-notehead grob)))
}

By the way, a quibble, but I probably should have used for-each instead of map in the earlier function:

#(define ((shift offsets) grob)
(let ((note-heads (ly:grob-array->list (ly:grob-object grob 'note-heads))))
    (for-each
      (lambda (p q) (set! (ly:grob-property p 'X-offset) q))
      note-heads offsets)))

Best,
David

Nice! That does the trick. I will have to learn more about 'before-line-breaking. I remain amazed at what is possible with LilyPond. Thanks for all the help, including switching "map" to "for-each". I will put it on my list to submit this to the LSR for future reference.

Thanks again!  All the best,
-Paul





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

Reply via email to