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" <l...@gmx.de> 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 <kieren_macmil...@sympatico.ca
> >:
>
>> 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: i...@kierenmacmillan.info
>>
>>
>> _______________________________________________
>> lilypond-user mailing list
>> lilypond-user@gnu.org
>> https://lists.gnu.org/mailman/listinfo/lilypond-user
>>
>
>
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to