lilypond-user
[Top][All Lists]
Advanced

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

Re: Line-breaking with non-aligned barlines


From: Thomas Morley
Subject: Re: Line-breaking with non-aligned barlines
Date: Mon, 29 Oct 2018 00:51:56 +0100

Am So., 28. Okt. 2018 um 08:07 Uhr schrieb Werner LEMBERG <address@hidden>:
>
> > A minimal would be:
> >
> > \paper { indent = 0 ragged-right = ##t }
> >
> > {
> >     \override Beam.breakable = ##t
> >     s2. s8
> >     c'8[
> >     \break
> >     c'16]
> > }
> >
> > Not sure I'd call it a bug.
>
> IMHO, it is a bug.
>
> > But I'd love to have a method to change this behaviour easily,
> > currently there's none.
>
> I fully agree.
>
> > Though, you can dive into Beam deeply and reset 'beam-segments with
> > custom values.  Leading to: [...]
>
> Very nice!  If possible, this should be made the default.  I even
> suggest to completely drop the current behaviour since I can't
> envision a situation where you really want this.
>
>
>     Werner

Hi Werner,

I'll open an issue on the tracker.

As workaround a much more elaborated coding below.
It's now possible to process complex Beams, affecting them before and
after a line-break.
Not yet coded is affecting the beam-segments of the middle-beam-parts
of a more than two times broken Beam.
Though, it will not happen very often. At least I hope so.

\version "2.19.82"

\paper { indent = 0 ragged-right = ##t }

#(define (devide-at-vertical-count beam-dir dir-pred lst)
;; 'lst' is supposed to be the list of beam-segments
;; A new list is returned where all entries of same vertical-count are wrapped
;; into a sublist.
;; Relying on dir-pred those sublists appear in reversed order.
;; This is important to get have 'new-beams' working on the correct
;; beam-segment. Empty sublists would disturb, they are removed.
  (remove
    null?
    (map
      (lambda (i)
        (let ((inner-list
                (filter
                  (lambda (el) (eqv? (assoc-get 'vertical-count el) i))
                  lst)))
          (cond ((eq? dir-pred 'first-beam)
                 (reverse inner-list))
                ((eq? dir-pred 'last-beam)
                 inner-list))))
    ;; TODO Unlikely to have more than 10 beam-segments.
    ;; Better than removing empty lists afterwards would be to find the correct
    ;; beam-count, though. Too lazy right now ...
    (iota 10 0 (- beam-dir)))))



#(define (new-beams amounts dir-predicate lst)
  ;; Returns a new list suitable for 'beam-segments.
  ;; Relying on 'dir-predicate' left or right side of the beam-segments are
  ;; changed.
  (append-map
    (lambda (a el)
      (cons
        (list (caar el)
              (let* ((hor (assoc-get 'horizontal (car el))))
                (cons 'horizontal
                      (cond ((eqv? dir-predicate LEFT)
                             (cons (+ a (car hor)) (cdr hor)))
                            ((eqv? dir-predicate RIGHT)
                             (cons (car hor) (+ a (cdr hor))))
                            (else hor)))))
        (cdr el)))
    amounts
    lst))


shortenBrokenBeams =
#(define-music-function (amount)(list?)
"
 Shorten broken Beams at line-break.

 We get the 'beam-segments, rebuilding it modified.
 The 'beam-segments-property is an alist of type:
    '(((vertical-count . 0) (horizontal 3.865018 . 5.93))
      ((vertical-count . 1) (horizontal 3.865018 . 5.93)))

    `vertical-count' is the beam-count, which may grow negative.
    `horizontal' is the X-extent relative to 'System's 'line-width.
    Regrettable this means changing `horizontal' will need to be adjusted
    frequently. P.e. if Beam-direction changes.

 @var{amount} is a list containing number-lists. Their values are applied to
 the beam-segments at line-break.
 At line-end they are applied to the right. At line-start to the left.
 An empty sublist will trigger default beaming.

 Limitations:
   Does not work for the inner beam-parts of more than two times broken Beams.
"
#{
  %% Add \once ?
  \override Beam.beam-segments =
    #(lambda (grob)
       (let* ((middle-of-broken-beam?
                (and (eq? (grob::name (ly:spanner-bound grob LEFT))
                          'NonMusicalPaperColumn)
                     (eq? (grob::name (ly:spanner-bound grob RIGHT))
                          'NonMusicalPaperColumn)))
              (first-of-broken-beam?
                (and (eq? (grob::name (ly:spanner-bound grob RIGHT))
                          'NonMusicalPaperColumn)
                     (not (eq? (grob::name (ly:spanner-bound grob LEFT))
                               'NonMusicalPaperColumn))))
              (last-of-broken-beam?
                (and (eq? (grob::name (ly:spanner-bound grob LEFT))
                          'NonMusicalPaperColumn)
                     (not (eq? (grob::name (ly:spanner-bound grob RIGHT))
                               'NonMusicalPaperColumn))))
              (beam-segments (ly:beam::calc-beam-segments grob))
              (dir (ly:grob-property grob 'direction)))
       (cond
         (middle-of-broken-beam?
           (ly:message
             "Tweaking left and right ends of a beam-segments is not yet coded.
Returning default.")
           beam-segments)
         (first-of-broken-beam?
           ;; uncomment to watch 'beam-segments' of first beam-part
           ;(format #t "\nBEAM-SEGMENTS of FIRST beam-part:\n~y" beam-segments)
           (if (null? (car amount))
               beam-segments
               (new-beams
                 (car amount)
                 RIGHT
                 (devide-at-vertical-count dir 'first-beam beam-segments))))
         (last-of-broken-beam?
           ;; uncomment to watch 'beam-segments' of last beam-part
           ;(format #t "\nBEAM-SEGMENTS of LAST beam-part:\n~y" beam-segments)
           (if (null? (cadr amount))
               beam-segments
               (new-beams
                 (cadr amount)
                 LEFT
                 (devide-at-vertical-count dir 'last-beam beam-segments))))
         (else beam-segments))))
#})

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\markup "Beam at start of line"
{
    \override Beam.breakable = ##t
    s8*5
    \shortenBrokenBeams
      %% empty sublist are possible
      %#'(()(0 2.239 2.239))
      %#'((0 -1.852)())
      #'((0 -1.852)(0 2.239 2.239))
    c'16[
    c'
    c'8.
    c'16
    \break
    c'32
    c'8
    c'16
    c']
}

{
    \override Beam.breakable = ##t
    s8*7
    \shortenBrokenBeams
      #'(()(0 1))
    c''8[
    \break
    c''16]
}

{
    \override Beam.breakable = ##t
    s16*15
    \shortenBrokenBeams
      #'((0 -1.2)())
    c''16[
    \break
    c''8]
}

Cheers,
  Harm



reply via email to

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