Guide, node Updating translation committishes..
@end ignore
-@c \version "2.19.21"
+@c \version "2.19.22"
@node Scheme tutorial
@chapter Scheme tutorial
users may simply choose @q{Run} from the Start menu and enter
@q{guile}.
-However, a hands-on Scheme sandbox with all of Lilypond loaded is
+However, a hands-on Scheme sandbox with all of LilyPond loaded is
available with this command line:
@example
lilypond scheme-sandbox
(1 2 3 "abc" 17.5)
@end lisp
-As can be seen, a list is displayed in the form of individual elements
-separated by whitespace and enclosed in parentheses. Unlike a pair,
-there is no period between the elements.
+Representing a list as individual
+elements separated by whitespace and enclosed in parentheses
+is actually a compacted rendition of the actual dotted pairs
+constituting the list, where the dot and an immediately following
+starting paren are removed along with the matching closing paren.
+Without this compaction, the output would have been
+@lisp
+(1 . (2 . (3 . ("abc" . (17.5 . ())))))
+@end lisp
-A list can also be entered as a literal list by enclosing its
-elements in parentheses, and adding a quote:
+As with the output, a list can also be entered (after adding a
+quote to avoid interpretation as a function call) as a literal
+list by enclosing its elements in parentheses:
@lisp
guile> '(17 23 "foo" "bar" "bazzle")
Another way to call the Scheme interpreter from LilyPond is the use of
dollar@tie{}@code{$} instead of a hash mark for introducing Scheme
-expressions. In this case, Lilypond evaluates the code right after the
+expressions. In this case, LilyPond evaluates the code right after the
lexer has read it. It checks the resulting type of the Scheme
expression and then picks a token type (one of several
@code{xxx_IDENTIFIER} in the syntax) for it. It creates a @emph{copy}
the expression is void (Guile's value of @code{*unspecified*}), nothing
at all is passed to the parser.
-This is, in fact, exactly the same mechanism that Lilypond employs when
+This is, in fact, exactly the same mechanism that LilyPond employs when
you call any variable or music function by name, as @code{\name}, with
-the only difference that the name is determined by the Lilypond lexer
+the only difference that the name is determined by the LilyPond lexer
without consulting the Scheme reader, and thus only variable names
-consistent with the current Lilypond mode are accepted.
-
-The immediate action of @code{$} can lead to surprises, @ref{Input
-variables and Scheme}. Using @code{#} where the parser supports it
-is usually preferable. Inside of music expressions, expressions
-created using @code{#} @emph{are} interpreted as music. However,
-they are @emph{not} copied before use. If they are part of some
-structure that might still get used, you may need to use
+consistent with the current LilyPond mode are accepted.
+
+The immediate action of @code{$} can lead to surprises, see
+@ref{Importing Scheme in LilyPond}. Using @code{#} where the
+parser supports it is usually preferable. Inside of music expressions,
+expressions created using @code{#} @emph{are} interpreted as
+music. However, they are @emph{not} copied before use. If they are
+part of some structure that might still get used, you may need to use
@code{ly:music-deep-copy} explicitly.
@funindex $@@
@end example
For the rest of this section, we will assume that the data is entered
-in a music file, so we add@tie{}@code{#}s at the beginning of each Scheme
+in a music file, so we add a @code{#} at the beginning of each Scheme
expression.
All of the top-level Scheme expressions in a LilyPond input file can
-be combined into a single Scheme expression by the use of the
+be combined into a single Scheme expression by use of the
@code{begin} statement:
@example
@end example
@noindent
-which would result in the number 24 being stored in the
-LilyPond (and Scheme) variable @code{twentyFour}.
-
-The usual way to refer to Lilypond variables, @ref{LilyPond Scheme
-syntax}, is to call them using a backslash, i.e., @code{\twentyFour}.
-Since this creates a copy of the value for most of LilyPond's internal
-types, in particular music expressions, music functions don't usually
-create copies of material they change. For this reason, music
-expressions given with @code{#} should usually not contain material that
-is not either created from scratch or explicitly copied rather than
-directly referenced.
+which would result in the number @emph{24} being stored in the LilyPond
+(and Scheme) variable @code{twentyFour}.
+
+Scheme allows modifying complex expressions in-place and LilyPond makes
+use of this @q{in-place modification} when using music functions. But
+when music expressions are stored in variables rather than entered
+directly the usual expectation, when passing them to music functions,
+would be that the original value is unmodified. So when referencing a
+music variable with leading backslash (such as @code{\twentyFour}),
+LilyPond creates a copy of that variable's music value for use in the
+surrounding music expression rather than using the variable's value
+directly.
+
+Therefore, Scheme music expressions written with the @code{#} syntax
+should be used for material that is created @q{from scratch} (or that is
+explicitly copied) rather than being used, instead, to directly
+reference material.
+
+@seealso
+Extending:
+@ref{LilyPond Scheme syntax}.
+
@node Input variables and Scheme
@subsection Input variables and Scheme
You can use @code{$} with a Scheme expression anywhere you could use
@code{\@var{name}} after having assigned the Scheme expression to a
variable @var{name}. This replacement happens in the @q{lexer}, so
-Lilypond is not even aware of the difference.
+LilyPond is not even aware of the difference.
One drawback, however, is that of timing. If we had been using @code{$}
instead of @code{#} for defining @code{newLa} in the above example, the
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}
+music function @code{\displayMusic}.
@example
@{
@end example
Guile's manual describes ports in detail. Closing the port is actually
-only necessary if you need to read the file before Lilypond finishes; in
+only necessary if you need to read the file before LilyPond finishes; in
the first example, we did not bother to do so.
A bit of reformatting makes the above information easier to read:
@example
(make-music 'SequentialMusic
'elements (list
- (make-music 'NoteEvent
+ (make-music 'NoteEvent
'articulations (list
- (make-music 'AbsoluteDynamicEvent
- 'text
- "f"))
- 'duration (ly:make-duration 2 0 1/1)
- 'pitch (ly:make-pitch 0 0 0))))
+ (make-music 'AbsoluteDynamicEvent
+ 'text
+ "f"))
+ 'duration (ly:make-duration 2 0 1/1)
+ 'pitch (ly:make-pitch 0 0 0))))
@end example
A @code{@{ @dots{} @}} music sequence has the name
@node Music properties
@subsection Music properties
+@ignore
TODO -- make sure we delineate between @emph{music} properties,
@emph{context} properties, and @emph{layout} properties. These
are potentially confusing.
+@end ignore
Let's look at an example:
@end example
Then the note pitch is accessed through the @code{'pitch} property
-of the @code{NoteEvent} object,
+of the @code{NoteEvent} object.
@example
#(display-scheme-music
(ly:make-pitch 0 0 0)
@end example
-The note pitch can be changed by setting this @code{'pitch} property,
+The note pitch can be changed by setting this @code{'pitch} property.
@funindex \displayLilyMusic
must be added @q{inside} the note (in its @code{articulations}
property).
-Now we examine the input,
+Now we examine the input.
@example
\displayMusic a'
put another element at the front of the @code{articulations} property.
@example
-doubleSlur = #(define-music-function (parser location note) (ly:music?)
+doubleSlur = #(define-music-function (note) (ly:music?)
"Return: @{ note ( note ) @}.
`note' is supposed to be a single note."
(let ((note2 (ly:music-deep-copy note)))
@noindent
but for the sake of this example, we will learn how to do this in
-Scheme. We begin by examining our input and desired output,
+Scheme. We begin by examining our input and desired output.
@example
% input
@code{articulations} property, we can return @code{note-event}, hence
the last line of the function.
-Now we transform the @code{add-accent} function into a music
-function (a matter of some syntactic sugar and a declaration of the type
-of its sole @q{real} argument).
+Now we transform the @code{add-accent} function into a music function (a
+matter of some syntactic sugar and a declaration of the type of its
+argument).
@example
-addAccent = #(define-music-function (parser location note-event)
+addAccent = #(define-music-function (note-event)
(ly:music?)
"Add an accent ArticulationEvent to the articulations of `note-event',
which is supposed to be a NoteEvent expression."
note-event)
@end example
-We may verify that this music function works correctly,
+We then verify that this music function works correctly:
@example
\displayMusic \addAccent c4
@ignore
@lilypond[quote,verbatim,ragged-right]
-padText = #(define-music-function (parser location padding) (number?)
+padText = #(define-music-function (padding) (number?)
#{
\once \override TextScript.padding = #padding
#})
@lilypond[quote,verbatim,ragged-right]
-tempoPadded = #(define-music-function (parser location padding tempotext)
+tempoPadded = #(define-music-function (padding tempotext)
(number? markup?)
#{
\once \override Score.MetronomeMark.padding = #padding
\tempo \markup { \bold #tempotext }
#})
-\relative c'' {
+\relative {
\tempo \markup { "Low tempo" }
- c4 d e f g1
+ c''4 d e f g1
\tempoPadded #4.0 "High tempo"
g4 f e d c1
}
Even music expressions can be passed in:
@lilypond[quote,verbatim,ragged-right]
-pattern = #(define-music-function (parser location x y) (ly:music? ly:music?)
+pattern = #(define-music-function (x y) (ly:music? ly:music?)
#{
#x e8 a b #y b a e
#})