Hi all,
On Thu, Mar 13, 2014 at 12:41 PM, David Kastrup <[email protected]> wrote:
>
> You should likely also use interval-index instead of doing your own code
> internally. It's shorter and much more flexible as it is not restrained
> to LEFT/CENTER/RIGHT.
>
Thanks for pointing this out. I've incorporated it in the function. So now
no "leveling" takes place: the user can use fractional values (interpreted
in the way they would be with, say, 'self-alignment-X).
I've moved usage information to a comment at the head of the file.
If anyone can come up with a better, more concise example, go for it. I
remember making the first one with an eye to squeezing as much as I could
into one line. And of course you wouldn't actually center stems on the
notehead with this command.
Best,
David
\version "2.18.0"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% A command to horizontally align a grob to another grob.
%%
%% Syntax:
%%
%% [\once] \alignGrob [Context.]Grob-to-align [Context.]Grob-to-align-to
%% alignment-direction(s) extra-offset(s)
%%
%% Usage:
%%
%% The argument "alignment-direction(s)" specifies the sides of our
%% grob and the reference grob to align. If a single number (or LEFT,
%% CENTER, RIGHT) is given, this is used for both objects. If a pair is
%% given, the first value refers to our grob, and the second to the
%% reference grob. Standard values are -1 for LEFT, 0 for CENTER, or 1 for
%% RIGHT. Fractional values are allowed, permitting greater refinement
%% of positioning.
%%
%% The argument extra-offset(s) can be a number or a pair of numbers. A
%% single number always indicates the vertical displacement of the object
%% from its default position: the single number or the second value of a
%% number-pair. The first value of a pair (e.g., (dx . dy) ) gives an
%% extra amount to add to the horizontal position. This allows you to tweak
%% the new alignment.
%%
%% Important: This command uses 'extra-offset, and thus only moves the object
%% in question. Other objects will not be moved out of the way in the case
%% of a collision.
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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* ((refp (ly:grob-system grob))
(default-coord (ly:grob-relative-coordinate grob refp X))
(array (ly:grob-object refp 'all-elements))
;; We only want the name of the grob we're aligning to. If
;; input is in the form Context.Grob, strip Context 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)))
;; all the grobs of the reference type in the current system
(lst (filter
(lambda (x) (eq? reference-grob (grob-name x)))
(ly:grob-array->list array)))
;; Find the grob with the X-coordinate closest to our grob.
(ref
(reduce
(lambda (elem prev)
(if (< (abs (- default-coord
(ly:grob-relative-coordinate elem refp X)))
(abs (- default-coord
(ly:grob-relative-coordinate prev refp X))))
elem prev))
'()
lst)))
(if (ly:grob? ref)
(let* ((grob-ext (ly:grob-extent grob refp X))
(grob-dir (if (pair? dir) (car dir) dir))
(grob-ext-idx (interval-index grob-ext grob-dir))
(ref-ext (ly:grob-extent ref refp X))
;; If user specified single direction, use it for both objects.
(ref-dir (if (pair? dir) (cdr dir) dir))
(ref-ext-idx (interval-index ref-ext ref-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)))
(cons
(+
(- ref-ext-idx grob-ext-idx)
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
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
[email protected]
https://lists.gnu.org/mailman/listinfo/lilypond-user