]> git.donarmstrong.com Git - lilypond.git/blobdiff - Documentation/extending/programming-interface.itely
issue 4804: table cells shoud be top-aligned in HTML manuals
[lilypond.git] / Documentation / extending / programming-interface.itely
index 0c1601f50f1c09d46dee9a2cdb52d67eb05d18b5..5e63eabcd4f96598e64c742beca832dadfedf3ca 100644 (file)
@@ -8,7 +8,7 @@
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.17.6"
+@c \version "2.19.24"
 
 @node Interfaces for programmers
 @chapter Interfaces for programmers
@@ -18,40 +18,70 @@ not familiar with Scheme, you may wish to read our
 @ref{Scheme tutorial}.
 
 @menu
-* Lilypond code blocks::
+* LilyPond code blocks::
 * Scheme functions::
 * Music functions::
 * Event functions::
 * Markup functions::
 * Contexts for programmers::
 * Callback functions::
-* Inline Scheme code::
 * Difficult tweaks::
 @end menu
 
-@node Lilypond code blocks
-@section Lilypond code blocks
+@node LilyPond code blocks
+@section LilyPond code blocks
+
+@cindex LilyPond code blocks
+@cindex code blocks, LilyPond
+@funindex #@{ @dots{} #@}
+@funindex $
+@funindex #
+
+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 by using LilyPond code blocks,
+which enable common LilyPond syntax to be used within Scheme.
+
+LilyPond code blocks look like
 
-Lilypond code blocks look like
 @example
-  #@{ @var{Lilypond code} #@}
+  #@{ @var{LilyPond code} #@}
 @end example
