lilypond-user
[Top][All Lists]
Advanced

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

Re: An alternative outside-staff spacing method (new version)


From: Aaron Hill
Subject: Re: An alternative outside-staff spacing method (new version)
Date: Tue, 11 Feb 2020 12:14:55 -0800
User-agent: Roundcube Webmail/1.4.2

On 2020-02-11 8:05 am, Paolo Prete wrote:
thanks to the _great_ support of Aaron and Harm, I implemented this new
version of the outside-staff spacing method I proposed some days ago.

I am getting quite a few errors and warnings compiling the code pasted in the email. I wonder if the email process has mangled something. It might be worth attaching the original source, so that formatting can be preserved.


================================================================
1) I could not find a way to add a box around piano pedals (and ask to
the gurus which ly:xxx::print interface should I use). Obviously, you can easily compensate this by adding two padding boxes above and below pedals,
as the following snippet shows.

The Internals Reference lists ly:piano-pedal-bracket::print for the PianoPedalBracket, ly:sustain-pedal::print for the SustainPedal and ly:text-interface::print for both SostenutoPedal and UnaCordaPedal.

But before going down that path, are you committed to supporting only 2.19 and newer? grob-transformer can make it easier to override the stencil for a grob without needing to know what the original procedure is:

%%%%
#(define* (make-stencil-boxer thickness padding
           #:optional (callback #f) (color red) (expand? #t))
  "Return function that adds a box around the grob passed as argument."
  (if (procedure? callback)
    (lambda (grob)
      (box-stencil (callback grob) thickness padding color expand?))
    (grob-transformer 'stencil (lambda (grob orig)
      (box-stencil orig thickness padding color expand?)))))
%%%%

The above should be a drop-in replacement for the existing definition. It makes callback optional, defaulting to using grob-transformer. But if one does need to specify a procedure, they can get the original behavior.

Then you should only need to use...

%%%%
  -\tweak stencil #(make-stencil-boxer thickness padding #f color)
%%%%

...for anything.  That might clean up a little bit of logic.


================================================================
3) Note too that the Scheme code is somewhat redundant. Any suggestion from
the Scheme gurus, for cleaning it, will be obviously greatly accepted.

member? should not be needed. Scheme already provides memq, memv, and member where the difference is which form of equality is used--eq?, eqv? and equal?, respectively.

There appears to be a typo where your logic is sorting the "up" list where it should be sorting the "down" list. This exists in both OSOObj and OSOPadder. Even with the correction, the duplication of logic and the number of globals to maintain these lists suggests it would be better to encapsulate this logic.

Assuming I understood your intention, here is one way to do it:

%%%%
\version "2.19.83"

#(define (make-indexer)
  (define ((less y) x) (< x y))
  (let ((indices '()) (prev 0))
    (lambda* (#:optional (index (1+ prev)) (keep-prev? #f) )
      (let loop ((lst (drop-while (less index) indices)) (idx index))
        (if (or (null? lst) (< idx (car lst)))
          (call-with-values
            (lambda () (span (less idx) indices))
            (lambda (before after)
              (set! indices (append before (list idx) after))
              (or keep-prev? (set! prev idx)) idx))
          (loop (cdr lst) (1+ idx)))))))

#(define foo (make-indexer))
#(define baz (make-indexer))

#(format #t "\n (foo)      : expecting 1, got ~a" (foo))
#(format #t "\n (foo 3)    : expecting 3, got ~a" (foo 3))
#(format #t "\n (foo 1)    : expecting 2, got ~a" (foo 1))
#(format #t "\n (foo)      : expecting 4, got ~a" (foo))

#(format #t "\n (baz 2)    : expecting 2, got ~a" (baz 2))
#(format #t "\n (baz 5 #t) : expecting 5, got ~a" (baz 5 #t))
#(format #t "\n (baz)      : expecting 3, got ~a" (baz))
%%%%

Invoking make-indexer will return a procedure for generating unique indices on demand. Each instance tracks its own returned indices to avoid duplicates. The generator function follows your original logic to return the numerically next unused index based on the most recently returned value. The first optional argument is a number requesting a specific index; though, if already used, the next available index is returned. The second optional argument is a boolean indicating the generator should preserve the prior recently returned value.


-- Aaron Hill



reply via email to

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