[ << Top ] | [Anfang][Inhalt][Index][ ? ] | [ Schnittstellen für Programmierer >> ] | ||
[ < Top ] | [ Nach oben : Top ] | [ Optimierungen mit Scheme > ] |
A. Scheme-Übung
LilyPond verwendet die Scheme-Programmiersprache sowohl als Teil der Eingabesyntax als auch als internen Mechanismus, um Programmmodule zusammenzufügen. Dieser Abschnitt ist ein sehr kurzer Überblick über die Dateneingabe mit Scheme. Wenn Sie mehr über Scheme wissen wollen, gehen Sie zu http://www.schemers.org.
LilyPond benutzt die GNU Guile-Implementation von Scheme, die auf dem „R5RS“-Standard von Scheme basiert. Wenn Sie Scheme lernen wollen, um es innerhalb von LilyPond zu benutzen, wird es nicht empfohlen, mit einer anderen Implementation (die sich auf einen anderen Standard bezieht) zu arbeiten. Information zu Guile findet sich unter http://www.gnu.org/software/guile/. Der „R5RS“-Standard von Scheme befindet sich unter der Adresse http://www.schemers.org/Documents/Standards/R5RS/.
Die LilyPond-Installation enthält gleichzeitig auch die
Guile-Implemenation von Scheme. Auf den meisten Systemen kann
man in einer Scheme-sandbox experimentieren, indem man ein
Kommandozeilen-Fenster öffnet und guile
auffruft. Unter
einigen Systemen, insbesondere unter Windows, muss man evtl.
die Umgebungsvariable GUILE_LOAD_PATH
auf das Verzeichnis
../usr/shr/guile/1.8
innerhalb des LilyPond-Installationsverzeichnisses
setzen (der vollständige Pfad ist erklärt in @ref{Other sources of information}).
Alternativ können Windows-Benutzer auch einfach „Ausführen“ im
Startmenü wählen und guile
schreiben.
Das Grundlegendste an einer Sprache sind Daten: Zahlen, Zeichen, Zeichenketten, Listen usw. Hier ist eine Liste der Datentypen, die für LilyPond-Eingabedateien relevant sind.
- Boolesche Variablen
Werte einer Booleschen Variable sind Wahr oder Falsch. Die Scheme-Entsprechung für Wahr ist
#t
und für Falsch#f
.- Zahlen
Zahlen werden wie üblich eingegeben,
1
ist die (ganze) Zahl Eins, während-1.5
ist eine Gleitkommazahl (also eine nicht-ganze).- Zeichenketten
Zeichenketten werden in doppelte Anführungszeichen gesetzt:
"Das ist eine Zeichenkette"
Zeichenketten können über mehrere Zeilen reichen:
"Das ist eine Zeichenkette"
Anführungszeichen und neue Zeilen können auch mit sogenannten Fluchtsequenzen eingefügt werden. Die Zeichenkette
a sagt "b"
wird wie folgt eingegeben:"a sagt \"b\""
Neue Zeilen und Backslashe werden mit
\n
bzw.\\
eingegeben.
In einer Notationsdatei werden kleine Scheme-Abschnitte mit der
Raute (#
) eingeleitet. Die vorigen Beispiele heißen also in
LilyPond:
##t ##f #1 #-1.5 #"Das ist eine Zeichenkette" #"Das ist eine Zeichenkette"
LilyPond-Kommentare (%
oder %{ %}
) können innerhalb
von Scheme-Code nicht benutzt werden. Kommentare in Guile Scheme
werden wie folgt notiert:
; Einzeiliges Kommentar #! Guile-Stil Blockkommentar (nicht schachtelbar) Diese Kommentare werden von Scheme-Programmierern selten benutzt und nie im Quellcode von LilyPond !# +
Merere aufeinander folgende Scheme-Ausdrücke in einer Notationsdatei
können kombiniert werden, wenn man begin
einsetzt. Das
erlaubt es, die Anzahl an Rauten auf eins zu begrenzen.
#(begin (define foo 0) (define bar 1))
Wenn #
von einer öffnenden Klammer, (
, gefolgt wird, wie
in dem Beispiel oben, bleibt der Parser im Scheme-Modus bis eine
passende schließende Klammer, )
, gefunden wird, sodass keine
weiteren #
-Zeichen benötigt werden, um einen Scheme-Abschnitt
anzuzeigen.
Für den Rest dieses Abschnitts nehmen wir an, dass die Daten immer in einer LilyPond-Datei stehen, darum wird immer die Raute verwendet.
Scheme kann verwendet werden, um Berechnungen durchzuführen. Es
verwendet eine Präfix-Syntax. Um 1 und 2 zu addieren, muss
man (+ 1 2)
schreiben, und nicht 1+2, wie in traditioneller
Mathematik.
#(+ 1 2) ⇒ #3 |
Der Pfeil ⇒ zeigt an, dass das Ergebnis der Auswertung von
(+ 1 2)
3
ist. Berechnungen können geschachtelt
werden und das Ergebnis einer Berechnung kann für eine neue
Berechnung eingesetzt werden.
#(+ 1 (* 3 4)) ⇒ #(+ 1 12) ⇒ #13 |
Diese Berechnungen sind Beispiele von Auswertungen. Ein Ausdruck
wie (* 3 4)
wird durch seinen Wert 12
ersetzt. Ähnlich
verhält es sich mit Variablen. Nachdem eine Variable definiert ist:
zwoefl = #12
kann man sie in Ausdrücken weiterverwenden:
vierundzwanzig = #(* 2 zwoelf)
Die 24 wird in der Variablen vierundzwanzig
gespeichert.
Die gleiche Zuweisung kann auch vollständig in Scheme geschrieben
werden:
#(define vierundzwanzig (* 2 zwoelf))
Der Name einer Variable ist auch ein Ausdruck, genauso wie eine Zahl oder eine Zeichenkette. Er wird wie folgt eingegeben:
#'vierundzwanzig
Das Apostroph '
verhindert, dass bei der Scheme-Auswertung
vierundzwanzig
durch 24
ersetzt wird. Anstatt dessen erhalten
wir die Bezeichnung vierundzwanzig
.
Diese Syntax wird sehr oft verwendet, weil es manche Einstellungsveränderungen erfordern, dass Scheme-Werte einer internen Variable zugewiesen werden, wie etwa
\override Stem #'thickness = #2.6
Diese Anweisung verändert die Erscheinung der Notenhälse. Der Wert
2.6
wird der Variable thickness
(Dicke) eines
Stem
-(Hals)-Objektes gleichgesetzt.
thickness
wird relativ zu den Notenlinien errechnet, in diesem
Fall sind die Hälse also 2,6 mal so dick wie die Notenlinien. Dadurch
werden Hälse fast zweimal so dick dargestellt, wie sie normalerweise sind.
Um zwischen Variablen zu unterscheiden, die in den Quelldateien direkt
definiert werden (wie vierundzwanzig
weiter oben), und zwischen denen,
die für interne Objekte zuständig sind, werden hier die ersteren
„Bezeichner“ genannt, die letzteren dagegen „Eigenschaften“.
Das Hals-Objekt hat also eine thickness
-Eigenschaft, während
vierundzwanzig
ein Bezeichner ist.
Sowohl zweidimensionale Abstände (X- und Y-Koordinaten) als auch
Größen von Objekten (Intervalle mit linker und rechter Begrenzung) werden
als pairs
(Paare) eingegeben. Ein Paar1 wird als (erster . zweiter)
eingegeben und sie müssen mit dem Apostroph eingeleitet werden, genauso
wie Symbole:
\override TextScript #'extra-offset = #'(1 . 2)
Hierdurch wird das Paar (1, 2) mit der Eigenschaft extra-offset
des TextScript-Objektes verknüpft. Diese Zahlen werden in
Systembreiten gemessen, so dass der Befehl das Objekt eine Systembreite
nach rechts verschiebt und zwei Breiten nach oben.
Die zwei Elemente eines Paares können von beliebigem Inhalt sein, etwa
#'(1 . 2) #'(#t . #f) #'("blah-blah" . 3.14159265)
Eine Liste wird eingegeben, indem die Elemente der Liste in Klammern geschrieben werden, mit einem Apostroph davor. Beispielsweise:
#'(1 2 3) #'(1 2 "string" #f)
Die ganze Zeit wurde hier schon Listen benutzt. Eine Berechnung,
wie (+ 1 2)
, ist auch eine Liste (welche das Symbol +
und die Nummern 1 und 2 enthält. Normalerweise werden Listen
als Berechnungen interpretiert und der Scheme-Interpreter ersetzt
die Liste mit dem Ergebnis der Berechnung. Um eine Liste an sich
einzugeben, muss die Auswertung angehalten werden. Das geschieht,
indem der Liste ein Apostroph vorangestellt wird. Für Berechnungen
kann man also den Apostroph nicht verwenden.
Innerhalb einer zitierten Liste (also mit Apostroph) muss man keine Anführungszeichen mehr setzen. Im Folgenden ein Symbolpaar, eine Symbolliste und eine Liste von Listen:
#'(stem . head) #'(staff clef key-signature) #'((1) (2))
A.1 Optimierungen mit Scheme |
Fußnoten
[1] In der
Scheme-Terminologie wird ein Paar cons
genannt und seine
zwei Elemente car
und cdr
.
[ << Top ] | [Anfang][Inhalt][Index][ ? ] | [ Schnittstellen für Programmierer >> ] | ||
[ < Top ] | [ Nach oben : Top ] | [ Optimierungen mit Scheme > ] |