-@c -*- coding: latin-1; mode: texinfo; -*-
+@c -*- coding: utf-8; mode: texinfo; -*-
@node Interfaces for programmers
@chapter Interfaces for programmers
* Internal music representation::
* Extending music syntax::
* Manipulating music expressions::
+* Displaying music expressions::
* Using LilyPond syntax inside Scheme::
@end menu
@subsection Input variables and Scheme
-The input format supports the notion of variable: in the following
+The input format supports the notion of variables: in the following
example, a music expression is assigned to a variable with the name
@code{traLaLa}.
@example
- traLaLa = @{ c'4 d'4 @}
+traLaLa = @{ c'4 d'4 @}
@end example
@noindent
@code{\layout} block also contains a @code{traLaLa} variable, which is
independent of the outer @code{\traLaLa}.
@example
- traLaLa = @{ c'4 d'4 @}
- \layout @{ 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{\layout} 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
+An anonymous Scheme module is attached to each scope. An assignment of
the form
@example
- traLaLa = @{ 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{... }''})
+(define traLaLa @var{Scheme value of ``@code{... }''})
@end example
This means that input variables and Scheme variables may be freely
mixed. In the following example, a music fragment is stored in the
-variable @code{traLaLa}, and duplicated using Scheme. The result is
-imported in a @code{\score} by means of a second variable
+variable @code{traLaLa}, and duplicated using Scheme. The result is
+imported in a @code{\score} block by means of a second variable
@code{twice}:
@example
- traLaLa = @{ 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))
+#(define newLa (map ly:music-deep-copy
+ (list traLaLa traLaLa)))
+#(define twice
+ (make-sequential-music newLa))
- @{ \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
+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
of defining @code{\twice}, the example above could also have been
written as
@example
- @dots{}
- @{ #(ly:export (make-sequential-music newLa)) @}
+@dots{}
+@{ #(ly:export (make-sequential-music (list newLa))) @}
@end example
+Scheme code is evaluated as soon as the parser encounters it. To
+define some scheme code in a macro (to be called later), use
+
+@example
+#(define (nopc)
+ (ly:set-option 'point-and-click #f))
+
+...
+#(nopc)
+@{ c'4 @}
+@end example
+
+
@refbugs
Mixing Scheme and LilyPond identifiers is not possible with the
@code{--safe} option.
+
@node 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
-it takes up time. Time is a rational number that measures the length
+Scheme music objects. The defining property of a music object is that
+it takes up time. Time is a rational number that measures the length
of a piece of music, in whole notes.
A music object has three kinds of types:
@itemize @bullet
@item
- music name: Each music expression has a name, for example, a note
+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
+a @internalsref{SimultaneousMusic}. A list of all expressions
available is in the internals manual, under
-@hyphenatedinternalsref{Music expressions,Music-expressions}.
+@internalsref{Music expressions}.
@item
- `type' or interface: Each music name has several `types' or
+`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}.
+@code{note-event}, a @code{rhythmic-event}, and a @code{melodic-event}.
- All classes of music are listed in the internals manual, under
- @hyphenatedinternalsref{Music classes,Music-classes}.
+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
+@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}
+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
under @internalsref{Music properties}.
A compound music expression is a music object that contains other
-music objects in its properties. A list of objects can be stored in
+music objects in its properties. A list of objects can be stored in
the @code{elements} property of a music object, or a single `child'
-music object in the @code{element} object. For example,
+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 stored in the @code{element}
+@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
@subsection Extending music syntax
-The syntax of composite music expressions, like
-@code{\repeat}, @code{\transpose} and @code{\context}
-follows the general form of
+@c TODO: rewrite example.
+@c The use of FUNC as example argument is rather confusing.
+
+The syntax of composite music expressions, like @code{\repeat},
+@code{\transpose}, and @code{\context} follows the general form of
@example
- \@code{keyword} @var{non-music-arguments} @var{music-arguments}
+\@code{keyword} @var{non-music-arguments} @var{music-arguments}
@end example
-Such syntax can also be defined as user code. To do this, it is
-necessary to create a @emph{music function}. This is a specially marked
-Scheme function. For example, the music function @code{\applymusic} applies
+Such syntax can also be defined as user code. To do this, it is
+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
-\applymusic #@var{func} @var{music}
+\applyMusic #@var{func} @var{music}
@end example
A music function is created with @code{ly:make-music-function},
@example
- (ly:make-music-function
+(ly:make-music-function
@end example
-@code{\applymusic} takes a Scheme function and a Music expression as
-argument. This is encoded in its first argument,
+@code{\applyMusic} takes a Scheme function and a Music expression as
+arguments. This is encoded in its parameter list,
@example
- (list procedure? ly:music?)
+(list procedure? ly:music?)
@end example
The function itself takes another argument, an Input location
-object. That object is used to provide error messages with file names
+object. That object is used to provide error messages with file names
and line numbers. The definition is the second argument of
-@code{ly:make-music-function}. The body is function simply calls the
-function
+@code{ly:make-music-function}. The body simply calls the function
@example
- (lambda (where func music)
- (func music))
+(lambda (where func music)
+ (func music))
@end example
-The above Scheme code only defines the functionality. The tag
-@code{\applymusic} is selected by defining
+The above Scheme code only defines the functionality. The tag
+@code{\applyMusic} is selected by defining
@example
- applymusic = #(ly:make-music-function
- (list procedure? ly:music?)
- (lambda (location func music)
- (func music)))
+applyMusic = #(ly:make-music-function
+ (list procedure? ly:music?)
+ (lambda (parser location func music)
+ (func music)))
@end example
-A @code{def-music-function} macro is introduced on top of
+A @code{define-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))
+applyMusic = #(define-music-function (parser location func music)
+ (procedure? ly:music?)
+ (func music))
@end example
-Examples of the use of @code{\applymusic} are in the next section.
+Examples of the use of @code{\applyMusic} are in the next section.
@seealso
-@file{ly/music-functions-init.ly}.
+@file{ly/@/music@/-functions@/-init@/.ly}.
@node Manipulating music expressions
@subsection Manipulating music expressions
Music objects and their properties can be accessed and manipulated
-directly, through the @code{\applymusic} mechanism.
-The syntax for @code{\applymusic} is
+directly, through the @code{\applyMusic} mechanism.
+The syntax for @code{\applyMusic} is
@example
-\applymusic #@var{func} @var{music}
+\applyMusic #@var{func} @var{music}
@end example
@noindent
An example is a function that reverses the order of elements in
its argument,
-@lilypond[verbatim,raggedright]
- #(define (rev-music-1 m)
- (ly:music-set-property! m 'elements (reverse
- (ly:music-property m 'elements)))
- m)
- \applymusic #rev-music-1 { c4 d4 }
+@lilypond[quote,verbatim,ragged-right]
+#(define (rev-music-1 m)
+ (ly:music-set-property! m 'elements
+ (reverse (ly:music-property m 'elements)))
+ m)
+
+\applyMusic #rev-music-1 { c'4 d'4 }
@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
+The use of such a function is very limited. The effect of this
+function is void when applied to an argument that does not have
multiple children. The following function application has no effect
@example
- \applymusic #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{\applymusic} must---like music expressions
+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
themselves -- be recursive.
The following example is such a recursive function: It first extracts
the @code{elements} of an expression, reverses them and puts them
-back. Then it recurses, both on @code{elements} and @code{element}
+back. Then it recurses, both on @code{elements} and @code{element}
children.
@example
#(define (reverse-music music)
@end example
A slightly more elaborate example is in
-@inputfileref{input/test,reverse-music.ly}.
+@inputfileref{input/@/test,reverse@/-music@/.ly}.
Some of the input syntax is also implemented as recursive music
-functions. For example, the syntax for polyphony
+functions. For example, the syntax for polyphony
@example
- <<a \\ b>>
+<<a \\ b>>
@end example
@noindent
-is actually implemented as a recursive function that replaces the
+is actually implemented as a recursive function that replaces the
above by the internal equivalent of
@example
- << \context Voice = "1" @{ \voiceOne a @}
- \context Voice = "2" @{ \voiceTwo b @} >>
+<< \context Voice = "1" @{ \voiceOne a @}
+ \context Voice = "2" @{ \voiceTwo b @} >>
@end example
-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
+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})
+@c no @inputfileref{} here
+(eg. @file{input/@/no@/-notation/@/to@/-xml@/.ly}).
+
+@seealso
+
+@file{scm/@/music@/-functions@/.scm}, @file{scm/@/music@/-types@/.scm},
+@inputfileref{input/@/test,add@/-staccato@/.ly},
+@inputfileref{input/@/test,unfold@/-all@/-repeats@/.ly}, and
+@inputfileref{input/@/test,music@/-box@/.ly}.
+
+
+@node Displaying music expressions
+@subsection Displaying music expressions
@cindex internal storage
@cindex @code{\displayMusic}
+@cindex @code{\displayLilyMusic}
+
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}
+a music expression is stored internally. This can be done with the
+music function @code{\displayMusic}.
-@seealso
+@example
+@{
+ \displayMusic @{ c'4\f @}
+@}
+@end example
-@file{scm/music-functions.scm}, @file{scm/music-types.scm},
-@inputfileref{input/test,add-staccato.ly},
-@inputfileref{input/test,unfold-all-repeats.ly}, and
-@inputfileref{input/test,music-box.ly}.
+Conversely, displaying a music expression in LilyPond notation can be
+done using the music function @code{\displayLilyMusic}. For instance:
+@example
+@{
+ \displayLilyMusic \transpose c a, @{ c e g a bes @}
+@}
+@end example
+
+will display:
+
+@example
+@{ a, cis e fis g @}
+@end example
@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
+heavily nested and the resulting Scheme code is large. For some
+simple tasks, this can be avoided, using common LilyPond 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' @} @}
+mynotes = @{ \override Stem #'thickness = #4
+ @{ c'8 d' @} @}
- #(define 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
+... @}} 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
+produce a single @code{$} 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"
-
- }
+@lilypond[quote,verbatim,ragged-right]
+#(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"
- }
+@lilypond[quote,verbatim,ragged-right]
+#(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:
+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"
- @}
+@{
+ 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"
- }
+@lilypond[quote,verbatim,ragged-right]
+withPadding =
+ #(define-music-function (parser 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
@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.
+@c Please rewrite the second sentence; I don't understand its meaning. AS
+
+Markups are 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::
@cindex defining markup commands
The @code{markup} macro builds markup expressions in Scheme while
-providing a LilyPond-like syntax. For example,
+providing a LilyPond-like syntax. For example,
@example
(markup #:column (#:line (#:bold #:italic "hello" #:raise 0.4 "world")
#:bigger #:line ("foo" "bar" "baz")))
@noindent
is equivalent to:
@example
-\markup \column < @{ \bold \italic "hello" \raise #0.4 "world" @}
- \bigger @{ foo bar baz @} >
+\markup \column @{ \line @{ \bold \italic "hello" \raise #0.4 "world" @}
+ \bigger \line @{ foo bar baz @} @}
@end example
@noindent
This example exposes the main translation rules between regular
LilyPond markup syntax and Scheme markup syntax, which are summed up
is this table:
-@multitable @columnfractions .5 .5
+
+@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{\command} @tab @code{#:command}
@item @code{\variable} @tab @code{variable}
-@item @code{@{ ... @}} @tab @code{#:line ( ... )}
-@item @code{\center-align < ... >} @tab @code{#:center ( ... )}
+@item @code{\center-align @{ ... @}} @tab @code{#:center-align ( ... )}
@item @code{string} @tab @code{"string"}
@item @code{#scheme-arg} @tab @code{scheme-arg}
@end multitable
+@end quotation
Besides, the whole scheme language is accessible inside the
@code{markup} macro: thus, one may use function calls inside
@code{markup} in order to manipulate character strings for
-instance. This proves useful when defining new markup commands (see
+instance. This proves useful when defining new markup commands (see
@ref{Markup command definition}).
@refbugs
One can not feed the @code{#:line} (resp @code{#:center},
@code{#:column}) command with a variable or the result of a function
-call. E.g.:
+call. Example:
+
@lisp
(markup #:line (fun-that-returns-markups))
@end lisp
-is illegal. One should use the @code{make-line-markup} (resp
-@code{make-center-markup}, @code{make-column-markup}) function
+
+@noindent
+is invalid. One should use the @code{make-line-markup} (resp.,
+@code{make-center-markup} or @code{make-column-markup}) function
instead,
@lisp
(markup (make-line-markup (fun-that-returns-markups)))
In a markup like
@example
- \raise #0.5 "foo"
+\raise #0.5 "foo"
@end example
@noindent
@code{\raise} is actually represented by the @code{raise-markup}
-function. The markup expression is stored as
+function. The markup expression is stored as
@example
- (list raise-markup 0.5 (list simple-markup 'latin1 "foo"))
+(list raise-markup 0.5 (list simple-markup "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
+@code{raise-markup} function is called as
@example
- (apply raise-markup
- @var{\layout object}
- @var{list of property alists}
- 0.5
- @var{the "foo" markup})
+(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}.
+The @code{raise-markup} function 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.
+with the @code{define-markup-command} scheme macro.
@lisp
-(def-markup-command (@var{command-name} @var{layout} @var{props} @var{arg1} @var{arg2} ...)
+(define-markup-command (@var{command-name} @var{layout} @var{props} @var{arg1} @var{arg2} ...)
(@var{arg1-type?} @var{arg2-type?} ...)
..command body..)
@end lisp
which selects @TeX{}'s small caps font. Normally, we could select the
small caps font as follows:
-@verbatim
- \markup { \override #'(font-shape . caps) Text-in-caps }
-@end verbatim
+@example
+\markup @{ \override #'(font-shape . caps) Text-in-caps @}
+@end example
This selects the caps font by setting the @code{font-shape} property to
@code{#'caps} for interpreting @code{Text-in-caps}.
To make the above available as @code{\smallcaps} command, we have to
-define a function using @code{def-markup-command}. The command should
-take a single argument, of markup type. Therefore, the start of the
+define a function using @code{define-markup-command}. The command should
+take a single argument, of type markup. Therefore, the start of the
definition should read
@example
- (def-markup-command (smallcaps layout props argument) (markup?)
+(define-markup-command (smallcaps layout props argument) (markup?)
@end example
@noindent
What follows is the content of the command: we should interpret
-the @code{argument} as a markup, i.e.
+the @code{argument} as a markup, i.e.,
@example
- (interpret-markup layout @dots{} argument)
+(interpret-markup layout @dots{} argument)
@end example
@noindent
This interpretation should add @code{'(font-shape . caps)} to the active
-properties, so we substitute the following for the @dots{} in the
+properties, so we substitute the following for the @dots{} in the
above example:
@example
- (cons (list '(font-shape . caps) ) props)
+(cons (list '(font-shape . caps) ) props)
@end example
@noindent
The variable @code{props} is a list of alists, and we prepend to it by
-consing a list with the extra setting.
+cons'ing a list with the extra setting.
Suppose that we are typesetting a recitative in an opera, and
we would like to define a command that will show character names in a
-custom manner. Names should be printed with small caps and translated a
+custom manner. Names should be printed with small caps and translated a
bit to the left and top. We will define a @code{\character} command
-that takes into account the needed translation, and uses the newly
+that takes into account the necessary translation, and uses the newly
defined @code{\smallcaps} command:
-@verbatim
-#(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 layout props
- (markup "" #:translate (cons -4 2) #:smallcaps name)))
-@end verbatim
+@example
+#(define-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 layout props
+ (markup #:hspace 0 #:translate (cons -3 1) #:smallcaps name)))
+@end example
There is one complication that needs explanation: texts above and below
the staff are moved vertically to be at a certain distance (the
-@code{padding} property) from the staff and the notes. To make sure
+@code{padding} property) from the staff and the notes. To make sure
that this mechanism does not annihilate the vertical effect of our
-@code{#:translate}, we add an empty string (@code{""}) before the
-translated text. Now the @code{""} will be put above the notes, and the
-@code{name} is moved in relation to that empty string. The net effect is
+@code{#:translate}, we add an empty string (@code{#:hspace 0}) before the
+translated text. Now the @code{#:hspace 0} will be put above the notes, and the
+@code{name} is moved in relation to that empty string. The net effect is
that the text is moved to the upper left.
The final result is as follows:
-@verbatim
- { \fatText
- c''^\markup \character #"Cleopatra"
- e'^\markup \character #"Giulio Cesare"
- }
-@end verbatim
-
-@lilypond[raggedright]
-#(def-markup-command (smallcaps layout props str) (string?)
- "Print the string argument in small caps. Syntax: \\smallcaps #\"string\""
- (interpret-markup layout props
- (make-line-markup
- (map (lambda (s)
- (if (= (string-length s) 0)
- s
- (markup #:large (string-upcase (substring s 0 1))
- #:translate (cons -0.6 0)
- #:tiny (string-upcase (substring s 1)))))
- (string-split str #\Space)))))
-
-#(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 layout props
- (markup "" #:translate (cons -4 0) #:smallcaps name)))
-
- { \fatText
- c''^\markup \character #"Cleopatra"
- e'^\markup \character #"Giulio Cesare"
- }
+@example
+@{
+ c''^\markup \character #"Cleopatra"
+ e'^\markup \character #"Giulio Cesare"
+@}
+@end example
+
+@lilypond[quote,ragged-right]
+#(define-markup-command (smallcaps layout props str) (string?)
+ "Print the string argument in small caps. Syntax: \\smallcaps #\"string\""
+ (interpret-markup layout props
+ (make-line-markup
+ (map (lambda (s)
+ (if (= (string-length s) 0)
+ s
+ (markup #:large (string-upcase (substring s 0 1))
+ #:translate (cons -0.6 0)
+ #:tiny (string-upcase (substring s 1)))))
+ (string-split str #\Space)))))
+
+#(define-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 layout props
+ (markup #:hspace 0 #:translate (cons -3 1) #:smallcaps name)))
+
+{
+ c''^\markup \character #"Cleopatra" c'' c'' c''
+ e'^\markup \character #"Giulio Cesare" e' e' e'
+}
@end lilypond
We have used the @code{caps} font shape, but suppose that our font
-that does not have a small-caps variant. In that case, we have to fake
-the small caps font, by setting a string in upcase, with the first
+does not have a small-caps variant. In that case we have to fake
+the small caps font by setting a string in upcase with the first
letter a little larger:
@example
-#(def-markup-command (smallcaps layout props str) (string?)
- "Print the string argument in small caps."
- (interpret-markup layout props
- (make-line-markup
- (map (lambda (s)
- (if (= (string-length s) 0)
- s
- (markup #:large (string-upcase (substring s 0 1))
- #:translate (cons -0.6 0)
- #:tiny (string-upcase (substring s 1)))))
- (string-split str #\Space)))))
+#(define-markup-command (smallcaps layout props str) (string?)
+ "Print the string argument in small caps."
+ (interpret-markup layout props
+ (make-line-markup
+ (map (lambda (s)
+ (if (= (string-length s) 0)
+ s
+ (markup #:large (string-upcase (substring s 0 1))
+ #:translate (cons -0.6 0)
+ #:tiny (string-upcase (substring s 1)))))
+ (string-split str #\Space)))))
@end example
The @code{smallcaps} command first splits its string argument into
each token, a markup is built with the first letter made large and
upcased (@code{#:large (string-upcase (substring s 0 1))}), and a
second markup built with the following letters made tiny and upcased
-(@code{#:tiny (string-upcase (substring s 1))}). As LilyPond
+(@code{#:tiny (string-upcase (substring s 1))}). As LilyPond
introduces a space between markups on a line, the second markup is
-translated to the left (@code{#:translate (cons -0.6 0) ...}). Then,
+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
+@code{(make-line-markup ...)}. Finally, the resulting markup is passed
to the @code{interpret-markup} function, with the @code{layout} and
@code{props} arguments.
@subsection Context evaluation
@cindex calling code during interpreting
-@cindex @code{\applycontext}
+@cindex @code{\applyContext}
-Contexts can be modified during interpretation with Scheme code. The
+Contexts can be modified during interpretation with Scheme code. The
syntax for this is
@example
- \applycontext @var{function}
+\applyContext @var{function}
@end example
@var{function} should be a Scheme function taking a single argument,
-being the context to apply it to. The following code will print the
+being the context to apply it to. 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)))
+\applyContext
+ #(lambda (x)
+ (format #t "\nWe were called in barnumber ~a.\n"
+ (ly:context-property x 'currentBarNumber)))
@end example
@cindex calling code on layout objects
-@cindex @code{\applyoutput}
+@cindex @code{\applyOutput}
-The most versatile way of tuning an object is @code{\applyoutput}. Its
+The most versatile way of tuning an object is @code{\applyOutput}. Its
syntax is
@example
-\applyoutput @var{proc}
+\applyOutput @var{proc}
@end example
@noindent
@itemize @bullet
@item the layout object itself,
@item the context where the layout object was created, and
-@item the context where @code{\applyoutput} is processed.
+@item the context where @code{\applyOutput} is processed.
@end itemize
-In addition, the cause of the layout object, i.e. the music
+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
@internalsref{NoteHead} event, and for a @internalsref{Stem} object,
this is a @internalsref{NoteHead} object.
-Here is a function to use for @code{\applyoutput}; it blanks
+Here is a function to use for @code{\applyOutput}; it blanks
note-heads on the center-line:
@example
(define (blanker grob grob-origin context)
- (if (and (memq (ly:grob-property grob 'interfaces)
- note-head-interface)
- (eq? (ly:grob-property grob 'staff-position) 0))
-
- (set! (ly:grob-property grob 'transparent) #t)))
+ (if (and (memq (ly:grob-property grob 'interfaces)
+ note-head-interface)
+ (eq? (ly:grob-property grob 'staff-position) 0))
+ (set! (ly:grob-property grob 'transparent) #t)))
@end example