]> git.donarmstrong.com Git - lilypond.git/blob - Documentation/de/extending/scheme-tutorial.itely
Various updates to reduce make doc output
[lilypond.git] / Documentation / de / extending / scheme-tutorial.itely
1 @c -*- coding: utf-8; mode: texinfo; documentlanguage: de -*-
2
3 @ignore
4     Translation of GIT committish: 8cbb38db1591ab95a178643e7bf41db018aa22c0
5
6     When revising a translation, copy the HEAD committish of the
7     version that you are working on.  For details, see the Contributors'
8     Guide, node Updating translation committishes..
9 @end ignore
10
11 @c \version "2.15.20"
12
13 @node Scheme-Übung
14 @chapter Scheme-Übung
15 @translationof Scheme tutorial
16
17 @funindex #
18 @cindex Scheme
19 @cindex GUILE
20 @cindex Scheme, in einer LilyPond-Datei
21 @cindex LISP
22 @cindex Auswertung von Scheme-Code
23
24 LilyPond verwendet die Scheme-Programmiersprache sowohl als Teil
25 der Eingabesyntax als auch als internen Mechanismus, um Programmmodule
26 zusammenzufügen.  Dieser Abschnitt ist ein sehr kurzer Überblick über
27 die Dateneingabe mit Scheme.  Wenn Sie mehr über Scheme wissen wollen,
28 gehen Sie zu @uref{http://@/www@/.schemers@/.org}.
29
30 LilyPond benutzt die GNU Guile-Implementation von Scheme, die auf dem
31 @qq{R5RS}-Standard von Scheme basiert.  Wenn Sie Scheme lernen wollen,
32 um es innerhalb von LilyPond zu benutzen, wird es nicht empfohlen,
33 mit einer anderen Implementation (die sich auf einen anderen
34 Standard bezieht) zu arbeiten.  Information zu Guile findet sich
35 unter @uref{http://www.gnu.org/software/guile/}.  Der
36 @qq{R5RS}-Standard von Scheme befindet sich unter der Adresse
37 @uref{http://www.schemers.org/Documents/Standards/R5RS/}.
38
39
40 @menu
41 * Einleitung in Scheme::
42 * Scheme in LilyPond::
43 * Komplizierte Funktionen erstellen::
44 @end menu
45
46 @node Einleitung in Scheme
47 @section Einleitung in Scheme
48 @translationof Introduction to Scheme
49
50 Wir wollen mit einer Einführung in Scheme beginnen.  Für diese kurze Einfürung
51 soll der GUILE-Interpreter genommen werden, um zu erforschen, wie die Sprache
52 funktioniert.  Nach besserer Bekanntschaft mit Scheme soll gezeigt werden, wie
53 die Sprache in LilyPond-Dateien eingefügt werden kann.
54
55 @menu
56 * Scheme-Sandkasten::
57 * Scheme-Variablen::
58 * Einfache Scheme-Datentypen::
59 * Zusammengesetzte Scheme-Datentypen::
60 * Berechnungen in Scheme::
61 * Scheme-Prozeduren::
62 * Scheme-Konditionale::
63 @end menu
64
65 @node Scheme-Sandkasten
66 @subsection Scheme-Sandkasten
67 @translationof Scheme sandbox
68
69 Die LilyPond-Installation enthält gleichzeitig auch die
70 Guile-Implementation von Scheme.  Auf den meisten Systemen kann
71 man in einer Scheme-sandbox experimentieren, indem man ein
72 Kommandozeilen-Fenster öffnet und @code{guile} aufruft.  Unter
73 einigen Systemen, insbesondere unter Windows, muss man evtl.
74 die Umgebungsvariable @code{GUILE_LOAD_PATH} auf das Verzeichnis
75 @code{../usr/shr/guile/1.8} innerhalb des LilyPond-Installationsverzeichnisses
76 setzen (der vollständige Pfad ist erklärt in @rlearning{Mehr Information}).
77 Alternativ können Windows-Benutzer auch einfach @qq{Ausführen} im
78 Startmenü wählen und @code{guile} schreiben.
79
80 Wenn guile einmal läuft, erhält man die Eingabeaufforderung von guile:
81
82 @lisp
83 guile>
84 @end lisp
85
86 Man kann Scheme-Ausdrucke hier eingeben und mit Scheme experimentieren.
87
88
89 @node Scheme-Variablen
90 @subsection Scheme-Variablen
91 @translationof Scheme variables
92
93 Scheme-Variablen können jedlichen gültigen Scheme-Wert erhalten, auch
94 Scheme-Prozeduren.
95
96 Scheme-Variablen werden mit @code{define} definiert:
97
98 @lisp
99 guile> (define a 2)
100 guile>
101 @end lisp
102
103 Scheme-Variablen können an der Guile-Eingabeaufforderung ausgewertet werden,
104 indem man einfach die Variable eintippt.
105
106 @lisp
107 guile> a
108 2
109 guile>
110 @end lisp
111
112 Scheme-Variablen können auf dem Bildschirm ausgegeben werden, indem man
113 @code{display} zum Anzeigen benutzt:
114
115 @lisp
116 guile> (display a)
117 2guile>
118 @end lisp
119
120 Sowohl der Wert @code{2} als auch die Eingabeaufforderung @code{guile}
121 werden auf der gleichen Zeile ausgegeben.  Das kann man vermeiden, indem
122 man eine @code{newline}-Prozedur für eine Leerzeile aufruft oder das
123 Zeichen für eine neue Zeile anzeigen lässt:
124
125 @lisp
126 guile> (display a)(newline)
127 2
128 guile> (display a)(display "\n")
129 2
130 guile>
131 @end lisp
132
133 Wenn eine Variable einmal erstellt wurde, kann ihr Wert durch @code{set!}
134 verändert werden:
135
136 @lisp
137 guile> (set! a 12345)
138 guile> a
139 12345
140 guile>
141 @end lisp
142
143 @node Einfache Scheme-Datentypen
144 @subsection Einfache Scheme-Datentypen
145 @translationof Scheme simple data types
146
147 Das Grundlegendste an einer Sprache sind Daten: Zahlen, Zeichen,
148 Zeichenketten, Listen usw.  Hier ist eine Liste der Datentypen, die für
149 LilyPond-Eingabedateien relevant sind.
150
151 @table @asis
152 @item Boolesche Variablen
153 Werte einer Booleschen Variable sind Wahr oder Falsch. Die Scheme-Entsprechung
154 für Wahr ist @code{#t} und für Falsch @code{#f}.
155 @funindex ##t
156 @funindex ##f
157
158 @item Zahlen
159 Zahlen werden wie üblich eingegeben, @code{1} ist die (ganze)
160 Zahl Eins, während @code{-1.5} eine Gleitkommazahl (also
161 eine nicht-ganze) ist.
162
163 @item Zeichenketten
164 Zeichenketten werden in doppelte Anführungszeichen gesetzt:
165
166 @example
167 "Das ist eine Zeichenkette"
168 @end example
169
170 Zeichenketten können über mehrere Zeilen reichen:
171
172 @example
173 "Das
174 ist
175 eine Zeichenkette"
176 @end example
177
178 @noindent
179 und die Zeichen für eine neue Zeile am Ende jeder Zeile werden auch
180 in die Zeichenkette aufgenommen.
181
182 Zeichen für eine neue Zeile können auch hinzugefügt werden, indem man
183 @code{\n} in die Zeichenkette aufnimmt.
184
185 @example
186 "das\nist eine\nmehrzeilige Zeichenkette"
187 @end example
188
189 Anführungszeichen und neue Zeilen können auch mit sogenannten
190 Fluchtsequenzen eingefügt werden. Die Zeichenkette
191 @code{a sagt "b"} wird wie folgt eingegeben:
192
193 @example
194 "a sagt \"b\""
195 @end example
196
197 @end table
198
199 Weitere zusätzliche Scheme-Datentypen, die hier nicht besprochen wurden,
200 finden sich in einer vollständigen Liste der Scheme-Datentypen in der
201 Guile-Referenzanleitung:
202 @uref{http://www.gnu.org/software/guile/manual/html_node/Simple-Data-Types.html}.
203
204
205 @node Zusammengesetzte Scheme-Datentypen
206 @subsection Zusammengesetzte Scheme-Datentypen
207 @translationof Scheme compound data types
208
209 Es gibt auch zusammengesetzte Datentypen in Scheme.  Die Datentypen, die in
210 LilyPond häufig benutzt werden, beinhalten Paare, Listen, assoziative Listen
211 und Hash-Tabellen.
212
213 @subheading Paare (pair)
214
215 Der wichtigeste zusammengesetzte Datentyp in Scheme ist ein Paar (@code{pair}).
216 Wie aus dem Namen schon hervorgeht, besteht ein Paar aus zwei zusammengeschweißten
217 Werten.  Die Prozedur um ein Paar zu erstellen ist @code{cons}.
218
219 @lisp
220 guile> (cons 4 5)
221 (4 . 5)
222 guile>
223 @end lisp
224
225 Das Paar wird dargestellt als zwei Elemente, von Klammern umgeben
226 und durch Leerzeichen und einen Punkt (@code{.}) getrennt.  Der Punkt ist
227 @emph{kein} Dezimalpunkt, sondern markiert die Gruppe als Paar.
228
229 Paare können auch wörtlich eingegeben werden, indem man ihnen voraus ein
230 einfaches Anführungszeichen (@code{'} setzt.
231
232 @lisp
233 guile> '(4 . 5)
234 (4 . 5)
235 guile>
236 @end lisp
237
238 Beide Elemente eines Paares können beliebige gültige Scheme-Werte sein:
239
240 @lisp
241 guile> (cons #t #f)
242 (#t . #f)
243 guile> '("blah-blah" . 3.1415926535)
244 ("blah-blah" . 3.1415926535)
245 guile>
246 @end lisp
247
248 Das erste Element eines Paares kann mit der Prozedur @code{car},
249 das zweite mit der Prozedur @code{cdr} angesprochen werden.
250
251 @lisp
252 guile> (define mypair (cons 123 "hello there")
253 ... )
254 guile> (car mypair)
255 123
256 guile> (cdr mypair)
257 "hello there"
258 guile>
259 @end lisp
260
261 @noindent
262
263 Achtung:  @code{cdr} wird ausgeprochen wie "kudd-err", nach Sussman und
264 Abelson, siehe
265 @uref{http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-14.html#footnote_Temp_133}
266
267 @subheading Listen (list)
268
269 Ein sehr häufiger Datentyp in Scheme ist die Liste (@emph{list}).  Formal
270 gesehen wird eine Liste entweder als leere Liste definiert
271 (repräsentiert als @code{'()}), oder als ein Paar, dessen @code{cdr}
272 eine Liste ist.
273
274 Es gibt viele Arten, Listen zu erstellen.  Die vielleicht häufigste Methode
275 ist die @code{list}-Prozedur:
276
277 @lisp
278 guile> (list 1 2 3 "abc" 17.5)
279 (1 2 3 "abc" 17.5)
280 @end lisp
281
282 Wie man sehen kann, wird eine Liste dargestellt in Form der einzelnen
283 Elemente, getrennt durch ein Leerzeichen und als Gruppe in Klammern eingeschlossen.
284 Anders als bei einem Paar, befindet sich kein Punkt zwischen den Elementen.
285
286 Eine Liste kann auch als wörtliche Liste notiert werden, indem man die
287 enthaltenen Elemente in Klammern einschließt und ein einfaches Anführungszeichen
288 voranschreibt:
289
290 @lisp
291 guile> '(17 23 "foo" "bar" "bazzle")
292 (17 23 "foo" "bar" "bazzle")
293 @end lisp
294
295 Listen haben eine zentrale Stellung in Scheme.  Scheme wird als Dialekt
296 von Lisp angesehen, und das Wort @qq{lisp} steht für @qq{List Processing}.
297 Scheme-Ausdrücke sind immer Listen.
298
299 @subheading Assoziative Listen (alist)
300
301 Eine besonderer Listentyp ist die @emph{assoziative Liste} oder @emph{alist}.
302 Eine Alist wird benutzt, um Daten zum einfachen Abrufen zu speichern.
303
304 Alisten sind Listen, deren Elemente als Paare kommen.  Der @code{car}-Teil
305 jedes Elements wird als @emph{Schlüssel} (key) bezeichnet, der
306 @code{cdr}-Teil jedes Elements wird @emph{Wert} (value) genannt.
307 Die Scheme-Prozedur @code{assoc} wird benutzt, um einen Eintrag aus einer
308 Aliste aufzurufen, und mit @code{cdr} wird sein Wert abgefragt:
309
310 @lisp
311 guile> (define my-alist '((1  . "A") (2 . "B") (3 . "C")))
312 guile> my-alist
313 ((1 . "A") (2 . "B") (3 . "C"))
314 guile> (assoc 2 my-alist)
315 (2 . "B")
316 guile> (cdr (assoc 2 my-alist))
317 "B"
318 guile>
319 @end lisp
320
321 Alisten werden sehr viel in LilyPond genutzt, um Eigenschaften und
322 andere Daten zu speichern.
323
324 @subheading Hash-Tabellen (hash table)
325
326 Eine Datenstruktur, die ab und zu in LilyPond eingesetzt wird.
327 Eine Hash-Tabelle ähnelt einem Array, aber die Indexe des Arrays
328 können beliebige Scheme-Werte sein, nicht nur Integre.
329
330 Hash-Tabellen sind effizienter als Alisten, wenn man viele Daten
331 speichern will und die Daten sich oft ändern.
332
333 Die Syntax, mit der Hash-Tabellen erstellt werden, ist etwas komplex,
334 aber man kann Beispiele hierzu im LilyPond-Quellcode finden.
335
336 @lisp
337 guile> (define h (make-hash-table 10))
338 guile> h
339 #<hash-table 0/31>
340 guile> (hashq-set! h 'key1 "val1")
341 "val1"
342 guile> (hashq-set! h 'key2 "val2")
343 "val2"
344 guile> (hashq-set! h 3 "val3")
345 "val3"
346 @end lisp
347
348 Werte werden aus den Hash-Tabellen mit @code{hashq-ref} ausgelesen.
349
350 @lisp
351 guile> (hashq-ref h 3)
352 "val3"
353 guile> (hashq-ref h 'key2)
354 "val2"
355 guile>
356 @end lisp
357
358 Schlüssel und Werte werden als Paar mit @code{hashq-get-handle} ausgelesen.
359 Das ist die beste Art, weil hier @code{#f} ausgegeben wird, wenn ein
360 Schlüssel nicht gefunden werden kann.
361
362 @lisp
363 guile> (hashq-get-handle h 'key1)
364 (key1 . "val1")
365 guile> (hashq-get-handle h 'frob)
366 #f
367 guile>
368 @end lisp
369
370
371 @node Berechnungen in Scheme
372 @subsection Berechnungen in Scheme
373 @translationof Calculations in Scheme
374
375 @ignore
376 We have been using lists all along.  A calculation, like @code{(+ 1 2)}
377 is also a list (containing the symbol @code{+} and the numbers 1
378 and@tie{}2).  Normally lists are interpreted as calculations, and the
379 Scheme interpreter substitutes the outcome of the calculation.  To enter a
380 list, we stop the evaluation.  This is done by quoting the list with a
381 quote @code{'} symbol.  So, for calculations do not use a quote.
382
383 Inside a quoted list or pair, there is no need to quote anymore.  The
384 following is a pair of symbols, a list of symbols and a list of lists
385 respectively,
386
387 @example
388 #'(stem . head)
389 #'(staff clef key-signature)
390 #'((1) (2))
391 @end example
392 @end ignore
393
394 Scheme kann verwendet werden, um Berechnungen durchzuführen. Es
395 verwendet eine @emph{Präfix}-Syntax. Um 1 und@tie{}2 zu addieren, muss
396 man @code{(+ 1 2)} schreiben, und nicht @math{1+2}, wie in traditioneller
397 Mathematik.
398
399 @lisp
400 guile> (+ 1 2)
401 3
402 @end lisp
403
404 Berechnungen können geschachtelt werden und das Ergebnis einer Berechnung
405 kann für eine neue Berechnung eingesetzt werden.
406
407 @lisp
408 guile> (+ 1 (* 3 4))
409 13
410 @end lisp
411
412 Diese Berechnungen sind Beispiele von Auswertungen. Ein Ausdruck
413 wie @code{(* 3 4)} wird durch seinen Wert @code{12} ersetzt.
414
415 Scheme-Berechnungen können zwischen Integren und Nich-Integren
416 unterscheiden.  Integre Berechnungen sind exakt, während Nicht-Integre
417 nach den passenden Genauigkeitseinschränkungen berechnet werden:
418
419 @lisp
420 guile> (/ 7 3)
421 7/3
422 guile> (/ 7.0 3.0)
423 2.33333333333333
424 @end lisp
425
426 Wenn der Scheme-Berechner einen Ausdruck antrifft, der eine Liste darstellt,
427 wird das erste Element der Liste als Prozedur behandelt, die mit
428 Argumenten des Restes der Liste ausgewertet werden.  Darum sind alle
429 Operatoren in Scheme vorangestellt.
430
431 Wenn das erste Element eines Scheme-Ausdrucks, der eine Liste darstellt,
432 @emph{kein} Operator oder keine Prozedur ist, gibt es einen Fehler:
433
434 @lisp
435 guile> (1 2 3)
436
437 Backtrace:
438 In current input:
439   52: 0* [1 2 3]
440
441 <unnamed port>:52:1: In expression (1 2 3):
442 <unnamed port>:52:1: Wrong type to apply: 1
443 ABORT: (misc-error)
444 guile>
445 @end lisp
446
447 Hier kann man sehen, dass Scheme versucht hat, 1 als einen Operator oder
448 eine Prozedur zu behandeln, was aber nicht möglich war.  Darum der Fehler
449 "Wrong type to apply: 1".
450
451 Wenn man also eine Liste erstellen will, braucht man also einen Listen-Operator
452 oder man muss die Liste als wörtliches Zitat schreiben, sodass Scheme sie
453 nicht auszuwerten versucht.
454
455 @lisp
456 guile> (list 1 2 3)
457 (1 2 3)
458 guile> '(1 2 3)
459 (1 2 3)
460 guile>
461 @end lisp
462
463 Dieser Fehler kann durchaus vorkommen, wenn man Scheme unter LilyPond
464 einsetzt.
465
466 @ignore
467 The same assignment can be done in completely in Scheme as well,
468
469 @example
470 #(define twentyFour (* 2 twelve))
471 @end example
472
473 @c this next section is confusing -- need to rewrite
474
475 The @emph{name} of a variable is also an expression, similar to a
476 number or a string.  It is entered as
477
478 @example
479 #'twentyFour
480 @end example
481
482 @funindex #'symbol
483 @cindex quoting in Scheme
484
485 The quote mark @code{'} prevents the Scheme interpreter from substituting
486 @code{24} for the @code{twentyFour}.  Instead, we get the name
487 @code{twentyFour}.
488 @end ignore
489
490
491 @node Scheme-Prozeduren
492 @subsection Scheme-Prozeduren
493 @translationof Scheme procedures
494
495 Scheme-Prozeduren sind ausführbare Scheme-Ausdrücke, die einen
496 Wert ausgeben, der das Resultat ihrer Ausführung darstellt.  Sie können
497 auch Variablen verändern, die außerhalb dieser Prozedur definiert wurden.
498
499 @subheading Prozeduren definieren
500
501 Prozeduren werden in Scheme mit @code{define} definiert:
502
503 @example
504 (define (function-name arg1 arg2 ... argn)
505  scheme-expression-that-gives-a-return-value)
506 @end example
507
508 Beispielsweise könnte man eine Prozedur definieren, die den Durchschnitt
509 berechnet:
510
511 @lisp
512 guile> (define (average x y) (/ (+ x y) 2))
513 guile> average
514 #<procedure average (x y)>
515 @end lisp
516
517 Wenn die Prozedur einmal definiert ist, wird sie aufgerufen indem man
518 die Prozedur und die Argumente in eine Liste schreibt.  Man könnte also den
519 Durchschnitt von 3 und 12 berechnen:
520
521 @lisp
522 guile> (average 3 12)
523 15/2
524 @end lisp
525
526 @subheading Prädikate
527
528 Scheme-Prozeduren, die Boolsche Werte ausgeben, werden oft als Prädikate
529 (predicate) bezeichnet.  Es herrscht die Übereinkunft, Prädikat-Bezeichnungen
530 mit einem Fragezeichen abzuschließen:
531
532 @lisp
533 guile> (define (less-than-ten? x) (< x 10))
534 guile> (less-than-ten? 9)
535 #t
536 guile> (less-than-ten? 15)
537 #f
538 @end lisp
539
540 @subheading Wiedergabe-Werte
541
542 Scheme-Prozeduren geben immer einen Wiedergabe-Wert (return value) aus, welcher
543 der Wert des letzten Ausdrucks ist, der in der Prozedur ausgeführt wurde.  Der
544 Wiedergabewert kann ein beliebiger gültiger Scheme-Wert sein, auch eine
545 komplexe Datenstruktur oder eine Prozedur.
546
547 Manchmal würden Benutzer gerne mehrere Scheme-Ausdrucke in einer Prozedur haben.
548 Es gibt zwei Arten, wie merhere Ausdrücke kombiniert werden können.  Die erste
549 Art ist die @code{begin}-Prozedur, der es ermöglicht, dass mehrere Ausdrücke
550 ausgewertet werden und den Wert des letzten Ausdrucks wiedergibt.
551
552 @lisp
553 guile> (begin (+ 1 2) (- 5 8) (* 2 2))
554 4
555 @end lisp
556
557 Die andere Art, mehrere Ausdrücke zu kombinieren, ist eine @code{let}-Umgebung.
558 In dieser Umgebung wird eine Serie von Verbindungen erstellt, und dann wird eine
559 Sequenz von Ausdrücken ausgewertet, die diese Bindungen einschließen können.
560 Der Wiedergabewert der let-Umgebung ist der Wiedergabewert der letzten Aussage
561 in der let-Umgebung:
562
563 @lisp
564 guile> (let ((x 2) (y 3) (z 4)) (display (+ x y)) (display (- z 4))
565 ... (+ (* x y) (/ z x)))
566 508
567 @end lisp
568
569
570 @node Scheme-Konditionale
571 @subsection Scheme-Konditionale
572 @translationof Scheme conditionals
573
574 @subheading if
575
576 Scheme hat eine @code{if}-Prozedur:
577
578 @example
579 (if test-expression true-expression false-expression)
580 @end example
581
582 @var{test-expression} ist ein Ausdruck, der einen Booleschen
583 Wert zurück gibt.  Wenn @var{test-expression} den Wert @code{#t}
584 ausgibt, gibt die if-Prozedur den Wert von @var{true-expression} aus,
585 in allen anderen Fällen den Wert von @var{false-expression}.
586
587 @lisp
588 guile> (define a 3)
589 guile> (define b 5)
590 guile> (if (> a b) "a is greater than b" "a is not greater than b")
591 "a is not greater than b"
592 @end lisp
593
594 @subheading cond
595
596 Eine andere konditionale Prozedur in Scheme ist
597 @code{cond}:
598
599 @example
600 (cond (test-expression-1 result-expression-sequence-1)
601       (test-expression-2 result-expression-sequence-2)
602       ...
603       (test-expression-n result-expression-sequence-n))
604 @end example
605
606 Beispielsweise:
607
608 @lisp
609 guile> (define a 6)
610 guile> (define b 8)
611 guile> (cond ((< a b) "a is less than b")
612 ...          ((= a b) "a equals b")
613 ...          ((> a b) "a is greater than b"))
614 "a is less than b"
615 @end lisp
616
617
618
619 @node Scheme in LilyPond
620 @section Scheme in LilyPond
621 @translationof Scheme in LilyPond
622
623 @menu
624 * LilyPond Scheme-Syntax::
625 * LilyPond-Variablen::
626 * Eingabe-Variablen und Scheme::
627 * Objekteigenschaften::
628 * Zusammengesetzte LilyPond-Variablen::
629 * Interne musikalische Repräsentation::
630 @end menu
631
632 @node LilyPond Scheme-Syntax
633 @subsection LilyPond Scheme-Syntax
634 @translationof LilyPond Scheme syntax
635
636 Der Guile-Auswerter ist ein Teil von LilyPond, sodass Scheme also auch in
637 normale LilyPond-Eingabedateien eingefügt werden kann.  Das Rautenzeichen
638 (@code{#}) wird benutzt, um dem LilyPond-Parser mitzuteilen, dass der nächste
639 Wert ein Scheme-Wert ist.
640
641 Wenn der Parser eine Raute sieht, wird der Eingabe-Code an den Guile-Auswerter
642 weitergereicht, der den Scheme-Ausdruck auswertet.  Der Auswerter behandelt
643 die Eingabe so lange, bis er zum Ende eines Scheme-Ausdrucks kommt.
644
645 Scheme-Prozeduren können in LilyPond-Eingabedateien definiert werden:
646
647 @example
648 #(define (average a b c) (/ (+ a b c) 3))
649 @end example
650
651 LilyPond-Kommentare (@code{%} oder @code{%@{ %@}}) können innerhalb
652 von Scheme-Code nicht benutzt werden.  Kommentare in Guile Scheme
653 werden wie folgt notiert:
654
655 @example
656 ; Einzeiliges Kommentar
657
658 #!
659   Guile-Stil Blockkommentar (nicht schachtelbar)
660   Diese Kommentare werden von Scheme-Programmierern
661   selten benutzt und nie im Quellcode
662   von LilyPond
663 !#
664 @end example
665
666 Für den Rest dieses Abschnitts soll angenommen werden, dass die Daten in
667 einer LilyPond-Eingabedatei notiert werden sollen, sodass immer @code{#}
668 vor die Scheme-Ausdrücke gestellt wird.
669
670 Alle Scheme-Ausdrücke auf oberster Ebene in einer LilyPond-Eingabedatei
671 können in einen einzigen Scheme-Ausdruck zusammengefasst werden mit
672 @code{begin}:
673
674 @example
675 #(begin
676   (define foo 0)
677   (define bar 1))
678 @end example
679
680
681 @node LilyPond-Variablen
682 @subsection LilyPond-Variablen
683 @translationof LilyPond variables
684
685 LilyPond-Variablen werden intern als Scheme-Variablen gespeichert. Darum
686 ist
687
688 @example
689 Zwoelf = 12
690 @end example
691
692 @noindent
693 das Gleiche wie
694
695 @example
696 #(define Zwoelf 12)
697 @end example
698
699 Das bedeutet, dass Scheme-Ausdrücke auf LilyPond-Variablen zugreifen können.
700 Man könnte also schreiben:
701
702 @example
703 Vierundzwanzig = #(* 2 Zwoelf)
704 @end example
705
706 @noindent
707 was zur Folge hätte, dass die Zahl 24 in der LilyPond (und Scheme-)Variablen
708 @code{Vierundzwanzig} gespeichert wird.
709
710
711 @node Eingabe-Variablen und Scheme
712 @subsection Eingabe-Variablen und Scheme
713 @translationof Input variables and Scheme
714
715 Das Eingabeformat unterstützt die Notation von Variablen: Im folgenden
716 Beispiel wird ein musikalischer Ausdruck einer Variablen mit der
717 Bezeichnung @code{traLaLa} zugewiesen:
718
719 @example
720 traLaLa = @{ c'4 d'4 @}
721 @end example
722
723 Variablen haben beschränkte Geltungsbereiche: im unten stehenden Beispiel
724 enthält auch die @code{\layout}-Umgebung eine @code{traLaLa}-Variable,
725 die sich aber von der @code{traLaLa}-Variable auf oberster Ebene unterscheidet:
726
727 @example
728 traLaLa = @{ c'4 d'4 @}
729 \layout @{ traLaLa = 1.0 @}
730 @end example
731
732 Jede Eingabedatei ist solch ein Gültigkeitsbereich, und alle
733 @code{\header}-, @code{\midi}- und @code{\layout}-Umgebungen
734 sind Gültigkeitsbereiche, die in diesen obersten Gültigkeitsbereich
735 eingebettet sind.
736
737 Sowohl Variablen als auch Gültigkeitsbereiche sind im Guile Modulsystem
738 eingebaut.  Ein anonymes Scheme-Modul wird jedem Gültigkeitsbereich
739 angehängt.  Eine Zuweisen in der Form von
740
741 @example
742 traLaLa = @{ c'4 d'4 @}
743 @end example
744
745 @noindent
746 wird intern in die Scheme-Definition
747
748 @example
749 (define traLaLa @var{Scheme-Wert von `@code{... }'})
750 @end example
751
752 @noindent
753 konvertiert.
754
755 Das bedeutet, dass LilyPond-Variablen und Scheme-Variablen frei gemischt
756 werden können.  Im folgenden Beispiel wird ein Notenfragment in der
757 Variable @code{traLaLa} gespeichert und mit Scheme dupliziert.  Das
758 Resultat wird in eine @code{\score}-Umgebung mit einer weiteren
759 Variable @code{twice} importiert:
760
761 @lilypond[verbatim]
762 traLaLa = { c'4 d'4 }
763
764 #(define newLa (map ly:music-deep-copy
765   (list traLaLa traLaLa)))
766 #(define twice
767   (make-sequential-music newLa))
768
769 { \twice }
770 @end lilypond
771
772 In diesem Beispiel geschieht die Zuweisung, nachdem der Parser sichergestellt
773 hat, dass nichts interessantes mehr nach @code{traLaLa = @{ ... @}} passiert.
774 Ohne die Dummy-Aussage in dem Beispiel würde die @code{newLa}-Definition ausgeführt,
775 bevor @code{traLaLa} definiert ist, was einen Syntax-Fehler hervorrufen würde.
776
777 Das Beispiel zeigt, wie man musikalische Ausdrücke aus der Eingabe in den
778 Scheme-Auswerter @qq{exportieren} kann.  Es geht auch andersherum.  Indem
779 man Scheme-Werten in die Funktion @code{ly:export} einschließt, wird ein
780 Scheme-Wert interpretiert, als ob er in LilyPond-Syntax eingeben wäre.
781 Anstatt @code{\twice} zu definieren, könne man also auch schreiben:
782
783 @example
784 ...
785 @{ $(make-sequential-music (list newLa)) @}
786 @end example
787
788 Scheme-Code wird sofort interpretiert, wenn der Parser darauf stößt.  Um
789 Scheme-Code als Makro zu definieren (das später aufgerufen werden soll),
790 muss man @ref{Leere Funktionen} benutzen oder
791
792 @example
793 #(define (nopc)
794   (ly:set-option 'point-and-click #f))
795
796 ...
797 #(nopc)
798 @{ c'4 @}
799 @end example
800
801 @knownissues
802
803 Scheme- und LilyPond-Variablen können nicht gemischt werden, wenn man die
804 @code{--safe}-Option benutzt.
805
806
807 @node Objekteigenschaften
808 @subsection Objekteigenschaften
809 @translationof Object properties
810
811 Objekteigenschaften werden in LilyPond in Form von Alisten-Ketten
812 gespeichert, also als Listen von Alisten.  Eigenschaften werden
813 geändert, indem man Werte an den Anfang der Eigenschaftsliste
814 hinzufügt.  Eigenschaften werden gelesen, indem Werte aus der
815 Aliste gelesen werden.
816
817 Ein neuer Wert für eine Eigenschaft kann gesetzt werden, indem man
818 der Alist einen Wert mit Schlüssel und dem Wert zuweist.  Die
819 LilyPond-Syntax hierfür ist:
820
821 @example
822 \override Stem #'thickness = #2.6
823 @end example
824
825 Diese Anweisung verändert die Erscheinung der Notenhälse. Der Alist-Eintrag
826 @code{'(thickness . 2.6)} wird zu der Eigenschaftsliste eines
827 @code{Stem}-(Hals-)Objektes hinzugefügt.
828 @code{thickness} wird relativ zu den Notenlinien errechnet, in diesem
829 Fall sind die Hälse also 2,6 mal so dick wie die Notenlinien.  Dadurch
830 werden Hälse fast zweimal so dick dargestellt, wie sie normalerweise sind.
831 Um zwischen Variablen zu unterscheiden, die in den Quelldateien direkt
832 definiert werden (wie @code{Vierundzwanzig} weiter oben), und zwischen denen,
833 die für interne Objekte zuständig sind, werden hier die ersteren
834 @qq{Variablen} genannt, die letzteren dagegen @qq{Eigenschaften}.
835 Das Hals-Objekt hat also eine @code{thickness}-Eigenschaft, während
836 @code{Vierundzwanzig} eine Variable ist.
837
838 @cindex Eigenschaften versus Bezeichner
839 @cindex Bezeichner versus Eigenschaften
840
841
842 @node Zusammengesetzte LilyPond-Variablen
843 @subsection Zusammengesetzte LilyPond-Variablen
844 @translationof LilyPond compound variables
845
846 @subheading Abstände (offset)
847
848
849
850 Zweidimensionale Abstände (X- und Y-Koordinaten) werden
851 als @code{pairs} (Paare) gespeichert. Der @code{car}-Wert des
852 Abstands ist die X-Koordinate und der @code{cdr}-Wert die
853 Y-Koordinate.
854
855 @example
856 \override TextScript #'extra-offset = #'(1 . 2)
857 @end example
858
859 Hierdurch wird das Paar @code{(1 . 2)} mit der Eigenschaft @code{extra-offset}
860 des TextScript-Objektes verknüpft. Diese Zahlen werden in
861 Systembreiten  gemessen, so dass der Befehl das Objekt eine Systembreite
862 nach rechts verschiebt und zwei Breiten nach oben.
863
864 Prozeduren, um mit Abständen zu arbeiten, finden sich in @file{scm/lily-library.scm}.
865
866 @subheading Bereiche (extend)
867
868 Paare werden auch benutzt, um Intervalle zu speichern, die einen Zahlenbereich
869 vom Minimum (dem @code{car}) bis zum Maximum (dem @code{cdr}) darstellen.
870 Intervalle werden benutzt, um die X- und Y-Ausdehnung von druckbaren
871 Objekten zu speichern.  Bei X-Ausdehnungen ist @code{car} die linke
872 X-Koordinate und @code{cdr} die rechte X-Koordinate.  Für Y-Ausdehnungen
873 ist @code{car} die untere Koordinate und @code{cdr} die obere Koordinate.
874
875 Prozeduren, um mit Intervallen zu arbeiten, finden sich in
876 @file{scm/lily-library.scm}.  Diese Prozeduren sollten benutzt, wenn es möglich
877 ist, um den Code konsistent zu halten.
878
879 @subheading Eigenschafts-Alisten (property alist)
880
881 Eine Eigenschafts-Aliste ist eine LilyPond-Datenstruktur, die eine Aliste
882 darstellt, deren Schlüssel Eigenschaften sind und deren Werte
883 Scheme-Ausdrücke sind, die den erwünschen Wert der Eigenschaft ausgeben.
884
885 LilyPond-Eigenschaften sind Scheme-Symbole, wie etwa @code{'thickness}
886 (Dicke).
887
888 @subheading Alisten-Ketten (alist chains)
889
890 Eine Alisten-Kette ist eine Liste, die Eigenschafts-Alisten enthält.
891
892 Die Menge aller Eigenschaften, die sich auf einen Grob auswirken, wird
893 typischerweise in einer Alisten-Kette gespeichert.  Um den Wert einer
894 bestimmten Eigenschaft zu finden, die ein Grob haben soll, wird jede
895 Liste in der Kette nach einander durchsucht, wobei nach einem Eintrag
896 geschaut wird, der den Eigenschaftsschlüssel enthält.  Der erste
897 gefundene Alisten-Eintrag wird benutzt und dessen Wert ist der
898 Wert der Eigenschaft.
899
900 Die Scheme-Prozedur @code{chain-assoc-get} wird normalerweise benutzt,
901 um Grob-Eigenschaftenwerte zu erhalten.
902
903
904 @node Interne musikalische Repräsentation
905 @subsection Interne musikalische Repräsentation
906 @translationof Internal music representation
907
908 Intern werden Noten als Scheme-Liste dargestellt.  Die Liste enthält
909 verschiedene Elemente, die die Druckausgabe beeinflussen.  Parsen
910 nennt man den Prozess, der die Noten aus der LilyPond-Repräsentation
911 in die interne Scheme-Repräsentation überführt.
912
913 Wenn ein musikalischer Ausdruck geparst wird, wird er in eine Gruppe
914 von Scheme-Musikobjekten konvertiert.  Die definierende Eigenschaft
915 eines Musikobjektes ist, dass es Zeit einnimmt.  Die Zeit, die
916 ein Objekt braucht, wird Dauer (engl. @emph{duration}) genannt.
917 Dauern werden in rationalen Zahlen ausgedrückt, die die Länge des
918 Musikobjekts in Ganzen Noten angeben.
919
920 Ein Musikobjekt hat drei Typen:
921
922 @itemize
923 @item
924 Musikbezeichnung (music name): Jeder Musikausdruck hat eine Bezeichnung.  Eine
925 Note beispielsweise erzeugt ein @rinternals{NoteEvent} und @code{\simultaneous}
926 produziert @rinternals{SimultaneousMusic}.  Eine Liste aller möglichen
927 Ausdrücke findet sich in der Referenz der Interna, unter
928 @rinternals{Music expressions}.
929
930 @item
931 Typ (type) oder Schnittstelle (interface): Jede Musikbezeichnung hat mehrere
932 Typen oder Schnittstellen, beispielsweise eine Note ist ein Ereignis (@code{event}),
933 aber auch ein Notenereignis (@code{note-event}), ein rhythmisches Ereignis
934 (@code{rhythmic-event}) und ein Melodieereignis (@code{melodic-event}).
935 Alle Musikklassen sind in der Referenz der Interna aufgelistet, unter
936 @rinternals{Music classes}.
937
938 @item
939 C++-Objekt: Jedes Musikobjekt ist durch ein Objekt der C++-Klasse @code{Music}
940 repräsentiert.
941 @end itemize
942
943 Die eigentliche Information eines musikalischen Ausdrucks wird in Eigenschaften
944 gespeichert.  Ein @rinternals{NoteEvent} beispielsweise hat die Eigenschaften
945 Tonhöhe (@code{pitch}) und Dauer (@code{duration}), die die Dauer und die
946 Tonhöhe der Note speichern.  Eine Liste aller möglichen Eigenschaften findet
947 sich in der Referenz der Interna, unter
948 @rinternals{Music properties}.
949
950 Ein zusammengesetzter musikalischer Ausdruck ist ein Musikobjekt, das andere
951 Musikobjekte als Eigenschaften enthält.  Eine Liste an Objekten kann in der
952 @code{elements}-Eigenschaft eines Musikobjekts bzw. ein einziges
953 Ableger-Musikelement in der @code{element}-Eigenschaft gespeichert werden.
954 @rinternals{SequentialMusic} beispielsweise hat sein einziges Argument in
955 @code{element}.  Der Körper einer Wiederholung wird in der @code{element}-Eigenschaft
956 von @rinternals{RepeatedMusic} gespeichert, und die alternativen Endungen
957 in @code{elements}.
958
959
960 @node Komplizierte Funktionen erstellen
961 @section Komplizierte Funktionen erstellen
962 @translationof Building complicated functions
963
964 Dieser Abschnitt zeigt, wie man Information zusammensucht,
965 um komplizierte musikalische Funktionen  zu erstellen.
966
967 @menu
968 * Musikalische Funktionen darstellen::
969 * Eigenschaften von Musikobjekten::
970 * Verdoppelung einer Note mit Bindebögen (Beispiel)::
971 * Artikulationszeichen zu Noten hinzufügen (Beispiel)::
972 @end menu
973
974
975 @node Musikalische Funktionen darstellen
976 @subsection Musikalische Funktionen darstellen
977 @translationof Displaying music expressions
978
979 @cindex interne Speicherung
980 @cindex Musikausdrücke anzeigen
981 @cindex Anzeigen von Musikausdrücken
982
983 @funindex displayMusic
984 @funindex \displayMusic
985
986 Wenn man eine musikalische Funktion erstellt, ist es oft
987 hilfreich sich anzuschauen, wie musikalische Funktionen
988 intern gespeichert werden.  Das kann mit der Funktion
989 @code{\displayMusic} erreicht werden:
990
991 @example
992 @{
993   \displayMusic @{ c'4\f @}
994 @}
995 @end example
996
997 @noindent
998 zeigt:
999
1000 @example
1001 (make-music
1002   'SequentialMusic
1003   'elements
1004   (list (make-music
1005           'EventChord
1006           'elements
1007           (list (make-music
1008                   'NoteEvent
1009                   'duration
1010                   (ly:make-duration 2 0 1 1)
1011                   'pitch
1012                   (ly:make-pitch 0 0 0))
1013                 (make-music
1014                   'AbsoluteDynamicEvent
1015                   'text
1016                   "f")))))
1017 @end example
1018
1019 Normalerweise gibt LilyPond diese Ausgabe auf der Konsole mit
1020 allen anderen Nachrichten aus.  Um die wichtigen Nachrichten
1021 in einer Datei zu speichern, kann die Ausgabe in eine Datei
1022 umgeleitet werden:
1023
1024 @example
1025 lilypond file.ly >display.txt
1026 @end example
1027
1028 Mit etwas Umformatierung ist die gleiche Information sehr viel
1029 einfacher zu lesen:
1030
1031 @example
1032 (make-music 'SequentialMusic
1033   'elements (list (make-music 'EventChord
1034                     'elements (list (make-music 'NoteEvent
1035                                       'duration (ly:make-duration 2 0 1 1)
1036                                       'pitch (ly:make-pitch 0 0 0))
1037                                     (make-music 'AbsoluteDynamicEvent
1038                                       'text "f")))))
1039 @end example
1040
1041 Eine musikalische @code{@{ ... @}}-Sequenz hat die Bezeichnung
1042 @code{SequentialMusic} und ihre inneren Ausdrücke werden als
1043 Liste in seiner @code{'elements}-Eigenschaft gespeichert.  Eine
1044 Note ist als als ein @code{EventChord}-Ausdruck dargestellt,
1045 der ein @code{NoteEvent}-Objekt (welches Dauer und
1046 Tonhöhe speichert) und zusätzliche Information enthält (in
1047 diesem Fall ein @code{AbsoluteDynamicEvent} mit einer
1048 @code{"f"}-Text-Eigenschaft.
1049
1050
1051 @node Eigenschaften von Musikobjekten
1052 @subsection Eigenschaften von Musikobjekten
1053 @translationof Music properties
1054
1055 Das @code{NoteEvent}-Objekt ist das erste Objekt der
1056 @code{'elements}-Eigenschaft von @code{someNote}.
1057
1058 @example
1059 someNote = c'
1060 \displayMusic \someNote
1061 ===>
1062 (make-music
1063   'EventChord
1064   'elements
1065   (list (make-music
1066           'NoteEvent
1067           'duration
1068           (ly:make-duration 2 0 1 1)
1069           'pitch
1070           (ly:make-pitch 0 0 0))))
1071 @end example
1072
1073 Die @code{display-scheme-music}-Funktion ist die Funktion, die von
1074 @code{\displayMusic} eingesetzt wird, um die Scheme-Repräsentation
1075 eines musikalischen Ausdrucks anzuzeigen.
1076
1077 @example
1078 #(display-scheme-music (first (ly:music-property someNote 'elements)))
1079 ===>
1080 (make-music
1081   'NoteEvent
1082   'duration
1083   (ly:make-duration 2 0 1 1)
1084   'pitch
1085   (ly:make-pitch 0 0 0))
1086 @end example
1087
1088 Danach wird die Tonhöhe der Note von der @code{'pitch}-Eigenschaft
1089 des @code{NoteEvent}-Objektes gelesen:
1090
1091 @example
1092 #(display-scheme-music
1093    (ly:music-property (first (ly:music-property someNote 'elements))
1094                       'pitch))
1095 ===>
1096 (ly:make-pitch 0 0 0)
1097 @end example
1098
1099 Die Tonhöhe einer Note kann geändert werden, indem man diese
1100 @code{'pitch}-Eigenschaft umdefiniert:
1101
1102 @funindex \displayLilyMusic
1103 @funindex displayLilyMusic
1104
1105 @example
1106 #(set! (ly:music-property (first (ly:music-property someNote 'elements))
1107                           'pitch)
1108        (ly:make-pitch 0 1 0)) ;; Die Tonhöhen auf d' verändern.
1109 \displayLilyMusic \someNote
1110 ===>
1111 d'
1112 @end example
1113
1114
1115 @node Verdoppelung einer Note mit Bindebögen (Beispiel)
1116 @subsection Verdoppelung einer Note mit Bindebögen (Beispiel)
1117 @translationof Doubling a note with slurs (example)
1118
1119 In diesem Abschnitt soll gezeigt, werden, wie man eine
1120 Funktion erstellt, die eine Eingabe wie @code{a}
1121 nach @code{a( a)} umdefiniert.  Dazu wird zuerst die
1122 interne Repräsentation der Musik betrachtet, die
1123 das Endergebnis darstellt:
1124
1125 @example
1126 \displayMusic@{ a'( a') @}
1127 ===>
1128 (make-music
1129   'SequentialMusic
1130   'elements
1131   (list (make-music
1132           'EventChord
1133           'elements
1134           (list (make-music
1135                   'NoteEvent
1136                   'duration
1137                   (ly:make-duration 2 0 1 1)
1138                   'pitch
1139                   (ly:make-pitch 0 5 0))
1140                 (make-music
1141                   'SlurEvent
1142                   'span-direction
1143                   -1)))
1144         (make-music
1145           'EventChord
1146           'elements
1147           (list (make-music
1148                   'NoteEvent
1149                   'duration
1150                   (ly:make-duration 2 0 1 1)
1151                   'pitch
1152                   (ly:make-pitch 0 5 0))
1153                 (make-music
1154                   'SlurEvent
1155                   'span-direction
1156                   1)))))
1157 @end example
1158
1159 Eine schlechte Nachricht ist, dass die
1160 @code{SlurEvent}-Ausdrücke @qq{innerhalb}
1161 der Noten (bzw. innerhalb der
1162 @code{EventChord}-Ausdrücke) hinzugefügt werden müssen.
1163
1164 Jetzt folgt eine Betrachtung der Eingabe:
1165
1166 @example
1167 (make-music
1168   'SequentialMusic
1169   'elements
1170   (list (make-music
1171           'EventChord
1172           'elements
1173           (list (make-music
1174                   'NoteEvent
1175                   'duration
1176                   (ly:make-duration 2 0 1 1)
1177                   'pitch
1178                   (ly:make-pitch 0 5 0))))))
1179 @end example
1180
1181 In der gewünschten Funktion muss also dieser Ausdruck
1182 kopiert werden (sodass zwei Noten vorhanden sind, die
1183 eine Sequenz bilden), dann müssen @code{SlurEvent}
1184 zu der @code{'elements}-Eigenschaft jeder Noten hinzugefügt
1185 werden, und schließlich muss eine @code{SequentialMusic}
1186 mit den beiden @code{EventChords} erstellt werden.
1187
1188 @example
1189 doubleSlur = #(define-music-function (parser location note) (ly:music?)
1190          "Return: @{ note ( note ) @}.
1191          `note' is supposed to be an EventChord."
1192          (let ((note2 (ly:music-deep-copy note)))
1193            (set! (ly:music-property note 'elements)
1194                  (cons (make-music 'SlurEvent 'span-direction -1)
1195                        (ly:music-property note 'elements)))
1196            (set! (ly:music-property note2 'elements)
1197                  (cons (make-music 'SlurEvent 'span-direction 1)
1198                        (ly:music-property note2 'elements)))
1199            (make-music 'SequentialMusic 'elements (list note note2))))
1200 @end example
1201
1202
1203 @node Artikulationszeichen zu Noten hinzufügen (Beispiel)
1204 @subsection Artikulationszeichen zu Noten hinzufügen (Beispiel)
1205 @translationof Adding articulation to notes (example)
1206
1207 Am einfachsten können Artikulationszeichen zu Noten
1208 hinzugefügt werden, indem man zwei musikalische Funktionen
1209 in einen Kontext einfügt, wie erklärt in
1210 @ruser{Kontexte erstellen}.  Hier soll jetzt eine musikalische
1211 Funktion entwickelt werden, die das vornimmt.
1212
1213 Eine @code{$variable} innerhalb von @code{#@{...#@}} ist das
1214 gleiche wie die normale Befehlsform @code{\variable} in
1215 üblicher LilyPond-Notation.  Es ist bekannt dass
1216
1217 @example
1218 @{ \music -. -> @}
1219 @end example
1220
1221 @noindent
1222 in LilyPond nicht funktioniert.  Das Problem könnte vermieden
1223 werden, indem das Artikulationszeichen an eine Pseudonote
1224 gehängt wird:
1225
1226 @example
1227 @{ << \music s1*0-.-> @}
1228 @end example
1229
1230 @noindent
1231 aber in diesem Beispiel soll gezeigt werden, wie man das in
1232 Scheme vornimmt.  Zunächst wird die Eingabe und die gewünschte
1233 Ausgabe examiniert:
1234
1235 @example
1236 %  Eingabe
1237 \displayMusic c4
1238 ===>
1239 (make-music
1240   'EventChord
1241   'elements
1242   (list (make-music
1243           'NoteEvent
1244           'duration
1245           (ly:make-duration 2 0 1 1)
1246           'pitch
1247           (ly:make-pitch -1 0 0))))
1248 =====
1249 %  gewünschte Ausgabe
1250 \displayMusic c4->
1251 ===>
1252 (make-music
1253   'EventChord
1254   'elements
1255   (list (make-music
1256           'NoteEvent
1257           'duration
1258           (ly:make-duration 2 0 1 1)
1259           'pitch
1260           (ly:make-pitch -1 0 0))
1261         (make-music
1262           'ArticulationEvent
1263           'articulation-type
1264           "marcato")))
1265 @end example
1266
1267 Dabei ist zu sehen, dass eine Note (@code{c4}) als @code{EventChord}
1268 repräsentiert ist, mit einem @code{NoteEvent}-Ausdruck in ihrer
1269 Elementenliste.  Um eine Marcato-Artikulation hinzuzufügen, muss
1270 ein @code{ArticulationEvent}-Ausdruck zu der Elementeigenschaft
1271 des @code{EventChord}-Ausdrucks hinzugefügt werden.
1272
1273 Um diese Funktion zu bauen, wird folgendermaßen begonnen:
1274
1275 @example
1276 (define (add-marcato event-chord)
1277   "Add a marcato ArticulationEvent to the elements of `event-chord',
1278   which is supposed to be an EventChord expression."
1279   (let ((result-event-chord (ly:music-deep-copy event-chord)))
1280     (set! (ly:music-property result-event-chord 'elements)
1281           (cons (make-music 'ArticulationEvent
1282                   'articulation-type "marcato")
1283                 (ly:music-property result-event-chord 'elements)))
1284     result-event-chord))
1285 @end example
1286
1287 Die erste Zeile definiert eine Funktion in Scheme: Die Bezeichnung
1288 der Funktion ist @code{add-marcato} und sie hat eine Variable
1289 mit der Bezeichnung @code{event-chord}.  In Scheme geht der Typ
1290 einer Variable oft direkt aus der Bezeichnung hervor (das ist auch
1291 eine gute Methode für andere Programmiersprachen).
1292
1293 @example
1294 "Add a marcato..."
1295 @end example
1296
1297 @noindent
1298 ist eine (englische) Beschreibung, was diese Funktion tut.  Sie ist
1299 nicht unbedingt notwendig, aber genauso wie klare Variablen-Bezeichnungen
1300 ist auch das eine gute Methode.
1301
1302 @example
1303 (let ((result-event-chord (ly:music-deep-copy event-chord)))
1304 @end example
1305
1306 @code{let} wird benutzt, um die lokalen Variablen zu definieren.  Hier
1307 wird eine lokale Variable benutzt: @code{result-event-chord}.  Sie erhält
1308 den Wert @code{(ly:music-deep-copy event-chord)}.  @code{ly:music-deep-copy}
1309 ist eine LilyPond-spezifische Funktion, die wie alle Funktionen mit dem
1310 Präfix @code{ly:} versehen ist.  Sie wird benutzt, um eine Kopie eines
1311 musikalischen Ausdrucks anzufertigen.  Hier wird @code{event-chord}
1312 (der Parameter der Funktion) kopiert.  Die Funktion soll ja nur ein
1313 Artikulationszeichen an einen @code{EventChord} gehängt werden, deshalb ist es besser,
1314 den @code{EventChord}, der als Argument gegeben wurde, nicht zu
1315 verändern, weil er woanders benutzt werden könnte.
1316
1317 Jetzt gibt es @code{result-event-chord}, wobei es sich um einen
1318 @code{NoteEventChord}-Ausdruck handelt, welcher gleichzeitig eine Kopie
1319 von @code{event-chord} ist.  Das Makro wird seiner Eigenschaftsliste
1320 hinzugefügt:
1321
1322 @example
1323 (set! place new-value)
1324 @end example
1325
1326 Was in diesem Fall @qq{gesetzt} werden soll (@qq{place}) ist die
1327 @q{elements}-Eigenschaft des @code{result-event-chord}-Ausdrucks.
1328
1329 @example
1330 (ly:music-property result-event-chord 'elements)
1331 @end example
1332
1333 @code{ly:music-property} ist die Funktion, mit der musikalische
1334 Eigenschaften erreicht werden können (die @code{'elements},
1335 @code{'duration}, @code{'pitch} usw., die in der Ausgabe von
1336 @code{\displayMusic} weiter oben angezeigt werden).  Der neue
1337 Wert ist, was ehemals die Elementeigenschaft war, mit einem
1338 zusätzlichen Element: dem @code{ArticulationEvent}-Ausdruck,
1339 der aus der Ausgabe von
1340 @code{\displayMusic} kopiert werden kann:
1341
1342 @example
1343 (cons (make-music 'ArticulationEvent
1344         'articulation-type "marcato")
1345       (ly:music-property result-event-chord 'elements))
1346 @end example
1347
1348 @code{cons} wird benutzt, um ein Element zu einer Liste hinzuzufügen,
1349 ohne dass die originale Liste verändert wird.  Das ist es, was die
1350 Funktion tun soll:  die gleiche Liste, aber mit dem neuen
1351 @code{ArticulationEvent}-Ausdruck.  Die Reihenfolge innerhalb
1352 der Elementeeigenschaft ist hier nicht relevant.
1353
1354 Wenn schließlich die Marcato-Artikulation zu der entsprechenden
1355 @code{elements}-Eigenschaft hinzugefügt ist, kann
1356 @code{result-event-chord} ausgegeben werden, darum die letzte Zeile
1357 der Funktion.
1358
1359 Jetzt wird die @code{add-marcato}-Funktion in eine musikalische
1360 Funktion umgewandelt:
1361
1362 @example
1363 addMarcato = #(define-music-function (parser location event-chord)
1364                                      (ly:music?)
1365     "Add a marcato ArticulationEvent to the elements of `event-chord',
1366     which is supposed to be an EventChord expression."
1367     (let ((result-event-chord (ly:music-deep-copy event-chord)))
1368       (set! (ly:music-property result-event-chord 'elements)
1369             (cons (make-music 'ArticulationEvent
1370                     'articulation-type "marcato")
1371                   (ly:music-property result-event-chord 'elements)))
1372       result-event-chord))
1373 @end example
1374
1375 Eine Überprüfung, dass die Funktion richtig arbeitet, geschieht
1376 folgendermaßen:
1377
1378 @example
1379 \displayMusic \addMarcato c4
1380 @end example
1381
1382
1383
1384
1385
1386
1387 @ignore
1388
1389 @menu
1390 * Optimierungen mit Scheme::
1391 @end menu
1392
1393 @c node Optimierungen mit Scheme
1394 @c appendixsec Optimierungen mit Scheme
1395 @c translationof Tweaking with Scheme
1396
1397 Wir haben gesehen wie LilyPond-Eingabe massiv beeinflusst
1398 werden kann, indem Befehle wie etwa
1399 @code{\override TextScript #'extra-offset = ( 1 . -1)}
1400 benutzt werden.  Aber es wurde gezeigt, dass Scheme noch
1401 mächtiger ist.  Eine bessere Erklärung findet sich in der@ref{Scheme-Übung} und in
1402 @ruser{Schnittstellen für Programmierer}.
1403
1404 Scheme kann auch in einfachen @code{\override}-Befehlen
1405 benutzt werden:
1406
1407 TODO Find a simple example
1408 @c This isn't a valid example with skylining
1409 @c It works fine without padText  -td
1410
1411
1412 @lilypond[quote,verbatim,ragged-right]
1413 padText = #(define-music-function (parser location padding) (number?)
1414 #{
1415   \once \override TextScript #'padding = #padding
1416 #})
1417
1418 \relative c''' {
1419   c4^"piu mosso" b a b
1420   \padText #1.8
1421   c4^"piu mosso" d e f
1422   \padText #2.6
1423   c4^"piu mosso" fis a g
1424 }
1425 @end lilypond
1426
1427
1428 Es kann auch benutzt werden, um Befehle zu erstellen:
1429
1430 @c Check this is a valid example with skylining
1431 @c It is - 'padding still works
1432
1433 @lilypond[quote,verbatim,ragged-right]
1434 tempoPadded = #(define-music-function (parser location padding tempotext)
1435   (number? string?)
1436 #{
1437   \once \override Score.MetronomeMark #'padding = $padding
1438   \tempo \markup { \bold #tempotext }
1439 #})
1440
1441 \relative c'' {
1442   \tempo \markup { "Low tempo" }
1443   c4 d e f g1
1444   \tempoPadded #4.0 #"High tempo"
1445   g4 f e d c1
1446 }
1447 @end lilypond
1448
1449 Sogar ganze Musikausdrücke können eingefügt werden:
1450
1451 @lilypond[quote,verbatim,ragged-right]
1452 pattern = #(define-music-function (parser location x y) (ly:music? ly:music?)
1453 #{
1454   $x e8 a b $y b a e
1455 #})
1456
1457 \relative c''{
1458   \pattern c8 c8\f
1459   \pattern {d16 dis} { ais16-> b\p }
1460 }
1461 @end lilypond
1462 @end ignore
1463