]> git.donarmstrong.com Git - lilypond.git/blobdiff - Documentation/extending/programming-interface.itely
Merge branch 'master' of /home/jcharles/GIT/Lily/. into translation
[lilypond.git] / Documentation / extending / programming-interface.itely
index 72ca39e83d01a25f17d90614e10513c50fa8dae6..be580034424071d97736417ecff76010be2b3fdb 100644 (file)
@@ -8,7 +8,7 @@
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.14.0"
+@c \version "2.19.2"
 
 @node Interfaces for programmers
 @chapter Interfaces for programmers
@@ -18,82 +18,310 @@ not familiar with Scheme, you may wish to read our
 @ref{Scheme tutorial}.
 
 @menu
+* 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
+
+@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
+
+@example
+  #@{ @var{LilyPond code} #@}
+@end example
+
+Here is a trivial example:
+
+@lilypond[verbatim,quote]
+ritpp = #(define-event-function (parser location) ()
+  #{ ^"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{#}.
+
+@cindex parser (function argument)
+@cindex location
+
+The reader extracts the LilyPond code block and generates a runtime
+call to the LilyPond @code{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{\}.
+
+If @code{location} (see @ref{Scheme functions}) refers to a valid
+input location (which it usually does inside of music/@/Scheme
+functions), all music generated inside the code block has its
+@samp{origin} set to @code{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
+@cindex Scheme functions (LilyPond syntax)
+
+@emph{Scheme functions} are Scheme procedures that can create Scheme
+expressions from input written in LilyPond syntax.  They can be called
+in pretty much all places where using @code{#} for specifying a value in
+Scheme syntax is allowed.  While Scheme has functions of its own, this
+chapter is concerned with @emph{syntactic} functions, functions that
+receive arguments specified in LilyPond syntax.
+
+@menu
+* Scheme function definitions::
+* Scheme function usage::
+* Void scheme functions::
+@end menu
+
+@node Scheme function definitions
+@subsection Scheme function definitions
+@funindex define-scheme-function
+
+The general form for defining scheme functions is:
+
+@example
+function =
+#(define-scheme-function
+     (parser location @var{arg1} @var{arg2} @dots{})
+     (@var{type1?} @var{type2?} @dots{})
+   @var{body})
+@end example
+
+@noindent
+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{location}
+@tab needs to be literally @code{location} in order to provide access
+to the input location object, which is used to provide error messages
+with file names and line numbers.
+
+@item @code{@var{argN}}
+@tab @var{n}th argument
+
+@item @code{@var{typeN?}}
+@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
+evaluated at definition time (including LilyPond code blocks!), so if
+you need a default calculated at runtime, instead write a special value
+you can easily recognize.  If you write the predicate in parentheses but
+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.
+
+@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}.
+
+If your function returns a music expression, it is given a useful value
+of @code{origin}.
+@end multitable
+
+@noindent
+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
+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.
+
+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 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}.
+
+@seealso
+
+Notation Reference:
+@ruser{Predefined type predicates}.
+
+Installed Files:
+@file{lily/music-scheme.cc},
+@file{scm/c++.scm},
+@file{scm/lily.scm}.
+
+@node Scheme function usage
+@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
+argument.
+
+There is one exception: if you write @code{\default} in the place of an
+optional argument, this and all following optional arguments are skipped
+and replaced by their default.  This works even when no mandatory
+argument follows since @code{\default} does not need to get backed up.
+The @code{mark} and @code{key} commands make use of that trick to
+provide their default behavior when just followed by @code{\default}.
+
+Apart from places where a Scheme value is required, there are a few
+places where @code{#} expressions are currently accepted and evaluated
+for their side effects but otherwise ignored.  Mostly those are the
+places where an assignment would be acceptable as well.
+
+Since it is a bad idea to return values that can be misinterpreted in
+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.
+
+@node Void scheme functions
+@subsection Void scheme functions
+@funindex define-void-function
+@funindex \void
+
+Sometimes a procedure is executed in order to perform an action rather
+than return a value.  Some programming languages (like C and Scheme) use
+functions for either concept and just discard the returned value
+(usually by allowing any expression to act as statement, ignoring the
+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
+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
+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
+
+If you want to evaluate an expression only for its side-effect and
+don't want any value it may return interpreted, you can do so by
+prefixing it with @code{\void}:
+
+@example
+\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
+returned value regardless of where it encounters it.  This will also
+work for music functions such as @code{\displayMusic}.
 
 @node Music functions
 @section Music functions
 
-@emph{Music functions} are scheme procedures that can create music
+@cindex music functions
+
+@emph{Music functions} are Scheme procedures that can create music
 expressions automatically, and can be used to greatly simplify the
 input file.
 
 @menu
-* Music function syntax::
+* Music function definitions::
+* Music function usage::
 * Simple substitution functions::
 * Intermediate substitution functions::
 * Mathematics in functions::
 * Functions without arguments::
-* Void functions::
+* Void music functions::
 @end menu
 
 
-@node Music function syntax
-@subsection Music function syntax
+@node Music function definitions
+@subsection Music function definitions
+@cindex defining music functions
+@funindex define-music-function
 
-The general form for music functions is:
+The general form for defining music functions is:
 
 @example
 function =
 #(define-music-function
      (parser location @var{arg1} @var{arg2} @dots{})
      (@var{type1?} @var{type2?} @dots{})
-   @var{music})
+   @var{body})
 @end example
 
 @noindent
