lilypond-user
[Top][All Lists]
Advanced

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

Re: Align above "current" staff


From: David Kastrup
Subject: Re: Align above "current" staff
Date: Sat, 07 Jul 2018 18:51:45 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

Urs Liska <address@hidden> writes:

> Am 07.07.2018 um 16:15 schrieb David Kastrup:
>> Urs Liska <address@hidden> writes:
>>
>>> Hi all,
>>>
>>> I want a music function to produce an ossia staff. The NR states that
>>> in order to place that above alignAboveContext should be used:
>>>
>>> \new Staff = "main" \relative {
>>>    c''4 b d c
>>>    <<
>>>      { c4 b d c }
>>>
>>>      \new Staff \with {
>>>        \remove "Time_signature_engraver"
>>>        alignAboveContext = #"main"
>>>        \magnifyStaff #2/3
>>>        firstClef = ##f
>>>      }
>>>      { e4 d f e }
>>>    >>
>>>    c4 b c2
>>> }
>>>
>>> But is that also possible when I  (or my music-function) doesn't know
>>> the staff's name
>> You can use \applyContext for getting it before you initiate your own
>> (hopefully uniquely named) Staff.

Ok, that was probably less than helpful.

> Thank you for the suggestion, which looks like it's what I
> need. However, unfortunately I didn't get anywhere looking at the
> various examples in the docs. It's still a mystery to me what does
> what and evaluates to what and when that happens or not ...
>
> OK, \applyContext passes the current context as the single argument to
> a function. Within that function one can access (retrieve and set) the
> properties of that context. I can sort of understand what that does in
> the example with "desaturating" colors.
>
> But that function call always returns a (make-music 'ApplyContext ...)
> music expression, which is nothing I can use for my purposes, it seems
> everything is about the side-effects.

Sure.  And the side-effect you want is setting the alignAboveContext
context property.  Which is not trivial if the context does not even
exist yet.  Cough cough.  It would be possible to \once\set
alignAboveContext in the mother context and let it be inherited but if
the mother context does not yet have a vertical axis group of its own,
this is going to end up one ugly mess.

>
> So I thought I'd define a variable and have the \applyContext function
> populate that variable with the context name, so I could use that
> later. But that doesn't work either, it looks like the \applyContext
> is only executed *after* I would need to use the variable:
>
> \version "2.19.80"
>
> ossia =
> #(define-music-function
>   (music ossia-music) (ly:music? ly:music?)
>   (let ((name "initialized"))
>     #{
>       \applyContext
>       #(lambda (context)
>          (set! name (ly:context-id (ly:context-parent context))) ; I know 
> this has to be more robust ...
>          (ly:message "1. context name inside \\applyContext: ~a" name)

           This is being called during iteration.  It is only during
           iteration that contexts actually exist.

>          ; the following \new Staff has no effect
>          #{ \new Staff { c' } #})

           The return value of applyContext, in this case a music
           expression, is not being used.

>       #(ly:message "2. context name after \\applyContext was called: ~a" name)

        This is being called during input, even before LilyPond's parser
        reads the following line (whatever may be in it and which ever
        music expression or score it may end up being used or even not
        used).

>       #music
>       % Create \new Staff with ossia-music
>     #}))
>
> \new Staff = "My Staff"
> \relative {
>   g'8 a b c
>   \ossia { d c b a } { c b a g }
>   g b d b g2
> }
>
> =>
> Parsing...
> 2. context name after \applyContext was called: initialized
> Interpreting music...
> 1. context name inside \applyContext: My Staff
>
> I'm sorry, but I need more concrete pointers or even an example.

I'll do an example in the spirit of my hand-waving original proposal but
it's, well, not pretty.

\version "2.19.80"

ossia =
#(define-music-function
  (music ossia-music) (ly:music? ly:music?)
  (let ((name "initialized"))
    #{
      \applyContext
      #(lambda (context)
         (set! name (ly:context-id (ly:context-find context 'Staff))) ; I know 
this has to be more robust ...
         (ly:message "1. context name inside \\applyContext: ~a" name))

      << \new Staff \with {
        #(ly:make-context-mod
          `((apply ,(lambda (c)
                       (set! (ly:context-property c 'alignAboveContext) name)
                     (ly:message "2. context name after \\applyContext was 
called: ~a" name)))))
      } { #ossia-music }
      #music
      >>
      % Create \new Staff with ossia-music
    #}))

\new Staff = "My Staff"
\relative {
  g'8 a b c
  \ossia { d c b a } { c b a g }
  g b d b g2
}

-- 
David Kastrup

reply via email to

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