Guide, node Updating translation committishes..
@end ignore
-@c \version "2.14.0"
+@c \version "2.17.6"
@node Interfaces for programmers
@chapter Interfaces for programmers
* Lilypond code blocks::
* Scheme functions::
* Music functions::
+* Event functions::
* Markup functions::
* Contexts for programmers::
* Callback functions::
@example
#@{ @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 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:
-
-@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
+They 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{#}.
+
+It extracts the Lilypond code block and generates a call to the
+LilyPond @code{parser} which is executed at runtime to interpret the
+LilyPond code block. Any embedded Scheme expression is executed in
+the lexical environment of the Lilypond code block, so you have access
+to local variables and function parameters at the point the Lilypond
+code block is written.
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
@node Scheme functions
@section Scheme functions
+@cindex Scheme functions (LilyPond syntax)
-@emph{Scheme functions} are scheme procedures that can create scheme
-expressions from input written in Lilypond syntax. They can be called
+@emph{Scheme functions} are Scheme procedures that can create Scheme
+expressions from input written in LilyPond syntax. They can be called
in pretty much all places where using @code{#} for specifying a value in
-Scheme syntax is allowed. While scheme has functions of its own, this
+Scheme syntax is allowed. While Scheme has functions of its own, this
chapter is concerned with @emph{syntactic} functions, functions that
-receive arguments specified in Lilypond syntax.
+receive arguments specified in LilyPond syntax.
@menu
* Scheme function definitions::
@node Scheme function definitions
@subsection Scheme function definitions
+@funindex define-scheme-function
The general form for defining scheme functions is:
where
@multitable @columnfractions .33 .66
+@item @code{parser}
+@tab needs to be literally @code{parser} in order to give LilyPond code
+blocks (@code{#@{}@dots{}@code{#@}}) access to the parser.
+
@item @code{@var{argN}}
@tab @var{n}th argument
@item @code{@var{typeN?}}
-@tab a scheme @emph{type predicate} for which @code{@var{argN}}
+@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.
+recognized by the parser, see below. 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
+evaluated at definition time (including LilyPond code blocks!), so if
+you need a default calculated at runtime, instead write a special value
+you can easily recognize. If you write the predicate in parentheses but
+don't follow it with a default value, @code{#f} is used as the default.
+Default values are not verified with @emph{predicate?} at either
+definition or run time: it is your responsibility to deal with the
+values you specify. Default values that happen to be music expressions
+are copied while setting @code{origin} to the @code{location} parameter.
@item @code{@var{body}}
-@tab A sequence of scheme forms evaluated in order, the last one being
+@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)}}).
+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
+Some type predicates are specially handled by the parser since it
+can't recognize the arguments reliably otherwise. Currently these are
+@code{ly:pitch?} and @code{ly:duration?}.
+
+Suitability of arguments for all other 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.
+
+For some kinds of expression (like most music not enclosed in braces)
+Lilypond needs to look further than the expression itself in order to
+determine its end. If such an expression were considered for an
+optional argument by evaluating its predicate, Lilypond would not be
+able to ``backup'' when it decides the expression does not fit the
+parameter. So some forms of music might need to be enclosed in braces
+to make them acceptable to Lilypond. There are also some other
+ambiguities that 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 decides by asking the predicates.
+That means that you should avoid permissive predicates like
+@code{scheme?} if you have a particular use in mind instead of a general
+purpose function.
+
+For a list of available predefined type predicates, see
@ruser{Predefined type predicates}.
@seealso
@node Scheme function usage
@subsection Scheme function usage
+
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.
+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
-
-Sometimes a function is only executed for its side effects. In that
-case, using a Scheme function means that its value will not usually be
-considered:
+@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
+(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 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
+sure that this special value (the only value satisfying the predicate
+@code{void?}) will be returned.
@example
noPointAndClick =
-#(define-scheme-function
+#(define-void-function
(parser location)
()
(ly:set-option 'point-and-click #f))
\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
-@emph{Music functions} are scheme procedures that can create music
+@cindex music functions
+
+@emph{Music functions} are Scheme procedures that can create music
expressions automatically, and can be used to greatly simplify the
input file.
@node Music function definitions
@subsection Music function definitions
+@cindex defining music functions
+@funindex define-music-function
The general form for defining music functions is:
@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. All trailing arguments of the music function with the
-predicate @code{ly:music?} will get parsed also as post-events. Note
-that returning post-events will also be acceptable for music functions
-called at top level, leading to a result roughly equivalent to
+As a post-event, explicitly started with a direction indicator (one of
+@code{-}, @code{^}, @w{and @code{_}}). 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
+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
polymorphic functions like @code{\tweak} that can be applied to
different constructs.
-There is another somewhat special rule: if you have a predicate
-@code{ly:music?} directly before a @code{ly:duration?} predicate, then
-the corresponding music expression must be either a music identifier, or
-literal sequential or parallel music enclosed in
-@code{@{}@dots{}@code{@}} or @code{<<}@dots{}@code{>>} explicitly.
-Otherwise, Lilypond could get confused about where the music ends and
-the duration starts.
-
@node Simple substitution functions
@subsection Simple substitution functions
(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' {
(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
@node Void music functions
@subsection Void music functions
-A music function must return a music expression. If you want to execute
-a function only for its side effect, it might make more sense to use a
-scheme function instead. But there may be cases where you sometimes
-want to produce a music expression, and sometimes not (like in the
-previous example). Returning a @code{void} music expression via
-@code{#@{ #@}} will do that.
+A music function must return a music expression. If you want to
+execute a function only for its side effect, you should use
+@code{define-void-function}. But there may be cases where you
+sometimes want to produce a music expression, and sometimes not (like
+in the previous example). Returning a @code{void} music expression
+via @code{#@{ #@}} will achieve that.
+
+@node Event functions
+@section Event functions
+@funindex define-event-function
+@cindex event functions
+
+To use a music function in the place of an event, you need to write a
+direction indicator before it. But sometimes, this does not quite match
+the syntax of constructs you want to replace. For example, if you want
+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,ragged-right]
+dyn=#(define-event-function (parser location arg) (markup?)
+ (make-dynamic-script arg))
+\relative c' { c\dyn pfsss }
+@end lilypond
+You could do the same using a music function, but then you always would
+have to write a direction indicator before calling it, like
+@code{@w{c-\dyn pfsss}}.
@node Markup functions
@noindent
This example demonstrates the main translation rules between regular
LilyPond markup syntax and Scheme markup syntax. Using @code{#@{
-@dots{} #@}} for entering in Lilypond syntax will often be most
+@dots{} #@}} for entering in LilyPond syntax will often be most
convenient, but we explain how to use the @code{markup} macro to get a
Scheme-only solution.
override it too:
@lilypond[quote,verbatim,ragged-right]
-\markup \override #'(box-padding . 0.4) \box \override #'(box-padding . 0.6) \box A
+\markup \override #'(box-padding . 0.4) \box
+ \override #'(box-padding . 0.6) \box A
@end lilypond
Repeating this lengthy markup would be painful. This is where a markup
"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
(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
#(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.
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))
@node Inline Scheme code
@section Inline Scheme code
+TODO: the example for this section is ill-chosen since
+@example
+F = -\tweak font-size #-3 -\flageolet
+@end example
+(note the @samp{-} marking it as a post event) will actually work fine
+for the stated purpose. 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.
@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.
(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
@example
\overrideProperty
-#"Score.NonMusicalPaperColumn" % Grob name
+Score.NonMusicalPaperColumn % Grob name
#'line-break-system-details % Property name
#'((next-padding . 20)) % Value
@end example