Hi David,
thank you for your head start.
See my attached results. I'd be grateful for any comments to improve the
coding.
One basic question is if it will be possible to extend it with other
types (dynamic text spanners etc.) without having to write another
engraver with duplicating code.
And unfortunately the attached file compiles, while applying it to a
real-world file I get an error:
In procedure ly:grob-set-property! in expression (ly:grob-set-property!
(car equal-hairpins) (quote color) ...):
/home/uliska/git/bfsc/fried/das-trunkne-lied/library/ly/to-lilylib/remove-double-hairpins-engraver.ily:91:19
<1>: Wrong type argument in position 1 (expecting Grob): (#<Grob Hairpin
> #<Grob Hairpin >)
Looks quite similar to the problems I had during development, but I
don't see yet what is actually wrong with it.
Best
Urs
Am 11.04.2015 um 16:07 schrieb David Nalesnik:
On Sat, Apr 11, 2015 at 9:01 AM, David Nalesnik
<david.nales...@gmail.com <mailto:david.nales...@gmail.com>> wrote:
Hi Urs,
On Sat, Apr 11, 2015 at 3:31 AM, Urs Liska <u...@openlilylib.org
<mailto:u...@openlilylib.org>> wrote:
Hi,
this is related to my previous thread and particularly to the
file attached to
http://lists.gnu.org/archive/html/lilypond-user/2015-04/msg00263.html
If I have a Scheme engraver listening to TextScript-s I can
get a list of entries at the same timestep and then compare
them for equality.
This even works without changes for DynamicText because that
also has a 'text property. But if i have spanners such as
hairpins it's not that simple anymore. So I'm asking myself if
I can access the starting and ending timesteps of hairpins
that are present in such a list. Of course I can collect
hairpins in a list like I can collect TextScripts (currently
I'm listening for line-interface). But is it possible to
retrieve the start *and* end position of such items?
The goal is to iterate over the list and find matching
hairpins to remove duplicate ones.
A simple way to determine when a hairpin starts and ends is by
using an acknowledger and an end-acknowledger:
myEngraver =
#(lambda (context)
(make-engraver
(acknowledgers
((hairpin-interface engraver grob source-engraver)
(format #t "My start is at ~a~%"
(ly:context-current-moment context))))
(end-acknowledgers
((hairpin-interface engraver grob source-engraver)
(format #t "My end is at ~a~%" (ly:context-current-moment
context))))
))
\layout {
\context {
\Score
\consists \myEngraver
}
}
{
c''1~\<
c''1\!
c''2.\< c''4\!
c''1~\>
\break
c''2~ c''\!
}
If you're collecting the hairpins for processing later, you could
find the timings of beginnings and endings through the columns at
their bounds:
myEngraver =
#(lambda (context)
(let ((hairpins '()))
(make-engraver
(acknowledgers
((hairpin-interface engraver grob source-engraver)
(set! hairpins (cons grob hairpins))))
((finalize trans)
(for-each
(lambda (hp)
(format #t "BEGINNING ~a END: ~a~%"
Not that you will use this method, but the following two lines ought to be
(grob::when (ly:spanner-bound hp LEFT))
(grob::when (ly:spanner-bound hp RIGHT))))
(grob::when (ly:item-get-column (ly:spanner-bound hp
LEFT)))
(grob::when (ly:item-get-column (ly:spanner-bound hp
RIGHT)))))
hairpins))
)))
DN
\version "2.19.18"
% Scheme engraver to remove duplicate hairpins (e.g. caused by the partcombiner)
% author: Urs Liska
% source: http://lists.gnu.org/archive/html/lilypond-user/2015-04/msg00276.html
% (Stub by David Nalesnik)
% String representation of a moment
#(define (moment->string mom)
(let*
((num (ly:moment-main-numerator mom))
(den (ly:moment-main-denominator mom)))
(string-append
(number->string num)
"-"
(number->string den))))
% Symbol representation of a moment, suitable as an alist key
#(define (moment->symbol mom)
(string->symbol (moment->string mom)))
% Symbol representation of a starting point of a hairpin
#(define (hp-start-symbol hp)
(moment->symbol
(grob::when (ly:spanner-bound hp LEFT))))
% Symbol representation of a hairpin end
% This is suffixed with a direction indicator
#(define (hp-end-symbol hp)
(string->symbol
(string-append
(moment->string
(grob::when (ly:spanner-bound hp RIGHT)))
"-"
(number->string (ly:grob-property hp 'grow-direction)))))
removeDoubleHairpinsEngraver =
#(lambda (context)
(let ((all-hairpins '())
(simultaneous-hairpins '()))
(make-engraver
(acknowledgers
((hairpin-interface engraver grob source-engraver)
(set! all-hairpins (cons grob all-hairpins))))
((finalize trans)
(begin
;; generate an alist simultaneous-hairpins containing lists
;; with all hairpins starting at the same moment
;; This discerns between equal and different hairpins
(for-each
(lambda (hp)
(let*
;; symbols to act as keys in alists
((start-symbol (hp-start-symbol hp))
(end-symbol (hp-end-symbol hp))
;; list of hairpins with the same starting point as the current one
(hp-siblings (assoc-ref simultaneous-hairpins start-symbol)))
(if (not hp-siblings)
;; no hairpin with the current starting moment yet
;; -> initialize node
(set! simultaneous-hairpins
(assoc-set! simultaneous-hairpins start-symbol
(list
(list end-symbol hp))))
;; There is already a hairpin starting at the current moment
;; -> check if we have an equal hairpin or not
(let
;; Equal hairpins are hairpins that also match the end-symbol
((equal-hairpins (assoc-ref hp-siblings end-symbol)))
(if equal-hairpins
(set! simultaneous-hairpins
(assoc-set!
simultaneous-hairpins
start-symbol
(list (list end-symbol (append equal-hairpins (list
hp)))))))))))
all-hairpins)
;; Walk over the equal hairpins
(for-each
(lambda (moment)
(let ((equal-hairpins (cadadr moment)))
;; non-equal hairpins are also passed into this function,
;; so we have to skip it
(if (list? equal-hairpins)
(begin
; temporarily color the kept hairpin red
(ly:grob-set-property! (car equal-hairpins) 'color red)
;; remove the stencil for all subsequent hairpins
(for-each
(lambda (duplicate)
(ly:grob-set-property! duplicate 'stencil #f))
(cdr equal-hairpins))))))
simultaneous-hairpins))))))
\layout {
\context {
\Score
\consists \removeDoubleHairpinsEngraver
}
}
music = {
\partcombineApart
c''1~\<
c''1\!
c''2.\< c''4\!
c''1~\>
\break
c''2~ c''\!
}
\score {
\new Staff {
\partcombine
{
\music
c''2 \< c''2 \!
c''1 \>
c''1 \>
c''1 \!
}
\transpose c c, {
\music
c''1
c''2 \> c''2 \!
c''1 \<
c''1 \!
}
}
\layout {}
}
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user