[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Add function for overriding broken spanners to LilyPond. (issue 6397

From: David Kastrup
Subject: Re: Add function for overriding broken spanners to LilyPond. (issue 6397054)
Date: Fri, 20 Jul 2012 07:38:03 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1.50 (gnu/linux)

David Nalesnik <address@hidden> writes:

> David,
>     Why does this have to be a list?  Why not just make it two
>     separate
>     arguments?
>     If, for whatever reason, you really really really have this
>     information
>     in a two-element list called whatever, you can still write
>     \once \alterBroken "Staff.BarLine" #'color address@hidden
> It certainly makes sense to use multiple arguments instead of a list
> for a music function that applies an override to a breakable item like
> a clef, since there are only two pieces to consider.  However, the
> function is designed to apply to spanners as well, and these of course
> may have more than two pieces (e.g., SystemStartBar).  I know it’s
> possible to have music functions with optional arguments, but are they
> able to accept an indeterminate number of arguments, one for each
> potential spanner sibling?


> Regarding optional arguments:  I’ve been experimenting, and I’ve hit
> several stumbling blocks.  In the following (very contrived) example,
> I expect that both key signatures will be green.  Both are when all
> arguments are present.  When the optional argument is omitted, both
> should again be green because (scheme? arg2) still returns #t.
>  Instead, both key signatures disappear.  I don’t understand this
> behavior.
> test =
> #(define-music-function (parser location property arg1 arg2)
>   (symbol? scheme? (scheme?))

An optional argument can be skipped only if there is some place in the
argument list where it can go.  So in final position, optional arguments
are indistinguishable from mandatory arguments (actually not quite,
since they make preceding optional arguments also mandatory).  You can,
however, still explicitly skip them by writing \default in the actual
argument list, like commands like \key and \mark let you do.

>   (display (scheme? arg2)) ; returns #t even if arg2 omitted
>   #{
>     \once \override Staff.KeySignature $property =
>       #(lambda (grob)
>         (if (eq? (ly:item-break-dir grob) LEFT)
>             arg1
>             (if (scheme? arg2) arg1)))
>   #})
> {
>   c''1
>   \break
>   \test #'color #green #red
>   %% key signatures disappear if following line used:
>   %\test #'color #green
>   \key cis \major

scheme? is a catchall predicate.  It will gladly also take a music
expression.  If you want a predicate that doesn't, write
(define (nomusic? x) (not (ly:music? x)))
and use that.  It will then throw an error in this case instead of
setting the color to a key signature.

> My second quandary is the fact that (scheme? arg2) returns #t when
> arg2 is omitted, so it appears useless as a criterion for whether an
> optional argument is there or not..  (I’ve chosen scheme? as my
> predicate so the generalized function can accept a wide variety of
> data types.)

scheme? always returns #t.  At the current point of time, the only
argument predicates specially coded into the parser are ly:pitch? and
ly:duration? so they don't mix with scheme? syntactically.  This will at
some point of time get removed as well.  It is just somewhat tricky to

The advantage of not special-casing argument predicates is that you can
write predicates markup-or-music? or number-or-markup? and similar, and
they will work fine.  It is just pitches and durations that have been
somewhat resistant against this unification.

David Kastrup

reply via email to

[Prev in Thread] Current Thread [Next in Thread]