Define function inside \ score in LilyPond

I am compiling a large book of songs, and for this I would like to have many local function definitions, which, in the end, will be in the \include d file, but that doesn't make any difference here. To do this, I need to define functions within the \score{ ... } . However, LilyPond continues to throw errors.

Inoperative example:

 \version "2.17.26" \book { \header { title = "This is a book" } \score { xyz = { a' b' c'' } abc = #(define-music-function ( parser location musicnotes ) ( ly:music? ) #{ c' $musicnotes e' #} ) { \abc { d' } f' \xyz } \header { piece = "First piece" opus = "op. 1024" } } \score { xyz = { a' a' a' } abc = #(define-music-function ( parser location musicnotes ) ( ly:music? ) #{ e' $musicnotes c' #} ) { \abc { d' } f' \xyz } \header { piece = "Second piece" opus = "op. 1025" } } } 

It produces an error message:

 test.ly:10:17: error: unrecognized string, not in text script or \lyricmode xyz = { a' b' c'' } 

The following works, however, I must provide functions for the unique names that I frowned at.

 \version "2.17.26" xyz = { a' b' c'' } abc = #(define-music-function ( parser location musicnotes ) ( ly:music? ) #{ c' $musicnotes e' #} ) xxyz = { a' a' a' } aabc = #(define-music-function ( parser location musicnotes ) ( ly:music? ) #{ e' $musicnotes c' #} ) \book { \header { title = "This is a book" } \score { { \abc { d' } f' \xyz } \header { piece = "First piece" opus = "op. 1024" } } \score { { \aabc { d' } f' \xxyz } \header { piece = "Second piece" opus = "op. 1025" } } } 
+8
scope lisp user-defined-functions lilypond
source share
2 answers

Unfortunately, it is not possible to fix the assignment in points. You can assign tasks only in the following places:

  • top level,
  • inside \display , \header and \midi blocks

In LilyPond's grammar, this is perfectly clear, even if the rest of the manual is a little biased. (See http://lilypond.org/doc/v2.17/Documentation/contributor/lilypond-grammar and find where the assignment rule is used).

Assuming your assignments are not suitable for the blocks listed above (which definitely takes place in this example) and assuming that you don't want to do something exotic like go, and define your own Scheme modules and figure out how to use them in your LilyPond file, you have two options:

  • Define xyz and abc , then determine the music that will go into the first score. Then override xyz and abc before defining music for the next score. This works because assignments overwrite everything that was before, and because LilyPond defines, they are usually processed in order. However, if you want some of your definitions to be used in both evaluations and be the same, you might get confused.
  • Arrange for your approach, although I would choose a prefix or suffix that makes it more clear what rating the search is for.

The first option will look something like this:

 \version "2.18.0" xyz = { a' b' c'' } abc = #(define-music-function (parser location musicnotes) (ly:music?) #{ c' $musicnotes e' #}) smus_a = { \abc { d' } f' \xyz } xyz = { a' a' a' } abc = #(define-music-function (parser location musicnotes) (ly:music?) #{ e' $musicnotes c' #}) smus_b = { \abc { d' } f' \xyz } \book { \header { title = "A Book!" } \score { \smus_a \header { piece = "First piece" } } \score { \smus_b \header { piece = "Second piece" } } } 

This also works if the music-defining parts are reorganized into separate LilyPond source files.

+6
source share

It is possible! But you need to define a command to define a variable or command:

 parserDefine = #(define-void-function (parser location name val)(symbol? scheme?) (ly:parser-define! parser name val)) 

This is a void function and can be called almost anywhere:

 \score { { % you have to be in your music-expression \parserDefine xyz { a' a' a' } % There must be something between parserDefine and the call! c'' \xyz \parserDefine abc #(define-music-function ( parser location musicnotes ) ( ly:music? ) #{ c' $musicnotes e' #} ) a' \abc d' } } 

If a team is defined, you can call inside your musical expressions. After you have done this, the parser needs to take a look for the variable to really be available - here is its c. '' You can optionally wrap the expression in another pair of curly braces.

+3
source share

All Articles