【问题标题】:Define function inside \score in LilyPond在 LilyPond 的 \score 中定义函数
【发布时间】:2014-01-18 10:20:22
【问题描述】:

我编写了一本大歌集,为此我希望有许多函数的本地定义,最终将在\include d 文件中,但这在这里没有区别。为此,我需要在\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"
        }
    }

}

【问题讨论】:

    标签: scope lisp user-defined-functions lilypond


    【解决方案1】:

    有可能! 但是你必须定义一个命令来定义变量或命令:

    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''。您可以选择将表达式包裹在另一对花括号中。

    【讨论】:

    • 现在这看起来超级性感!我现在不能尝试,但如果我能成功,我就欠你一杯啤酒 :)
    【解决方案2】:

    很遗憾,不能将作业粘贴到乐谱中。您只能将作业放置在以下位置:

    • 顶层,
    • \display\header\midi 块内

    LilyPond 语法很清楚地说明了这一点,即使手册的其余部分对此有点回避。 (查看 http://lilypond.org/doc/v2.17/Documentation/contributor/lilypond-grammar 并查找 assignment 规则的使用位置)。

    假设你的分配不适合上面列出的块(在这个例子中肯定是这种情况),并假设你不想做一些奇特的事情,比如去定义你自己的 Scheme 模块并弄清楚如何在你的 LilyPond 文件中使用它们,你有两个选择:

    1. 定义xyzabc,然后定义将进入第一乐谱的音乐。然后重新定义xyzabc,然后再定义下一个乐谱的音乐。这是有效的,因为分配会覆盖以前存在的任何内容,并且因为 LilyPond 定义通常是按顺序处理的。但是,如果您希望您的某些定义在两个分数中都使用并且相同,您可能会感到困惑。
    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 源文件,这也可以工作。

    【讨论】:

    • smus_asmus_b 的东西很酷!我知道作业会被重写,但我不知道函数会立即得到评估!
    • 好答案。可惜我的赏金为时已晚。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-23
    • 1970-01-01
    • 2014-08-18
    • 2021-07-18
    相关资源
    最近更新 更多