OK,

On Thu, Mar 13, 2014 at 11:43 AM, David Nalesnik
<[email protected]>wrote:


> I'll post a revision of this in a little while.  It incorporates reduce as
> David K. suggests, and it also allows you to specify alignments as pairs:
> left/center/right of one to left/center/right of the other.
>
> I'm not too wild about it, as the function uses 'extra-offset, which is
> usually "contraindicated."
>

Here's a bit of a revision of the original function.

**It finds the nearest whatever-it-is-you-want-to-align-your-grob-to in a
more elegant way.  (Thank you, David K., for suggesting it.)  Note that it
might snap to a grob you didn't expect, since we simply look for the
closest such grob.

**It allows you to specify alignment points for both objects.  The old
pattern is supported.  If you give it a single number: #-1 --> LEFT to
LEFT, #0 --> CENTER to CENTER, #1 --> RIGHT to RIGHT

**I did not address the interface.

For what it's worth...

--David
\version "2.18.0"

alignGrob =
#(define-music-function (parser location grob-to-align reference-grob dir extra-offset-Y)
                        (symbol? symbol? number-or-pair? number?)
 #{
    \overrideProperty  $grob-to-align . extra-offset #(lambda (grob)
      (let* ((sys (ly:grob-system grob))
             (array (ly:grob-object sys 'all-elements))
             (default-coord (ly:grob-relative-coordinate grob sys X))
             (grob-name (lambda (x) (assq-ref (ly:grob-property x 'meta) 'name)))
             (lst (filter
                    (lambda (x) (eq? reference-grob (grob-name x)))
                    (ly:grob-array->list array)))
             ;; find the grob with the X-coordinate closest to object to be aligned
             (ref
               (reduce
                 (lambda (elem prev)
                   (if (< (abs (- default-coord
                                   (ly:grob-relative-coordinate elem sys X)))
                           (abs (- default-coord
                                   (ly:grob-relative-coordinate prev sys X))))
                       elem prev))
                 '()
                 lst))
             ;; if user specified single direction, use it for both objects
             (dir (if (pair? dir) dir (cons dir dir)))
             ;; Select requested alignment.  Note: fractional values are
             ;; leveled off to RIGHT or LEFT.
             (proc
               (lambda (x)
                 (cond
                   ((= x 0) interval-center)
                   ((< x 0) car)
                   (else cdr)))))
        
        (if (ly:grob? ref)
            (cons
              (- ((proc (cdr dir)) (ly:grob-extent ref sys X))
                 ((proc (car dir)) (ly:grob-extent grob sys X)))
              extra-offset-Y)
            (cons 0.0 0.0))))
  #}
)

ln = \markup \with-color #red \draw-line #'(0 . 6)
uparrow = \markup \combine \arrow-head #Y #UP ##f \draw-line #'(0 . -2)
downarrow = \markup \combine \arrow-head #Y #DOWN ##f \draw-line #'(0 . 2)

\relative c' {

  %% bar 1
  \time 3/4
  \key d \major
  d
  \alignGrob TextScript KeySignature #CENTER #6
  e-\ln
  \alignGrob TextScript Clef #RIGHT #5.5
  fis-\ln

  %% bar 2
  \time 5/4
  \alignGrob TextScript BarLine #CENTER #-5.5
  e^\ln
  \alignGrob TextScript Hairpin #RIGHT #1
  d(_\ln
  \alignGrob TextScript Slur #CENTER #0
  e_\uparrow
  \alignGrob TextScript StaffSymbol #CENTER #0
  fis^\markup \center-column { "mid-staff" \downarrow  } d)\<

  %% bar 3
  \time 3/4
  \alignGrob TextScript TimeSignature #LEFT #-5
  e^\ln
  \alignGrob TextScript TimeSignature #RIGHT #-5
  fis^\ln d

  %% bar 5
  \alignGrob TextScript Stem #CENTER #-5.5
  e\!^\ln fis
  \alignGrob TextScript Accidental #CENTER #0
  d!_\uparrow

  %% bar 6
  \time 2/4
  \alignGrob Stem NoteHead #CENTER #0
   fis
  \alignGrob Stem NoteHead #CENTER #0
  \alignGrob Script BarLine #CENTER #0.5
  \alignGrob TextScript StaffSymbol #RIGHT #0
  d\fermata _"end"
  \bar "||"
}

thickln = \markup {
  \override #'(thickness . 5) \with-color #red \draw-line #'(0 . 6)
}

\new Staff {
  \relative c' {
    \override Staff.TimeSignature.layer = #2
    \time 3/4
    \alignGrob TextScript TimeSignature #'(1 . -1) #5.5
    %% alternately:
    %% \alignGrob TextScript TimeSignature #(cons RIGHT LEFT) #5.5
    s2.-\thickln
    \time 3/4
    \alignGrob TextScript TimeSignature #'(0 . -1) #5.5
    s-\thickln
    \time 3/4
    \alignGrob TextScript TimeSignature #'(-1 . -1) #5.5
    s-\thickln
    \alignGrob TextScript TimeSignature #'(1 . 0) #5.5
    \time 3/4
    s-\thickln
    \alignGrob TextScript TimeSignature #'(0 . 0) #5.5
    \time 3/4
    s-\thickln
    \alignGrob TextScript TimeSignature #'(-1 . 0) #5.5
    \time 3/4
    s-\thickln
    \alignGrob TextScript TimeSignature #'(1 . 1) #5.5
    \time 3/4
    s-\thickln
    \alignGrob TextScript TimeSignature #'(0 . 1) #5.5
    \time 3/4
    s-\thickln
    \alignGrob TextScript TimeSignature #(cons LEFT RIGHT) #5.5
    \time 3/4
    s-\thickln
    
  }
}
_______________________________________________
lilypond-user mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to