Guide, node Updating translation committishes..
@end ignore
-@c \version "2.14.0"
+@c \version "2.19.2"
@node Interfaces for programmers
@chapter Interfaces for programmers
@ref{Scheme tutorial}.
@menu
-* Lilypond code blocks::
+* LilyPond code blocks::
* Scheme functions::
* Music functions::
* Event functions::
* Markup functions::
* Contexts for programmers::
* Callback functions::
-* Inline Scheme code::
* Difficult tweaks::
@end menu
-@node Lilypond code blocks
-@section Lilypond code blocks
+@node LilyPond code blocks
+@section LilyPond code blocks
+
+@cindex LilyPond code blocks
+@cindex code blocks, LilyPond
+@funindex #@{ @dots{} #@}
+@funindex $
+@funindex #
+
+Creating music expressions in Scheme can be tedious, as they are
+heavily nested and the resulting Scheme code is large. For some
+simple tasks this can be avoided by using LilyPond code blocks,
+which enable common LilyPond syntax to be used within Scheme.
+
+LilyPond code blocks look like
-Lilypond code blocks look like
@example
- #@{ @var{Lilypond code} #@}
+ #@{ @var{LilyPond code} #@}
@end example
-They can be used anywhere where you can write Scheme code: the Scheme
-reader actually is changed for accommodating LilyPond code blocks. When
-the LilyPond code block is being read, it is parsed superficially and
-replaced by a call to the LilyPond @code{parser} which is executed at
-runtime to interpret the LilyPond code block.
-The point of the superficial parsing is the interpretation of @code{$}
-signs which can be used for splicing in expressions from the surrounding
-lexical Scheme context (like @code{let} variables and function
-parameters). @code{$} can be used in the following ways:
+Here is a trivial example:
-@table @code
-@item $$
-just passes a single @code{$} to the LilyPond parser.
-@item $@var{form}
-will evaluate the Scheme form at runtime and splice its value as an
-identifier @code{\form} into the LilyPond parser. Depending on the
-value type, it may be interpreted as several different syntactic
-entities.
-@item #$@var{form}
-will evaluate the Scheme form at runtime and splice its value as a
-Scheme expression into the LilyPond parser.
-@item #@var{form}
-Forms in Scheme expressions started with @code{#} are read and parsed
-recursively for @code{$} signs. Those are treated as follows:
-@item #@dots{}$@var{variable}
-splices the value of the variable into the surrounding expression.
-@item #@dots{}($ @var{form} @dots{})
-splices the value of the form into the surrounding expression. As
-opposed to a LilyPond level @code{$@var{form}}, you need to separate the
-form with a blank, making @code{$} be recognizable as a separate Scheme
-symbol.
-@end table
+@lilypond[verbatim,quote]
+ritpp = #(define-event-function (parser location) ()
+ #{ ^"rit." \pp #}
+)
+
+{ c'4 e'4\ritpp g'2 }
+@end lilypond
-A LilyPond code block may contain anything that you can use on the right
-side of an assignment. In addition, an empty LilyPond block corresponds
-to a void music expression, and a LilyPond block containing multiple
-music events gets turned into a sequential music expression.
+LilyPond code blocks can be used anywhere where you can write Scheme
+code. The Scheme reader actually is changed for accommodating
+LilyPond code blocks and can deal with embedded Scheme expressions
+starting with @code{$} and@w{ }@code{#}.
+
+@cindex parser (function argument)
+@cindex location
+
+The reader extracts the LilyPond code block and generates a runtime
+call to the LilyPond @code{parser} to interpret the LilyPond code.
+Scheme expressions embedded in the LilyPond code are evaluated in the
+lexical environment of the LilyPond code block, so all local variables
+and function parameters available at the point the LilyPond code block
+is written may be accessed. Variables defined in other Scheme modules,
+like the modules containing @code{\header} and @code{\layout} blocks,
+are not accessible as Scheme variables, i.e. prefixed
+with@tie{}@code{#}, but they are accessible as LilyPond variables, i.e.
+prefixed with@tie{}@code{\}.
+
+If @code{location} (see @ref{Scheme functions}) refers to a valid
+input location (which it usually does inside of music/@/Scheme
+functions), all music generated inside the code block has its
+@samp{origin} set to @code{location}.
+
+A LilyPond code block may contain anything that you can use on the
+right side of an assignment. In addition, an empty LilyPond block
+corresponds to a void music expression, and a LilyPond block
+containing multiple music events gets turned into a sequential music
+expression.
@node Scheme functions
@section Scheme functions
@tab needs to be literally @code{parser} in order to give LilyPond code
blocks (@code{#@{}@dots{}@code{#@}}) access to the parser.
+@item @code{location}
+@tab needs to be literally @code{location} in order to provide access
+to the input location object, which is used to provide error messages
+with file names and line numbers.
+
@item @code{@var{argN}}
@tab @var{n}th argument
@item @code{@var{typeN?}}
@tab a Scheme @emph{type predicate} for which @code{@var{argN}}
-must return @code{#t}. Some of these predicates are specially
-recognized by the parser, see below. There is also a special form
+must return @code{#t}. There is also a special form
@code{(@emph{predicate?} @emph{default})} for specifying optional
arguments. If the actual argument is missing when the function is being
called, the default value is substituted instead. Default values are
@tab A sequence of Scheme forms evaluated in order, the last one being
used as the return value of the scheme function. It may contain
LilyPond code blocks enclosed in hashed braces
-(@tie{}@w{@code{#@{@dots{}#@}}}@tie{}), like described in @ref{Lilypond
-code blocks}. Within LilyPond code blocks, use @code{$} to reference
-function arguments (eg., @samp{$arg1}) or to start an inline Scheme
-expression containing function arguments (eg., @w{@samp{$(cons arg1
-arg2)}}). If your function returns a music expression, it is cloned and
-given the correct @code{origin}.
+(@tie{}@w{@code{#@{@dots{}#@}}}@tie{}), like described in
+@ref{LilyPond code blocks}. Within LilyPond code blocks, use @code{#}
+to reference function arguments (eg., @samp{#arg1}) or to start an
+inline Scheme expression containing function arguments (eg.,
+@w{@samp{#(cons arg1 arg2)}}). Where normal Scheme expressions using
+@code{#} don't do the trick, you might need to revert to immediate
+Scheme expressions using @code{$}, for example as @samp{$music}.
+
+If your function returns a music expression, it is given a useful value
+of @code{origin}.
@end multitable
@noindent
-Some type predicates are specially recognized by the parser and will
-make the parser look for the respective arguments in LilyPond syntax
-rather than in Scheme syntax. Currently these are @code{ly:music?},
-@code{markup?}, @code{ly:pitch?}, and @code{ly:duration?}.
-
-If you really want to input one of the special items as a Scheme rather
-than a LilyPond expression, you may write them as a Scheme expression
-that calls @code{ly:export} at its outermost level.
-
-Other type predicates, including user-defined ones, will make the
-respective argument only be accepted as a Scheme expression, usually
-introduced with @code{#} or as the result of calling a scheme function
-itself.
-
-For a list of available type predicates, see
+Suitability of arguments for the predicates is determined by
+actually calling the predicate after LilyPond has already converted them
+into a Scheme expression. As a consequence, the argument can be
+specified in Scheme syntax if desired (introduced with @code{#} or as
+the result of calling a scheme function), but LilyPond will also convert
+a number of LilyPond constructs into Scheme before actually checking the
+predicate on them. Currently, those include music, postevents, simple
+strings (with or without quotes), numbers, full markups and markup
+lists, score, book, bookpart, context definition and output definition
+blocks.
+
+Some
+ambiguities LilyPond sorts out by checking with predicate
+functions: is @samp{-3} a fingering postevent or a negative number? Is
+@code{"a" 4} in lyric mode a string followed by a number, or a lyric
+event of duration @code{4}? LilyPond tries the argument
+predicate on successive interpretations until success, with an
+order designed to minimize inconsistent interpretations and
+lookahead.
+
+For example, a predicate accepting both music expressions and
+pitches will consider @code{c''} to be a pitch rather than a music
+expression. Immediately following durations or postevents will
+change that interpretation. It's best to avoid overly
+permissive predicates like @code{scheme?} when the application
+rather calls for more specific argument types.
+
+For a list of available predefined type predicates, see
@ruser{Predefined type predicates}.
@seealso
Scheme functions can be called pretty much anywhere where a Scheme
expression starting with @code{#} can be written. You call a scheme
function by writing its name preceded by @code{\}, followed by its
-arguments. The last argument can't be an optional argument. If there
-are several optional arguments in a row, they are filled with values
-left to right. Once an optional argument can't match input, it and all
-immediately following optional arguments are replaced with their default
-values, and the matching continues with the next non-optional argument.
+arguments. Once an optional argument predicate does not match an
+argument, LilyPond skips this and all following optional arguments,
+replacing them with their specified default, and @q{backs up} the
+argument that did not match to the place of the next mandatory argument.
+Since the backed up argument needs to go somewhere, optional arguments
+are not actually considered optional unless followed by a mandatory
+argument.
+
+There is one exception: if you write @code{\default} in the place of an
+optional argument, this and all following optional arguments are skipped
+and replaced by their default. This works even when no mandatory
+argument follows since @code{\default} does not need to get backed up.
+The @code{mark} and @code{key} commands make use of that trick to
+provide their default behavior when just followed by @code{\default}.
Apart from places where a Scheme value is required, there are a few
-places where @code{#} expressions are accepted and evaluated for their
-side effects but otherwise ignored. Mostly those are the places where
-an assignment would be acceptable as well.
-
-There are a few special places where an argument matching
-@code{ly:music?} has to be either a music identifier or a music
-expression enclosed in @code{@{}@dots{}@code{@}} or
-@code{<<}@dots{}@code{>>} explicitly, so that possibly following
-optional durations or postevents can't be confused with additional
-arguments. One obvious place is before a @code{ly:duration?}
-predicate. Another is as the last argument of a scheme function when it
-is used in a place where such optional parts could be considered either
-part of the music argument or not.
-
-In those rare cases, you have to delimit your music arguments
-appropriately to spare LilyPond from getting confused.
+places where @code{#} expressions are currently accepted and evaluated
+for their side effects but otherwise ignored. Mostly those are the
+places where an assignment would be acceptable as well.
+
+Since it is a bad idea to return values that can be misinterpreted in
+some context, you should use normal scheme functions only for those
+cases where you always return a useful value, and use void scheme
+functions (@pxref{Void scheme functions}) otherwise.
@node Void scheme functions
@subsection Void scheme functions
@funindex define-void-function
+@funindex \void
Sometimes a procedure is executed in order to perform an action rather
-than return a value. Some programming languages (like C and Scheme)
-use functions for either concept and just discard the returned value
+than return a value. Some programming languages (like C and Scheme) use
+functions for either concept and just discard the returned value
(usually by allowing any expression to act as statement, ignoring the
result). This is clever but error-prone: most C compilers nowadays
offer warnings for various non-``void'' expressions being discarded.
-For many functions executing an action, the Scheme standards declare
-the return value to be unspecified. Lilypond's Scheme interpreter
-Guile has a unique ``unspecified'' value that it usually (such when
-using @code{set!} directly on a variable) but unfortunately not
-consistently returns in such cases.
+For many functions executing an action, the Scheme standards declare the
+return value to be unspecified. LilyPond's Scheme interpreter Guile has
+a unique value @code{*unspecified*} that it usually (such when using
+@code{set!} directly on a variable) but unfortunately not consistently
+returns in such cases.
-Defining a Lilypond function with @code{define-void-function} makes
+Defining a LilyPond function with @code{define-void-function} makes
sure that this special value (the only value satisfying the predicate
@code{void?}) will be returned.
(parser location)
()
(ly:set-option 'point-and-click #f))
-...
+@dots{}
\noPointAndClick % disable point and click
@end example
+If you want to evaluate an expression only for its side-effect and
+don't want any value it may return interpreted, you can do so by
+prefixing it with @code{\void}:
+
+@example
+\void #(hashq-set! some-table some-key some-value)
+@end example
+
+That way, you can be sure that LilyPond will not assign meaning to the
+returned value regardless of where it encounters it. This will also
+work for music functions such as @code{\displayMusic}.
+
@node Music functions
@section Music functions
@noindent
quite in analogy to @ref{Scheme function definitions}. More often than
-not, @var{body} will be a @ref{Lilypond code blocks, Lilypond code block}.
+not, @var{body} will be a @ref{LilyPond code blocks, LilyPond code block}.
For a list of available type predicates, see
@ruser{Predefined type predicates}.
@node Music function usage
@subsection Music function usage
-Music functions may currently be used in three places. Depending on
+Music functions may currently be used in several places. Depending on
where they are used, restrictions apply in order to be able to parse
them unambiguously. The result a music function returns must be
compatible with the context in which it is called.
@itemize
@item
-At top level in a music expression. There are no special restrictions
-on the argument list.
+At top level in a music expression. No restriction apply here.
@item
As a post-event, explicitly started with a direction indicator (one of
-@code{-}, @code{^}, @w{and @code{_}}). All trailing arguments of the
-music function with the predicate @code{ly:music?} will get parsed also
-as post-events (if the last argument is a scheme function, this will
-hold for trailing @code{ly:music?} arguments of the scheme function
-instead). Note that returning a post-event will be acceptable for music
-functions called as normal music, leading to a result roughly equivalent
-to
-@example
-s 1*0-\fun
-@end example
+@code{-}, @code{^}, @w{and @code{_}}).
+
+In this case, you can't use an @emph{open} music expression as the last
+argument, one that would end with a music expression able to accept
+additional postevents.
@item
-As a chord constituent. All trailing arguments of the music function
-with the predicate @code{ly:music?} will get parsed also as chord
-constituents.
+As a chord constituent. The returned expression must be of
+@code{rhythmic-event} type, most likely a @code{NoteEvent}.
@end itemize
@noindent
(parser location beg-end)
(pair?)
#@{
- \once \override Beam #'positions = $beg-end
+ \once \override Beam.positions = #beg-end
#@})
\relative c' @{
(parser location beg end)
(number? number?)
#{
- \once \override Beam #'positions = $(cons beg end)
+ \once \override Beam.positions = #(cons beg end)
#})
\relative c' {
}
@end lilypond
+@funindex \temporary
+@cindex temporary overrides
+@cindex overrides, temporary
+@cindex properties, popping previous value
+
+Properties are maintained conceptually using one stack per property
+per grob per context. Music functions may need to override one or
+several properties for the duration of the function, restoring them
+to their previous value before exiting. However, normal overrides
+pop and discard the top of the current property stack before
+pushing to it, so the previous value of the property is lost when it
+is overridden. When the previous value must be preserved, prefix the
+@code{\override} command with @code{\temporary}, like this:
+
+@example
+\temporary \override @dots{}
+@end example
+
+The use of @code{\temporary} causes the (usually set) @code{pop-first}
+property in the override to be cleared, so the previous value is not
+popped off the property stack before pushing the new value onto it.
+When a subsequent @code{\revert} pops off the temporarily overriden
+value, the previous value will re-emerge.
+
+In other words, calling @code{\temporary \override} and @code{\revert}
+in succession on the same property will have a net effect of zero.
+Similarly, pairing @code{\temporary} and @code{\undo} on the same
+music containing overrides will have a net effect of zero.
+
+Here is an example of a music function which makes use of this.
+The use of @code{\temporary} ensures the values of the
+@code{cross-staff} and @code{style} properties are restored on exit
+to whatever values they had when the @code{crossStaff} function was
+called. Without @code{\temporary} the default values would have been
+set on exit.
+
+@example
+crossStaff =
+#(define-music-function (parser location notes) (ly:music?)
+ (_i "Create cross-staff stems")
+ #@{
+ \temporary \override Stem.cross-staff = #cross-staff-connect
+ \temporary \override Flag.style = #'no-flag
+ #notes
+ \revert Stem.cross-staff
+ \revert Flag.style
+#@})
+@end example
+
@node Mathematics in functions
@subsection Mathematics in functions
(parser location mag)
(number?)
#{
- \override Stem #'length = $(* 7.0 mag)
- \override NoteHead #'font-size =
- $(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
+ \override Stem.length = #(* 7.0 mag)
+ \override NoteHead.font-size =
+ #(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
#})
AltOff = {
- \revert Stem #'length
- \revert NoteHead #'font-size
+ \revert Stem.length
+ \revert NoteHead.font-size
}
\relative c' {
(parser location mag music)
(number? ly:music?)
#{
- \override Stem #'length = $(* 7.0 mag)
- \override NoteHead #'font-size =
- $(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
- $music
- \revert Stem #'length
- \revert NoteHead #'font-size
+ \override Stem.length = #(* 7.0 mag)
+ \override NoteHead.font-size =
+ #(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
+ #music
+ \revert Stem.length
+ \revert NoteHead.font-size
#})
\relative c' {
(parser location)
()
(if (eq? #t (ly:get-option 'display-bar-numbers))
- #@{ \once \override Score.BarNumber #'break-visibility = ##f #@}
+ #@{ \once \override Score.BarNumber.break-visibility = ##f #@}
#@{#@}))
@end example
to write dynamics commands, those are usually attached without direction
indicator, like @code{c'\pp}. Here is a way to write arbitrary
dynamics:
-@lilypond[quote,verbatim,raggedright]
+@lilypond[quote,verbatim,ragged-right]
dyn=#(define-event-function (parser location arg) (markup?)
(make-dynamic-script arg))
\relative c' { c\dyn pfsss }
@subsection Markup construction in Scheme
@cindex defining markup commands
+@funindex \displayScheme
+
+Markup expressions are internally represented in Scheme using the
+@code{markup} macro:
+
+@example
+(markup @var{expr})
+@end example
+
+To see a markup expression in its Scheme form, use the
+@code{\displayScheme} command:
-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")))
+\displayScheme
+\markup @{
+ \column @{
+ \line @{ \bold \italic "hello" \raise #0.4 "world" @}
+ \larger \line @{ foo bar baz @}
+ @}
+@}
@end example
@noindent
-is equivalent to:
+Compiling the code above will send the following to the display
+console:
+
@example
-#@{ \markup \column @{ \line @{ \bold \italic "hello" \raise #0.4 "world" @}
- \larger \line @{ foo bar baz @} @} #@}
+(markup
+ #:line
+ (#:column
+ (#:line
+ (#:bold (#:italic "hello") #:raise 0.4 "world")
+ #:larger
+ (#:line
+ (#:simple "foo" #:simple "bar" #:simple "baz")))))
@end example
+To prevent the markup from printing on the page, use
+@w{@samp{\void \displayScheme @var{markup}}}. Also, as with the
+@code{\displayMusic} command, the output of @code{\displayScheme}
+can be saved to an external file. See
+@ref{Displaying music expressions}.
+
@noindent
This example demonstrates the main translation rules between regular
LilyPond markup syntax and Scheme markup syntax. Using @code{#@{
@multitable @columnfractions .3 .3
@item @b{LilyPond} @tab @b{Scheme}
@item @code{\markup markup1} @tab @code{(markup markup1)}
-@item @code{\markup @{ markup1 markup2 ... @}} @tab
- @code{(markup markup1 markup2 ... )}
+@item @code{\markup @{ markup1 markup2 @dots{} @}} @tab
+ @code{(markup markup1 markup2 @dots{} )}
@item @code{\markup-command} @tab @code{#:markup-command}
@item @code{\variable} @tab @code{variable}
-@item @code{\center-column @{ ... @}} @tab @code{#:center-column ( ... )}
+@item @code{\center-column @{ @dots{} @}} @tab
+ @code{#:center-column ( @dots{} )}
@item @code{string} @tab @code{"string"}
@item @code{#scheme-arg} @tab @code{scheme-arg}
@end multitable
@code{define-markup-command} Scheme macro, at top-level.
@lisp
-(define-markup-command (@var{command-name} @var{layout} @var{props} @var{arg1} @var{arg2} ...)
- (@var{arg1-type?} @var{arg2-type?} ...)
+(define-markup-command (@var{command-name} @var{layout} @var{props} @var{arg1} @var{arg2} @dots{})
+ (@var{arg1-type?} @var{arg2-type?} @dots{})
[ #:properties ((@var{property1} @var{default-value1})
- ...) ]
- ..command body..)
+ @dots{}) ]
+ @dots{}command body@dots{})
@end lisp
The arguments are
the leading arguments of markup functions that take a markup as
their last argument.
+@funindex \markup
+@cindex markup macro
+@funindex interpret-markup
+Markup commands have a rather complex life cycle. The body of a
+markup command definition is responsible for converting the
+arguments of the markup command into a stencil expression which is
+returned. Quite often this is accomplished by calling the
+@code{interpret-markup} function on a markup expression, passing
+the @var{layout} and @var{props} arguments on to it. Those
+arguments are usually only known at a very late stage in
+typesetting. Markup expressions have their components assembled
+into markup expressions already when @code{\markup} in a LilyPond
+expression or the @code{markup} macro in Scheme is expanded. The
+evaluation and typechecking of markup command arguments happens at
+the time @code{\markup}/@code{markup} are interpreted.
+
+But the actual conversion of markup expressions into stencil
+expressions by executing the markup function bodies only happens
+when @code{interpret-markup} is called on a markup expression.
+
@node On properties
@unnumberedsubsubsec On properties
"Draw a double box around text."
(interpret-markup layout props
#@{\markup \override #'(box-padding . 0.4) \box
- \override #'(box-padding . 0.6) \box @{ $text @}#@}))
+ \override #'(box-padding . 0.6) \box @{ #text @}#@}))
@end lisp
-or, equivalently
+or, equivalently
@lisp
#(define-markup-command (double-box layout props text) (markup?)
(box-padding 0.6))
"Draw a double box around text."
(interpret-markup layout props
- #@{\markup \override #`(box-padding . ,$inter-box-padding) \box
- \override #`(box-padding . ,$box-padding) \box
- @{ $text @} #@}))
+ #@{\markup \override #`(box-padding . ,inter-box-padding) \box
+ \override #`(box-padding . ,box-padding) \box
+ @{ #text @} #@}))
@end lisp
Again, the equivalent version using the markup macro would be:
(box-padding 0.6))
"Draw a double box around text."
(interpret-markup layout props
- #{\markup \override #`(box-padding . ,$inter-box-padding) \box
- \override #`(box-padding . ,$box-padding) \box
- { $text } #}))
+ #{\markup \override #`(box-padding . ,inter-box-padding) \box
+ \override #`(box-padding . ,box-padding) \box
+ { #text } #}))
\markup \double-box A
\markup \override #'(inter-box-padding . 0.8) \double-box A
(number-pair?)
#:category graphic
#:properties ((thickness 1))
- "..documentation.."
+ "@dots{}documentation@dots{}"
(let ((th (* (ly:output-def-lookup layout 'line-thickness)
thickness))
(x (car dest))
(define-markup-command (draw-double-line layout props dest)
(number-pair?)
#:properties ((thickness 1))
- "..documentation.."
+ "@dots{}documentation@dots{}"
(let ((th (* (ly:output-def-lookup layout 'line-thickness)
thickness))
(x (car dest))
(number-pair?)
#:properties ((thickness 1)
(line-gap 0.6))
- "..documentation.."
- ...
+ "@dots{}documentation@dots{}"
+ @dots{}
@end lisp
Finally, the code for drawing two lines is added. Two calls to
@node New markup list command definition
@subsection New markup list command definition
+@funindex define-markup-list-command
+@funindex interpret-markup-list
Markup list commands are defined with the
@code{define-markup-list-command} Scheme macro, which is similar to the
@code{define-markup-command} macro described in
@ref{New markup command definition}, except that where the latter returns
a single stencil, the former returns a list of stencils.
+In a similar vein, @code{interpret-markup-list} is used instead of
+@code{interpret-markup} for converting a markup list into a list
+of stencils.
+
In the following example, a @code{\paragraph} markup list command is
defined, which returns a list of justified lines, the first one being
indented. The indent width is taken from the @code{props} argument.
#(define-markup-list-command (paragraph layout props args) (markup-list?)
#:properties ((par-indent 2))
(interpret-markup-list layout props
- #@{\markuplines \justified-lines @{ \hspace #$par-indent $args @} #@}))
+ #@{\markuplist \justified-lines @{ \hspace #par-indent #args @} #@}))
@end example
This new markup list command can be used as follows:
@example
-\markuplines @{
+\markuplist @{
\paragraph @{
The art of music typography is called \italic @{(plate) engraving.@}
The term derives from the traditional process of music printing.
@cindex calling code on layout objects
@funindex \applyOutput
-
The most versatile way of tuning an object is @code{\applyOutput} which
works by inserting an event into the specified context
(@rinternals{ApplyOutputEvent}). Its syntax is
@example
-\applyOutput @var{context} @var{proc}
+\applyOutput @var{Context} @var{proc}
@end example
@noindent
where @code{@var{proc}} is a Scheme function, taking three arguments.
When interpreted, the function @code{@var{proc}} is called for
-every layout object found in the context @code{@var{context}} at
+every layout object found in the context @code{@var{Context}} at
the current time step, with the following arguments:
@itemize
@item the layout object itself,
}
@end lilypond
+To have @var{function} interpreted at the @code{Score} or @code{Staff}
+level use these forms
+
+@example
+\applyOutput #'Score #@var{function}
+\applyOutput #'Staff #@var{function}
+@end example
+
@node Callback functions
@section Callback functions
set at fixed values with @code{\override}, e.g.
@example
-\override Stem #'thickness = #2.0
+\override Stem.thickness = #2.0
@end example
Properties can also be set to a Scheme procedure,
@lilypond[fragment,verbatim,quote,relative=2]
-\override Stem #'thickness = #(lambda (grob)
+\override Stem.thickness = #(lambda (grob)
(if (= UP (ly:grob-property grob 'direction))
2.0
7.0))
The procedure always takes a single argument, being the grob.
+That procedure may access the usual value of the property, by first
+calling the function that is the usual callback for that property, which
+can by found in the Internals Reference or the file 'define-grobs.scm':
+
+@example
+\relative c'' @{
+ \override Flag #'X-offset = #(lambda (flag)
+ (let ((default (ly:flag::calc-x-offset flag)))
+ (* default 4.0)))
+ c4. d8 a4. g8
+@}
+@end example
+
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},
(grob-interpret-markup grob (markup "foo")))
@end example
-@node Inline Scheme code
-@section Inline Scheme code
+@ignore
+
+@n ode Inline Scheme code
+@s ection Inline Scheme code
+
+TODO: after this section had been written, LilyPond has improved
+to the point that finding a @emph{simple} example where one would
+@emph{have} to revert to Scheme has become rather hard.
+
+Until this section gets a rewrite, let's pretend we don't know.
The main disadvantage of @code{\tweak} is its syntactical
-inflexibility. For example, the following produces a syntax error.
+inflexibility. For example, the following produces a syntax error
+(or rather, it did so at some point in the past).
@example
-F = \tweak #'font-size #-3 -\flageolet
+F = \tweak font-size #-3 -\flageolet
\relative c'' @{
c4^\F c4_\F
@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.
written back with @code{set!}. The last element of the
@code{let} block is the return value, @code{m} itself.
+@end ignore
@node Difficult tweaks
(ly:grob-set-property! grob 'extra-offset '(-2 . 5)))))
\relative c'' {
- \override Tie #'after-line-breaking =
+ \override Tie.after-line-breaking =
#my-callback
c1 ~ \break
- c2 ~ c
+ c2 ~ 2
}
@end lilypond
@example
\overrideProperty
-#"Score.NonMusicalPaperColumn" % Grob name
-#'line-break-system-details % Property name
-#'((next-padding . 20)) % Value
+Score.NonMusicalPaperColumn % Grob name
+ . line-break-system-details % Property name
+ . next-padding % Optional subproperty name
+ #20 % Value
@end example
Note, however, that @code{\override}, applied to