[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: improving Janek's \dynamic function (for combo dynamics)
From: |
Thomas Morley |
Subject: |
Re: improving Janek's \dynamic function (for combo dynamics) |
Date: |
Sat, 26 Aug 2017 15:13:08 +0200 |
2017-08-25 0:01 GMT+02:00 Kieren MacMillan <address@hidden>:
> Hi Saul,
>
>> 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.
>
> Perhaps better if this is a preference/parameter, with the default being
> *left-aligned* not *dynamic-aligned*.
> (I would personally keep it left-aligned, and then use the edition-engraver
> to tweak the position of the rare "outliers".)
>
>> 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).
>
> Gould (pg. 107) addresses this. There are definitely more ambiguities and
> potential problems with dynamic-aligning such texts than there are "safe
> situations" (e.g., with preceding rests) — which is why, like you, I always
> prefer to have the dynamic first (when possible).
>
> Cheers,
> Kieren.
Hi all,
the here so far proposed codes fail, if punctuation comes into the game.
\new Staff { c''\dynamic "poco f, but p sub. ma non troppo" }
Thus I based my own code on the previous work of Valentin Villenave:
https://codereview.appspot.com/2220041/
https://codereview.appspot.com/20660044/
One problem for the event-function persists:
To get the first dynamic-word center-aligned under the NoteColumn you
need to do some calculations for tweaking X-offset or
self-alignment-X. (I choosed X-offset because the calculation is a
little easier ...)
Whatever you choose, a certain tweak is hardcoded now. And further
tweaking after applying the event-function will at first not work:
Having set a hardcoded tweak for X-offset makes it impossible to get a
tweak for self-alignment-X to work, neither would an additional
X-offset-tweak work. If I would have gone for self-alignment-X in the
event-function further tweaks of the same property would not work
either.
I think that's what David K explained here:
http://lists.gnu.org/archive/html/lilypond-user/2017-08/msg00194.html
Thus I coded a possibilty to lookup for an additional X-offset-tweak,
which will add it's value to the setting caused by the event-function.
Theoretically this could be done with self-alignment-X as well, but I
regarded the results from a users points of view too unpredictable.
Here's the code:
\version "2.19.64"
#(define (char-punctuation? ch)
(char-set-contains? char-set:punctuation ch))
#(define char-set:dynamics
(char-set #\f #\m #\p #\r #\s #\z))
#(define composite-chars
(char-set-union char-set:dynamics char-set:punctuation))
#(define-markup-command (dynamic-text layout props str) (string?)
"Takes a string, puts out a line-markup.
Parts of @var{strg} containing only characters used for dynamics are printed
using \\dynamic (punctuation-signs are disregarded.
Other parts are printed \\italic.
@lilypond[verbatim,quote]
\\markup {
\\dynamic-text #\"poco f, but p sub. ma non troppo\"
}
@end lilypond
"
(let* ((str-list (string-split str #\space))
(text-markup
(lambda (s) (make-normal-text-markup (make-italic-markup s)))))
(interpret-markup layout props
(make-line-markup
;; iterate over 'str-list'
;; - parts only containing dynamics/punctuation are splitted.
;; dynamics are printed \dynamic, others \italic
;; and finally \concat is applied
;; - others are printed \italic
(map
(lambda (word)
(if (string-every composite-chars word)
(let ((word-lst (string->list word)))
(make-concat-markup
(map
(lambda (ch)
(let ((print-ch (string ch)))
(if (char-punctuation? ch)
(text-markup print-ch)
(make-dynamic-markup print-ch))))
word-lst)))
(text-markup word)))
str-list)))))
dynamicH =
#(define-event-function (strg) (string?)
"Takes a string and puts out a (composed) dynamic script.
If the first word of the composed string is a dynamic sign, the ready dynamic-
script center-aligns this word at the parent-grob.
Further adapting the result with additional tweaks for X-offset are possible.
"
(let* ((first-word (car (string-split strg #\space)))
;; don't take punctuation into account
(trimmed-first-word (string-trim-both first-word char-set:punctuation))
(offset
(lambda (grob)
(let* (;; get previous tweaks for X-offset and add their values
;; they are added to the final result
(x-offset-tweaks
(filter
(lambda (tw)
(and (number? (cdr tw)) (eq? (car tw) 'X-offset)))
(ly:prob-property
(ly:grob-property grob 'cause)
'tweaks)))
(x-off (apply + (map cdr x-offset-tweaks))))
;; if 'first-word' is a dynamic, calculate it's x-extent and
;; return half of it's value
;; always take 'x-off' into account
(if (string-every composite-chars first-word)
(let* ((layout (ly:grob-layout grob))
(props
(ly:grob-alist-chain grob
(ly:output-def-lookup
layout
'text-font-defaults)))
(first-word-stil
(interpret-markup layout props
(make-dynamic-text-markup trimmed-first-word)))
(first-word-stil-center
(interval-center
(ly:stencil-extent first-word-stil X))))
(+ x-off (- first-word-stil-center)))
;; adding -1 is my choice
(+ x-off -1))))))
#{
-\tweak X-offset $offset
#(make-dynamic-script (make-dynamic-text-markup strg))
#}))
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\new StaffGroup <<
\new Staff { c''\dynamicH "fffff dramatically" }
\new Staff { c''-\tweak X-offset -1 -\dynamicH "fffff dramatically" }
\new Staff { c''-\tweak X-offset 1 -\dynamicH "fffff dramatically" }
\new Staff { c''\dynamicH "fffff,,,,,,,,,, dramatically" }
\new Staff { c''\dynamicH "poco f, but p sub. ma non troppo" }
\new Staff { c''\dynamicH "slightly more pp" }
>>
Though, because of the problems mentioned above I'm not sure whether
putting dynamic-script-creation _and_ settings for aligning it into
the same function.
The possibility to create dynamic-scripts on the fly and have them
aligned properly while having a nice user interface is nice, ofcourse,
but one needs to set more or less hardcoded defaults which then are
not changeable easily anymore, if at all.
HTH,
Harm
- improving Janek's \dynamic function (for combo dynamics), Kieren MacMillan, 2017/08/15
- Re: improving Janek's \dynamic function (for combo dynamics), Shevek, 2017/08/19
- Re: improving Janek's \dynamic function (for combo dynamics), Kieren MacMillan, 2017/08/20
- Re: improving Janek's \dynamic function (for combo dynamics), Lukas-Fabian Moser, 2017/08/24
- Re: improving Janek's \dynamic function (for combo dynamics), Saul Tobin, 2017/08/24
- Re: improving Janek's \dynamic function (for combo dynamics), Kieren MacMillan, 2017/08/24
- Re: improving Janek's \dynamic function (for combo dynamics),
Thomas Morley <=
- Re: improving Janek's \dynamic function (for combo dynamics), David Kastrup, 2017/08/26
- Re: improving Janek's \dynamic function (for combo dynamics), Thomas Morley, 2017/08/26
- Re: improving Janek's \dynamic function (for combo dynamics), David Kastrup, 2017/08/26
- Re: improving Janek's \dynamic function (for combo dynamics), Thomas Morley, 2017/08/26
- Re: improving Janek's \dynamic function (for combo dynamics), David Kastrup, 2017/08/26
- Re: improving Janek's \dynamic function (for combo dynamics), Thomas Morley, 2017/08/27
- Re: improving Janek's \dynamic function (for combo dynamics), Thomas Morley, 2017/08/27
- Re: improving Janek's \dynamic function (for combo dynamics), David Kastrup, 2017/08/27
- Re: improving Janek's \dynamic function (for combo dynamics), Thomas Morley, 2017/08/27
- Re: improving Janek's \dynamic function (for combo dynamics), David Kastrup, 2017/08/27