-They can be used anywhere where you can write Scheme code: the Scheme
-reader actually is changed for accommodating LilyPond code blocks and
-can deal with embedded Scheme expressions starting with @code{$}
-and@w{ }@code{#}.
-
-It extracts the Lilypond code block and generates a call to the
-LilyPond @code{parser} which is executed at runtime to interpret the
-LilyPond code block.  Any embedded Scheme expression is executed in
-the lexical environment of the Lilypond code block, so you have access
-to local variables and function parameters at the point the Lilypond
-code block is written.
-
-A LilyPond code block may contain anything that you can use on the right
-side of an assignment.  In addition, an empty LilyPond block corresponds
-to a void music expression, and a LilyPond block containing multiple
-music events gets turned into a sequential music expression.
+
+Here is a trivial example:
+
+@lilypond[verbatim,quote]
+ritpp = #(define-event-function () ()
+  #{ ^"rit." \pp #}
+)
+
+{ c'4 e'4\ritpp g'2 }
+@end lilypond
+
+LilyPond code blocks can be used anywhere where you can write Scheme
+code.  The Scheme reader actually is changed for accommodating
+LilyPond code blocks and can deal with embedded Scheme expressions
+starting with @code{$} and@w{ }@code{#}.
+
+The reader extracts the LilyPond code block and generates a runtime
+call to the LilyPond parser to interpret the LilyPond code.
+Scheme expressions embedded in the LilyPond code are evaluated in the
+lexical environment of the LilyPond code block, so all local variables
+and function parameters available at the point the LilyPond code block
+is written may be accessed.  Variables defined in other Scheme modules,
+like the modules containing @code{\header} and @code{\layout} blocks,
+are not accessible as Scheme variables, i.e. prefixed
+with@tie{}@code{#}, but they are accessible as LilyPond variables, i.e.
+prefixed with@tie{}@code{\}.
+
+All music generated inside the code block has its
+@samp{origin} set to the current input location.
+
+A LilyPond code block may contain anything that you can use on the
+right side of an assignment.  In addition, an empty LilyPond block
+corresponds to a void music expression, and a LilyPond block
+containing multiple music events gets turned into a sequential music
+expression.
 
 @node Scheme functions
 @section Scheme functions
@@ -79,7 +109,7 @@ The general form for defining scheme functions is:
 @example
 function =
 #(define-scheme-function
-     (parser location @var{arg1} @var{arg2} @dots{})
+     (@var{arg1} @var{arg2} @dots{})
      (@var{type1?} @var{type2?} @dots{})
    @var{body})
 @end example
@@ -88,17 +118,12 @@ function =
 where
 
 @multitable @columnfractions .33 .66
-@item @code{parser}
-@tab needs to be literally @code{parser} in order to give LilyPond code
-blocks (@code{#@{}@dots{}@code{#@}}) access to the parser.
-
 @item @code{@var{argN}}
-@tab @var{n}th argument
+@tab @var{n}th argument.
 
 @item @code{@var{typeN?}}
-@tab a Scheme @emph{type predicate} for which @code{@var{argN}}
-must return @code{#t}.  Some of these predicates are specially
-recognized by the parser, see below.  There is also a special form
+@tab A Scheme @emph{type predicate} for which @code{@var{argN}}
+must return @code{#t}.  There is also a special form
 @code{(@emph{predicate?} @emph{default})} for specifying optional
 arguments.  If the actual argument is missing when the function is being
 called, the default value is substituted instead.  Default values are
@@ -109,54 +134,51 @@ don't follow it with a default value, @code{#f} is used as the default.
 Default values are not verified with @emph{predicate?} at either
 definition or run time: it is your responsibility to deal with the
 values you specify.  Default values that happen to be music expressions
-are copied while setting @code{origin} to the @code{location} parameter.
+are copied while setting @code{origin} to the current input location.
 
 @item @code{@var{body}}
 @tab A sequence of Scheme forms evaluated in order, the last one being
 used as the return value of the scheme function.  It may contain
 LilyPond code blocks enclosed in hashed braces
-(@tie{}@w{@code{#@{@dots{}#@}}}@tie{}), like described in @ref{Lilypond
-code blocks}.  Within LilyPond code blocks, use @code{#} to reference
-function arguments (eg., @samp{#arg1}) or to start an inline Scheme
-expression containing function arguments (eg., @w{@samp{#(cons arg1
-arg2)}}).  Where normal Scheme expressions using @code{#} don't do the
-trick, you might need to revert to immediate Scheme expressions using
-@code{$}, for example as @samp{$music}.
+(@tie{}@w{@code{#@{@dots{}#@}}}@tie{}), like described in
+@ref{LilyPond code blocks}.  Within LilyPond code blocks, use @code{#}
+to reference function arguments (eg., @samp{#arg1}) or to start an
+inline Scheme expression containing function arguments (eg.,
+@w{@samp{#(cons arg1 arg2)}}).  Where normal Scheme expressions using
+@code{#} don't do the trick, you might need to revert to immediate
+Scheme expressions using @code{$}, for example as @samp{$music}.
 
 If your function returns a music expression, it is given a useful value
 of @code{origin}.
 @end multitable
 
 @noindent
-Some type predicates are specially handled by the parser since it
-can't recognize the arguments reliably otherwise.  Currently these are
-@code{ly:pitch?} and @code{ly:duration?}.
-
-Suitability of arguments for all other predicates is determined by
-actually calling the predicate after Lilypond has already converted them
+Suitability of arguments for the predicates is determined by
+actually calling the predicate after LilyPond has already converted them
 into a Scheme expression.  As a consequence, the argument can be
 specified in Scheme syntax if desired (introduced with @code{#} or as
-the result of calling a scheme function), but Lilypond will also convert
-a number of Lilypond constructs into Scheme before actually checking the
+the result of calling a scheme function), but LilyPond will also convert
+a number of LilyPond constructs into Scheme before actually checking the
 predicate on them.  Currently, those include music, postevents, simple
 strings (with or without quotes), numbers, full markups and markup
 lists, score, book, bookpart, context definition and output definition
 blocks.
 
-For some kinds of expression (like most music not enclosed in braces)
-Lilypond needs to look further than the expression itself in order to
-determine its end.  If such an expression were considered for an
-optional argument by evaluating its predicate, Lilypond would not be
-able to ``backup'' when it decides the expression does not fit the
-parameter.  So some forms of music might need to be enclosed in braces
-to make them acceptable to Lilypond.  There are also some other
-ambiguities that Lilypond sorts out by checking with predicate
+Some
+ambiguities LilyPond sorts out by checking with predicate
 functions: is @samp{-3} a fingering postevent or a negative number?  Is
 @code{"a" 4} in lyric mode a string followed by a number, or a lyric
-event of duration @code{4}?  Lilypond decides by asking the predicates.
-That means that you should avoid permissive predicates like
-@code{scheme?} if you have a particular use in mind instead of a general
-purpose function.
+event of duration @code{4}?  LilyPond tries the argument
+predicate on successive interpretations until success, with an
+order designed to minimize inconsistent interpretations and
+lookahead.
+
+For example, a predicate accepting both music expressions and
+pitches will consider @code{c''} to be a pitch rather than a music
+expression.  Immediately following durations or postevents will
+change that interpretation.  It's best to avoid overly
+permissive predicates like @code{scheme?} when the application
+rather calls for more specific argument types.
 
 For a list of available predefined type predicates, see
 @ruser{Predefined type predicates}.
@@ -175,14 +197,15 @@ Installed Files:
 @subsection Scheme function usage
 
 Scheme functions can be called pretty much anywhere where a Scheme
-expression starting with @code{#} can be written.  You call a scheme
-function by writing its name preceded by @code{\}, followed by its
-arguments.  Once an optional argument predicate does not match an
-argument, Lilypond skips this and all following optional arguments,
-replacing them with their specified default, and @q{backs up} the
-argument that did not match to the place of the next mandatory argument.
-Since the backed up argument needs to go somewhere, optional arguments
-are not actually considered optional unless followed by a mandatory
+expression starting with @code{#} can be written.  You call a
+scheme function from LilyPond by writing its name preceded by
+@code{\}, followed by its arguments.  Once an optional argument
+predicate does not match an argument, LilyPond skips this and all
+following optional arguments, replacing them with their specified
+default, and @q{backs up} the argument that did not match to the
+place of the next mandatory argument.  Since the backed up
+argument needs to go somewhere, optional arguments are not
+actually considered optional unless followed by a mandatory
 argument.
 
 There is one exception: if you write @code{\default} in the place of an
@@ -202,6 +225,14 @@ some context, you should use normal scheme functions only for those
 cases where you always return a useful value, and use void scheme
 functions (@pxref{Void scheme functions}) otherwise.
 
+For convenience, scheme functions may also be called directly from
+Scheme bypassing the LilyPond parser.  Their name can be used like
+the name of an ordinary function.  Typechecking of the arguments
+and skipping optional arguments will happen in the same manner as
+when called from within LilyPond, with the Scheme value
+@code{*unspecified*} taking the role of the @code{\default}
+reserved word for explicitly skipping optional arguments.
+
 @node Void scheme functions
 @subsection Void scheme functions
 @funindex define-void-function
@@ -214,22 +245,22 @@ functions for either concept and just discard the returned value
 result).  This is clever but error-prone: most C compilers nowadays
 offer warnings for various non-``void'' expressions being discarded.
 For many functions executing an action, the Scheme standards declare the
-return value to be unspecified.  Lilypond's Scheme interpreter Guile has
+return value to be unspecified.  LilyPond's Scheme interpreter Guile has
 a unique value @code{*unspecified*} that it usually (such when using
 @code{set!} directly on a variable) but unfortunately not consistently
 returns in such cases.
 
-Defining a Lilypond function with @code{define-void-function} makes
+Defining a LilyPond function with @code{define-void-function} makes
 sure that this special value (the only value satisfying the predicate
 @code{void?}) will be returned.
 
 @example
 noPointAndClick =
 #(define-void-function
-     (parser location)
+     ()
      ()
    (ly:set-option 'point-and-click #f))
-...
+@dots{}
 \noPointAndClick   % disable point and click
 @end example
 
@@ -241,7 +272,7 @@ prefixing it with @code{\void}:
 \void #(hashq-set! some-table some-key some-value)
 @end example
 
-That way, you can be sure that Lilypond will not assign meaning to the
+That way, you can be sure that LilyPond will not assign meaning to the
 returned value regardless of where it encounters it.  This will also
 work for music functions such as @code{\displayMusic}.
 
@@ -275,14 +306,14 @@ The general form for defining music functions is:
 @example
 function =
 #(define-music-function
-     (parser location @var{arg1} @var{arg2} @dots{})
+     (@var{arg1} @var{arg2} @dots{})
      (@var{type1?} @var{type2?} @dots{})
    @var{body})
 @end example
 
 @noindent
 quite in analogy to @ref{Scheme function definitions}.  More often than
-not, @var{body} will be a @ref{Lilypond code blocks, Lilypond code block}.
+not, @var{body} will be a @ref{LilyPond code blocks, LilyPond code block}.
 
 For a list of available type predicates, see
 @ruser{Predefined type predicates}.
@@ -300,37 +331,32 @@ Installed Files:
 
 @node Music function usage
 @subsection Music function usage
-Music functions may currently be used in several places.  Depending on
-where they are used, restrictions apply in order to be able to parse
-them unambiguously.  The result a music function returns must be
-compatible with the context in which it is called.
+A @q{music function} has to return an expression matching the predicate
+@code{ly:music?}.  This makes music function calls suitable as arguments
+of type @code{ly:music?} for another music function call.
+
+When using a music function call in other contexts, the context may
+cause further semantic restrictions.
 
 @itemize
 @item
-At top level in a music expression.  No restriction apply here.
+At the top level in a music expression a post-event is not accepted.
 
 @item
-As a post-event, explicitly started with a direction indicator (one of
-@code{-}, @code{^}, @w{and @code{_}}).  Note that returning a post-event
-will be acceptable for music functions called as normal music, leading
-to a result roughly equivalent to
-@example
-s 1*0-\fun
-@end example
-
-In this case, you can't use an @emph{open} music expression as the last
-argument, one that would end with a music expression able to accept
-additional postevents.
+When a music function (as opposed to an event function) returns an
+expression of type post-event, LilyPond requires one of the named
+direction indicators (@code{-}, @code{^}, @w{and @code{_}}) in order to
+properly integrate the post-event produced by the music function call
+into the surrounding expression.
 
 @item
-As a chord constituent.  The returned expression must be of
+As a chord constituent.  The returned expression must be of a
 @code{rhythmic-event} type, most likely a @code{NoteEvent}.
 @end itemize
 
 @noindent
-The special rules for trailing arguments make it possible to write
-polymorphic functions like @code{\tweak} that can be applied to
-different constructs.
+@q{Polymorphic} functions, like @code{\tweak}, can be applied to
+post-events, chord constituent and top level music expressions.
 
 @node Simple substitution functions
 @subsection Simple substitution functions
@@ -356,7 +382,7 @@ using a @code{pair?} variable:
 @example
 manualBeam =
 #(define-music-function
-     (parser location beg-end)
+     (beg-end)
      (pair?)
    #@{
      \once \override Beam.positions = #beg-end
@@ -375,7 +401,7 @@ music expression:
 @lilypond[quote,verbatim,ragged-right]
 manualBeam =
 #(define-music-function
-     (parser location beg end)
+     (beg end)
      (number? number?)
    #{
      \once \override Beam.positions = #(cons beg end)
@@ -386,6 +412,55 @@ manualBeam =
 }
 @end lilypond
 
+@funindex \temporary
+@cindex temporary overrides
+@cindex overrides, temporary
+@cindex properties, popping previous value
+
+Properties are maintained conceptually using one stack per property
+per grob per context.  Music functions may need to override one or
+several properties for the duration of the function, restoring them
+to their previous value before exiting.  However, normal overrides
+pop and discard the top of the current property stack before
+pushing to it, so the previous value of the property is lost when it
+is overridden.  When the previous value must be preserved, prefix the
+@code{\override} command with @code{\temporary}, like this:
+
+@example
+\temporary \override @dots{}
+@end example
+
+The use of @code{\temporary} causes the (usually set) @code{pop-first}
+property in the override to be cleared, so the previous value is not
+popped off the property stack before pushing the new value onto it.
+When a subsequent @code{\revert} pops off the temporarily overriden
+value, the previous value will re-emerge.
+
+In other words, calling @code{\temporary \override} and @code{\revert}
+in succession on the same property will have a net effect of zero.
+Similarly, pairing @code{\temporary} and @code{\undo} on the same
+music containing overrides will have a net effect of zero.
+
+Here is an example of a music function which makes use of this.
+The use of @code{\temporary} ensures the values of the
+@code{cross-staff} and @code{style} properties are restored on exit
+to whatever values they had when the @code{crossStaff} function was
+called.  Without @code{\temporary} the default values would have been
+set on exit.
+
+@example
+crossStaff =
+#(define-music-function (notes) (ly:music?)
+  (_i "Create cross-staff stems")
+  #@{
+  \temporary \override Stem.cross-staff = #cross-staff-connect
+  \temporary \override Flag.style = #'no-flag
+  #notes
+  \revert Stem.cross-staff
+  \revert Flag.style
+#@})
+@end example
+
 
 @node Mathematics in functions
 @subsection Mathematics in functions
@@ -396,7 +471,7 @@ addition to simple substitution,
 @lilypond[quote,verbatim,ragged-right]
 AltOn =
 #(define-music-function
-     (parser location mag)
+     (mag)
      (number?)
    #{
      \override Stem.length = #(* 7.0 mag)
@@ -409,8 +484,8 @@ AltOff = {
   \revert NoteHead.font-size
 }
 
-\relative c' {
-  c2 \AltOn #0.5 c4 c
+\relative {
+  c'2 \AltOn #0.5 c4 c
   \AltOn #1.5 c c \AltOff c2
 }
 @end lilypond
@@ -421,7 +496,7 @@ This example may be rewritten to pass in music expressions,
 @lilypond[quote,verbatim,ragged-right]
 withAlt =
 #(define-music-function
-     (parser location mag music)
+     (mag music)
      (number? ly:music?)
    #{
      \override Stem.length = #(* 7.0 mag)
@@ -432,8 +507,8 @@ withAlt =
      \revert NoteHead.font-size
    #})
 
-\relative c' {
-  c2 \withAlt #0.5 { c4 c }
+\relative {
+  c'2 \withAlt #0.5 { c4 c }
   \withAlt #1.5 { c c } c2
 }
 @end lilypond
@@ -455,7 +530,7 @@ 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 #@}
@@ -492,9 +567,9 @@ to write dynamics commands, those are usually attached without direction
 indicator, like @code{c'\pp}.  Here is a way to write arbitrary
 dynamics:
 @lilypond[quote,verbatim,ragged-right]
-dyn=#(define-event-function (parser location arg) (markup?)
+dyn=#(define-event-function (arg) (markup?)
          (make-dynamic-script arg))
-\relative c' { c\dyn pfsss }
+\relative { c'\dyn pfsss }
 @end lilypond
 You could do the same using a music function, but then you always would
 have to write a direction indicator before calling it, like
@@ -519,21 +594,49 @@ Markups are implemented as special Scheme functions which produce a
 @subsection Markup construction in Scheme
 
 @cindex defining markup commands
+@funindex \displayScheme
+
+Markup expressions are internally represented in Scheme using the
+@code{markup} macro:
 
-The @code{markup} macro builds markup expressions in Scheme while
-providing a LilyPond-like syntax.  For example,
 @example
-(markup #:column (#:line (#:bold #:italic "hello" #:raise 0.4 "world")
-                  #:larger #:line ("foo" "bar" "baz")))
+(markup @var{expr})
+@end example
+
+To see a markup expression in its Scheme form, use the
+@code{\displayScheme} command:
+
+@example
+\displayScheme
+\markup @{
+  \column @{
+    \line @{ \bold \italic "hello" \raise #0.4 "world" @}
+    \larger \line @{ foo bar baz @}
+  @}
+@}
 @end example
 
 @noindent
-is equivalent to:
+Compiling the code above will send the following to the display
+console:
+
 @example
-#@{ \markup \column @{ \line @{ \bold \italic "hello" \raise #0.4 "world" @}
-                  \larger \line @{ foo bar baz @} @} #@}
+(markup
+  #:line
+  (#:column
+   (#:line
+    (#:bold (#:italic "hello") #:raise 0.4 "world")
+    #:larger
+    (#:line
+     (#:simple "foo" #:simple "bar" #:simple "baz")))))
 @end example
 
+To prevent the markup from printing on the page, use
+@w{@samp{\void \displayScheme @var{markup}}}.  Also, as with the
+@code{\displayMusic} command, the output of @code{\displayScheme}
+can be saved to an external file.  See
+@ref{Displaying music expressions}.
+
 @noindent
 This example demonstrates the main translation rules between regular
 LilyPond markup syntax and Scheme markup syntax.  Using @code{#@{
@@ -545,11 +648,12 @@ Scheme-only solution.
 @multitable @columnfractions .3 .3
 @item @b{LilyPond} @tab @b{Scheme}
 @item @code{\markup markup1} @tab @code{(markup markup1)}
-@item @code{\markup @{ markup1 markup2 ... @}} @tab
-        @code{(markup markup1 markup2 ... )}
+@item @code{\markup @{ markup1 markup2 @dots{} @}} @tab
+        @code{(markup markup1 markup2 @dots{} )}
 @item @code{\markup-command} @tab @code{#:markup-command}
 @item @code{\variable} @tab @code{variable}
-@item @code{\center-column @{ ... @}} @tab @code{#:center-column ( ... )}
+@item @code{\center-column @{ @dots{} @}} @tab
+        @code{#:center-column ( @dots{} )}
 @item @code{string} @tab @code{"string"}
 @item @code{#scheme-arg} @tab @code{scheme-arg}
 @end multitable
@@ -636,11 +740,11 @@ New markup commands can be defined using the
 @code{define-markup-command} Scheme macro, at top-level.
 
 @lisp
-(define-markup-command (@var{command-name} @var{layout} @var{props} @var{arg1} @var{arg2} ...)
-    (@var{arg1-type?} @var{arg2-type?} ...)
+(define-markup-command (@var{command-name} @var{layout} @var{props} @var{arg1} @var{arg2} @dots{})
+    (@var{arg1-type?} @var{arg2-type?} @dots{})
     [ #:properties ((@var{property1} @var{default-value1})
-                    ...) ]
-  ..command body..)
+                    @dots{}) ]
+  @dots{}command body@dots{})
 @end lisp
 
 The arguments are
@@ -685,6 +789,26 @@ you avoid performance pitfalls by just using Scheme arguments for
 the leading arguments of markup functions that take a markup as
 their last argument.
 
+@funindex \markup
+@cindex markup macro
+@funindex interpret-markup
+Markup commands have a rather complex life cycle.  The body of a
+markup command definition is responsible for converting the
+arguments of the markup command into a stencil expression which is
+returned.  Quite often this is accomplished by calling the
+@code{interpret-markup} function on a markup expression, passing
+the @var{layout} and @var{props} arguments on to it.  Those
+arguments are usually only known at a very late stage in
+typesetting.  Markup expressions have their components assembled
+into markup expressions already when @code{\markup} in a LilyPond
+expression or the @code{markup} macro in Scheme is expanded.  The
+evaluation and typechecking of markup command arguments happens at
+the time @code{\markup}/@code{markup} are interpreted.
+
+But the actual conversion of markup expressions into stencil
+expressions by executing the markup function bodies only happens
+when @code{interpret-markup} is called on a markup expression.
+
 @node On properties
 @unnumberedsubsubsec On properties
 
@@ -759,7 +883,7 @@ padding.
             \override #'(box-padding . 0.6) \box @{ #text @}#@}))
 @end lisp
 
-or, equivalently 
+or, equivalently
 
 @lisp
 #(define-markup-command (double-box layout props text) (markup?)
@@ -859,7 +983,7 @@ follow (documentation stripped):
   (number-pair?)
   #:category graphic
   #:properties ((thickness 1))
-  "..documentation.."
+  "@dots{}documentation@dots{}"
   (let ((th (* (ly:output-def-lookup layout 'line-thickness)
                thickness))
         (x (car dest))
@@ -876,7 +1000,7 @@ documentation, and is of no use for user-defined markup commands.
 (define-markup-command (draw-double-line layout props dest)
   (number-pair?)
   #:properties ((thickness 1))
-  "..documentation.."
+  "@dots{}documentation@dots{}"
   (let ((th (* (ly:output-def-lookup layout 'line-thickness)
                thickness))
         (x (car dest))
@@ -892,8 +1016,8 @@ Then, a property for setting the gap between two lines is added, called
   (number-pair?)
   #:properties ((thickness 1)
                 (line-gap 0.6))
-  "..documentation.."
-  ...
+  "@dots{}documentation@dots{}"
+  @dots{}
 @end lisp
 
 Finally, the code for drawing two lines is added.  Two calls to
@@ -928,12 +1052,18 @@ stencils are combined using @code{ly:stencil-add}:
 
 @node New markup list command definition
 @subsection New markup list command definition
+@funindex define-markup-list-command
+@funindex interpret-markup-list
 Markup list commands are defined with the
 @code{define-markup-list-command} Scheme macro, which is similar to the
 @code{define-markup-command} macro described in
 @ref{New markup command definition}, except that where the latter returns
 a single stencil, the former returns a list of stencils.
 
+In a similar vein, @code{interpret-markup-list} is used instead of
+@code{interpret-markup} for converting a markup list into a list
+of stencils.
+
 In the following example, a @code{\paragraph} markup list command is
 defined, which returns a list of justified lines, the first one being
 indented.  The indent width is taken from the @code{props} argument.
@@ -1000,25 +1130,137 @@ This new markup list command can be used as follows:
 
 @cindex calling code during interpreting
 @funindex \applyContext
+@funindex make-apply-context
+@funindex ly:context-property
+@funindex ly:context-set-property!
+@funindex ly:context-grob-definition
+@funindex ly:assoc-get
+@funindex ly:context-pushpop-property
+
+Contexts can be modified during interpretation with Scheme code.
+In a LilyPond code block, the syntax for this is:
 
-Contexts can be modified during interpretation with Scheme code.  The
-syntax for this is
 @example
 \applyContext @var{function}
 @end example
 
+In Scheme code, the syntax is:
+
+@example
+(make-apply-context @var{function})
+@end example
+
 @code{@var{function}} should be a Scheme function that takes a
 single argument: the context in which the @code{\applyContext}
-command is being called.  The following code will print the
-current bar number on the standard output during the compile:
+command is being called.  The function can access as well as
+override/set grob properties and context properties.  Any actions
+taken by the function that depend on the state of the context are
+limited to the state of the context @emph{when the function is
+called}.  Also, changes effected by a call to @code{\applyContext}
+remain in effect until they are directly modified again, or
+reverted, even if the initial conditions that they depended on
+have changed.
+
+The following scheme functions are useful when using
+@code{\applyContext}:
 
-@example
+@table @code
+@item ly:context-property
+look up a context property value
+
+@item ly:context-set-property!
+set a context property
+
+@item ly:context-grob-definition
+@itemx ly:assoc-get
+look up a grob property value
+
+@item ly:context-pushpop-property
+do a @code{\temporary@tie{}\override}
+or a @code{\revert} on a grob property
+@end table
+
+
+The following example looks up the current @code{fontSize} value, and
+then doubles it:
+
+@lilypond[quote,verbatim]
+doubleFontSize =
 \applyContext
-  #(lambda (x)
-    (format #t "\nWe were called in barnumber ~a.\n"
-     (ly:context-property x 'currentBarNumber)))
-@end example
+  #(lambda (context)
+     (let ((fontSize (ly:context-property context 'fontSize)))
+       (ly:context-set-property! context 'fontSize (+ fontSize 6))))
+
+{
+  \set fontSize = -3
+  b'4
+  \doubleFontSize
+  b'
+}
+@end lilypond
+
+
+The following example looks up the current colors of the
+@code{NoteHead}, @code{Stem}, and @code{Beam} grobs, and then changes
+each to a less saturated shade.
 
+@lilypond[quote,verbatim]
+desaturate =
+\applyContext
+  #(lambda (context)
+     (define (desaturate-grob grob)
+       (let* ((grob-def (ly:context-grob-definition context grob))
+              (color (ly:assoc-get 'color grob-def black))
+              (new-color (map (lambda (x) (min 1 (/ (1+ x) 2))) color)))
+         (ly:context-pushpop-property context grob 'color new-color)))
+     (for-each desaturate-grob '(NoteHead Stem Beam)))
+
+\relative {
+  \time 3/4
+  g'8[ g] \desaturate g[ g] \desaturate g[ g]
+  \override NoteHead.color = #darkred
+  \override Stem.color = #darkred
+  \override Beam.color = #darkred
+  g[ g] \desaturate g[ g] \desaturate g[ g]
+}
+@end lilypond
+
+
+This also could be implemented as a music function, in order to
+restrict the modifications to a single music block.  Notice how
+@code{ly:context-pushpop-property} is used both as a
+@code{\temporary@tie{}\override} and as a @code{\revert}:
+
+@lilypond[quote,verbatim]
+desaturate =
+#(define-music-function
+   (music) (ly:music?)
+   #{
+     \applyContext
+     #(lambda (context)
+        (define (desaturate-grob grob)
+          (let* ((grob-def (ly:context-grob-definition context grob))
+                 (color (ly:assoc-get 'color grob-def black))
+                 (new-color (map (lambda (x) (min 1 (/ (1+ x) 2))) color)))
+            (ly:context-pushpop-property context grob 'color new-color)))
+        (for-each desaturate-grob '(NoteHead Stem Beam)))
+     #music
+     \applyContext
+     #(lambda (context)
+        (define (revert-color grob)
+          (ly:context-pushpop-property context grob 'color))
+        (for-each revert-color '(NoteHead Stem Beam)))
+   #})
+
+\relative {
+  \override NoteHead.color = #darkblue
+  \override Stem.color = #darkblue
+  \override Beam.color = #darkblue
+  g'8 a b c
+  \desaturate { d c b a }
+  g b d b g2
+}
+@end lilypond
 
 
 @node Running a function on all layout objects
@@ -1028,20 +1270,24 @@ current bar number on the standard output during the compile:
 @cindex calling code on layout objects
 @funindex \applyOutput
 
-
 The most versatile way of tuning an object is @code{\applyOutput} which
 works by inserting an event into the specified context
-(@rinternals{ApplyOutputEvent}).  Its syntax is
+(@rinternals{ApplyOutputEvent}).  Its syntax is either
+@example
+\applyOutput @var{Context} @var{proc}
+@end example
+or
 @example
-\applyOutput @var{context} @var{proc}
+\applyOutput @var{Context}.@var{Grob} @var{proc}
 @end example
 
 @noindent
 where @code{@var{proc}} is a Scheme function, taking three arguments.
 
 When interpreted, the function @code{@var{proc}} is called for
-every layout object found in the context @code{@var{context}} at
-the current time step, with the following arguments:
+every layout object (with grob name @var{Grob} if specified) found
+in the context @code{@var{Context}} at the current time step, with
+the following arguments:
 @itemize
 @item the layout object itself,
 @item the context where the layout object was created, and
@@ -1060,15 +1306,22 @@ note-heads on the center-line and next to it:
 
 @lilypond[quote,verbatim,ragged-right]
 #(define (blanker grob grob-origin context)
-   (if (and (memq 'note-head-interface (ly:grob-interfaces grob))
-            (< (abs (ly:grob-property grob 'staff-position)) 2))
+   (if (< (abs (ly:grob-property grob 'staff-position)) 2)
        (set! (ly:grob-property grob 'transparent) #t)))
 
-\relative c' {
-  a'4 e8 <<\applyOutput #'Voice #blanker a c d>> b2
+\relative {
+  a'4 e8 <<\applyOutput Voice.NoteHead #blanker a c d>> b2
 }
 @end lilypond
 
+To have @var{function} interpreted at the @code{Score} or @code{Staff}
+level use these forms
+
+@example
+\applyOutput Score@dots{}
+\applyOutput Staff@dots{}
+@end example
+
 
 @node Callback functions
 @section Callback functions
@@ -1080,14 +1333,14 @@ set at fixed values with @code{\override}, e.g.
 \override Stem.thickness = #2.0
 @end example
 
-Properties can also be set to a Scheme procedure,
+Properties can also be set to a Scheme procedure:
 
-@lilypond[fragment,verbatim,quote,relative=2]
+@lilypond[fragment,verbatim,quote]
 \override Stem.thickness = #(lambda (grob)
     (if (= UP (ly:grob-property grob 'direction))
         2.0
         7.0))
-c b a g b a g b
+\relative { c'' b a g b a g b }
 @end lilypond
 
 @noindent
@@ -1108,38 +1361,19 @@ Properties that typically use callbacks include
 
 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},
+That procedure may access the usual value of the property, by first
+calling the function that is the usual callback for that property, which
+can by found in the Internals Reference or the file 'define-grobs.scm':
 
 @example
-`(X-offset .
-  ,(ly:make-simple-closure
-    `(,+
-        ,(ly:make-simple-closure
-           (list ly:self-alignment-interface::centered-on-x-parent))
-      ,(ly:make-simple-closure
-           (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})))
+\relative @{
+  \override Flag.X-offset = #(lambda (flag)
+    (let ((default (ly:flag::calc-x-offset flag)))
+      (* default 4.0)))
+  c''4. d8 a4. g8
+@}
 @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.
-
 From within a callback, the easiest method for evaluating a markup is
 to use grob-interpret-markup.  For example:
 
@@ -1148,25 +1382,26 @@ my-callback = #(lambda (grob)
                  (grob-interpret-markup grob (markup "foo")))
 @end example
 
-@node Inline Scheme code
-@section Inline Scheme code
+@ignore
+
+@n ode Inline Scheme code
+@s ection Inline Scheme code
 
-TODO: the example for this section is ill-chosen since
-@example
-F = -\tweak font-size #-3 -\flageolet
-@end example
-(note the @samp{-} marking it as a post event) will actually work fine
-for the stated purpose.  Until this section gets a rewrite, let's
-pretend we don't know.
+TODO: after this section had been written, LilyPond has improved
+to the point that finding a @emph{simple} example where one would
+@emph{have} to revert to Scheme has become rather hard.
+
+Until this section gets a rewrite, let's pretend we don't know.
 
 The main disadvantage of @code{\tweak} is its syntactical
-inflexibility.  For example, the following produces a syntax error.
+inflexibility.  For example, the following produces a syntax error
+(or rather, it did so at some point in the past).
 
 @example
 F = \tweak font-size #-3 -\flageolet
 
-\relative c'' @{
-  c4^\F c4_\F
+\relative @{
+  c''4^\F c4_\F
 @}
 @end example
 
@@ -1183,8 +1418,8 @@ F = #(let ((m (make-music 'ArticulationEvent
                     (ly:music-property m 'tweaks)))
        m)
 
-\relative c'' @{
-  c4^\F c4_\F
+\relative @{
+  c''4^\F c4_\F
 @}
 @end example
 
@@ -1197,6 +1432,7 @@ font size is prepended to the property list with the
 written back with @code{set!}.  The last element of the
 @code{let} block is the return value, @code{m} itself.
 
+@end ignore
 
 
 @node Difficult tweaks
@@ -1257,11 +1493,11 @@ of the broken tie is repositioned.
               (eq? (car (last-pair siblings)) grob))
          (ly:grob-set-property! grob 'extra-offset '(-2 . 5)))))
 
-\relative c'' {
+\relative {
   \override Tie.after-line-breaking =
   #my-callback
-  c1 ~ \break
-  c2 ~ c
+  c''1 ~ \break
+  c2 ~ 2
 }
 @end lilypond
 
@@ -1300,4 +1536,3 @@ This chapter covers the various tools provided by LilyPond to help
 Scheme programmers get information into and out of the music streams.
 
 TODO -- figure out what goes in here and how to organize it
-