-@c -*-texinfo-*-
+@c -*- coding: latin-1; mode: texinfo; -*-
@node Interfaces for programmers
@chapter Interfaces for programmers
* Input variables and Scheme::
* Internal music representation::
* Extending music syntax::
-* Manipulating music expressions::
-* Using LilyPond syntax inside Scheme::
+* Manipulating music expressions::
+* Using LilyPond syntax inside Scheme::
@end menu
@node Input variables and Scheme
@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 = @{ c'4 d'4 @}
- \paper @{ traLaLa = 1.0 @}
+ \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.
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
@refbugs
-Mixing Scheme and lily identifiers is not possible with @code{--safe}.
+Mixing Scheme and LilyPond identifiers is not possible with the
+@code{--safe} option.
@node Internal music representation
@subsection Internal music representation
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}.
functions:
@example
- applymusic = #(def-music-function (location func music) (procedure? ly:music?)
+ applymusic = #(def-music-function (location func music)
+ (procedure? ly:music?)
(func music))
@end example
@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
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
\applymusic #rev-music-1 \grace @{ c4 d4 @}
@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{\applymusic} 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
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
@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
+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.
+Scheme, with the dedicated @code{#@{ ... #@}} syntax.
The following two expressions give equivalent music expressions:
@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.
+@code{SequentialMusic} music object, is then returned and usable in Scheme.
-Arbitrary scheme forms, including variables, can be used in @code{#@{ ... #@}}
+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
@node 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
-@subsection 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
@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
@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)))
{ \fatText
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.