-where
+quite in analogy to @ref{Scheme function definitions}.  More often than
+not, @var{body} will be a @ref{LilyPond code blocks, LilyPond code block}.
 
-@multitable @columnfractions .33 .66
-@item @code{@var{argN}}
-@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, making the respective values be read in
-Lilypond syntax rather than in Scheme syntax.  Currently these are
-@code{ly:music?}, @code{markup?}, @code{ly:pitch?}, and
-@code{ly:duration?}.  Not all combinations are allowed: i.e., you can't
-look for a duration after music since music may end @emph{optionally}
-with a duration.
-
-If you really want to input some of those items as a Scheme rather than
-a Lilypond expression, you may wrap them in a call of @code{ly:export}.
-@c TODO: document what kind of argument lists are permitted in what
-@c syntactical context of a music function call.
-
-@item @code{@var{music}}
-@tab A music expression, optionally written in scheme, with any
-LilyPond code enclosed in hashed braces
-(@tie{}@w{@code{#@{@dots{}#@}}}@tie{}).  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)}}).
-
-@end multitable
-
-@noindent
 For a list of available type predicates, see
-@ruser{Predefined type predicates}.  User-defined type predicates
-are also allowed.
-
+@ruser{Predefined type predicates}.
 
 @seealso
 
@@ -106,6 +334,35 @@ Installed Files:
 @file{scm/lily.scm}.
 
 
+@node Music function usage
+@subsection Music function usage
+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 the top level in a music expression a post-event is not accepted.
+
+@item
+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 a
+@code{rhythmic-event} type, most likely a @code{NoteEvent}.
+@end itemize
+
+@noindent
+@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
 
@@ -133,7 +390,7 @@ manualBeam =
      (parser location beg-end)
      (pair?)
    #@{
-     \once \override Beam #'positions = $beg-end
+     \once \override Beam.positions = #beg-end
    #@})
 
 \relative c' @{
@@ -152,7 +409,7 @@ manualBeam =
      (parser location beg end)
      (number? number?)
    #{
-     \once \override Beam #'positions = $(cons beg end)
+     \once \override Beam.positions = #(cons beg end)
    #})
 
 \relative c' {
@@ -160,6 +417,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 (parser location 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
@@ -173,14 +479,14 @@ AltOn =
      (parser location mag)
      (number?)
    #{
-     \override Stem #'length = $(* 7.0 mag)
-     \override NoteHead #'font-size =
-       $(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
+     \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
+  \revert Stem.length
+  \revert NoteHead.font-size
 }
 
 \relative c' {
@@ -198,12 +504,12 @@ withAlt =
      (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
+     \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
    #})
 
 \relative c' {
@@ -232,7 +538,7 @@ displayBarNum =
      (parser location)
      ()
    (if (eq? #t (ly:get-option 'display-bar-numbers))
-       #@{ \once \override Score.BarNumber #'break-visibility = ##f #@}
+       #@{ \once \override Score.BarNumber.break-visibility = ##f #@}
        #@{#@}))
 @end example
 
@@ -244,31 +550,35 @@ lilypond -d display-bar-numbers FILENAME.ly
 @end example
 
 
-@node Void functions
-@subsection Void functions
+@node Void music functions
+@subsection Void music 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.
+A music function must return a music expression.  If you want to
+execute a function only for its side effect, you should use
+@code{define-void-function}.  But there may be cases where you
+sometimes want to produce a music expression, and sometimes not (like
+in the previous example).  Returning a @code{void} music expression
+via @code{#@{ #@}} will achieve that.
 
-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.
+@node Event functions
+@section Event functions
+@funindex define-event-function
+@cindex event functions
 
-@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
+To use a music function in the place of an event, you need to write a
+direction indicator before it.  But sometimes, this does not quite match
+the syntax of constructs you want to replace.  For example, if you want
+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?)
+         (make-dynamic-script arg))
+\relative c' { 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
+@code{@w{c-\dyn pfsss}}.
 
 
 @node Markup functions
@@ -289,34 +599,66 @@ 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.
+LilyPond markup syntax and Scheme markup syntax.  Using @code{#@{
+@dots{} #@}} for entering in LilyPond syntax will often be most
+convenient, but we explain how to use the @code{markup} macro to get a
+Scheme-only solution.
 
 @quotation
 @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
@@ -403,11 +745,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
@@ -452,6 +794,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
 
@@ -509,7 +871,8 @@ Then, the padding between the two boxes is considered too small, so we
 override it too:
 
 @lilypond[quote,verbatim,ragged-right]
-\markup \override #'(box-padding . 0.4) \box \override #'(box-padding . 0.6) \box A
+\markup \override #'(box-padding . 0.4) \box
+     \override #'(box-padding . 0.6) \box A
 @end lilypond
 
 Repeating this lengthy markup would be painful.  This is where a markup
@@ -517,6 +880,16 @@ command is needed.  Thus, we write a @code{double-box} markup command,
 taking one argument (the text).  This draws the two boxes, with some
 padding.
 
+@lisp
+#(define-markup-command (double-box layout props text) (markup?)
+  "Draw a double box around text."
+  (interpret-markup layout props
+    #@{\markup \override #'(box-padding . 0.4) \box
+            \override #'(box-padding . 0.6) \box @{ #text @}#@}))
+@end lisp
+
+or, equivalently
+
 @lisp
 #(define-markup-command (double-box layout props text) (markup?)
   "Draw a double box around text."
@@ -528,10 +901,10 @@ padding.
 @code{text} is the name of the command argument, and @code{markup?} its
 type: it identifies it as a markup.  The @code{interpret-markup}
 function is used in most of markup commands: it builds a stencil, using
-@code{layout}, @code{props}, and a markup.  Here, this markup is built
-using the @code{markup} scheme macro, see @ref{Markup construction in Scheme}.
-The transformation from @code{\markup} expression to scheme
-markup expression is straight-forward.
+@code{layout}, @code{props}, and a markup.  In the second case, this
+markup is built using the @code{markup} scheme macro, see @ref{Markup
+construction in Scheme}.  The transformation from @code{\markup}
+expression to scheme markup expression is straight-forward.
 
 The new command can be used as follow:
 
@@ -548,6 +921,19 @@ and the text.  So we will introduce a new property,
 @code{box-padding} will be used for the inner padding.  The new code is
 now as follows:
 
+@lisp
+#(define-markup-command (double-box layout props text) (markup?)
+  #:properties ((inter-box-padding 0.4)
+                (box-padding 0.6))
+  "Draw a double box around text."
+  (interpret-markup layout props
+    #@{\markup \override #`(box-padding . ,inter-box-padding) \box
+               \override #`(box-padding . ,box-padding) \box
+               @{ #text @} #@}))
+@end lisp
+
+Again, the equivalent version using the markup macro would be:
+
 @lisp
 #(define-markup-command (double-box layout props text) (markup?)
   #:properties ((inter-box-padding 0.4)
@@ -577,8 +963,9 @@ customized:
                 (box-padding 0.6))
   "Draw a double box around text."
   (interpret-markup layout props
-    (markup #:override `(box-padding . ,inter-box-padding) #:box
-            #:override `(box-padding . ,box-padding) #:box text)))
+    #{\markup \override #`(box-padding . ,inter-box-padding) \box
+              \override #`(box-padding . ,box-padding) \box
+              { #text } #}))
 
 \markup \double-box A
 \markup \override #'(inter-box-padding . 0.8) \double-box A
@@ -601,7 +988,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))
@@ -618,7 +1005,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))
@@ -634,8 +1021,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
@@ -670,15 +1057,31 @@ 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.
+
+@example
+#(define-markup-list-command (paragraph layout props args) (markup-list?)
+   #:properties ((par-indent 2))
+   (interpret-markup-list layout props
+     #@{\markuplist \justified-lines @{ \hspace #par-indent #args @} #@}))
+@end example
+
+
+The version using just Scheme is more complex:
 @example
 #(define-markup-list-command (paragraph layout props args) (markup-list?)
    #:properties ((par-indent 2))
@@ -694,16 +1097,16 @@ Besides the usual @code{layout} and @code{props} arguments, the
 First, the function gets the indent width, a property here named
 @code{par-indent}, from the property list @code{props}.  If the
 property is not found, the default value is @code{2}.  Then, a
-list of justified lines is made using the
-@code{make-justified-lines-markup-list} function, which is related
-to the @code{\justified-lines} built-in markup list command.  A
-horizontal space is added at the beginning using the
-@code{make-hspace-markup} function.  Finally, the markup list is
+list of justified lines is made using the built-in markup list command
+@code{\justified-lines}, which is related to the
+@code{make-justified-lines-markup-list} function.  A
+horizontal space is added at the beginning using @code{\hspace} (or the
+@code{make-hspace-markup} function).  Finally, the markup list is
 interpreted using the @code{interpret-markup-list} function.
 
 This new markup list command can be used as follows:
 @example
-\markuplines @{
+\markuplist @{
   \paragraph @{
     The art of music typography is called \italic @{(plate) engraving.@}
     The term derives from the traditional process of music printing.
@@ -732,25 +1135,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 g' {
+  \time 3/4
+  g8[ 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
+   (parser location 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 g' {
+  \override NoteHead.color = #darkblue
+  \override Stem.color = #darkblue
+  \override Beam.color = #darkblue
+  g8 a b c
+  \desaturate { d c b a }
+  g b d b g2
+}
+@end lilypond
 
 
 @node Running a function on all layout objects
@@ -760,19 +1275,18 @@ 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
 @example
-\applyOutput @var{context} @var{proc}
+\applyOutput @var{Context} @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
+every layout object found in the context @code{@var{Context}} at
 the current time step, with the following arguments:
 @itemize
 @item the layout object itself,
@@ -801,6 +1315,14 @@ note-heads on the center-line and next to it:
 }
 @end lilypond
 
+To have @var{function} interpreted at the @code{Score} or @code{Staff}
+level use these forms
+
+@example
+\applyOutput #'Score #@var{function}
+\applyOutput #'Staff #@var{function}
+@end example
+
 
 @node Callback functions
 @section Callback functions
@@ -809,13 +1331,13 @@ Properties (like @code{thickness}, @code{direction}, etc.) can be
 set at fixed values with @code{\override}, e.g.
 
 @example
-\override Stem #'thickness = #2.0
+\override Stem.thickness = #2.0
 @end example
 
 Properties can also be set to a Scheme procedure,
 
 @lilypond[fragment,verbatim,quote,relative=2]
-\override Stem #'thickness = #(lambda (grob)
+\override Stem.thickness = #(lambda (grob)
     (if (= UP (ly:grob-property grob 'direction))
         2.0
         7.0))
@@ -840,38 +1362,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},
-
-@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
+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
-(ly:make-simple-closure (ly:make-simple-closure (list @var{proc})))
+\relative c'' @{
+  \override Flag #'X-offset = #(lambda (flag)
+    (let ((default (ly:flag::calc-x-offset flag)))
+      (* default 4.0)))
+  c4. 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:
 
@@ -880,14 +1383,23 @@ 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: 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
+F = \tweak font-size #-3 -\flageolet
 
 \relative c'' @{
   c4^\F c4_\F
@@ -895,10 +1407,6 @@ F = \tweak #'font-size #-3 -\flageolet
 @end example
 
 @noindent
-In other words, @code{\tweak} doesn't behave like an articulation
-regarding the syntax; in particular, it can't be attached with
-@code{^} and @code{_}.
-
 Using Scheme, this problem can be avoided.  The route to the
 result is given in @ref{Adding articulation to notes (example)},
 especially how to use @code{\displayMusic} as a helping guide.
@@ -925,6 +1433,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
@@ -986,10 +1495,10 @@ of the broken tie is repositioned.
          (ly:grob-set-property! grob 'extra-offset '(-2 . 5)))))
 
 \relative c'' {
-  \override Tie #'after-line-breaking =
+  \override Tie.after-line-breaking =
   #my-callback
   c1 ~ \break
-  c2 ~ c
+  c2 ~ 2
 }
 @end lilypond
 
@@ -1009,9 +1518,10 @@ and @code{PaperColumn}.  They can be changed with the
 
 @example
 \overrideProperty
-#"Score.NonMusicalPaperColumn"  % Grob name
-#'line-break-system-details     % Property name
-#'((next-padding . 20))         % Value
+Score.NonMusicalPaperColumn       % Grob name
+  . line-break-system-details     % Property name
+  . next-padding                  % Optional subproperty name
+  #20                             % Value
 @end example
 
 Note, however, that @code{\override}, applied to