From 2c07180488ae2bc50d06e9c752a0d24bc32f5cc6 Mon Sep 17 00:00:00 2001 From: nsceaux Date: Sun, 20 Jun 2004 08:28:19 +0000 Subject: [PATCH] * input/regression/lily-in-scheme.ly: regression test for #{ ... #} syntax * scm/ly-from-scheme.scm (read-lily-expression): #$( ... ) was causing an error. * Documentation/user/programming-interface.itely (Using LilyPond syntax inside Scheme): documentation for #{ ... #} syntax. --- ChangeLog | 11 ++ .../user/programming-interface.itely | 128 +++++++++++++++++- input/regression/lily-in-scheme.ly | 39 ++++++ 3 files changed, 173 insertions(+), 5 deletions(-) create mode 100644 input/regression/lily-in-scheme.ly diff --git a/ChangeLog b/ChangeLog index a09682c67a..67b99e5d16 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2004-06-20 Nicolas Sceaux + + * input/regression/lily-in-scheme.ly: regression test for #{ + ... #} syntax + + * scm/ly-from-scheme.scm (read-lily-expression): #$( ... ) + was causing an error. + + * Documentation/user/programming-interface.itely (Using LilyPond + syntax inside Scheme): documentation for #{ ... #} syntax. + 2004-06-19 Heikki Junes * Documentation/index.html.in: use black thin
. diff --git a/Documentation/user/programming-interface.itely b/Documentation/user/programming-interface.itely index 661d9ae09e..a29c1f2e5d 100644 --- a/Documentation/user/programming-interface.itely +++ b/Documentation/user/programming-interface.itely @@ -17,7 +17,8 @@ * Input variables and Scheme:: * Internal music representation:: * Extending music syntax:: -* Manipulating music expressions:: +* Manipulating music expressions:: +* Using LilyPond syntax inside Scheme:: @end menu @node Input variables and Scheme @@ -189,14 +190,25 @@ The above Scheme code only defines the functionality. The tag @code{\applymusic} is selected by defining @example - apply = #(ly:make-music-function - (list procedure? ly:music?) - (lambda (where func music) - (func music))) + applymusic = #(ly:make-music-function + (list procedure? ly:music?) + (lambda (location func music) + (func music))) +@end example + +A @code{def-music-function} macro is introduced on top of +@code{ly:make-music-function} to ease the definition of music +functions: + +@example + applymusic = #(def-music-function (location func music) (procedure? ly:music?) + (func music)) @end example Examples of the use of @code{\applymusic} are in the next section. +@seealso +@file{ly/music-functions-init.ly}. @node Manipulating music expressions @appendixsubsec Manipulating music expressions @@ -290,6 +302,112 @@ LilyPond input to other formats (@inputfileref{input/test,to-xml.ly}) @inputfileref{input/test,music-box.ly}. +@node Using LilyPond syntax inside Scheme +@appendixsubsec Using LilyPond syntax inside Scheme + +Creating music expressions in scheme can be tedious, as they are +heavily nested and the resulting scheme code is large. For some +simple tasks, this can be avoided, using LilyPond usual syntax inside +scheme, with the dedicated @code{#@{ ... #@}} syntax. + +The following two expressions give equivalent music expressions: +@example + mynotes = @{ \override Stem #'thickness = #4 + \notes @{ c'8 d' @} @} + + #(define mynotes #@{ \override Stem #'thickness = #4 + \notes @{ c'8 d' @} #@}) +@end example + +The content of @code{#@{ ... #@}} is enclosed in an implicit @code{@{ +... @}} block, which is parsed. The resulting music expression, a +@code{SequentialMusic} music object, is then returned and usable in scheme. + +Arbitrary scheme forms, including variables, can be used in @code{#@{ ... #@}} +expressions with the @code{$} character (@code{$$} can be used to +produce a single $ character). This makes the creation of simple +functions straightforward. In the following example, a function +setting the TextScript's padding is defined: + +@lilypond[verbatim,raggedright] + #(use-modules (ice-9 optargs)) + #(define* (textpad padding #:optional once?) + (ly:export ; this is necessary for using the expression + ; directly inside a \notes block + (if once? + #{ \once \override TextScript #'padding = #$padding #} + #{ \override TextScript #'padding = #$padding #}))) + + \score { + \notes { + c'^"1" + #(textpad 3.0 #t) % only once + c'^"2" + c'^"3" + #(textpad 5.0) + c'^"4" + c'^"5" + + } + } +@end lilypond + +Here, the variable @code{padding} is a number; music expression +variables may also be used in a similar fashion, as in the following +example: + +@lilypond[verbatim,raggedright] + #(define (with-padding padding) + (lambda (music) + #{ \override TextScript #'padding = #$padding + $music + \revert TextScript #'padding #})) + + \score { + \notes { + c'^"1" + \applymusic #(with-padding 3) + { c'^"2" c'^"3"} + c'^"4" + } + } +@end lilypond + +The function created by @code{(with-padding 3)} adds @code{\override} and +@code{\revert} statements around the music given as an argument, and returns +this new expression. Thus, this example is equivalent to: + +@example + \score @{ + \notes @{ + c'^"1" + @{ \override TextScript #'padding = #3 + @{ c'^"2" c'^"3"@} + \revert TextScript #'padding + @} + c'^"4" + @} + @} +@end example + +This function may also be defined as a music function: + +@lilypond[verbatim,raggedright] + withPadding = #(def-music-function (location padding music) (number? ly:music?) + #{ \override TextScript #'padding = #$padding + $music + \revert TextScript #'padding #}) + + \score { + \notes { + c'^"1" + \withPadding #3 + { c'^"2" c'^"3"} + c'^"4" + } + } +@end lilypond + @node Markup programmer interface @appendixsec Markup programmer interface diff --git a/input/regression/lily-in-scheme.ly b/input/regression/lily-in-scheme.ly new file mode 100644 index 0000000000..b3fc634da2 --- /dev/null +++ b/input/regression/lily-in-scheme.ly @@ -0,0 +1,39 @@ +\header { + texidoc = "LilyPond syntax can be used inside scheme to +build music expressions, with the @code{#@{ ... #@}} syntax. +Scheme forms can be introduced inside these blocks by escaping +them with a @code{$}, both in a LilyPond context (see the @code{music} variable) or in a Scheme +context (see the @code{$padding} and @code{$(* padding 2)} forms.)" +} +\version "2.3.4" +\paper { raggedright = ##t } + +withPaddingA = #(def-music-function (location padding music) (number? ly:music?) + #{ \override TextScript #'padding = #$padding + $music + \revert TextScript #'padding #}) + +withPaddingB = #(def-music-function (location padding music) (number? ly:music?) + #{ \override TextScript #'padding = #$(* padding 2) + $music + \revert TextScript #'padding #}) + +withPaddingC = #(def-music-function (location padding music) (number? ly:music?) + #{ \override TextScript #'padding = #(+ 1 $(* padding 2)) + $music + \revert TextScript #'padding #}) + + \score { + \notes { + c'^"1" + \withPaddingA #2 + { c'^"2" c'^"3"} + c'^"4" + \withPaddingB #2 + { c'^"5" c'^"6"} + c'^"7" + \withPaddingC #2 + { c'^"8" c'^"9"} + c'^"10" + } + } -- 2.39.5