X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=Documentation%2Fuser%2Fprogramming-interface.itely;h=1cadde8f2ecedbc21556b1ca58c6a8562ad44e78;hb=af770f3440264c18ce01525dce1aa76b86ace0d5;hp=8b40fe3140c0d97a7504e935813989395414da7f;hpb=cfb0511f85f9691bfeebecaaaf962f7e0feb3ce0;p=lilypond.git diff --git a/Documentation/user/programming-interface.itely b/Documentation/user/programming-interface.itely index 8b40fe3140..1cadde8f2e 100644 --- a/Documentation/user/programming-interface.itely +++ b/Documentation/user/programming-interface.itely @@ -12,7 +12,7 @@ not familiar with Scheme, you may wish to read our * Building complicated functions:: * Markup programmer interface:: * Contexts for programmers:: -* Scheme procedures as properties:: +* Scheme procedures as properties:: @end menu @@ -27,6 +27,7 @@ This section discusses how to create music functions within LilyPond. * Paired substitution functions:: * Mathematics in functions:: * Void functions:: +* Overview of available music functions:: @end menu @node Overview of music functions @@ -122,7 +123,7 @@ tempoMark = #(define-music-function (parser location padding marktext) (number? string?) #{ \once \override Score . RehearsalMark #'padding = $padding - \once \override Score . RehearsalMark #'no-spacing-rods = ##t + \once \override Score . RehearsalMark #'extra-spacing-width = #'(+inf.0 . -inf.0) \mark \markup { \bold $marktext } #}) @@ -236,6 +237,15 @@ noPointAndClick = \noPointAndClick % disable point and click @end example +@node Overview of available music functions +@subsection Overview of available music functions + +@c fixme ; this should be move somewhere else? +The following commands are music functions + +@include identifiers.tely + + @node Programmer interfaces @section Programmer interfaces @@ -292,23 +302,35 @@ mixed. In the following example, a music fragment is stored in the variable @code{traLaLa}, and duplicated using Scheme. The result is imported in a @code{\score} block by means of a second variable @code{twice}: -@example -traLaLa = @{ c'4 d'4 @} + +@lilypond[verbatim] +traLaLa = { c'4 d'4 } + +%% dummy action to deal with parser lookahead +#(display "this needs to be here, sorry!") #(define newLa (map ly:music-deep-copy (list traLaLa traLaLa))) #(define twice (make-sequential-music newLa)) -@{ \twice @} -@end example +{ \twice } +@end lilypond + +Due to parser lookahead -In the above example, music expressions can be `exported' from the +In this example, the assignment happens after parser has verified that +nothing interesting happens after @code{traLaLa = @{ ... @}}. Without +the dummy statement in the above example, the @code{newLa} definition +is executed before @code{traLaLa} is defined, leading to a syntax +error. + +The above example shows how to `export' music expressions from the input to the Scheme interpreter. The opposite is also possible. By wrapping a Scheme value in the function @code{ly:export}, a Scheme -value is interpreted as if it were entered in LilyPond syntax. Instead -of defining @code{\twice}, the example above could also have been -written as +value is interpreted as if it were entered in LilyPond syntax. +Instead of defining @code{\twice}, the example above could also have +been written as @example @dots{} @{ #(ly:export (make-sequential-music (list newLa))) @} @@ -593,7 +615,7 @@ have two notes to build the sequence), add @code{SlurEvents} to the @code{SequentialMusic} with the two @code{EventChords}. @example -doubleSlur = #(def-music-function (parser location note) (ly:music?) +doubleSlur = #(define-music-function (parser location note) (ly:music?) "Return: @{ note ( note ) @}. `note' is supposed to be an EventChord." (let ((note2 (ly:music-deep-copy note))) @@ -1152,8 +1174,26 @@ Properties can also be set to a Scheme procedure, c b a g b a g b @end lilypond -Procedures may also be combined like that with -"grob closure". Here is a setting from +@noindent +In this case, the procedure is executed as soon as the value of the +property is requested during the formatting process. + +Most of the typesetting engine is driven by such callbacks. +Properties that typically use callbacks include + +@table @code +@item stencil + The printing routine, that constructs a drawing for the symbol +@item X-offset + The routine that sets the horizontal position +@item X-extent + The routine that computes the width of an object +@end table + +The procedure always takes a single argument, being the grob. + +If routines with multiple arguments must be called, the current grob +can be inserted with a grob closure. Here is a setting from @code{AccidentalSuggestion}, @example @@ -1166,4 +1206,20 @@ Procedures may also be combined like that with (list ly:self-alignment-interface::x-aligned-on-self))))) @end example +@noindent +In this example, both @code{ly:self-alignment-interface::x-aligned-on-self} and +@code{ly:self-alignment-interface::centered-on-x-parent} are called +with the grob as argument. The results are added with the @code{+} +function. To ensure that this addition is properly executed, the whole +thing is enclosed in @code{ly:make-simple-closure}. +In fact, using a single procedure as property value is equivalent to + +@example +(ly:make-simple-closure (ly:make-simple-closure (list @var{proc}))) +@end example + +@noindent +The inner @code{ly:make-simple-closure} supplies the grob as argument +to @var{proc}, the outer ensures that result of the function is +returned, rather than the @code{simple-closure} object.