]> git.donarmstrong.com Git - lilypond.git/blobdiff - Documentation/extending/programming-interface.itely
Imported Upstream version 2.14.2
[lilypond.git] / Documentation / extending / programming-interface.itely
diff --git a/Documentation/extending/programming-interface.itely b/Documentation/extending/programming-interface.itely
new file mode 100644 (file)
index 0000000..acbff57
--- /dev/null
@@ -0,0 +1,1019 @@
+@c -*- coding: utf-8; mode: texinfo; -*-
+
+@ignore
+    Translation of GIT committish: FILL-IN-HEAD-COMMITTISH
+
+    When revising a translation, copy the HEAD committish of the
+    version that you are working on.  For details, see the Contributors'
+    Guide, node Updating translation committishes..
+@end ignore
+
+@c \version "2.14.0"
+
+@node Interfaces for programmers
+@chapter Interfaces for programmers
+
+Advanced tweaks may be performed by using Scheme.  If you are
+not familiar with Scheme, you may wish to read our
+@ref{Scheme tutorial}.
+
+@menu
+* Music functions::
+* Markup functions::
+* Contexts for programmers::
+* Callback functions::
+* Inline Scheme code::
+* Difficult tweaks::
+@end menu
+
+
+@node Music functions
+@section 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::
+* Simple substitution functions::
+* Intermediate substitution functions::
+* Mathematics in functions::
+* Functions without arguments::
+* Void functions::
+@end menu
+
+
+@node Music function syntax
+@subsection Music function syntax
+
+The general form for music functions is:
+
+@example
+function =
+#(define-music-function
+     (parser location @var{arg1} @var{arg2} @dots{})
+     (@var{type1?} @var{type2?} @dots{})
+   @var{music})
+@end example
+
+@noindent
+where
+
+@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}.
+
+@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.
+
+
+@seealso
+
+Notation Reference:
+@ruser{Predefined type predicates}.
+
+Installed Files:
+@file{lily/music-scheme.cc},
+@file{scm/c++.scm},
+@file{scm/lily.scm}.
+
+
+@node Simple substitution functions
+@subsection Simple substitution functions
+
+Simple substitution functions are music functions whose output
+music expression is written in LilyPond format and contains
+function arguments in the output expression.  They are described
+in @ruser{Substitution function examples}.
+
+
+@node Intermediate substitution functions
+@subsection Intermediate substitution functions
+
+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 @emph{cons cell} in Scheme).
+
+The pair can be directly passed into the music function,
+using a @code{pair?} variable:
+
+@example
+manualBeam =
+#(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
+
+Alternatively, the numbers making up the pair can be
+passed as separate arguments, and the Scheme code
+used to create the pair can be included in the
+music expression:
+
+@lilypond[quote,verbatim,ragged-right]
+manualBeam =
+#(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
+}
+@end lilypond
+
+
+@node Mathematics in functions
+@subsection Mathematics in functions
+
+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)))
+   #})
+
+AltOff = {
+  \revert Stem #'length
+  \revert NoteHead #'font-size
+}
+
+\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
+   #})
+
+\relative c' {
+  c2 \withAlt #0.5 { c4 c }
+  \withAlt #1.5 { c c } c2
+}
+@end lilypond
+
+
+@node Functions without arguments
+@subsection Functions without arguments
+
+In most cases a function without arguments should be written
+with a variable,
+
+@example
+dolce = \markup@{ \italic \bold dolce @}
+@end example
+
+However, in rare cases it may be useful to create a music function
+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 #@}
+       #@{#@}))
+@end example
+
+To actually display bar numbers where this function is called,
+invoke @command{lilypond} with
+
+@example
+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
+
+Markups are implemented as special Scheme functions which produce a
+@code{Stencil} object given a number of arguments.
+
+@menu
+* Markup construction in Scheme::
+* How markups work internally::
+* New markup command definition::
+* New markup list command definition::
+@end menu
+
+
+@node Markup construction in Scheme
+@subsection Markup construction in Scheme
+
+@cindex defining markup commands
+
+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")))
+@end example
+
+@noindent
+is equivalent to:
+@example
+\markup \column @{ \line @{ \bold \italic "hello" \raise #0.4 "world" @}
+                  \larger \line @{ foo bar baz @} @}
+@end example
+
+@noindent
+This example demonstrates the main translation rules between regular
+LilyPond markup syntax and Scheme markup syntax.
+
+@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-command} @tab @code{#:markup-command}
+@item @code{\variable} @tab @code{variable}
+@item @code{\center-column @{ ... @}} @tab @code{#:center-column ( ... )}
+@item @code{string} @tab @code{"string"}
+@item @code{#scheme-arg} @tab @code{scheme-arg}
+@end multitable
+@end quotation
+
+The whole Scheme language is accessible inside the
+@code{markup} macro.  For example, You may use function calls inside
+@code{markup} in order to manipulate character strings.  This is
+useful when defining new markup commands (see
+@ref{New markup command definition}).
+
+
+@knownissues
+
+The markup-list argument of commands such as @code{#:line},
+@code{#:center}, and @code{#:column} cannot be a variable or
+the result of a function call.
+
+@lisp
+(markup #:line (function-that-returns-markups))
+@end lisp
+
+@noindent
+is invalid.  One should use the @code{make-line-markup},
+@code{make-center-markup}, or @code{make-column-markup} functions
+instead,
+
+@lisp
+(markup (make-line-markup (function-that-returns-markups)))
+@end lisp
+
+
+@node How markups work internally
+@subsection How markups work internally
+
+In a markup like
+
+@example
+\raise #0.5 "text example"
+@end example
+
+@noindent
+@code{\raise} is actually represented by the @code{raise-markup}
+function.  The markup expression is stored as
+
+@example
+(list raise-markup 0.5 (list simple-markup "text example"))
+@end example
+
+When the markup is converted to printable objects (Stencils), the
+@code{raise-markup} function is called as
+
+@example
+(apply raise-markup
+       @var{\layout object}
+       @var{list of property alists}
+       0.5
+       @var{the "text example" markup})
+@end example
+
+The @code{raise-markup} function first creates the stencil for the
+@code{text example} string, and then it raises that Stencil by 0.5
+staff space.  This is a rather simple example; more complex examples
+are in the rest
+of this section, and in @file{scm/define-markup-commands.scm}.
+
+
+@node New markup command definition
+@subsection New markup command definition
+
+This section discusses the definition of new markup commands.
+
+@menu
+* Markup command definition syntax::
+* On properties::
+* A complete example::
+* Adapting builtin commands::
+@end menu
+
+@node Markup command definition syntax
+@unnumberedsubsubsec Markup command definition syntax
+
+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?} ...)
+    [ #:properties ((@var{property1} @var{default-value1})
+                    ...) ]
+  ..command body..)
+@end lisp
+
+The arguments are
+
+@table @code
+@item @var{command-name}
+the markup command name
+@item layout
+the @q{layout} definition.
+@item props
+a list of associative lists, containing all active properties.
+@item @var{argi}
+@var{i}th command argument
+@item @var{argi-type?}
+a type predicate for the i@var{th} argument
+@end table
+
+If the command uses properties from the @code{props} arguments,
+the @code{#:properties} keyword can be used to specify which
+properties are used along with their default values.
+
+Arguments are distinguished according to their type:
+@itemize
+@item a markup, corresponding to type predicate @code{markup?};
+@item a list of markups, corresponding to type predicate
+@code{markup-list?};
+@item any other scheme object, corresponding to type predicates such as
+@code{list?}, @code{number?}, @code{boolean?}, etc.
+@end itemize
+
+There is no limitation on the order of arguments (after the
+standard @code{layout} and @code{props} arguments).  However,
+markup functions taking a markup as their last argument are
+somewhat special as you can apply them to a markup list, and the
+result is a markup list where the markup function (with the
+specified leading arguments) has been applied to every element of
+the original markup list.
+
+Since replicating the leading arguments for applying a markup
+function to a markup list is cheap mostly for Scheme arguments,
+you avoid performance pitfalls by just using Scheme arguments for
+the leading arguments of markup functions that take a markup as
+their last argument.
+
+@node On properties
+@unnumberedsubsubsec On properties
+
+The @code{layout} and @code{props} arguments of markup commands bring a
+context for the markup interpretation: font size, line width, etc.
+
+The @code{layout} argument allows access to properties defined in
+@code{paper} blocks, using the @code{ly:output-def-lookup} function.
+For instance, the line width (the same as the one used in scores) is
+read using:
+
+@example
+(ly:output-def-lookup layout 'line-width)
+@end example
+
+The @code{props} argument makes some properties accessible to markup
+commands.  For instance, when a book title markup is interpreted, all
+the variables defined in the @code{\header} block are automatically
+added to @code{props}, so that the book title markup can access the book
+title, composer, etc.  It is also a way to configure the behaviour of a
+markup command: for example, when a command uses font size during
+processing, the font size is read from @code{props} rather than having a
+@code{font-size} argument.  The caller of a markup command may change
+the value of the font size property in order to change the behaviour.
+Use the @code{#:properties} keyword of @code{define-markup-command} to
+specify which properties shall be read from the @code{props} arguments.
+
+The example in next section illustrates how to access and override
+properties in a markup command.
+
+@node A complete example
+@unnumberedsubsubsec A complete example
+
+The following example defines a markup command to draw a double box
+around a piece of text.
+
+Firstly, we need to build an approximative result using markups.
+Consulting the @ruser{Text markup commands} shows us the @code{\box}
+command is useful:
+
+@lilypond[quote,verbatim,ragged-right]
+\markup \box \box HELLO
+@end lilypond
+
+Now, we consider that more padding between the text and the boxes is
+preferable.  According to the @code{\box} documentation, this command
+uses a @code{box-padding} property, which defaults to 0.2.  The
+documentation also mentions how to override it:
+
+@lilypond[quote,verbatim,ragged-right]
+\markup \box \override #'(box-padding . 0.6) \box A
+@end lilypond
+
+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
+@end lilypond
+
+Repeating this lengthy markup would be painful.  This is where a markup
+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
+
+@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.
+
+The new command can be used as follow:
+
+@example
+\markup \double-box A
+@end example
+
+It would be nice to make the @code{double-box} command customizable:
+here, the @code{box-padding} values are hard coded, and cannot be
+changed by the user.  Also, it would be better to distinguish the
+padding between the two boxes, from the padding between the inner box
+and the text.  So we will introduce a new property,
+@code{inter-box-padding}, for the padding between the two boxes.  The
+@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
+
+Here, the @code{#:properties} keyword is used so that the
+@code{inter-box-padding} and @code{box-padding} properties are read from
+the @code{props} argument, and default values are given to them if the
+properties are not defined.
+
+Then, these values are used to override the @code{box-padding}
+properties used by the two @code{\box} commands.  Note the backquote and
+the comma in the @code{\override} argument: they allow you to introduce
+a variable value into a literal expression.
+
+Now, the command can be used in a markup, and the boxes padding be
+customized:
+
+@lilypond[quote,verbatim,ragged-right]
+#(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)))
+
+\markup \double-box A
+\markup \override #'(inter-box-padding . 0.8) \double-box A
+\markup \override #'(box-padding . 1.0) \double-box A
+@end lilypond
+
+@node Adapting builtin commands
+@unnumberedsubsubsec Adapting builtin commands
+
+A good way to start writing a new markup command, is to take example on
+a builtin one.  Most of the markup commands provided with LilyPond can be
+found in file @file{scm/define-markup-commands.scm}.
+
+For instance, we would like to adapt the @code{\draw-line} command, to
+draw a double line instead.  The @code{\draw-line} command is defined as
+follow (documentation stripped):
+
+@lisp
+(define-markup-command (draw-line layout props dest)
+  (number-pair?)
+  #:category graphic
+  #:properties ((thickness 1))
+  "..documentation.."
+  (let ((th (* (ly:output-def-lookup layout 'line-thickness)
+               thickness))
+        (x (car dest))
+        (y (cdr dest)))
+    (make-line-stencil th 0 0 x y)))
+@end lisp
+
+To define a new command based on an existing one, copy the definition,
+and change the command name.  The @code{#:category} keyword can be
+safely removed, as it is only used for generating LilyPond
+documentation, and is of no use for user-defined markup commands.
+
+@lisp
+(define-markup-command (draw-double-line layout props dest)
+  (number-pair?)
+  #:properties ((thickness 1))
+  "..documentation.."
+  (let ((th (* (ly:output-def-lookup layout 'line-thickness)
+               thickness))
+        (x (car dest))
+        (y (cdr dest)))
+    (make-line-stencil th 0 0 x y)))
+@end lisp
+
+Then, a property for setting the gap between two lines is added, called
+@code{line-gap}, defaulting e.g. to 0.6:
+
+@lisp
+(define-markup-command (draw-double-line layout props dest)
+  (number-pair?)
+  #:properties ((thickness 1)
+                (line-gap 0.6))
+  "..documentation.."
+  ...
+@end lisp
+
+Finally, the code for drawing two lines is added.  Two calls to
+@code{make-line-stencil} are used to draw the lines, and the resulting
+stencils are combined using @code{ly:stencil-add}:
+
+@lilypond[quote,verbatim,ragged-right]
+#(define-markup-command (my-draw-line layout props dest)
+  (number-pair?)
+  #:properties ((thickness 1)
+                (line-gap 0.6))
+  "..documentation.."
+  (let* ((th (* (ly:output-def-lookup layout 'line-thickness)
+                thickness))
+         (dx (car dest))
+         (dy (cdr dest))
+         (w (/ line-gap 2.0))
+         (x (cond ((= dx 0) w)
+                  ((= dy 0) 0)
+                  (else (/ w (sqrt (+ 1 (* (/ dx dy) (/ dx dy))))))))
+         (y (* (if (< (* dx dy) 0) 1 -1)
+               (cond ((= dy 0) w)
+                     ((= dx 0) 0)
+                     (else (/ w (sqrt (+ 1 (* (/ dy dx) (/ dy dx))))))))))
+     (ly:stencil-add (make-line-stencil th x y (+ dx x) (+ dy y))
+                     (make-line-stencil th (- x) (- y) (- dx x) (- dy y)))))
+
+\markup \my-draw-line #'(4 . 3)
+\markup \override #'(line-gap . 1.2) \my-draw-line #'(4 . 3)
+@end lilypond
+
+
+@node New markup list command definition
+@subsection New markup list command definition
+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 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
+     (make-justified-lines-markup-list (cons (make-hspace-markup par-indent)
+                                             args))))
+@end example
+
+Besides the usual @code{layout} and @code{props} arguments, the
+@code{paragraph} markup list command takes a markup list argument, named
+@code{args}.  The predicate for markup lists is @code{markup-list?}.
+
+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
+interpreted using the @code{interpret-markup-list} function.
+
+This new markup list command can be used as follows:
+@example
+\markuplines @{
+  \paragraph @{
+    The art of music typography is called \italic @{(plate) engraving.@}
+    The term derives from the traditional process of music printing.
+    Just a few decades ago, sheet music was made by cutting and stamping
+    the music into a zinc or pewter plate in mirror image.
+  @}
+  \override-lines #'(par-indent . 4) \paragraph @{
+    The plate would be inked, the depressions caused by the cutting
+    and stamping would hold ink.  An image was formed by pressing paper
+    to the plate.  The stamping and cutting was completely done by
+    hand.
+  @}
+@}
+@end example
+
+@node Contexts for programmers
+@section Contexts for programmers
+
+@menu
+* Context evaluation::
+* Running a function on all layout objects::
+@end menu
+
+@node Context evaluation
+@subsection Context evaluation
+
+@cindex calling code during interpreting
+@funindex \applyContext
+
+Contexts can be modified during interpretation with Scheme code.  The
+syntax for this is
+@example
+\applyContext @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:
+
+@example
+\applyContext
+  #(lambda (x)
+    (format #t "\nWe were called in barnumber ~a.\n"
+     (ly:context-property x 'currentBarNumber)))
+@end example
+
+
+
+@node Running a function on all layout objects
+@subsection Running a function on all layout objects
+
+
+@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}
+@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:
+@itemize
+@item the layout object itself,
+@item the context where the layout object was created, and
+@item the context where @code{\applyOutput} is processed.
+@end itemize
+
+
+In addition, the cause of the layout object, i.e., the music
+expression or object that was responsible for creating it, is in the
+object property @code{cause}.  For example, for a note head, this is a
+@rinternals{NoteHead} event, and for a stem object,
+this is a @rinternals{Stem} object.
+
+Here is a function to use for @code{\applyOutput}; it blanks
+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))
+       (set! (ly:grob-property grob 'transparent) #t)))
+
+\relative c' {
+  a'4 e8 <<\applyOutput #'Voice #blanker a c d>> b2
+}
+@end lilypond
+
+
+@node Callback functions
+@section Callback functions
+
+Properties (like @code{thickness}, @code{direction}, etc.) can be
+set at fixed values with @code{\override}, e.g.
+
+@example
+\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)
+    (if (= UP (ly:grob-property grob 'direction))
+        2.0
+        7.0))
+c b a g b a g b
+@end lilypond
+
+@noindent
+In this case, the procedure is executed as soon as the value of the
+property is requested during the formatting process.
+
+Most of the typesetting engine is driven by such callbacks.
+Properties that typically use callbacks include
+
+@table @code
+@item stencil
+  The printing routine, that constructs a drawing for the symbol
+@item X-offset
+  The routine that sets the horizontal position
+@item X-extent
+  The routine that computes the width of an object
+@end table
+
+The procedure always takes a single argument, being the grob.
+
+If routines with multiple arguments must be called, the current grob
+can be inserted with a grob closure.  Here is a setting from
+@code{AccidentalSuggestion},
+
+@example
+`(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})))
+@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:
+
+@example
+my-callback = #(lambda (grob)
+                 (grob-interpret-markup grob (markup "foo")))
+@end example
+
+@node Inline Scheme code
+@section Inline Scheme code
+
+The main disadvantage of @code{\tweak} is its syntactical
+inflexibility.  For example, the following produces a syntax error.
+
+@example
+F = \tweak #'font-size #-3 -\flageolet
+
+\relative c'' @{
+  c4^\F c4_\F
+@}
+@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.
+
+@example
+F = #(let ((m (make-music 'ArticulationEvent
+                          'articulation-type "flageolet")))
+       (set! (ly:music-property m 'tweaks)
+             (acons 'font-size -3
+                    (ly:music-property m 'tweaks)))
+       m)
+
+\relative c'' @{
+  c4^\F c4_\F
+@}
+@end example
+
+@noindent
+Here, the @code{tweaks} properties of the flageolet object
+@code{m} (created with @code{make-music}) are extracted with
+@code{ly:music-property}, a new key-value pair to change the
+font size is prepended to the property list with the
+@code{acons} Scheme function, and the result is finally
+written back with @code{set!}.  The last element of the
+@code{let} block is the return value, @code{m} itself.
+
+
+
+@node Difficult tweaks
+@section Difficult tweaks
+
+There are a few classes of difficult adjustments.
+
+@itemize
+
+
+@item
+One type of difficult adjustment involves the appearance of
+spanner objects, such as slurs and ties.  Usually, only one
+spanner object is created at a time, and it can be adjusted with
+the normal mechanism.  However, occasionally a spanner crosses a
+line break.  When this happens, the object is cloned.  A separate
+object is created for every system in which the spanner appears.
+The new objects are clones of the original object and inherit all
+properties, including @code{\override}s.
+
+
+In other words, an @code{\override} always affects all pieces of a
+broken spanner.  To change only one part of a spanner at a line break,
+it is necessary to hook into the formatting process.  The
+@code{after-line-breaking} callback contains the Scheme procedure that
+is called after the line breaks have been determined and layout
+objects have been split over different systems.
+
+In the following example, we define a procedure
+@code{my-callback}.  This procedure
+
+@itemize
+@item
+determines if the spanner has been split across line breaks
+@item
+if yes, retrieves all the split objects
+@item
+checks if this grob is the last of the split objects
+@item
+if yes, it sets @code{extra-offset}.
+@end itemize
+
+This procedure is installed into @rinternals{Tie}, so the last part
+of the broken tie is repositioned.
+
+@lilypond[quote,verbatim,ragged-right]
+#(define (my-callback grob)
+   (let* (
+          ;; have we been split?
+          (orig (ly:grob-original grob))
+
+          ;; if yes, get the split pieces (our siblings)
+          (siblings (if (ly:grob? orig)
+                        (ly:spanner-broken-into orig)
+                        '())))
+
+     (if (and (>= (length siblings) 2)
+              (eq? (car (last-pair siblings)) grob))
+         (ly:grob-set-property! grob 'extra-offset '(-2 . 5)))))
+
+\relative c'' {
+  \override Tie #'after-line-breaking =
+  #my-callback
+  c1 ~ \break
+  c2 ~ c
+}
+@end lilypond
+
+@noindent
+When applying this trick, the new @code{after-line-breaking} callback
+should also call the old one, if such a default exists.  For example,
+if using this with @code{Hairpin}, @code{ly:spanner::kill-zero-spanned-time}
+should also be called.
+
+
+@item
+Some objects cannot be changed with @code{\override} for
+technical reasons.  Examples of those are @code{NonMusicalPaperColumn}
+and @code{PaperColumn}.  They can be changed with the
+@code{\overrideProperty} function, which works similar to @code{\once
+\override}, but uses a different syntax.
+
+@example
+\overrideProperty
+#"Score.NonMusicalPaperColumn"  % Grob name
+#'line-break-system-details     % Property name
+#'((next-padding . 20))         % Value
+@end example
+
+Note, however, that @code{\override}, applied to
+@code{NonMusicalPaperColumn} and @code{PaperColumn}, still works as
+expected within @code{\context} blocks.
+
+@end itemize
+
+@node LilyPond Scheme interfaces
+@chapter LilyPond Scheme interfaces
+
+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
+