Hello,

On Thu, Mar 13, 2014 at 12:25 PM, David Nalesnik
<david.nales...@gmail.com>wrote:
>
>
> On Thu, Mar 13, 2014 at 11:43 AM, David Nalesnik <david.nales...@gmail.com
> > 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.
>

Well, not one to leave well enough alone, here's another version.

I think at the time this was first posted years ago, \overrideProperty was
necessary.  Now it appears \override is the better choice.  Changed
accordingly.  Put \once before \alignGrob for \once \override.

You can now input the name of a grob as Context.Grob

It's possible to displace the X-alignment.  The reason I allow this is that
I've found a little tweaking may be necessary.  The final example of the
attached file shows why.  Here, without the tiny offset to X (0.08), the
barline doesn't look right--due
to the fact that the rounded end of the staff-lines isn't considered in the
staff's grob-extent.  0.08 happens to be the "blot-diameter" or the
protruding rounded ends.
.

>
> **I did not address the interface.
>

I have no idea how to make the user's experience nicer.  Suggestions
welcome.

Anyway, the syntax as it stands is this:

[\once] \alignGrob  [Context].Grob-to-align  [Context].Grob-to-align-to
 alignment-dir(s)  extra-offset(s)

*The second Context isn't needed ever, but _not_ permitting it seems more
confusing to me.

*alignment-dir(s):
  --a number (-1 or LEFT, 0 or CENTER, 1 or RIGHT; fractional values are
converted to one of these) or a pair of such numbers
  --if a single number is given, the same side of both objects is used

*extra-offset(s):
  --if a single number, that's the Y part of the override of extra-offset
that \alignGrob basically is
  --if a pair, the first number is a correction (in staff-spaces) to the
new alignment of X (an "extra-extra-offset");
    the second number is, again, the Y value of extra-offset.

Yuck.  Well, the attached examples should make it clearer.

Several observations:

This all is a glorified version of \override Grob.extra-offset.
 'extra-offset is useful for recklessly moving stuff around in
post-processing.  You, the user, are the collision detector.

The automated alignment concerns the X-axis only.

Enjoy,
David
\version "2.18.0"

alignGrob =
#(define-music-function (parser location grob-to-align reference-grob dir extra-displacement)
                        (symbol-list? symbol-list? number-or-pair? number-or-pair?)
 #{
    \override $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))
             ;; We only want the name of the grob we're aligning to.  If
             ;; input is Context.Grob, deal with it silently.
             (reference-grob
               (if (pair? reference-grob)
                   (car (reverse reference-grob))
                   reference-grob))
             (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))))
             (grob-side (proc (car dir)))
             (ref-side (proc (cdr dir)))
             (extra-X-offset
               (if (pair? extra-displacement)
                   (car extra-displacement)
                   0.0))
             (extra-Y-offset
               (if (pair? extra-displacement)
                   (cdr extra-displacement)
                   extra-displacement)))
        
        (if (ly:grob? ref)
            (cons
              (+
                (- (ref-side (ly:grob-extent ref sys X))
                   (grob-side (ly:grob-extent grob sys X)))
                extra-X-offset)
              extra-Y-offset)
            (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
    
  }
}
%}
\new Staff {
  \override Staff.StaffSymbol.width = 50
  \alignGrob Score.BarLine StaffSymbol #RIGHT #'(0.08 . 0)
  c''4 d e 
  f
  s2.
}
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to