-@c -*-texinfo-*-
+@c -*- coding: latin-1; mode: texinfo; -*-
@node Interfaces for programmers
-@appendix Interfaces for programmers
+@chapter Interfaces for programmers
@end menu
@node Programmer interfaces for input
-@appendixsec Programmer interfaces for input
+@section Programmer interfaces for input
@menu
* Input variables and Scheme::
* Internal music representation::
* Extending music syntax::
* Manipulating music expressions::
+* Using LilyPond syntax inside Scheme::
@end menu
@node Input variables and Scheme
-@appendixsubsec Input variables and Scheme
+@subsection Input variables and Scheme
The input format supports the notion of variable: in the following
example, a music expression is assigned to a variable with the name
@code{traLaLa}.
@example
- traLaLa = \notes @{ c'4 d'4 @}
+ traLaLa = @{ c'4 d'4 @}
@end example
@noindent
There is also a form of scoping: in the following example, the
-@code{\paper} block also contains a @code{traLaLa} variable, which is
+@code{\layout} block also contains a @code{traLaLa} variable, which is
independent of the outer @code{\traLaLa}.
@example
- traLaLa = \notes @{ c'4 d'4 @}
- \paper @{ traLaLa = 1.0 @}
+ traLaLa = @{ c'4 d'4 @}
+ \layout @{ traLaLa = 1.0 @}
@end example
@c
In effect, each input file is a scope, and all @code{\header},
-@code{\midi} and @code{\paper} blocks are scopes nested inside that
+@code{\midi} and @code{\layout} blocks are scopes nested inside that
toplevel scope.
Both variables and scoping are implemented in the GUILE module system.
An anonymous Scheme module is attached to each scope. An assignment of
the form
@example
- traLaLa = \notes @{ c'4 d'4 @}
+ traLaLa = @{ c'4 d'4 @}
@end example
@noindent
is internally converted to a Scheme definition
@example
- (define traLaLa @var{Scheme value of ``@code{\notes ... }''})
+ (define traLaLa @var{Scheme value of ``@code{... }''})
@end example
This means that input variables and Scheme variables may be freely
imported in a @code{\score} by means of a second variable
@code{twice}:
@example
- traLaLa = \notes @{ c'4 d'4 @}
+ traLaLa = @{ c'4 d'4 @}
#(define newLa (map ly:music-deep-copy
(list traLaLa traLaLa)))
#(define twice
(make-sequential-music newLa))
- \score @{ \twice @}
+ @{ \twice @}
@end example
In the above example, music expressions can be `exported' from the
input to the Scheme interpreter. The opposite is also possible. By
wrapping a Scheme value in the function @code{ly:export}, a Scheme
-value is interpreted as if it were entered in LilyPond syntax: instead
+value is interpreted as if it were entered in LilyPond syntax. Instead
of defining @code{\twice}, the example above could also have been
written as
@example
@dots{}
- \score @{ #(ly:export (make-sequential-music newLa)) @}
+ @{ #(ly:export (make-sequential-music newLa)) @}
@end example
+@refbugs
+
+Mixing Scheme and LilyPond identifiers is not possible with the
+@code{--safe} option.
@node Internal music representation
-@appendixsubsec Internal music representation
+@subsection Internal music representation
When a music expression is parsed, it is converted into a set of
Scheme music objects. The defining property of a music object is that
music name: Each music expression has a name, for example, a note
leads to a @internalsref{NoteEvent}, and @code{\simultaneous} leads to
a @internalsref{SimultaneousMusic}. A list of all expressions
-available is in the internals manual, under @internalsref{Music
-expressions}.
+available is in the internals manual, under
+@hyphenatedinternalsref{Music expressions,Music-expressions}.
@item
- `type' or interface: Each music name has several `types' or interface,
- for example, a note is an @code{event}, but it is also a @code{note-event},
- a @code{rhythmic-event} and a @code{melodic-event}.
+ `type' or interface: Each music name has several `types' or
+interfaces, for example, a note is an @code{event}, but it is also a
+@code{note-event}, a @code{rhythmic-event} and a @code{melodic-event}.
All classes of music are listed in the internals manual, under
- @internalsref{Music classes}.
-@item
-C++ object: Each music object is represented by a C++ object. For technical
-reasons, different music objects may be represented by different C++
-object types. For example, a note is @code{Event} object, while
-@code{\grace} creates a @code{Grace_music} object.
+ @hyphenatedinternalsref{Music classes,Music-classes}.
+
+ @item
+C++ object: Each music object is represented by a C++ object. For
+technical reasons, different music objects may be represented by
+different C++ object types. For example, a note is @code{Event}
+object, while @code{\grace} creates a @code{Grace_music} object.
We expect that distinctions between different C++ types will disappear
in the future.
music object in the @code{element} object. For example,
@internalsref{SequentialMusic} has its children in @code{elements},
and @internalsref{GraceMusic} has its single argument in
-@code{element}. The body of a repeat is in @code{element} property of
-@internalsref{RepeatedMusic}, and the alternatives in @code{elements}.
+@code{element}. The body of a repeat is stored in the @code{element}
+property of @internalsref{RepeatedMusic}, and the alternatives in
+@code{elements}.
@node Extending music syntax
-@appendixsubsec Extending music syntax
+@subsection Extending music syntax
The syntax of composite music expressions, like
@code{\repeat}, @code{\transpose} and @code{\context}
@end example
Such syntax can also be defined as user code. To do this, it is
-necessary to create a @em{music function}. This is a specially marked
-Scheme function. For example, the music function @code{\apply} applies
+necessary to create a @emph{music function}. This is a specially marked
+Scheme function. For example, the music function @code{\applymusic} applies
a user-defined function to a music expression. Its syntax is
@example
-\apply #@var{func} @var{music}
+\applymusic #@var{func} @var{music}
@end example
A music function is created with @code{ly:make-music-function},
(ly:make-music-function
@end example
-@code{\apply} takes a Scheme function and a Music expression as
+@code{\applymusic} takes a Scheme function and a Music expression as
argument. This is encoded in its first argument,
@example
@end example
The above Scheme code only defines the functionality. The tag
-@code{\apply} is selected by defining
+@code{\applymusic} is selected by defining
@example
- apply = #(ly:make-music-function
- (list procedure? ly:music?)
- (lambda (where func music)
- (func music)))
+ applymusic = #(ly:make-music-function
+ (list procedure? ly:music?)
+ (lambda (location func music)
+ (func music)))
+@end example
+
+A @code{def-music-function} macro is introduced on top of
+@code{ly:make-music-function} to ease the definition of music
+functions:
+
+@example
+ applymusic = #(def-music-function (location func music)
+ (procedure? ly:music?)
+ (func music))
@end example
-Examples of the use of @code{\apply} are in the next section.
+Examples of the use of @code{\applymusic} are in the next section.
+@seealso
+@file{ly/music-functions-init.ly}.
@node Manipulating music expressions
-@appendixsubsec Manipulating music expressions
+@subsection Manipulating music expressions
Music objects and their properties can be accessed and manipulated
-directly, through the @code{\apply} mechanism.
-The syntax for @code{\apply} is
+directly, through the @code{\applymusic} mechanism.
+The syntax for @code{\applymusic} is
@example
-\apply #@var{func} @var{music}
+\applymusic #@var{func} @var{music}
@end example
@noindent
-This means that the scheme function @var{func} is called with
+This means that the Scheme function @var{func} is called with
@var{music} as its argument. The return value of @var{func} is the
result of the entire expression. @var{func} may read and write music
properties using the functions @code{ly:music-property} and
@code{ly:music-set-property!}.
An example is a function that reverses the order of elements in
-its argument:
+its argument,
@lilypond[verbatim,raggedright]
#(define (rev-music-1 m)
(ly:music-set-property! m 'elements (reverse
(ly:music-property m 'elements)))
m)
- \score { \notes \apply #rev-music-1 { c4 d4 } }
+ \applymusic #rev-music-1 { c4 d4 }
@end lilypond
The use of such a function is very limited. The effect of this
function is void when applied to an argument which is does not have
-multiple children. The following function application has no effect:
+multiple children. The following function application has no effect
@example
- \apply #rev-music-1 \grace @{ c4 d4 @}
+ \applymusic #rev-music-1 \grace @{ c4 d4 @}
@end example
@noindent
In this case, @code{\grace} is stored as @internalsref{GraceMusic}, which has no
@code{elements}, only a single @code{element}. Every generally
-applicable function for @code{\apply} must -- like music expressions
+applicable function for @code{\applymusic} must---like music expressions
themselves -- be recursive.
The following example is such a recursive function: It first extracts
\context Voice = "2" @{ \voiceTwo b @} >>
@end example
-Other applications of @code{\apply} are writing out repeats
+Other applications of @code{\applymusic} are writing out repeats
automatically (@inputfileref{input/test,unfold-all-repeats.ly}),
saving keystrokes (@inputfileref{input/test,music-box.ly}) and
-exporting
-LilyPond input to other formats (@inputfileref{input/test,to-xml.ly})
+exporting LilyPond input to other formats
+(@inputfileref{input/test,to-xml.ly})
+
+@cindex internal storage
+@cindex @code{\displayMusic}
+When writing a music function, it is often instructive to inspect how
+a music expression is stored internally. This can be done with the
+music function @code{\displayMusic}
@seealso
@inputfileref{input/test,music-box.ly}.
+@node Using LilyPond syntax inside Scheme
+@subsection Using LilyPond syntax inside Scheme
+
+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, using LilyPond usual syntax inside
+Scheme, with the dedicated @code{#@{ ... #@}} syntax.
+
+The following two expressions give equivalent music expressions:
+@example
+ mynotes = @{ \override Stem #'thickness = #4
+ @{ c'8 d' @} @}
+
+ #(define mynotes #@{ \override Stem #'thickness = #4
+ @{ c'8 d' @} #@})
+@end example
+
+The content of @code{#@{ ... #@}} is enclosed in an implicit @code{@{
+... @}} block, which is parsed. The resulting music expression, a
+@code{SequentialMusic} music object, is then returned and usable in Scheme.
+
+Arbitrary Scheme forms, including variables, can be used in @code{#@{ ... #@}}
+expressions with the @code{$} character (@code{$$} can be used to
+produce a single $ character). This makes the creation of simple
+functions straightforward. In the following example, a function
+setting the TextScript's padding is defined:
+
+@lilypond[verbatim,raggedright]
+ #(use-modules (ice-9 optargs))
+ #(define* (textpad padding #:optional once?)
+ (ly:export ; this is necessary for using the expression
+ ; directly inside a block
+ (if once?
+ #{ \once \override TextScript #'padding = #$padding #}
+ #{ \override TextScript #'padding = #$padding #})))
+
+ {
+ c'^"1"
+ #(textpad 3.0 #t) % only once
+ c'^"2"
+ c'^"3"
+ #(textpad 5.0)
+ c'^"4"
+ c'^"5"
+
+ }
+@end lilypond
+
+Here, the variable @code{padding} is a number; music expression
+variables may also be used in a similar fashion, as in the following
+example:
+
+@lilypond[verbatim,raggedright]
+ #(define (with-padding padding)
+ (lambda (music)
+ #{ \override TextScript #'padding = #$padding
+ $music
+ \revert TextScript #'padding #}))
+
+ {
+ c'^"1"
+ \applymusic #(with-padding 3)
+ { c'^"2" c'^"3"}
+ c'^"4"
+ }
+@end lilypond
+
+The function created by @code{(with-padding 3)} adds @code{\override} and
+@code{\revert} statements around the music given as an argument, and returns
+this new expression. Thus, this example is equivalent to:
+
+@example
+ @{
+ c'^"1"
+ @{ \override TextScript #'padding = #3
+ @{ c'^"2" c'^"3"@}
+ \revert TextScript #'padding
+ @}
+ c'^"4"
+ @}
+@end example
+
+This function may also be defined as a music function:
+
+@lilypond[verbatim,raggedright]
+ withPadding = #(def-music-function (location padding music) (number? ly:music?)
+ #{ \override TextScript #'padding = #$padding
+ $music
+ \revert TextScript #'padding #})
+
+ {
+ c'^"1"
+ \withPadding #3
+ { c'^"2" c'^"3"}
+ c'^"4"
+ }
+@end lilypond
+
@node Markup programmer interface
-@appendixsec Markup programmer interface
+@section Markup programmer interface
+Markups implemented as special Scheme functions. When applied with as
+arguments an output definition (@code{\layout} or @code{\paper}),
+and a list of properties and other arguments, produce a Stencil
+object.
@menu
-* Markup construction in scheme::
+* Markup construction in Scheme::
+* How markups work internally ::
* Markup command definition::
@end menu
-@node Markup construction in scheme
-@appendixsubsec Markup construction in scheme
+@node Markup construction in Scheme
+@subsection Markup construction in Scheme
@cindex defining markup commands
@noindent
This example exposes the main translation rules between regular
-LilyPond markup syntax and scheme markup syntax, which are summed up
+LilyPond markup syntax and Scheme markup syntax, which are summed up
is this table:
@multitable @columnfractions .5 .5
@item @b{LilyPond} @tab @b{Scheme}
@end lisp
is illegal. One should use the @code{make-line-markup} (resp
@code{make-center-markup}, @code{make-column-markup}) function
-instead:
+instead,
@lisp
(markup (make-line-markup (fun-that-returns-markups)))
@end lisp
+@node How markups work internally
+@subsection How markups work internally
+
+In a markup like
+
+@example
+ \raise #0.5 "foo"
+@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 'latin1 "foo"))
+@end example
+
+@noindent
+In this case, @code{latin1} is the input encoding, which is set with
+the @code{\encoding} command.
+
+When the markup is converted to printable objects (Stencils), the
+raise markup is called as
+
+@example
+ (apply raise-markup
+ @var{\layout object}
+ @var{list of property alists}
+ 0.5
+ @var{the "foo" markup})
+@end example
+
+The @code{raise-markup} first creates the stencil for the @code{foo}
+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 Markup command definition
-@appendixsubsec Markup command definition
+@subsection Markup command definition
New markup commands can be defined
with the @code{def-markup-command} scheme macro.
@lisp
-(def-markup-command (@var{command-name} @var{paper} @var{props} @var{arg1} @var{arg2} ...)
+(def-markup-command (@var{command-name} @var{layout} @var{props} @var{arg1} @var{arg2} ...)
(@var{arg1-type?} @var{arg2-type?} ...)
..command body..)
@end lisp
@var{i}th command argument
@item argi-type?
a type predicate for the i@var{th} argument
-@item paper
-the `paper' definition
+@item layout
+the `layout' definition
@item props
a list of alists, containing all active properties.
@end table
take a single argument, of markup type. Therefore, the start of the
definition should read
@example
- (def-markup-command (smallcaps paper props argument) (markup?)
+ (def-markup-command (smallcaps layout props argument) (markup?)
@end example
@noindent
the @code{argument} as a markup, i.e.
@example
- (interpret-markup paper @dots{} argument)
+ (interpret-markup layout @dots{} argument)
@end example
@noindent
defined @code{\smallcaps} command:
@verbatim
-#(def-markup-command (character paper props name) (string?)
+#(def-markup-command (character layout props name) (string?)
"Print the character name in small caps, translated to the left and
top. Syntax: \\character #\"name\""
- (interpret-markup paper props
+ (interpret-markup layout props
(markup "" #:translate (cons -4 2) #:smallcaps name)))
@end verbatim
The final result is as follows:
@verbatim
-\score {
- \notes { \fatText
+ { \fatText
c''^\markup \character #"Cleopatra"
e'^\markup \character #"Giulio Cesare"
}
-}
@end verbatim
@lilypond[raggedright]
-#(def-markup-command (smallcaps paper props str) (string?)
+#(def-markup-command (smallcaps layout props str) (string?)
"Print the string argument in small caps. Syntax: \\smallcaps #\"string\""
- (interpret-markup paper props
+ (interpret-markup layout props
(make-line-markup
(map (lambda (s)
(if (= (string-length s) 0)
#:tiny (string-upcase (substring s 1)))))
(string-split str #\Space)))))
-#(def-markup-command (character paper props name) (string?)
+#(def-markup-command (character layout props name) (string?)
"Print the character name in small caps, translated to the left and
top. Syntax: \\character #\"name\""
- (interpret-markup paper props
+ (interpret-markup layout props
(markup "" #:translate (cons -4 0) #:smallcaps name)))
-\score {
- \notes { \fatText
+ { \fatText
c''^\markup \character #"Cleopatra"
e'^\markup \character #"Giulio Cesare"
}
-}
@end lilypond
We have used the @code{caps} font shape, but suppose that our font
letter a little larger:
@example
-#(def-markup-command (smallcaps paper props str) (string?)
+#(def-markup-command (smallcaps layout props str) (string?)
"Print the string argument in small caps."
- (interpret-markup paper props
+ (interpret-markup layout props
(make-line-markup
(map (lambda (s)
(if (= (string-length s) 0)
translated to the left (@code{#:translate (cons -0.6 0) ...}). Then,
the markups built for each token are put in a line by
@code{(make-line-markup ...)}. Finally, the resulting markup is passed
-to the @code{interpret-markup} function, with the @code{paper} and
+to the @code{interpret-markup} function, with the @code{layout} and
@code{props} arguments.
@node Contexts for programmers
-@appendixsec Contexts for programmers
+@section Contexts for programmers
@menu
@end menu
@node Context evaluation
-@appendixsubsec Context evaluation
+@subsection Context evaluation
+
+@cindex calling code during interpreting
+@cindex @code{\applycontext}
Contexts can be modified during interpretation with Scheme code. The
syntax for this is
@node Running a function on all layout objects
-@appendixsubsec Running a function on all layout objects
+@subsection Running a function on all layout objects
+
+
+@cindex calling code on layout objects
+@cindex @code{\applyoutput}
+
The most versatile way of tuning an object is @code{\applyoutput}. Its
syntax is