Here's a patch to reorganize the music functions material in Notation and Extending. This also includes (finally) some code to auto-document the available type predicates in type-p-name-alist.
Before I finish the re-editing, however, I'd like to see how this question gets answered: http://lists.gnu.org/archive/html/lilypond-devel/2010-04/msg00350.html Notwithstanding that specific issue, any suggestions, objections, etc? - Mark
From 1117e3e62b740f513a8372a10a6fec32dbf012be Mon Sep 17 00:00:00 2001 From: Mark Polesky <markpole...@yahoo.com> Date: Sun, 25 Apr 2010 17:33:58 -0700 Subject: [PATCH] Doc: Reorganize music functions material. * Remove nodes from Extending that are covered in Notation: 2.1.1 Music function syntax 2.1.2 Simple substitution functions * In Extending 2.1, move `Void functions' to end of section, so `Functions without arguments' comes first. * Use a consistent indentation format for music functions. * Make some minor formatting/wording changes. * Create type-predicates-doc-string to document type-p-name-alist automatically. * Add notation appendix `Music function type predicates' to include type-predicates-doc-string. --- .../extending/programming-interface.itely | 259 ++++++------------- Documentation/notation/changing-defaults.itely | 113 +++++---- Documentation/notation/notation-appendices.itely | 7 + scm/c++.scm | 2 +- scm/documentation-generate.scm | 9 +- 5 files changed, 156 insertions(+), 234 deletions(-) diff --git a/Documentation/extending/programming-interface.itely b/Documentation/extending/programming-interface.itely index 7045b49..e8e44cf 100644 --- a/Documentation/extending/programming-interface.itely +++ b/Documentation/extending/programming-interface.itely @@ -30,137 +30,25 @@ not familiar with Scheme, you may wish to read our @node Music functions @section Music functions -Music functions are scheme functions that are used to -automatically create music expressions. They can be used to -greatly simplify the input file. +...@emph{music functions} are scheme procedures that can create music +expressions automatically. They can be used to greatly simplify +the input file. This section assumes that you are already +familiar with simple substitution functions, which are described +in @ruser{Using music functions}. @menu -* Music function syntax:: -* Simple substitution functions:: * Intermediate substitution functions:: * Mathematics in functions:: -* Void functions:: * Functions without arguments:: +* Void functions:: @end menu -...@node Music function syntax -...@subsection Music function syntax - -The general syntax of a music function is: - -...@example -myFunction = -#(define-music-function (parser location @var{var_1} @var{var_2}...@var{var_n}) - (@var{var_1-type?} @var{var_2-type?}...@var{var_n-type?}) - @var{...valid music expression...}) -...@end example - -...@noindent -where - -...@multitable @columnfractions .33 .66 -...@item @var{var_i} @tab @var{i}th variable -...@item @var{var_i-type?} @tab type of @var{i}th variable -...@item @var{...valid music expression...} @tab expression that returns -valid music, generally in the form of a Scheme expression. There is -also special syntax that allows LilyPond input code in this music -expression. -...@end multitable - -The variable type checkers are scheme procedures that will return -...@code{#t} if a variable is of a given type. Some common types -are shown in the table below. Other types can be found in the files -...@file{lily/music-scheme.cc} and @file{scm/c++.scm}. The complete -list of named type checkers for LilyPond is found in the -...@var{type-p-name-alist} of @file{scm/lily.scm}. - -...@c TODO -- automatically document type-p-name-alist - -...@multitable @columnfractions .33 .66 -...@headitem Input type @tab @var{vari-type?} notation -...@item Integer @tab @code{integer?} -...@item Float (decimal number) @tab @code{number?} -...@item Text string @tab @code{string?} -...@item Markup @tab @code{markup?} -...@item Music expression @tab @code{ly:music?} -...@item A pair of variables @tab @code{pair?} -...@end multitable - -The @code{parser} and @code{location} arguments are mandatory. -The @code{parser} argument is used in the body of the function -to gain access to the value of another LilyPond variable. -The @code{location} argument is used to set the @q{origin} -of the music expression that is built by the music function, -so that in case of a syntax error LilyPond -can tell the user an appropriate place to look in the input file. - -...@node Simple substitution functions -...@subsection Simple substitution functions - -A simple substitution function is a music function whose output music -expression is written in LilyPond code, but with an input variable -substituted into the LilyPond code. The general form of these functions is - -...@example -myFunction = -#(define-music-function (parser location @var{var1}) - (@var{var1-type?}) - #...@{ - @emph{... LilyPond input code with} @code{#$var1} @emph{for substition ...} - #...@}) -...@end example - -Note that the special characters @cod...@{} and @cod...@}} surround the -LilyPond music. - -...@multitable @columnfractions .33 .66 -...@item @var{vari} @tab @var{i}th variable -...@item @var{vari-type?} @tab type of @var{i}th variable -...@item @var{...music...} @tab normal LilyPond input, using - variables as @code{#$var1}, etc. -...@end multitable - -For example, a function can be defined that simplifies -setting the padding of a TextScript: - -...@lilypond[quote,verbatim,ragged-right] -padText = #(define-music-function (parser location padding) (number?) - #{ - \once \override TextScript #'padding = #$padding - #}) - -\relative c''' { - c4^"piu mosso" b a b - \padText #1.8 - c4^"piu mosso" d e f - \padText #2.6 - c4^"piu mosso" fis a g -} -...@end lilypond - -In addition to numbers, we can use music expressions such -as notes for arguments to music functions: - -...@lilypond[quote,verbatim,ragged-right] -custosNote = #(define-music-function (parser location note) - (ly:music?) - #{ - \once \override Voice.NoteHead #'stencil = - #ly:text-interface::print - \once \override Voice.NoteHead #'text = - \markup \musicglyph #"custodes.mensural.u0" - \once \override Voice.Stem #'stencil = ##f - $note - #}) -...@end lilypond @node Intermediate substitution functions @subsection Intermediate substitution functions -Slightly more complicated than simple substitution function, -intermediate substitution functions involve a mix of Scheme code and -LilyPond code in the music expression to be -returned. +Intermediate substitution functions involve a mix of Scheme code +and LilyPond code in the music expression to be returned. Some @code{\override} commands require an argument consisting of a pair of numbers (called a @code{cons cell} in Scheme). @@ -168,20 +56,19 @@ a pair of numbers (called a @code{cons cell} in Scheme). The pair can be directly passed into the music function, using a @code{pair?} variable: -...@quotation @example manualBeam = -#(define-music-function (parser location beg-end) - (pair?) -...@{ - \once \override Beam #'positions = #$beg-end -...@}) +#(define-music-function + (parser location beg-end) + (pair?) + #...@{ + \once \override Beam #'positions = #$beg-end + #...@}) \relative c' @{ \manualBeam #'(3 . 6) c8 d e f @} @end example -...@end quotation Alternatively, the numbers making up the pair can be passed as separate arguments, and the Scheme code @@ -190,11 +77,12 @@ music expression: @lilypond[quote,verbatim,ragged-right] manualBeam = -#(define-music-function (parser location beg end) - (number? number?) -#{ - \once \override Beam #'positions = #(cons $beg $end) -#}) +#(define-music-function + (parser location beg end) + (number? number?) + #{ + \once \override Beam #'positions = #(cons $beg $end) + #}) \relative c' { \manualBeam #3 #6 c8 d e f @@ -209,60 +97,49 @@ Music functions can involve Scheme programming in addition to simple substitution, @lilypond[quote,verbatim,ragged-right] -AltOn = #(define-music-function (parser location mag) (number?) - #{ \override Stem #'length = #$(* 7.0 mag) - \override NoteHead #'font-size = - #$(inexact->exact (* (/ 6.0 (log 2.0)) (log mag))) #}) +AltOn = +#(define-music-function + (parser location mag) + (number?) + #{ + \override Stem #'length = #$(* 7.0 mag) + \override NoteHead #'font-size = + #$(inexact->exact (* (/ 6.0 (log 2.0)) (log mag))) + #}) AltOff = { \revert Stem #'length \revert NoteHead #'font-size } -{ c'2 \AltOn #0.5 c'4 c' - \AltOn #1.5 c' c' \AltOff c'2 } +\relative c' { + c2 \AltOn #0.5 c4 c + \AltOn #1.5 c c \AltOff c2 +} @end lilypond @noindent This example may be rewritten to pass in music expressions, @lilypond[quote,verbatim,ragged-right] -withAlt = #(define-music-function (parser location mag music) (number? ly:music?) - #{ \override Stem #'length = #$(* 7.0 mag) - \override NoteHead #'font-size = - #$(inexact->exact (* (/ 6.0 (log 2.0)) (log mag))) - $music - \revert Stem #'length - \revert NoteHead #'font-size #}) - -{ c'2 \withAlt #0.5 {c'4 c'} - \withAlt #1.5 {c' c'} c'2 } -...@end lilypond - -...@node Void functions -...@subsection Void functions - -A music function must return a music expression, but sometimes we -may want to have a function that does not involve music (such as -turning off Point and Click). To do this, we return a @code{void} -music expression. - -That is why the form -that is returned is the @code{(make-music ...)}. With the -...@code{'void} property set to @code{#t}, the parser is told to -actually disregard this returned music -expression. Thus the important part of the void music function is the -processing done by the function, not the music expression that is -returned. +withAlt = +#(define-music-function + (parser location mag music) + (number? ly:music?) + #{ + \override Stem #'length = #$(* 7.0 mag) + \override NoteHead #'font-size = + #$(inexact->exact (* (/ 6.0 (log 2.0)) (log mag))) + $music + \revert Stem #'length + \revert NoteHead #'font-size + #}) -...@example -noPointAndClick = -#(define-music-function (parser location) () - (ly:set-option 'point-and-click #f) - (make-music 'SequentialMusic 'void #t)) -... -\noPointAndClick % disable point and click -...@end example +\relative c' { + c2 \withAlt #0.5 { c4 c } + \withAlt #1.5 { c c } c2 +} +...@end lilypond @node Functions without arguments @@ -280,10 +157,12 @@ without arguments, @example displayBarNum = -#(define-music-function (parser location) () - (if (eq? #t (ly:get-option 'display-bar-numbers)) - #...@{ \once \override Score.BarNumber #'break-visibility = ##f #...@} - #...@{#@})) +#(define-music-function + (parser location) + () + (if (eq? #t (ly:get-option 'display-bar-numbers)) + #...@{ \once \override Score.BarNumber #'break-visibility = ##f #...@} + #...@{#@})) @end example To actually display bar numbers where this function is called, @@ -294,6 +173,32 @@ lilypond -d display-bar-numbers FILENAME.ly @end example +...@node Void functions +...@subsection Void functions + +A music function must return a music expression, but sometimes we +may want to have a function that does not involve music (such as +turning off Point and Click). To do this, we return a @code{void} +music expression. + +That is why the form that is returned is the +...@w{@code{(make-music @dots{})}}. With the @code{'void} property +set to @code{#t}, the parser is told to actually disregard this +returned music expression. Thus the important part of the void +music function is the processing done by the function, not the +music expression that is returned. + +...@example +noPointAndClick = +#(define-music-function + (parser location) + () + (ly:set-option 'point-and-click #f) + (make-music 'SequentialMusic 'void #t)) +... +\noPointAndClick % disable point and click +...@end example + @node Markup functions @section Markup functions diff --git a/Documentation/notation/changing-defaults.itely b/Documentation/notation/changing-defaults.itely index e743ac1..091e2d2 100644 --- a/Documentation/notation/changing-defaults.itely +++ b/Documentation/notation/changing-defaults.itely @@ -3572,16 +3572,15 @@ of ties as required. @c TODO -- add @seealso, etc. to these subsections -Where tweaks need to be reused with different music expressions, it -is often convenient to make the tweak part of a music function. -In this section, we discuss only @emph{substitution} functions, where -the object is to substitute a variable into a piece of LilyPond -input code. Other more complex functions are described in -...@rextend{music functions}. +Where tweaks need to be reused with different music expressions, +it is often convenient to make the tweak part of a @emph{music +function}. In this section, we discuss only @emph{substitution} +functions, where the object is to substitute a variable into a +piece of LilyPond input code. Other more complex functions are +described in @rextend{Music functions}. @menu * Substitution function syntax:: -* Common argument types:: * Substitution function examples:: @end menu @@ -3593,10 +3592,11 @@ code is easy. The general form of these functions is @example function = -#(define-music-function (parser location @var{var1} @var{var2}...@var{vari}... ) - (@var{var1-type?} @var{var2-type?}...@var{vari-type?}...) +#(define-music-function + (parser location @var{arg1} @var{arg2} @dots{}) + (@var{type1?} @var{type2?} @dots{}) #...@{ - @emph{...music...} + @v...@dots{}music@dots{}} #...@}) @end example @@ -3604,63 +3604,60 @@ function = where @multitable @columnfractions .33 .66 -...@item @var{vari} @tab @var{i}th variable -...@item @var{vari-type?} @tab type of @var{i}th variable -...@item @var{...music...} @tab normal LilyPond input, using - variables as @code{#$var1}, etc. -...@end multitable +...@item @co...@var{argn}} +...@tab @var{n}th argument -Common variable types are described in @ref{Common argument types}. -A more complete description of variable types is found in -...@rextend{music function syntax}. The complete list of defined variable -types is found in the @var{type-p-name-alist} entry of -...@file{scm/lily.scm}. +...@item @co...@var{typen?}} +...@tab a scheme @emph{type predicate} for which @co...@var{argn}} +must return @code{#t}. -...@c TODO -- find an automatic way of documenting the type-p-name-alist +...@item @co...@var{@dots{}mu...@dots{}}} +...@tab normal LilyPond input, with arguments referenced as +...@samp{$arg1} or @samp{#$arg1}, depending on context. +...@end multitable -The @code{parser} and @code{location} arguments are mandatory, -and are used in some advanced situations as described in -...@rextend{music function syntax}. For substitution functions, just be sure -to include them. -...@seealso +The @code{parser} and @code{location} arguments are mandatory, and +are used in some advanced situations as described in +...@rextend{music function syntax}. For substitution functions, just +be sure to include them. -Notation Reference: -...@ref{common argument types}. +The list of type predicates is also required. Some of the most +common type predicates used in music functions are: -Extending LilyPond: -...@rextend{music function syntax}. +...@example +boolean? +list? +ly:music? +markup? +number? +pair? +string? +symbol? +...@end example -...@node Common argument types -...@subsection Common argument types +...@noindent +For the complete list of available type predicates, see +...@ref{music function type predicates}. -In order to allow for error checking, the type of each argument -that is passed to a music function must be defined. Some of the -common types of variables are shown in the table below. -The following input types may be used as variables in a music -function. This list is not exhaustive; -more information about possible variable types -can be found in @rextend{Music function syntax}. +TODO: Explain @q...@code{#$} vs. @code{$}} once and for all. -...@multitable @columnfractions .33 .66 -...@headitem Input type @tab @var{vari-type?} notation -...@item Integer @tab @code{integer?} -...@item Float (decimal number) @tab @code{number?} -...@item Text string @tab @code{string?} -...@item Markup @tab @code{markup?} -...@item Music expression @tab @code{ly:music?} -...@item A Scheme pair @tab @code{pair?} -...@end multitable +Properly referencing arguments inside the music block may be +confusing at first. ... @seealso +Notation Reference: +...@ref{music function type predicates}. + Extending LilyPond: -...@rextend {Music function syntax}. +...@rextend{music function syntax}. Installed Files: @file{lily/music-scheme.cc}, -...@file{scm/c++.scm}. +...@file{scm/c++.scm}, +...@file{scm/lily.scm}. @node Substitution function examples @@ -3674,7 +3671,10 @@ In the first example, a function is defined that simplifies setting the padding of a TextScript: @lilypond[quote,verbatim,ragged-right] -padText = #(define-music-function (parser location padding) (number?) +padText = +#(define-music-function + (parser location padding) + (number?) #{ \once \override TextScript #'padding = #$padding #}) @@ -3692,8 +3692,10 @@ In addition to numbers, we can use music expressions such as notes for arguments to music functions: @lilypond[quote,verbatim,ragged-right] -custosNote = #(define-music-function (parser location note) - (ly:music?) +custosNote = +#(define-music-function + (parser location note) + (ly:music?) #{ \once \override Voice.NoteHead #'stencil = #ly:text-interface::print @@ -3709,7 +3711,9 @@ custosNote = #(define-music-function (parser location note) Substitution functions with multiple arguments can be defined: @lilypond[quote,verbatim,ragged-right] -tempoPadded = #(define-music-function (parser location padding tempotext) +tempoPadded = +#(define-music-function + (parser location padding tempotext) (number? string?) #{ \once \override Score.MetronomeMark #'padding = $padding @@ -3726,3 +3730,4 @@ tempoPadded = #(define-music-function (parser location padding tempotext) @seealso +TODO: add missing @@ref's here. diff --git a/Documentation/notation/notation-appendices.itely b/Documentation/notation/notation-appendices.itely index b18810e..e46f990 100644 --- a/Documentation/notation/notation-appendices.itely +++ b/Documentation/notation/notation-appendices.itely @@ -47,6 +47,7 @@ and just before * All context properties:: * Layout properties:: * Available music functions:: +* Music function type predicates:: * Scheme functions:: @end menu @@ -1343,6 +1344,12 @@ Internals Reference: @include identifiers.tely +...@node Music function type predicates +...@appendixsec Music function type predicates + +...@include type-predicates.tely + + @node Scheme functions @appendixsec Scheme functions diff --git a/scm/c++.scm b/scm/c++.scm index 362e358..78e0a2c 100644 --- a/scm/c++.scm +++ b/scm/c++.scm @@ -58,7 +58,7 @@ ;; moved list to end of lily.scm: then all type-predicates are ;; defined. -(define type-p-name-alist '()) +(define-public type-p-name-alist '()) (define (match-predicate obj alist) (if (null? alist) diff --git a/scm/documentation-generate.scm b/scm/documentation-generate.scm index c64fb3a..0e6cfe3 100644 --- a/scm/documentation-generate.scm +++ b/scm/documentation-generate.scm @@ -32,6 +32,7 @@ "document-functions.scm" "document-translation.scm" "document-music.scm" + "document-type-predicates.scm" "document-identifiers.scm" "document-backend.scm" "document-markup.scm")) @@ -42,7 +43,7 @@ (slot-ref (all-scheme-functions-doc) 'text) (open-output-file "scheme-functions.tely")) -;;(display +;;(display ;; (markup-doc-string) ;; (open-output-file "markup-commands.tely")) @@ -54,7 +55,11 @@ (lambda (port) (dump-node (markup-list-doc-node) port 2))) -(display +(display + type-predicates-doc-string + (open-output-file "type-predicates.tely")) + +(display (identifiers-doc-string) (open-output-file "identifiers.tely")) -- 1.6.3.3
_______________________________________________ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel