On 5/17/23 16:30, Valentin Petzel wrote:
Also gotta say that this is most likely not a good thing to do. Changing
global scope variables like that can lead to confusing behaviour. Maybe if you
can elaborate on what you want to achieve we might find a more ideomatic way to
get there.

Am Mittwoch, 17. Mai 2023, 22:24:54 CEST schrieb Valentin Petzel:
Hello David,

there is some confusing going on here about how certain things are
evaluated. When you do

{ ... something ... }

this is evaluated pretty much as it is parsed,  returning some music object.
So

\keepWithTag #'textI \tag #'textII { #(define l "B") }

this will first evaluate the expression { #(define l "B") } which returns an
empty music object and as side effect sets a variable, then it will call
\tag upon that music, and then call \keepWithTag on that Music.

What you intend to do is in fact not possible with \tag. What you want to do
is to delay the evaluation until the point where you have the information
to make this decision. This can be done using a music function:

\version "2.24.1"

#(define l '())

musicfn =
#(define-music-function (tag) (symbol?)
    #{
      #(if (equal? tag 'textI) (set! l "A"))
      #(if (equal? tag 'textII) (set! l "B"))
      c''1^\markup\l
      #(if (equal? tag 'textI) (set! l "C"))
      #(if (equal? tag 'textII) (set! l "D"))
      c''1^\markup\l
    #})

\musicfn textI
\musicfn textII

Note that here it is necessary to first create the global binding using
#(define ...) and then use (set! ...) to change that binding.

Cheers,
Valentin

Am Mittwoch, 17. Mai 2023, 21:58:49 CEST schrieb dfro:
I want to define and change variables mid-stream in a music expression,
while also using tags. Below is an example of what I am trying; but, it
does not work.


\version "2.24.1"

\keepWithTag #'textI
%\keepWithTag #'textII


{

    \tag #'textI { #(define l "A") }
    \tag #'textII { #(define l "B") }
    c''1 ^\markup \l
    \tag #'textI { #(define l "C") }
    \tag #'textII { #(define l "D") }
    c''1 ^\markup \l

}


The tags are not keeping lilypond from skipping the define's that are in
\tag #'textII. Is there a way to make this work?

Is there a way to define variables using lilypond syntax inside a music
expression?


Peace,

David


I think I have a version that is better and requires less typing.

I can define the global variables in the music expression before calling the symbol's music function, then I can have the symbol's music function add it when calling its markup function. There is no need to input the variable when calling the symbol's music function in the music expression.


\version "2.24.1"

#(define-markup-command
  (symbol
   layout props
   var staff-variable)
  (markup? markup?)
  (interpret-markup
   layout props
   #{ \markup \concat { "Symbol " #var #staff-variable } #}
   )
  )

symbol =
#(define-music-function
  ()
  ()
  #{ -\tag #'staff-one ^\markup \symbol #var "staff-one-var"
     -\tag #'staff-two ^\markup \symbol #var "staff-two-var"
  #})


music =
{

  #(define var "var-1 ")
  c1 \symbol
  #(define var "var-2 ")
  c1 \symbol

}

<<
  \new Staff = "one"
  {
    \keepWithTag #'staff-one
    \relative c' {

      \textLengthOn
      \music

    }
  }
  \new Staff = "two"
  {
    \keepWithTag #'staff-two
    \relative c' {

      \textLengthOn
      \music

    }
  }
>>


Peace,

David



Reply via email to