On Fri, Nov 7, 2014 at 2:19 PM, David Nalesnik <david.nales...@gmail.com> wrote:
> > Hi all, > > Ideally, for this sort of thing there should be a special grob. This grob > could also encompass the very common piano notation that shows that a note > ought to be taken by the other hand (the bracket with one wing). > > The attached file creates a basic grob, which I've called PianoBracket. > Overlooked augmentation dots. See attached. --David
\version "2.19.15" %% functions for grob creation are adapted from `scheme-text-spanner.ly' \header { tagline = ##f } #(define-event-class 'piano-bracket-event 'music-event) #(define (add-grob-definition grob-name grob-entry) (let* ((meta-entry (assoc-get 'meta grob-entry)) (class (assoc-get 'class meta-entry)) (ifaces-entry (assoc-get 'interfaces meta-entry))) (set-object-property! grob-name 'translation-type? ly:grob-properties?) (set-object-property! grob-name 'is-grob? #t) (set! ifaces-entry (append (case class ((Item) '(item-interface)) ((Spanner) '(spanner-interface)) ((Paper_column) '((item-interface paper-column-interface))) ((System) '((system-interface spanner-interface))) (else '(unknown-interface))) ifaces-entry)) (set! ifaces-entry (uniq-list (sort ifaces-entry symbol<?))) (set! ifaces-entry (cons 'grob-interface ifaces-entry)) (set! meta-entry (assoc-set! meta-entry 'name grob-name)) (set! meta-entry (assoc-set! meta-entry 'interfaces ifaces-entry)) (set! grob-entry (assoc-set! grob-entry 'meta meta-entry)) (set! all-grob-descriptions (cons (cons grob-name grob-entry) all-grob-descriptions)))) #(define piano-bracket (lambda (grob) (let* ((th (ly:grob-property grob 'thickness 0.2)) (pro (ly:grob-property grob 'protrusion -0.5)) (pos (ly:grob-property grob 'positions)) (bracket (ly:bracket Y pos th pro)) (layout (ly:grob-layout grob)) (props (ly:grob-alist-chain grob (ly:output-def-lookup layout 'text-font-defaults))) (text (ly:grob-property grob 'text)) (text-stil (ly:text-interface::interpret-markup layout props text)) (text-stil (ly:stencil-aligned-to text-stil Y 0)) (bracket-ext (interval-length (ly:stencil-extent bracket Y))) (mid-bracket-pos (/ (+ (cdr pos) (car pos)) 2)) (text-stil (ly:stencil-translate-axis text-stil mid-bracket-pos Y)) (padding (ly:grob-property grob 'padding)) (bracket (ly:stencil-combine-at-edge bracket X 1 text-stil padding))) bracket))) #(add-grob-definition 'PianoBracket `( (direction . ,RIGHT) (padding . 0.5) (positions . ,ly:arpeggio::calc-positions) (script-priority . 0) (side-axis . ,X) (staff-position . 0.0) (stencil . ,piano-bracket) (Y-extent . ,(grob::unpure-Y-extent-from-stencil ly:arpeggio::pure-height)) (Y-extent . ,grob::unpure-Y-extent-from-stencil) (X-offset . ,ly:side-position-interface::x-aligned-side) (Y-offset . ,ly:staff-symbol-referencer::callback) (meta . ((class . Item) (interfaces . (font-interface side-position-interface staff-symbol-referencer-interface text-interface)))))) #(define piano-bracket-types '( (PianoBracketEvent . ((description . "Used to signal vertical brackets to indicate hands in piano music.") (types . (general-music piano-bracket-event event)) )) )) #(set! piano-bracket-types (map (lambda (x) (set-object-property! (car x) 'music-description (cdr (assq 'description (cdr x)))) (let ((lst (cdr x))) (set! lst (assoc-set! lst 'name (car x))) (set! lst (assq-remove! lst 'description)) (hashq-set! music-name-to-property-table (car x) lst) (cons (car x) lst))) piano-bracket-types)) #(set! music-descriptions (append piano-bracket-types music-descriptions)) #(set! music-descriptions (sort music-descriptions alist<?)) %%% based on `arpeggio-engraver.cc' #(define piano-bracket-engraver (lambda (grob) (let ((event #f) (bracket #f)) `((listeners (piano-bracket-event . ,(lambda (engraver ev) (if (not event) (set! event ev))))) (acknowledgers (stem-interface . ,(lambda (engraver grob source-engraver) (if (ly:grob? bracket) (begin (if (not (ly:grob-parent bracket Y)) (set! (ly:grob-parent bracket Y) grob)) (ly:pointer-group-interface::add-grob bracket 'stems grob))))) (dots-interface . ,(lambda (engraver grob source-engraver) (if (ly:grob? bracket) (ly:pointer-group-interface::add-grob bracket 'side-support-elements grob)))) (rhythmic-head-interface . ,(lambda (engraver grob source-engraver) (if (ly:grob? bracket) (ly:pointer-group-interface::add-grob bracket 'side-support-elements grob))))) (process-music . ,(lambda (trans) (if event (set! bracket (ly:engraver-make-grob trans 'PianoBracket event))))) (stop-translation-timestep . ,(lambda (trans) (set! event #f) (set! bracket #f))))))) pianoBracket = #(make-music 'PianoBracketEvent) %%%%%%%%%%%%%%%%%%%%%% EXAMPLE %%%%%%%%%%%%%%%%%%%%%%%%%%%% \score { \new PianoStaff << \set PianoStaff.connectArpeggios = ##t \new Staff { s1 } \new Staff << \clef bass \new Voice { \voiceOne \override PianoBracket.text = #"RH" \pianoBracket <e g b! dis'>2.\arpeggio \override PianoBracket.font-size = #-2 \pianoBracket <e g b! dis'>4\arpeggio } \new Voice { \voiceTwo \override PianoBracket.text = #"LH" \pianoBracket <e, f, bes,>2.\arpeggio \override PianoBracket.protrusion = #-2 \override PianoBracket.font-size = #-2 \override PianoBracket.font-shape = #'italic \pianoBracket <e, f, bes,>4\arpeggio } >> >> \layout { \context { \Global \grobdescriptions #all-grob-descriptions } \context { \Voice \consists #piano-bracket-engraver } } }
_______________________________________________ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user