lilypond-user
[Top][All Lists]
Advanced

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

Re: improving Janek's \dynamic function (for combo dynamics)


From: Saul Tobin
Subject: Re: improving Janek's \dynamic function (for combo dynamics)
Date: Thu, 24 Aug 2017 14:51:44 -0700

Thanks for putting that together. I'm no Scheme expert, but it looks good to me.

Personally, I think the behavior would be better if it aligned on the first dynamic to appear in the markup, rather than default to left. With something like "poco f", it can be visually unclear where the f is supposed to begin — at the beginning of "poco" or at the "f"? That's a bit clearer of the dynamic itself is always the alignment point (though I prefer to always have the dynamic first for maximum clarity). The Scheme code to find the first appearance of a dynamic would be a bit more intricate, though, since it would have to keep track of the width of text on either side of the alignment point.

On Aug 24, 2017 3:16 AM, "Lukas-Fabian Moser" <address@hidden> wrote:
Hello,

I'm almost embarassed to post this as it's the ugly result of "trying to learn scheme and lilypond internals all at the same time" - but at least it seems to work. I've tried to achieve exactly what you described: _If_ the first word is a dynamic _expression_, then Shevek's adjustment is applied.

Best
Lukas


%%%  SNIPPET BEGINS
\version "2.19.44"

#(use-modules (ice-9 regex))

dynamic =
#(define-event-function (text) (markup?)
   (if (string? text)
       (let* ((underscores-replaced
               (string-map
                (lambda (x) (if (eq? x #\_) #\space x))
                text)
               )
              (split-text (string-split underscores-replaced #\space))
              (first-is-dynamic (string-match "^[mrzfps]*$" (car split-text)))
              (formatted (map
                          (lambda (word)
                            (if (string-match "^[mrzfps]*$" word)
                                (markup #:dynamic word #:hspace 0.25)
                                (markup #:normal-text #:fontsize 0.625 #:italic word)))
                          split-text))
              (offset (lambda (grob)
                        (if first-is-dynamic
                            (let* (
                                    (first-as-dynamic
                                     (list (markup #:dynamic (car split-text)))
                                     )
                                    (layout (ly:grob-layout grob))
                                    (props (ly:grob-alist-chain grob
                                             (ly:output-def-lookup layout 'text-font-defaults)))
                                    (dyn-X-extent
                                     (ly:stencil-extent

                                      (ly:text-interface::interpret-markup layout props (make-line-markup first-as-dynamic))
                                      X))
                                    (width (abs
                                            (- (cdr dyn-X-extent) (car dyn-X-extent))))
                                    )
                              (- 1 (/ width 2))
                              )
                            0)
                        )))
         #{
           -\tweak X-offset #offset
           #(make-dynamic-script (make-line-markup formatted))
         #})

       ;; user provided a full-blown markup, so we don't mess with it:
       #{
         #(make-dynamic-script (markup #:normal-text #:fontsize 0.625 text))
       #}))

<<
  \new Staff { c''\dynamic "fffff dramatically" }
  \new Staff { c''\dynamic "slightly more pp" }
>>
%%%  SNIPPET ENDS




2017-08-20 22:24 GMT+02:00 Kieren MacMillan <address@hidden>:
Hi Shevek,

> I posted a snippet to do correct custom dynamic alignment a month or so ago.

Yes, I know. I like the alignment very much.

But I prefer Janek's interface, which offers the ability to put an arbitrary string (e.g., "poco f, but p sub. ma non troppo") and it Does The Right Thing™… well, the Right Thing modulo alignment when the leading word is a dynamic.  =\

> I tried just copy and pasting my offset callback into Janek's snippet, but
> it doesn't quite work because the callback relies on assuming the dynamic is
> at the beginning, and any additional text follows it.

I think a single "if" added to Janek's function would suffice: if the word in question is a dynamic (which Janek's function already works out) *AND* it's the first word (Janek's function *doesn't* do this), then apply an appropriate X-offset adjustment (similar or identical to yours), otherwise left-align (which Janek's function already does).

I'm scrambling to get a commission engraving out the door — what else is new!? — so I don't have time to climb the Scheme-fu learning curve to get that done right now… If nobody's done it before this score gets sent off (mid-week?), I'll try to tackle it myself.

Thanks,
Kieren.
________________________________

Kieren MacMillan, composer
‣ website: www.kierenmacmillan.info
‣ email: address@hidden


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


reply via email to

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