Hi Jim

On Sun, Nov 13, 2011 at 9:57 AM, Jim Long <[email protected]> wrote:
>
> > (...)  I do recall hitting a wall once when I discovered that Lily won't
> > accept two consecutive 'mark' directives, like for a
> >
> > \mark default
> > \mark \markup \musicglyph #"scripts.segno"
> >
> > when you want to have rehearsal letter A and a Segno at the same
> > location.  I have noticed the \concat and \column operators, so
> > maybe using \column like
> >
> > \mark \markup \column { { \musicglyph #"scripts.segno" } { \mark default
> } }
> >
> > is the way to put a Segno vertically aligned over a rehearsal letter?
>
> See:
>
> http://lsr.dsi.unimi.it/LSR/Item?id=735
>
> and
>
> http://lsr.dsi.unimi.it/LSR/Item?id=736
>
> another example
>
> http://lsr.dsi.unimi.it/LSR/Item?id=575
>
> more complex
>
> http://lsr.dsi.unimi.it/LSR/Item?id=202
>
> I think best and most comfortable is using the new multi-mark-engraver by
Neil Puttock.
->
http://old.nabble.com/Nice-workaround-for-simultaneous-rehearsal-marks-%E2%80%93-thanks-Neil!-td32212763.html

>
> (...)
> > BTW, is there any hope for my suggestion of being able to use a
> > 'chordmode' section as a RhythmicStaff music expression without
> > getting the funny doubled note heads from the pitch-collapse
> > engraver?
>
> Searching in the archives I found some helpful functions by Gilles
Thibault.
-> http://lists.gnu.org/archive/html/lilypond-user/2009-01/msg00588.html
-> http://lists.gnu.org/archive/html/lilypond-user/2009-01/msg00628.html

If you add \accepts "ChordNames" to the RhythmicStaff they will work. (To
be complete I added the deleteFirstNote-function, although it isn't used in
the snippet below)

Finally I append my own chordAlign-function.

HTH,
  Harm
\version "2.14.2"

% http://lists.gnu.org/archive/html/lilypond-user/2009-01/msg00588.html
% http://lists.gnu.org/archive/html/lilypond-user/2009-01/msg00628.html 

#(define (has-duration? music) 
(ly:duration? (ly:music-property music 'duration))) 

#(define (not-has-duration? music) 
(not (has-duration? music))) 

keepsOnlyFirstNote = #(define-music-function (parser location music) (ly:music?) 
(music-map 
  (lambda (evt) 
   (if (eq? 'EventChord (ly:music-property evt 'name)) 
      (let ((elts (ly:music-property evt 'elements))) 
       (if (has-duration? (car elts)) 
            (ly:music-set-property! evt 'elements (cons 
                 (car elts) 
                 (filter not-has-duration? (cdr elts))))))) 
  evt) 
music)) 

deleteFirstNote = #(define-music-function (parser location music) (ly:music?) 
(music-map 
  (lambda (evt) 
   (if (eq? 'EventChord (ly:music-property evt 'name)) 
      (let ((elts (ly:music-property evt 'elements))) 
           (if (has-duration? (car elts)) 
                (ly:music-set-property! evt 'elements  (cdr elts))))) 
  evt) 
music)) 

% http://old.nabble.com/Nice-workaround-for-simultaneous-rehearsal-marks-%E2%80%93-thanks-Neil!-td32212763.html
% defined by Neil Puttock

#(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)))))))
                             
markDown =
#(define-music-function (parser location text) (markup?)
   (make-music 'MarkEvent
               'direction DOWN
               'label text))

myMark =
#(define-music-function (parser location text) (markup?)
  (make-music 'MarkEvent
              'label text))

toCoda = {
 \tweak #'self-alignment-X #RIGHT
 \tweak #'break-visibility #begin-of-line-invisible
 \myMark \markup  { to \hspace #1.25 \raise #1.25  \musicglyph #"scripts.coda" }
}

smiley = {
 \tweak #'color #red
 \tweak #'break-visibility #begin-of-line-invisible
 \markDown \markup \rotate #-90 { ";-)" }
}

chordAlign =
#(define-music-function (parser location dir)(number?)
#{
        #(define (chordNameCallback grob)
	"
	LEFT = -1
	RIGHT = 1
	CENTER = 0
	"
          (let* ((ch (ly:text-interface::print grob)))
          	(ly:stencil-aligned-to ch X $dir)))
   	
        %\once 
        \override ChordNames.ChordName #'stencil = #chordNameCallback
#})
\paper {
%  annotate-spacing = ##t
}

Changes = \chordmode { \chordAlign #-0.3 r4 g:m r4 f8 d8:m7 ~ d1:m7 r4 g:m r4 f8 d8:m7 ~ d1:m7}
Melody  = \relative c'' { 
        g4 c a f ~ 
        \mark\default \markDown \markup { \bold "1" }
        f1 \break  
        \mark\default \toCoda
        g4 c a f ~ 
        \mark\default \markDown \markup { \bold "3" }
        f1	   
        \mark\default \smiley
}



\score {
        <<
        \new RhythmicStaff \with { 
        	\override VerticalAxisGroup #'staff-staff-spacing =		
 		      #'((basic-distance . 1)
 		         (minimum-distance . 1)
 		         (padding . 1))
 	\accepts "ChordNames"
        } 
        <<
        \new Voice \chords { \Changes }
        \new Voice { \keepsOnlyFirstNote \Changes }
        >>
          
        \new Staff {
                \key f \major
                \clef treble
                \time 4/4
                \Melody  
        }
 >>
 \layout {
   indent=0
            \context {
            	    \Score
            	      \remove "Mark_engraver"
            	      \consists #multi-mark-engraver
            	      \consists "Tweak_engraver"
            }
            \context {
            	    \ChordNames
            	      \override ChordName #'Y-offset = #4
            	      \override ChordName #'font-size = #'-1
            	      noChordSymbol = ##f
            	      chordChanges = ##t
            }
            \context {
            	    \RhythmicStaff
     	      \override StaffSymbol #'staff-space = #(magstep -3)
     	      \override StaffSymbol #'line-count = #0
     	      \override BarLine #'stencil = ##f
     	      \override TimeSignature #'transparent = ##t
     	      \override NoteHead #'style = #'slash 
     	      fontSize = #-7
     	      \override Stem #'direction = #UP % = \stemUp 
            }
            
 } % layout
} % score  
_______________________________________________
lilypond-user mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to