[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: multiple \keys and \time problem
From: |
Werner LEMBERG |
Subject: |
Re: multiple \keys and \time problem |
Date: |
Mon, 04 Sep 2017 21:35:39 +0200 (CEST) |
>>> The idea is to make `supressRedundantKeySigs' set an
>>> `is-redundant' flag in the redundant grob instead of calling
>>> `ly:grob-suicide!'. A modified stencil function for KeySignature
>>> can now check this flag together with `ly:item-break-dir' to
>>> suppress the grob if necessary.
>
> I've no clue how to do it different, so this might be the best we
> can hope of.
Thanks for confirmation. I also think that this is the correct
solution.
> I think we should not ignore user-settings, better: we should
> provide a mechanism to reflect them. Why not similiar to Clef?
> Ignore repeated settings unless the relevant context-property is set
> true.
>
> { \clef alto R1
> \clef alto R1
> \set Staff.forceClef = ##t \clef alto R1 }
Yes!
> One could use make-engrever...
> Maybe the if-expresseion in the stencil-override could be:
>
> (if (or at-bol? (not is-redundant?))
> (ly:key-signature-interface::print grob)
> empty-stencil)
Thanks. Attached is a new version, with another slight improvement
and more documentation.
Werner
% Suppress redundant time and key signatures.
%
% Lilypond already does something similar with Clef grobs.
% Collect TimeSignature grobs in a list, then make the elements of the list
% which have the same fractions as the previous one remove themselves.
%
suppressRedundantTimeSig =
#(lambda (ctx)
(let ((time-sig '()))
`((acknowledgers
(time-signature-interface
. ,(lambda (engraver grob source-engraver)
(set! time-sig (cons grob time-sig)))))
(finalize
. ,(lambda (trans)
(reduce
(lambda (elem prev)
(if (equal? (ly:grob-property elem 'fraction)
(ly:grob-property prev 'fraction))
(begin
(ly:grob-suicide! elem)
prev)
elem))
'()
(reverse time-sig))
(set! time-sig '()))))))
% A new property `is-redundant', needed for KeySignature grobs.
%
#(set-object-property! 'is-redundant 'backend-type? boolean?)
% Collect KeySignature grobs in a list, then set `is-redundant' for all
% elements of the list which have the same signature as the previous one.
%
suppressRedundantKeySig =
#(lambda (ctx)
(let ((key-sig '()))
`((acknowledgers
(key-signature-interface
. ,(lambda (engraver grob source-engraver)
(let* ((cause (ly:grob-property grob 'cause)))
(if (and (ly:stream-event? cause)
(eq? (grob::name grob) 'KeySignature))
(set! key-sig
(cons
(list
grob
(cons (ly:prob-property cause 'tonic)
(ly:prob-property cause 'pitch-alist)))
key-sig)))))))
(finalize
. ,(lambda (trans)
(reduce
(lambda (elem prev)
(if (equal? (cdr elem) (cdr prev))
(ly:grob-set-property! (car elem) 'is-redundant #t))
elem)
'()
(reverse key-sig))
(set! key-sig '()))))))
% A stencil for KeySignature grobs that outputs a key signature only if it
% is at the beginning of a line, or if the `is-redundant' flag is not set.
%
#(define-public (remove-redundant-keys-stencil grob)
"Only print key signatures that change the key."
(let* ((is-redundant? (eq? (ly:grob-property grob 'is-redundant) #t))
(at-bol? (eq? (ly:item-break-dir grob) 1)))
(if (or at-bol? (not is-redundant?))
(ly:key-signature-interface::print grob)
empty-stencil)))
% An example.
%
\score {
\relative c' {
\key d \major \time 2/2 d1 |
\key d \major \time 2/2 d1 \break |
\key d \major \time 2/2 d1 |
d1 \break |
\key d \major \time 2/2 d1 |
\key d \minor \time 2/2 d1 |
\key d \minor \time 3/4 d2. |
}
\layout {
\context {
\Score
\consists #suppressRedundantTimeSig
\consists #suppressRedundantKeySig
\override KeySignature.stencil = #remove-redundant-keys-stencil
}
}
}
% eof