On 27 February 2012 13:48, Graham Percival <gra...@percival-music.ca> wrote:
> What would be involved in making a clean solution for this? I > imagine that a separate TextMark engraver (just like the > RehearsalMark engraver and MetronomeMark engravers) would do the > trick, but that's a bunch of icky C++ code. Is there any way to > use scheme to create a new engraver that behaves like an existing > engraver (i.e. TextMark), but has its own data (so it doesn't > merge the rehearsal mark event with the "text mark" event?) Attached is a scheme engraver I hacked up a few years ago. It naturally has a few limitations, particularly if you use multiple \mark \default commands at the same timestep. Cheers, Neil
\version "2.15.8" #(define (multi-mark-engraver ctx) (let ((texts '()) (final-texts '()) (events '())) `((start-translation-timestep . ,(lambda (trans) (set! final-texts '()))) (listeners (mark-event . ,(lambda (trans ev) (set! events (cons ev events))))) (acknowledgers (break-alignment-interface . ,(lambda (trans grob source) (for-each (lambda (mark) (set! (ly:grob-parent mark X) grob)) texts)))) (process-music . ,(lambda (trans) (for-each (lambda (ev) (let* ((mark-grob (ly:engraver-make-grob trans 'RehearsalMark ev)) (label (ly:event-property ev 'label)) (formatter (ly:context-property ctx 'markFormatter))) (if (and (procedure? formatter) (not (markup? label))) (begin (if (not (number? label)) (set! label (ly:context-property ctx 'rehearsalMark))) (if (and (integer? label) (exact? label)) (set! (ly:context-property ctx 'rehearsalMark) (1+ label))) (if (number? label) (set! label (apply formatter (list label ctx))) (ly:warning "rehearsalMark must have integer value")))) (if (markup? label) (begin (set! (ly:grob-property mark-grob 'text) label) (let ((dir (ly:event-property ev 'direction))) (and (ly:dir? dir) (set! (ly:grob-property mark-grob 'direction) dir)))) (ly:warning "mark label must be a markup object")) (set! texts (cons mark-grob texts)))) (reverse events)))) (stop-translation-timestep . ,(lambda (trans) (if (pair? texts) (let ((staves (ly:context-property ctx 'stavesFound)) (priority-index 0)) (for-each (lambda (grob) (let ((my-priority (ly:grob-property grob 'outside-staff-priority 1500))) (for-each (lambda (stave) (ly:pointer-group-interface::add-grob grob 'side-support-elements stave)) staves) (set! (ly:grob-property grob 'outside-staff-priority) (+ my-priority priority-index)) (set! priority-index (1+ priority-index)) (set! final-texts (cons grob final-texts)))) (reverse texts)) (set! texts '()) (set! events '()))))) (finalize . ,(lambda (trans) (and (pair? final-texts) (for-each (lambda (grob) (set! (ly:grob-property grob 'break-visibility) end-of-line-visible)) final-texts))))))) \layout { \context { \Score \remove "Mark_engraver" \consists #multi-mark-engraver } } markDown = #(define-music-function (parser location text) (markup?) (make-music 'MarkEvent 'direction DOWN 'label text)) \relative c' { \mark "1" \mark "2" \mark "3" \markDown "1" \markDown "2" \markDown "3" c1 } \relative c' { c1 \mark \default \mark "play violently" d }
_______________________________________________ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel