lilypond-user
[Top][All Lists]
Advanced

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

Re: always set beam outside of staff


From: David Nalesnik
Subject: Re: always set beam outside of staff
Date: Thu, 8 Sep 2016 13:08:06 -0500

On Thu, Sep 8, 2016 at 11:01 AM, Michael Winter
<address@hidden> wrote:
> Thank you David!
>
> This is a great start. And at the very least gets me to the point where
> manual overrides will not be as numerous.
>
> I also think I can play with this to get a bit more natural dampening.
> Plus this is a good opportunity to get my feet wet with scheme.
>
> Quick thought (to maybe deal with the dampening part) and since you
> clearly know how to get values from the grobs which is where I was
> unclear...
>
> Is there a way to get the min and max note positions. Then this could be
> done by setting Stem.details.beamed-lengths and allowing the dampening
> to remain.

Yes, you can get this information fairly easily with the use of
several Scheme functions and the Internals Reference constantly at
hand.

Perhaps it will be useful to go through the process I use in a general way.

Reading a property that a grob directly possesses is a simple matter
of using ly:grob-property (though be careful -- if the property is set
to a callback, invoking ly:grob-property will actually *execute* the
callback, which can have bizarre consequences, especially when you're
looking for vertical dimensions.  You just have to see what happens.)

If a grob doesn't have a particular property you're interested in,
hope that it stores a reference to another object which does.  Or that
it points to another object which points to another object which...
How can you tell what pointers you have to work with? The Internal
Reference pages for the various interfaces list such objects under
"Internal Properties": as "(graphical (layout) object" or "(array of
grobs)".

You get the object with ly:grob-object.

Another possibility of getting another grob from the grob at hand is
to use ly:grob-parent.  A grob has an X-parent and a Y-parent, and
those parents have parents, etc. , until you arrive at One Grob to
Rule Them All = System.  Of course, any grob along that parentage
chain has its own pointers,

So, start the treasure hunt.

As to your particular request -- getting note positions from a Beam
grob -- here is one path:

(1) the Beam grob supports the beam-interface (well, duh) which,
according to 
http://lilypond.org/doc/v2.18/Documentation/internals/beam_002dinterface
holds a 'stem property.  This holds a grob-array of encompassed Stem
objects;

(2) a Stem grob has a 'stem-interface,and looking at
http://lilypond.org/doc/v2.18/Documentation/internals/stem_002dinterface)
we find a property 'note-heads storing an array of NoteHead grobs

(3) Finding the staff-position of a NoteHead is a little trickier.
Unexpectedly, there's no ordinary grob property and the obvious
interface candidate -- 'note-head-interface' -- has nothing for us.
According to the IR page for NoteHead
(http://lilypond.org/doc/v2.18/Documentation/internals/notehead),
'staff-symbol-referencer-interface is supported, however  That
interface has a 'staff-position property..

So, to get the positions of the note-heads under a Beam, you could
write something like:

\version "2.19.46"

#(define my-positions
   (lambda (grob)
     (let* ((stems (ly:grob-object grob 'stems))
            ;; convert grob array to a list because few Scheme
facilities exist for dealing with grob arrays
            (stem-list (ly:grob-array->list stems))
            ;; list of grob arrays of NoteHead grobs for each Stem
            (note-heads (map (lambda (x) (ly:grob-object x
'note-heads)) stem-list))
            ;; convert the above to a list of lists of NoteHead grobs
-- again, for convenience
            (note-heads-list
             (map (lambda (x)
                    ;; if no note heads (i.e. beamed rest), no
array... - this seems like a design flaw to me
                    (if (ly:grob-array? x) (ly:grob-array->list x) '()))
               note-heads))
            ;; staff-positions of beamed notes, a list for each group
            (note-positions
             (map (lambda (x)
                    (map (lambda (y) (ly:grob-property y 'staff-position)) x))
               note-heads-list))
            ;; since we just want absolute max and min, we can flatten
the nested list
            ;; for convenience:
            ;; i.e., ((1 2) (3) (4 5 6)) --> (1 2 3 4 5 6)
            (flattened-list (append-map identity note-positions))
            (highest (apply max flattened-list))
            (lowest (apply min flattened-list)))

       (format #t "highest: ~a lowest: ~a~%" highest lowest)

       ; return default positions for sake of demo (since we're
overriding 'positions, we need a valid return)
       (beam::place-broken-parts-individually grob))))

{
  \override Beam.positions = #my-positions
  f''16 d'' b' g'
  <f'' b''>16 <d'' f''> <b' d''> <g' b'>
  r16 d'' b''' g,
}

%%%%%%%%%%%%%%%%%%%%%%%%%%

This answers the question, though I wish the Scheme would have been as
straightforward as the example...

Hope this helps--

David



reply via email to

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