8

私は大きな歌の本を編集します。そのために、関数のローカル定義を多くしたいと思います。最終的には\included ファイルになりますが、ここでは違いはありません。このためには、\score{ ... }スコープ内で関数を定義する必要があります。しかし、LilyPond はエラーをスローし続けます。

動作しない例:

\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"
        }
    }

}

エラーをスローします:

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

ただし、次の作業では、関数に一意の名前を付ける必要があり、眉をひそめています。

\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"
        }
    }

}
4

2 に答える 2

6

残念ながら、割り当てをスコアに貼り付けることはできません。課題は次の場所にのみ配置できます。

  • トップレベル、
  • \display\header、および\midiブロックの内側

LilyPond の文法は、マニュアルの残りの部分が少し回避しているとしても、これを非常に明確にしています。( http://lilypond.org/doc/v2.17/Documentation/contributor/lilypond-grammarを見て、assignmentルールが使用されている場所を探してください)。

あなたの割り当てが上記のブロックに適していないと仮定し (この例では間違いなくそうです)、独自の Scheme モジュールを定義し、それらをあなたの LilyPond ファイルには、次の 2 つの選択肢があります。

  1. xyzとを定義abcしてから、最初のスコアに入る音楽を定義します。次に、次のスコアの音楽を定義する前にand を再定義します。 これが機能するのは、代入が以前にあったものを上書きし、LilyPond 定義が一般的に順番に処理されるためです。ただし、定義の一部を両方のスコアで使用して同じにしたい場合は、混乱する可能性があります。xyzabc
  2. あなたのアプローチで解決しますが、定義がどのスコアと一致するかを明確にする接頭辞または接尾辞を選択します。

最初のオプションは次のようになります。

\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" }
  }
}

これは、音楽を定義する部分が別の LilyPond ソース ファイルにリファクタリングされている場合にも機能します。

于 2014-01-11T09:13:41.233 に答える
4

可能です! ただし、変数またはコマンドを定義するには、コマンドを定義する必要があります。

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

これは void 関数であり、ほとんどどこでも呼び出すことができます。

\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'
    }
}

コマンドが定義されている場合、音楽式内で呼び出すことができます。これを行った後、変数が実際に使用可能になるように、パーサーは少し先読みする必要があります。ここでは c'' です。必要に応じて、別の中かっこのペアで式をラップできます。

于 2014-03-07T13:53:03.977 に答える