]> git.donarmstrong.com Git - lilypond.git/blobdiff - Documentation/de/extending/programming-interface.itely
Rerun scripts/auxiliar/update-with-convert-ly.sh
[lilypond.git] / Documentation / de / extending / programming-interface.itely
index 8bc446fbbdb798d34d48a04aeb4936786b37ab7c..4b1b43a00646d3cebdcfdb3248d87cd0fcaaadc1 100644 (file)
@@ -1,14 +1,14 @@
 @c -*- coding: utf-8; mode: texinfo; -*-
 
 @ignore
-    Translation of GIT committish: 3d7ffa1f82bb44673134b28becf7898482fe7316
+    Translation of GIT committish: e5a609e373eae846857f9a6d70a402a3d42b7d94
 
     When revising a translation, copy the HEAD committish of the
     version that you are working on.  For details, see the Contributors'
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.12.0"
+@c \version "2.17.6"
 
 @c Translators: Till Paala
 
 Fortgeschrittene Anpassungen können mithilfe der Programmiersprache
 Scheme vorgenommen werden.  Wenn Sie Scheme nicht kennen, gibt
 es eine grundlegende Einleitung in LilyPonds
-@rlearning{Scheme-Übung}.
+@ref{Scheme-Übung}.
 
 @menu
+* LilyPond-Codeabschnitte::
+* Scheme-Funktionen::
 * Musikalische Funktionen::
-* Schnittstelle für Programmierer::
-* Komplizierte Funktionen erstellen::
-* Programmierungsschnittstelle für Textbeschriftungen::
+* Ereignisfunktionen::
+* Textbeschriftungsfunktionen::
 * Kontexte für Programmierer::
-* Scheme-Vorgänge als Eigenschaften::
-* Scheme-Code anstelle von \tweak verwenden::
+* Callback-Funktionen::
+* Scheme-Code innerhalb LilyPonds::
 * Schwierige Korrekturen::
 @end menu
 
 
-@node Musikalische Funktionen
-@section Musikalische Funktionen
-@translationof Music functions
-
-Dieser Abschnitt behandelt die Erstellung von musikalischen Funktionen
-innerhalb von LilyPond.
-
-@menu
-* Überblick über musikalische Funktionen::
-* Einfache Ersetzungsfunktionen::
-* Paarige Ersetzungsfunktionen::
-* Mathematik in Funktionen::
-* Leere Funktionen::
-* Funktionen ohne Argumente::
-* Überblick über vorhandene musikalische Funktionen::
-@end menu
-
-@node Überblick über musikalische Funktionen
-@subsection Überblick über musikalische Funktionen
-@translationof Overview of music functions
+@node LilyPond-Codeabschnitte
+@section LilyPond-Codeabschnitte
+@translationof Lilypond code blocks
 
-Es ist einfach, eine Funktion zu erstellen, die Variablen
-im LilyPond-Code ersetzt.  Die allgemeine Form derartiger
-Funktionen ist
+Codeabschnitte in LilyPond sehen etwa so aus:
 
 @example
-function =
-#(define-music-function (parser location @var{var1} @var{var2}...@var{vari}... )
-                        (@var{var1-type?} @var{var2-type?}...@var{vari-type?}...)
-  #@{
-    @emph{...Noten...}
-  #@})
+  #@{ @var{Lilypond code} #@}
 @end example
 
-@noindent
-wobei
-
-@multitable @columnfractions .33 .66
-@item @var{vari}         @tab die @var{i}te Variable
-@item @var{vari-type?}   @tab die Art der @var{i}ten Variable
-@item @var{...Noten...}  @tab normaler LilyPond-Code, in dem Variablen 
-wie @code{#$var1} usw. benutzt werden.
-@end multitable
+Sie können überall eingesetzt werden, wo man Scheme-Code schreiben
+kann: der Scheme-Einleser wurde geändert, um LilyPond-Codeabschnitte
+zu akzeptieren und kann mit eingebetteten Scheme-Ausdrücken umgehen,
+die mit @code{$} und@w{ }@code{#} beginnen.
 
-Die folgenden Eingabetypen können als Variablen in einer musikalischen
-Funktion benutzt werden.  Diese Liste ist nicht vollständig -- siehe
-auch andere Dokumentationen über Scheme für weitere Variablenarten.
+Er extrahiert den LilyPond-Codeabschnitt und erstellt einen Aufruf
+zum LilyPond-Parser, welcher während der Prorammausführung zur
+Interpretation des LilyPond-Codeabschnittes aufgerufen wird.  Alle
+eingebetteten Scheme-Ausdrücke werden in der lokalen Umgebung des
+LilyPond-Codeabschnittes ausgeführt, sodass man Zugruff auf lokale
+Variablen und Funktionsparameter zu dem Zeitpunkt hat, an dem
+der LilyPond-Codeabschnitt geschrieben wird.
 
-@multitable @columnfractions .33 .66
-@headitem Eingabetyp           @tab @var{vari-type?}-Notation
-@item Ganzzahl                 @tab @code{integer?}
-@item Float (Dezimalzahl)      @tab @code{number?}
-@item Zeichenkette             @tab @code{string?}
-@item Textbeschriftung         @tab @code{markup?}
-@item Musikalischer Ausdruck   @tab @code{ly:music?}
-@item Ein Variablenpaar        @tab @code{pair?}
-@end multitable
+Ein LilyPond-Codeabschnitt kann jeden Inhalt haben, den man auf
+der rechten Seite einer Zuweisung einsetzt.  Zusätzlich entspricht
+ein leerer LilyPond-Abschnitt einem gültigen musikalischen Ausdruck,
+und ein LilyPond-Abschnitt, der mehrere musikalische Ereignisse enthält,
+wird in einen sequenziellen musikalischen Ausdruck umgewandelt.
 
-Die Argumente @code{parser} und @code{location} sind zwingend erforderlich
-und werden in einigen fortgeschrittenen Situationen eingesetzt.  Das
-Argument @code{parser} wird benutzt, um auf den Wert einer weiteren
-LilyPond-Variable zuzugreifen.  Das Argument @code{location} wird
-benutzt, um den @qq{Ursprung} des musikalischen Ausdrucks zu definieren, der von
-der musikalischen Funktion erzeugt wird.  Das hilft, wenn ein
-Syntaxfehler auftaucht: in solchen Fällen kann LilyPond mitteilen,
-an welcher Stelle in der Eingabedatei sich der Fehler befindet.
 
+@node Scheme-Funktionen
+@section Scheme-Funktionen
+@translationof Scheme functions
 
-@node Einfache Ersetzungsfunktionen
-@subsection Einfache Ersetzungsfunktionen
-@translationof Simple substitution functions
+@cindex Scheme-Funktionen (LilyPond syntax)
 
-Hier ist ein einfaches Beispiel:
+@emph{Scheme-Funktionen} sind Scheme-Prozeduren, die Scheme-Ausdrücke
+aus einer Eingabe erstellen können, die in LilyPond-Syntax geschrieben
+wurde.  Sie können in so gut wie allen Fällen aufgerufen werden, in
+denen es erlaubt ist, @code{#} zur Angabe eines Wertes in Scheme-Syntax
+einzusetzen.  Während Scheme auch eigene Funktionen besitzt, handelt
+% dieses kapitel von @emph{syntaktischen} Funktionen, Funktionen, die
+Argumente in LilyPond-Syntax annehmen.
 
-@lilypond[quote,verbatim,ragged-right]
-padText = #(define-music-function (parser location padding) (number?)
-  #{
-    \once \override TextScript #'padding = #$padding
-  #})
-
-\relative c''' {
-  c4^"piu mosso" b a b
-  \padText #1.8
-  c4^"piu mosso" d e f
-  \padText #2.6
-  c4^"piu mosso" fis a g
-}
-@end lilypond
-
-Musikalische Ausdrücke können auch ersetzt werden:
-
-@lilypond[quote,verbatim,ragged-right]
-custosNote = #(define-music-function (parser location note)
-                                     (ly:music?)
-  #{
-    \once \override Voice.NoteHead #'stencil =
-      #ly:text-interface::print
-    \once \override Voice.NoteHead #'text =
-      \markup \musicglyph #"custodes.mensural.u0"
-    \once \override Voice.Stem #'stencil = ##f
-    $note
-  #})
-
-{ c' d' e' f' \custosNote g' }
-@end lilypond
-
-Mehrere Variablen können benutzt werden:
-
-@lilypond[quote,verbatim,ragged-right]
-tempoPadded = #(define-music-function (parser location padding tempotext)
-  (number? string?)
-#{
-  \once \override Score.MetronomeMark #'padding = $padding
-  \tempo \markup { \bold $tempotext }
-#})
-
-\relative c'' {
-  \tempo \markup { "Low tempo" }
-  c4 d e f g1
-  \tempoPadded #4.0 #"High tempo"
-  g4 f e d c1
-}
-@end lilypond
+@menu
+* Definition von Scheme-Funktionen::
+* Benutzung von Scheme-Funktionen::
+* Leere Scheme-Funktionen::
+@end menu
 
+@node Definition von Scheme-Funktionen
+@subsection Definition von Scheme-Funktionen
+@translationof Scheme function definitions
 
-@node Paarige Ersetzungsfunktionen
-@subsection Paarige Ersetzungsfunktionen
-@translationof Paired substitution functions
+@funindex define-scheme-function
 
-Einige @code{\override}-Befehle benötigen ein Zahlenpaar
-(als @code{cons}-Zelle in Scheme bezeichnet).  Um beide Zahlen
-einer Funktion zuzuweisen, kann entweder die Variable @code{pair?}
-benutzt werden oder die @code{cons} in die musikalische Funktion
-eingefügt werden.
+Die übliche Form zur Definition von Scheme-Funktionen ist:
 
-@quotation
 @example
-manualBeam =
-#(define-music-function (parser location beg-end)
-                        (pair?)
-#@{
-  \once \override Beam #'positions = #$beg-end
-#@})
-
-\relative @{
-  \manualBeam #'(3 . 6) c8 d e f
-@}
+function =
+#(define-scheme-function
+     (parser location @var{Arg1} @var{Arg2} @dots{})
+     (@var{Typ1?} @var{Typ2?} @dots{})
+   @var{body})
 @end example
-@end quotation
 
 @noindent
-oder
-
-@lilypond[quote,verbatim,ragged-right]
-manualBeam =
-#(define-music-function (parser location beg end)
-                        (number? number?)
-#{
-  \once \override Beam #'positions = #(cons $beg $end)
-#})
-
-\relative {
-  \manualBeam #3 #6 c8 d e f
-}
-@end lilypond
-
-
-@node Mathematik in Funktionen
-@subsection Mathematik in Funktionen
-@translationof Mathematics in functions
-
-Musikalische Funktionen können neben einfachen Ersetzungen
-auch Scheme-Programmcode enthalten:
-
-@lilypond[quote,verbatim,ragged-right]
-AltOn = #(define-music-function (parser location mag) (number?)
-  #{ \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
-}
+wobei
 
-{ c'2 \AltOn #0.5 c'4 c'
-  \AltOn #1.5 c' c' \AltOff c'2 }
-@end lilypond
+@multitable @columnfractions .33 .66
+@item @code{parser}
+@tab ganz genau das Wort @code{parser} sein muss, damit LilyPond
+eine Umgebung (@code{#@{}@dots{}@code{#@}}) mit Zugriff
+auf den Parser bekommt.
+
+@item @code{@var{ArgN}}
+@tab @var{n}te Argument
+
+@item @code{@var{TypN?}}
+@tab eine Scheme-@emph{Typenprädikat}, für welches @code{@var{argN}}
+@code{#t} ausgeben muss.  Manche dieser Prädikate werden vom Parser
+besonders erkannt, siehe unten.  Es gibt auch eine Spezialform
+@code{(@emph{predicate?} @emph{default})}, um optionale Argumente
+anzugeben.  Wenn das eigentlich Argument fehlt, während die Funktion
+aufgerufen wird, wird der Standardwert anstelle eingesetzt.  Standardwerte
+werden bei ihrer Definition evaluiert (gilt auch für
+LilyPond-Codeabschnitte), so dass man besser einen speziellen Wert
+schreibt, den man einfach erkennen kann, wenn der Wert während der
+Ausführung der Position evaluiert weren soll.  Wenn man das Prädikat
+in Klammern setzt, aber  kein Standardwert folt, wird @code{#f}
+als Standard eingesetzt.  Standardwerte werden weder bei der Definition
+noch bei der Ausführung mit @emph{predicate?} verifiziert, sodass
+man selber verantworlich für funktionsfähige Werte ist.  Standardwerte,
+die musikalische Ausdrücke darstellen, werden kopiert und @code{origin}
+auf den Parameter @code{location} gesetzt.
+
+@item @code{@var{body}}
+@tab Eine Folge von Scheme-Formeln, die der Reihe nach ausgewertet
+werden, wobei die letzte als Ausgabewert der Scheme-Funktion eingesetzt
+wird.  Sie kann LilyPond-Codeabschnitte enthalten, eingeschlossen mit
+Raute-Klammern (@tie{}@w{@code{#@{@dots{}#@}}}@tie{}), wie beschrieben
+in @ref{LilyPond-Codeabschnitte}.  Innerhalb von LilyPond-Codeabschnitten
+wird mit @code{#} auf Funktionsargumente (etwa @samp{#Arg1}) verwiesen
+oder ein neuer Scheme-Ausdruck mit Funktionsargumenten begonnen
+(etwa @w{@samp{#(cons Arg1 Arg2)}}).  Wo normale Scheme-Ausdrücke mit
+@code{#} nicht funktionieren, kann man auf direkte Scheme-Ausdrücke
+zurückgreifen, die mit @code{$} begonnen werden (etwa @samp{$music}).
+
+Wenn die Funktion eine musikalische Funktion ausgibt, bekommt sie einen
+Wert von @code{origin}. zugewiesen.
+@end multitable
 
 @noindent
-Dieses Beispiel kann auch umformuliert werden, um musikalische Ausdrücke
-zu integrieren:
-
-@lilypond[quote,verbatim,ragged-right]
-withAlt = #(define-music-function (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 #})
-
-{ c'2 \withAlt #0.5 {c'4 c'}
-  \withAlt #1.5 {c' c'} c'2 }
-@end lilypond
-
-
-@node Leere Funktionen
-@subsection Leere Funktionen
-@translationof Void functions
-
-Eine musikalische Funktion muss einen musikalischen Ausdruck
-ausgeben, aber in manchen Fällen müssen Funktionen erstellt werden,
-die keine Notation enthalten (wie etwa eine Funktion, mit der
-man @qq{Point and Click} ausschalten kann).  Um das vornehmen zu
-können, wird ein @code{leere}r musikalischer Ausdruck ausgegeben.
-
-Das ist der Grund, warum die Form, die ausgegeben wird,
-@code{(make-music ...)} heißt.  Wird die Eigenschaft
-@code{'void} (engl. für @qq{leer}) auf @code{#t} gesetzt, wird der
-Parser angewiesen, den ausgegebenen musikalischen Ausdruck zu ignorieren.
-Der maßgebliche Teil der @code{'void}-Funktion ist also die Verarbeitung,
-die die Funktion vornimmt, nicht der musikalische Ausdruck, der ausgegeben
-wird.
+Einige Typenprädikate werden vom Parser besonders behandelt, weil
+er sonst die Argumente nicht zuverlässig erkennen könnte.  Im Moment
+handelt es sich um @code{ly:pitch?} und @code{ly:duration?}.
+
+Die Eignung der Argumente für alle anderen Prädikate wird festgestellt,
+indem das Prädikat aufgerufen wird, nachdem LilyPond es schon in einen
+Scheme-Ausdruck umgewandelt hat.  Demzufolge kann das Argument in
+Scheme-Syntax angegeben werden, wenn nötig (beginnend mit @code{#} oder
+als Result des Aufrufes einer Scheme-Funktion), aber LilyPond
+konvertiert auch eine Reihe von LilyPond-Strukturen nach Scheme,
+bevor dann tatsächlich die Prädikate überprüft werden.  Bei den
+letzteren handelt es sich im Moment um music (Noten), postevents,
+simple strings (einfache Zeichenketten mit oder ohne Anführungszeichen)
+numbers (Zahlen), markup (Beschriftung) und markup lists
+(Beschriftungslisten), score (Partitur), book (Buch), bookpart
+(Buchteil), Kontextdefinitions- und Ausgabedefinitionsumgebungen.
+
+Für einige Arten von Ausdrücken (wie die meisten Noten, die nicht
+in Klammern geschrieben werden) muss LilyPond weiter nach vorne
+schauen als der Ausdruck selber reicht, um das Ende des Ausdrucks
+zu bestimmen.  Wenn solche Ausdrücke für optionale Argumente mit
+einbezogen würden, indem ihre Prädikate ausgewählt würden, könnte
+LilyPond nicht mehr zurückgehen, wenn es feststellt, dass der
+Ausdruck nicht zu dem Parameter passt.  Darum müssen manche Formen
+von Noten möglicherweise in Klammern eingeschlossen werden, damit
+LilyPond sie akzeptiert.  Es gibt auch einige andere Mehrdeutigkeiten,
+die LilyPond durch Testen von Prädikatfunktionen eingrenzt:
+ist etwa @samp{-3} die Anmerkung für einen Fingersatz oder eine
+negative Zahl? Ist @code{"a" 4} im Gesangskontext eine Zeichenkette
+gefolgt von einer Zahl oder ein Gesangstextereignis mit der Dauer
+@code{4}?  LilyPond entscheidet, indem es Prädaikate befragt.  Das
+heißt, dass man zu durchlässige Prädikate wie @code{scheme?}
+vermeiden sollte, wenn man eine bestimmmte Verwendung beabsichtigt
+und nicht nur eine Funktion für die allgemeine Verwendung schreibt.
+
+Eine Liste der möglichen vordefinierten Typenprädikte findet sich in
+@ruser{Vordefinierte Typenprädikate}.
+
+@seealso
+
+Notationsreferenz
+@ruser{Vordefinierte Typenprädikate}.
+
+Installierte Dateien:
+@file{lily/music-scheme.cc},
+@file{scm/c++.scm},
+@file{scm/lily.scm}.
+
+
+@node Benutzung von Scheme-Funktionen
+@subsection Benutzung von Scheme-Funktionen
+@translationof Scheme function usage
+
+Scheme-Funktionen können überall aufgerufen werden, wo ein
+Scheme-Ausdruck beginnend mit @code{#} geschrieben werden kann.
+Man kann eine Scheme-Funktion aufrufen, indem man ihrer Bezeichnung
+@code{\} voranstellt und Argumente hinten anfügt.  Wenn ein optionales
+Argumentenprädikat nicht mit einem Argument übereinstimmt, lässt
+LilyPond dieses und alle folgenden Argumente aus und ersetzt sie
+durch ihre Standardwerte und @qq{speichert} das Argument, das nicht
+gepasst hat, bis zum nächsten zwingenden Argument.  Da das gespeicherte
+Argument auch noch irgendwo untergebracht werden muss, werden
+optionale Argumente nicht wirklich als optional angesehen, es sei denn,
+sie werden von einem zwingenden Argument gefolgt.
+
+Es gibt eine Ausnahme:  Wenn man @code{\default} anstelle eines optionalen
+Arguments schreibt, wird dieses und alle folgenden Argumente ausgelassen
+und durch ihre Standardwerte ersetzt.  Das funktioniert auch, wenn kein
+zwingendes Argument folgt, weil @code{\default} nicht gespeichert werden
+muss.  Die Befehle @code{mark} und @code{key} benützten diesen Trick,
+um ihr Standardverhalten zur verfügung zu stellen, wenn sie
+@code{\default} nachgestellt haben.
+
+Abgesehen von Stellen, wo ein Scheme-Wert benötigt ist, gibt es
+wenige Stellen, wo @code{#}-Ausdrücke zwar für ihre (Neben-)Wirkung
+akzeptiert und ausgewertet, aber ansonsten ignoriert werden.  Meistens
+handelt es sich dabei um Stellen, wo eine Zuweisung auch in Ordnung
+wäre.
+
+Weil es eine schlechte Idee ist, einen Wert auszugeben, der in einigen
+Kontexten misinterpretiert werden könnte, sollte man Scheme-Funktionen
+nur in den Fällen benutzen, in welchen sie immer einen sinnvollen
+Wert ausgeben, und leere Scheme-Funktionen an anderen stellen
+einsetzen.  Siehe auch @pxref{Leere Scheme-Funktionen}.
+
+
+@node Leere Scheme-Funktionen
+@subsection Leere Scheme-Funktionen
+@translationof Void scheme functions
+
+@funindex define-void-function
+@funindex \void
+
+Manchmal wird eine Prozedur ausgeführt, um eine Aktion zu machen und nicht,
+um einen Wert auszugeben.  Einige Programmiersprachen (wie C oder Scheme)
+setzen Funktionen für beide Konzepte ein und verwerfen einfach den
+Rückgabewert (normalerweise, indem einem Ausdruck erlaubt wird, als
+Aussage zu funktionieren und das Ergebnis ignoriert wird).  Das ist
+klug, aber auch fehleranfällig:  die meisten C-Kompilierer haben heutzutage
+Warnungen für verschiedene nicht-@qq{gültige} Ausdrücke, die verworfen
+werden.  Viele Funktionen, die eine Aktion ausführen, werden von den
+Scheme-Standards als Funktionen betrachtet, deren Wiedergabewert unspezifiert
+ist.  Der Scheme-Interpreter von LilyPond, Guile, hat den eindeutigen
+Wert @code{*unspecified*}, der normalerweise (etwa wenn man @code{set!}
+direkt auf eine Variable anwendet), aber leider nicht konsistent in
+diesen Fällen ausgegeben wird.
+
+Indem man eine LilyPond-Funktion mit @code{define-void-function} definiert,
+geht man sicher, dass dieser Spezialwert (der einzige Wert, der das
+Prädikat @code{void?} erfüllt) wiedergegeben wird.
 
 @example
 noPointAndClick =
-#(define-music-function (parser location) ()
-   (ly:set-option 'point-and-click #f)
-   (make-music 'SequentialMusic 'void #t))
+#(define-void-function
+     (parser location)
+     ()
+   (ly:set-option 'point-and-click #f))
 ...
-\noPointAndClick   % disable point and click
+\noPointAndClick   % Point and Click deaktivieren
 @end example
 
-
-@node Funktionen ohne Argumente
-@subsection Funktionen ohne Argumente
-@translationof Functions without arguments
-
-In den meisten Fällen sollten Funktionen ohne Argumente mit einer
-Variable notiert werden:
+Wenn man einen Ausdruck nur wegen seiner Nebeneffekte evaluieren will
+und keinen der möglicherweise ausgegebenen Werte interpretiert haben
+will, kann man dem Ausdruck @code{\void} voranstellen:
 
 @example
-dolce = \markup@{ \italic \bold dolce @}
+\void #(hashq-set! eine-Tabelle ein-Schlüssel ein-Wert)
 @end example
 
-In einigen wenigen Fällen kann es aber auch sinnvoll sein, eine
-musikalische Funktion ohne Argumente zu erstellen:
-
-@example
-displayBarNum =
-#(define-music-function (parser location) ()
-   (if (eq? #t (ly:get-option 'display-bar-numbers))
-       #@{ \once \override Score.BarNumber #'break-visibility = ##f #@}
-       #@{#@}))
-@end example
-
-Damit auch wirklich Taktzahlen angezeigt werden, wo die
-Funktion eingesetzt wurde, muss @command{lilypond} mit
-der Option
-
-@example
-lilypond -d display-bar-numbers Dateiname.ly
-@end example
-
-@noindent
-aufgerufen werden.
-
-
-@node Überblick über vorhandene musikalische Funktionen
-@subsection Überblick über vorhandene musikalische Funktionen
-@translationof Overview of available music functions
-
-@c fixme ; this should be move somewhere else?
-Die folgenden Befehle sind musikalische Funktionen:
-
-@include identifiers.tely
+Auf diese Weise kann man sicher sein, dass LilyPond dem ausgegebenen
+Wert keine Bedeutung zuweist, unabhängig davon, wo er angetroffen wird.
+Das funktioniert auch für musikalische Funktionen wie @code{\displayMusic}.
 
 
+@node Musikalische Funktionen
+@section Musikalische Funktionen
+@translationof Music functions
 
-@node Schnittstelle für Programmierer
-@section Schnittstelle für Programmierer
-@translationof Programmer interfaces
+@cindex musikalische Funktionen
 
-Dieser Abschnitt zeigt, wie LilyPond und
-Scheme gemischt werden können.
+@emph{Musikalische Funktionen} sind Scheme-Prozeduren,
+die musikalische Ausdrücke automatisch erstellen können und dadurch die
+Eingabedatei maßgeblich vereinfachen können.
 
 @menu
-* Eingabevariablen und Scheme::
-* Interne Repräsentation der Musik::
+* Definition der musikalischen Funktionen::
+* Benutzung von musikalischen Funktionen::
+* Einfache Ersetzungsfunktionen::
+* Mittlere Ersetzungsfunktionen::
+* Mathematik in Funktionen::
+* Funktionen ohne Argumente::
+* Leere musikalische Funktionen::
 @end menu
 
 
-@node Eingabevariablen und Scheme
-@subsection Eingabevariablen und Scheme
-@translationof Input variables and Scheme
+@node Definition der musikalischen Funktionen
+@subsection Definition der musikalischen Funktionen
+@translationof Music function definitions
 
-Das Eingabeformat unterstützt die Notation von Variablen: im
-folgenden Beispiel wird ein musikalischer Ausdruck einer Variable
-mit der Bezeichnung @code{traLaLa} zugewiesen:
+Die allgemeine Form zur Definition musikalischer Funktionen ist:
 
 @example
-traLaLa = @{ c'4 d'4 @}
-@end example
-
-Der Geltungsbereich von Variablen ist beschränkt: im folgenden
-Beispiel enthält die @code{\layout}-Umgebung auch eine
-@code{traLaLa}-vVariable, die unabhängig von der äußeren
-@code{\traLaLa}-Variable ist:
-
-@example
-traLaLa = @{ c'4 d'4 @}
-\layout @{ traLaLa = 1.0 @}
-@end example
-
-Grundsätzlich ist jede Eingabedatei ein Geltungsbereich, und
-alle @code{\header}-, @code{\midi}- und @code{\layout}-Umgebungen
-sind Geltungsbereiche, die unterhalb des globalen Geltungsbereiches
-angeordnet sind.
-
-Sowohl Variablen als auch Geltungsbereiche sind in Form des
-GUILE-Modulsystems implementiert.  Ein anonymes Scheme-Modul
-wird an jeden Geltungsbereich angehängt.  Eine Zuweisung der Form
-
-@example
-traLaLa = @{ c'4 d'4 @}
-@end example
-
-@noindent
-wird intern in die Scheme-Definition
-
-@example
-(define traLaLa @var{Scheme-Wert von `@code{... }'})
+function =
+#(define-music-function
+     (parser location @var{Arg1} @var{Arg2} @dots{})
+     (@var{Typ1?} @var{Typ2?} @dots{})
+   @var{body})
 @end example
 
 @noindent
-umgewandelt.
-
-Das bedeutet, dass Eingabe- und Scheme-Variablen frei vermischt
-werden können.  Im nächsten Beispiel wird ein Notenfragment in
-der Variable @code{traLaLa} gespeichert und mithilfe von Scheme
-dupliziert.  Das Ergebnis wird in eine @code{\score}-Umgebung
-mit der zweiten Variable @code{twice} integriert:
-
-@lilypond[verbatim]
-traLaLa = { c'4 d'4 }
-
-%% dummy action to deal with parser lookahead
-#(display "this needs to be here, sorry!")
-
-#(define newLa (map ly:music-deep-copy
-  (list traLaLa traLaLa)))
-#(define twice
-  (make-sequential-music newLa))
-
-{ \twice }
-@end lilypond
-
-In diesem Beispiel geschieht die Zuweisung, nachdem der Parser
-festgestellt hat, dass nichts interessantes mehr nach
-@code{traLaLa = @{ ... @}} vorkommt.  Ohne die Pseudovariable
-in dem Beispiel würde die @code{newLa}-Definition ausgeführt
-werden, bevor @code{traLaLa} definiert ist, was zu einem
-Syntax-Fehler führen würde.
-
-Das obige Beispiel zeigt, wie man musikalische Ausdrücke
-von der Eingabe in den Scheme-Interpretierer @qq{exportieren}
-kann.  Es geht auch in die andere Richtung.  Indem man einen
-Scheme-Wert in die Funktion @code{ly:export} einpackt, wird
-der Scheme-Wert interpretiert als ob er in LilyPond-Syntax
-notiert worden wäre.  Anstatt @code{\twice} zu definieren,
-hätte man also auch schreiben können:
-
-@example
-...
-@{ #(ly:export (make-sequential-music (list newLa))) @}
-@end example
+analot zu Scheme-Funktionen, siehe @ref{Definition von Scheme-Funktionen}.
+In der Mehrzahl der Fälle ist @var{body} ein LilyPond-Codeabschnitt (siehe
+@ref{LilyPond-Codeabschnitte}.
 
-Scheme-Code wird sofort ausgewertet, wenn der Parser darauf
-stößt.  Um Scheme-Code in einem Makro zu definieren (das dann
-erst später aufgerufen werden soll), müssen leere Funktionen
-benutzt werden (siehe @ref{Leere Funktionen}) oder das Folgende:
+Eine Liste der möglichen Typenprädikate findet sich in
+@ruser{Vordefinierte Typenprädikate}.
 
-@example
-#(define (nopc)
-  (ly:set-option 'point-and-click #f))
-
-...
-#(nopc)
-@{ c'4 @}
-@end example
+@seealso
 
-@knownissues
+Notationsreferenz:
+@ruser{Vordefinierte Typenprädikate}.
 
-Scheme- und LilyPond-Variablen können im LilyPond-Modus mit der
-@code{--safe}-Option nicht vermischt werden.
+Installierte Dateien:
+@file{lily/music-scheme.cc},
+@file{scm/c++.scm},
+@file{scm/lily.scm}.
 
 
-@node Interne Repräsentation der Musik
-@subsection Interne Repräsentation der Musik
-@translationof Internal music representation
+@node Benutzung von musikalischen Funktionen
+@subsection Benutzung von musikalischen Funktionen
+@translationof Music function usage
 
-Wenn ein musikalischer Ausdruck ausgewertet wird, wird er in eine
-Anzahl von musikalischen Scheme-Objekten konvertiert.  Die Eigenschaft, die ein
-musikalisches Objekt definiert, ist, dass es Zeit einnimmt.  Zeit ist
-eine rationale Zahl, die die Länge eines Stückes in ganzen Noten
-misst.
+Musikalische Funktionen können zur Zeit an verschiedenen Stellen benützt
+werden.  Abhängig davon, wo sie eingesetzt werden, gibt es Begrenzungen,
+damit die Funktionen eindeutig interpretiert werden können.  Das Resultat,
+das eine musikalische Funktion wiedergibt, muss mit dem Kontext kompatibel
+sein, indem sie aufgerufen wird.
 
-Ein musikalisches Objekt hat drei Typusarten:
 @itemize
 @item
-musikalische Bezeichnung: Jeder musikalische Ausdruck hat eine Bezeichnung.
-Eine Note beispielsweise führt zu einem @rinternals{NoteEvent} und
-@code{\simultaneous} führt zu @rinternals{SimultaneousMusic}.  Eine Liste
-aller möglichen Ausdrücke findet sich in der Referenz der Interna, unter
-@rinternals{Music expressions}.
-
-@item
-@q{Typ} oder Schnittstelle:  Jede musikalische Bezeichnung hat mehrere
-@qq{Typen} oder Schnittstellten, beispielsweise ist eine Note ein
-@code{event}, ober sie ist auch ein @code{note-event}, ein
-@code{rhythmic-event} und ein @code{melodic-event}.  Alle diese
-Notationsklassen finden sich in der Referenz der Interna unter
-@rinternals{Music classes}.
+Auf höchster Ebene in einer musikalischen Funktion.  Keine Begrenzungen.
 
 @item
-C++-Objekt:  Jedes musikalische Objekt wird von einem Objekt der
-C++-Klasse @code{Music} repräsentiert.
-@end itemize
-
-Die eigentlich Information eines musikalischen Ausdrucks ist in
-Eigenschaften gespeichert.  Ein @rinternals{NoteEvent} hat zum
-Beispiel @code{pitch}- und @code{duration}-Eigenschaften, die
-die Tonhöhe und die Dauer dieser Note speichern.  Eine Liste aller
-verfügbaren Eigenschaften findet sich in der Referenz der Interna unter
-@rinternals{Music properties}.
-
-Ein zusammengesetzter musikalischer Ausdruck ist ein musikalisches
-Objekt, das andere Objekte in seinen Eigenschaften enthält.  Eine Liste
-der Objekte kann in der @code{elements}-Eigenschaft eines
-musikalischen Objektes gespeichert werden, oder ein einziges
-@qq{Kind}-Objekt in der @code{element}-Eigenschaft.  Sa hat etwa
-@rinternals{SequentialMusic} seine @qq{Kinder} in @code{elements},
-und @rinternals{GraceMusic} hat sein einziges Argument in
-@code{element}.  Der Hauptteil einer Wiederholung wird in der
-@code{element}-Eigenschaft von @rinternals{RepeatedMusic} gespeichert,
-und die Alternativen in @code{elements}.
-
-
-
-@node Komplizierte Funktionen erstellen
-@section Komplizierte Funktionen erstellen
-@translationof Building complicated functions
-
-Dieser Abschnitt zeigt, wie man Information zusammensucht,
-um komplizierte musikalische Funktionen  zu erstellen.
-
-@menu
-* Musikalische Funktionen darstellen::
-* Eigenschaften von Musikobjekten::
-* Verdoppelung einer Note mit Bindebögen (Beispiel)::
-* Artikulationszeichen zu Noten hinzufügen (Beispiel)::
-@end menu
-
-
-@node Musikalische Funktionen darstellen
-@subsection Musikalische Funktionen darstellen
-@translationof Displaying music expressions
-
-@cindex interne Speicherung
-@cindex Musikausdrücke anzeigen
-@cindex Anzeigen von Musikausdrücken
-
-@funindex displayMusic
-@funindex \displayMusic
-
-Wenn man eine musikalische Funktion erstellt, ist es oft
-hilfreich sich anzuschauen, wie musikalische Funktionen
-intern gespeichert werden.  Das kann mit der Funktion
-@code{\displayMusic} erreicht werden:
-
-@example
-@{
-  \displayMusic @{ c'4\f @}
-@}
-@end example
-
-@noindent
-zeigt:
-
-@example
-(make-music
-  'SequentialMusic
-  'elements
-  (list (make-music
-          'EventChord
-          'elements
-          (list (make-music
-                  'NoteEvent
-                  'duration
-                  (ly:make-duration 2 0 1 1)
-                  'pitch
-                  (ly:make-pitch 0 0 0))
-                (make-music
-                  'AbsoluteDynamicEvent
-                  'text
-                  "f")))))
-@end example
-
-Normalerweise gibt LilyPond diese Ausgabe auf der Konsole mit
-allen anderen Nachrichten aus.  Um die wichtigen Nachrichten
-in einer Datei zu speichern, kann die Ausgabe in eine Datei
-umgeleitet werden:
-
-@example
-lilypond file.ly >display.txt
-@end example
-
-Mit etwas Umformatierung ist die gleiche Information sehr viel
-einfacher zu lesen:
-
-@example
-(make-music 'SequentialMusic
-  'elements (list (make-music 'EventChord
-                    'elements (list (make-music 'NoteEvent
-                                      'duration (ly:make-duration 2 0 1 1)
-                                      'pitch (ly:make-pitch 0 0 0))
-                                    (make-music 'AbsoluteDynamicEvent
-                                      'text "f")))))
-@end example
-
-Eine musikalische @code{@{ ... @}}-Sequenz hat die Bezeichnung
-@code{SequentialMusic} und ihre inneren Ausdrücke werden als
-Liste in seiner @code{'elements}-Eigenschaft gespeichert.  Eine
-Note ist als als ein @code{EventChord}-Ausdruck dargestellt,
-der ein @code{NoteEvent}-Objekt (welches Dauer und
-Tonhöhe speichert) und zusätzliche Information enthält (in
-diesem Fall ein @code{AbsoluteDynamicEvent} mit einer
-@code{"f"}-Text-Eigenschaft.
-
-
-@node Eigenschaften von Musikobjekten
-@subsection Eigenschaften von Musikobjekten
-@translationof Music properties
-
-Das @code{NoteEvent}-Objekt ist das erste Objekt der
-@code{'elements}-Eigenschaft von @code{someNote}.
+Als ein Nach-Ereignis, explizit begonnen mit einem Richtungsindikator
+(einer von @code{-}, @code{^}, @w{und @code{_}}).  Wichtig dabei ist,
+dass musikalische Funktionen, die das Nachereignis ausgeben, als
+normale Noten akzeptiert werden.  Dabei erhält man ein Resultat, das
+etwa folgendem entspricht:
 
 @example
-someNote = c'
-\displayMusic \someNote
-===>
-(make-music
-  'EventChord
-  'elements
-  (list (make-music
-          'NoteEvent
-          'duration
-          (ly:make-duration 2 0 1 1)
-          'pitch
-          (ly:make-pitch 0 0 0))))
+s 1*0-\fun
 @end example
 
-Die @code{display-scheme-music}-Funktion ist die Funktion, die von
-@code{\displayMusic} eingesetzt wird, um die Scheme-Repräsentation
-eines musikalischen Ausdrucks anzuzeigen.
+In diesem Fall kann man keinen @emph{offenen} musikalischen Ausdruck als
+letztes Argument einsetzen, also ein Argument, das in einem musikalischen
+Ausdruck schließt, der weitere Nach-Ereignisse akzeptieren kann.
 
-@example
-#(display-scheme-music (first (ly:music-property someNote 'elements)))
-===>
-(make-music
-  'NoteEvent
-  'duration
-  (ly:make-duration 2 0 1 1)
-  'pitch
-  (ly:make-pitch 0 0 0))
-@end example
-
-Danach wird die Tonhöhe der Note von der @code{'pitch}-Eigenschaft
-des @code{NoteEvent}-Objektes gelesen:
+@item
+Als Element eines Akkordes.  Der ausgegebene Ausdruck muss vom Typ
+@code{rhythmic-event} sein, wahrscheinlich auch @code{NoteEvent}.
 
-@example
-#(display-scheme-music
-   (ly:music-property (first (ly:music-property someNote 'elements))
-                      'pitch))
-===>
-(ly:make-pitch 0 0 0)
-@end example
+@end itemize
 
-Die Tonhöhe einer Note kann geändert werden, indem man diese
-@code{'pitch}-Eigenschaft umdefiniert:
+@noindent
+Die besonderen Regeln für noch nicht abgearbeitete Argumente machen es
+möglich, polymorphe Funktionen wie @code{\tweak} zu schreiben,
+die auf unterschiedliche Konstruktionen angewendet werden können.
 
-@funindex \displayLilyMusic
-@funindex displayLilyMusic
 
-@example
-#(set! (ly:music-property (first (ly:music-property someNote 'elements))
-                          'pitch)
-       (ly:make-pitch 0 1 0)) ;; Die Tonhöhen auf d' verändern.
-\displayLilyMusic \someNote
-===>
-d'
-@end example
+@node Einfache Ersetzungsfunktionen
+@subsection Einfache Ersetzungsfunktionen
+@translationof Simple substitution functions
 
+Einfache Ersetzungsfunktionen sind musikalische Funktionen, deren
+musikalische Ausgabe-Funktion im LilyPond-Format geschrieben ist
+und Funktionsargumente in der Ausgabefunktion enthält.  Sie werden
+beschrieben in @ruser{Beispiele der Ersetzungsfunktionen}
 
-@node Verdoppelung einer Note mit Bindebögen (Beispiel)
-@subsection Verdoppelung einer Note mit Bindebögen (Beispiel)
-@translationof Doubling a note with slurs (example)
 
-In diesem Abschnitt soll gezeigt, werden, wie man eine
-Funktion erstellt, die eine Eingabe wie @code{a}
-nach @code{a( a)} umdefiniert.  Dazu wird zuerst die
-interne Repräsentation der Musik betrachtet, die
-das Endergebnis darstellt:
+@node Mittlere Ersetzungsfunktionen
+@subsection Mittlere Ersetzungsfunktionen
+@translationof Intermediate substitution functions
 
-@example
-\displayMusic@{ a'( a') @}
-===>
-(make-music
-  'SequentialMusic
-  'elements
-  (list (make-music
-          'EventChord
-          'elements
-          (list (make-music
-                  'NoteEvent
-                  'duration
-                  (ly:make-duration 2 0 1 1)
-                  'pitch
-                  (ly:make-pitch 0 5 0))
-                (make-music
-                  'SlurEvent
-                  'span-direction
-                  -1)))
-        (make-music
-          'EventChord
-          'elements
-          (list (make-music
-                  'NoteEvent
-                  'duration
-                  (ly:make-duration 2 0 1 1)
-                  'pitch
-                  (ly:make-pitch 0 5 0))
-                (make-music
-                  'SlurEvent
-                  'span-direction
-                  1)))))
-@end example
+Mittlere Ersetzungsfunktionen setzen sich aus einer Mischung von
+Scheme-Code und LilyPond-Code in der musikalischen Ausgabe-Funktion
+zusammen.
 
-Eine schlechte Nachricht ist, dass die
-@code{SlurEvent}-Ausdrücke @qq{innerhalb}
-der Noten (bzw. innerhalb der
-@code{EventChord}-Ausdrücke) hinzugefügt werden müssen.
+Einige @code{\override}-Befehle benötigen ein Zahlenpaar
+(als @code{cons}-Zelle in Scheme bezeichnet).
 
-Jetzt folgt eine Betrachtung der Eingabe:
+Das Paar kann direkt an die musikalische Funktion
+mit der Variable @code{pair?} weitergeleitet werden:
 
 @example
-(make-music
-  'SequentialMusic
-  'elements
-  (list (make-music
-          'EventChord
-          'elements
-          (list (make-music
-                  'NoteEvent
-                  'duration
-                  (ly:make-duration 2 0 1 1)
-                  'pitch
-                  (ly:make-pitch 0 5 0))))))
+manualBeam =
+#(define-music-function
+     (parser location beg-end)
+     (pair?)
+   #@{
+     \once \override Beam.positions = #beg-end
+   #@})
+
+\relative c' @{
+  \manualBeam #'(3 . 6) c8 d e f
+@}
 @end example
 
-In der gewünschten Funktion muss also dieser Ausdruck
-kopiert werden (sodass zwei Noten vorhanden sind, die
-eine Sequenz bilden), dann müssen @code{SlurEvent}
-zu der @code{'elements}-Eigenschaft jeder Noten hinzugefügt
-werden, und schließlich muss eine @code{SequentialMusic}
-mit den beiden @code{EventChords} erstellt werden.
-
-@example
-doubleSlur = #(define-music-function (parser location note) (ly:music?)
-         "Return: @{ note ( note ) @}.
-         `note' is supposed to be an EventChord."
-         (let ((note2 (ly:music-deep-copy note)))
-           (set! (ly:music-property note 'elements)
-                 (cons (make-music 'SlurEvent 'span-direction -1)
-                       (ly:music-property note 'elements)))
-           (set! (ly:music-property note2 'elements)
-                 (cons (make-music 'SlurEvent 'span-direction 1)
-                       (ly:music-property note2 'elements)))
-           (make-music 'SequentialMusic 'elements (list note note2))))
-@end example
+Anstelle dessen können auch die Zahlen, aus denen das Paar besteht,
+einzeln als eigenständige Argumente weitergeleitet und der
+Scheme-Code, der das Paar erstellt, in die musikalische Funktion
+augenommen werden:
 
+@lilypond[quote,verbatim,ragged-right]
+manualBeam =
+#(define-music-function
+     (parser location beg end)
+     (number? number?)
+   #{
+     \once \override Beam.positions = #(cons beg end)
+   #})
+
+\relative c' {
+  \manualBeam #3 #6 c8 d e f
+}
+@end lilypond
 
-@node Artikulationszeichen zu Noten hinzufügen (Beispiel)
-@subsection Artikulationszeichen zu Noten hinzufügen (Beispiel)
-@translationof Adding articulation to notes (example)
 
-Am einfachsten können Artikulationszeichen zu Noten
-hinzugefügt werden, indem man zwei musikalische Funktionen
-in einen Kontext einfügt, wie erklärt in
-@ref{Kontexte erstellen}.  Hier soll jetzt eine musikalische
-Funktion entwickelt werden, die das vornimmt.
+@node Mathematik in Funktionen
+@subsection Mathematik in Funktionen
+@translationof Mathematics in functions
 
-Eine @code{$variable} innerhalb von @code{#@{...#@}} ist das
-gleiche wie die normale Befehlsform @code{\variable} in
-üblicher LilyPond-Notation.  Es ist bekannt dass
+Musikalische Funktionen können neben einfachen Ersetzungen
+auch Scheme-Programmcode enthalten:
 
-@example
-@{ \music -. -> @}
-@end example
+@lilypond[quote,verbatim,ragged-right]
+AltOn =
+#(define-music-function
+     (parser location mag)
+     (number?)
+   #{
+     \override Stem.length = #(* 7.0 mag)
+     \override NoteHead.font-size =
+       #(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
+   #})
 
-@noindent
-in LilyPond nicht funktioniert.  Das Problem könnte vermieden
-werden, indem das Artikulationszeichen an eine Pseudonote
-gehängt wird:
+AltOff = {
+  \revert Stem.length
+  \revert NoteHead.font-size
+}
 
-@example
-@{ << \music s1*0-.-> @}
-@end example
+\relative c' {
+  c2 \AltOn #0.5 c4 c
+  \AltOn #1.5 c c \AltOff c2
+}
+@end lilypond
 
 @noindent
-aber in diesem Beispiel soll gezeigt werden, wie man das in
-Scheme vornimmt.  Zunächst wird die Eingabe und die gewünschte
-Ausgabe examiniert:
-
-@example
-%  Eingabe
-\displayMusic c4
-===>
-(make-music
-  'EventChord
-  'elements
-  (list (make-music
-          'NoteEvent
-          'duration
-          (ly:make-duration 2 0 1 1)
-          'pitch
-          (ly:make-pitch -1 0 0))))
-=====
-%  gewünschte Ausgabe
-\displayMusic c4->
-===>
-(make-music
-  'EventChord
-  'elements
-  (list (make-music
-          'NoteEvent
-          'duration
-          (ly:make-duration 2 0 1 1)
-          'pitch
-          (ly:make-pitch -1 0 0))
-        (make-music
-          'ArticulationEvent
-          'articulation-type
-          "marcato")))
-@end example
+Dieses Beispiel kann auch umformuliert werden, um musikalische Ausdrücke
+zu integrieren:
 
-Dabei ist zu sehen, dass eine Note (@code{c4}) als @code{EventChord}
-repräsentiert ist, mit einem @code{NoteEvent}-Ausdruck in ihrer
-Elementenliste.  Um eine Marcato-Artikulation hinzuzufügen, muss
-ein @code{ArticulationEvent}-Ausdruck zu der Elementeigenschaft
-des @code{EventChord}-Ausdrucks hinzugefügt werden.
+@lilypond[quote,verbatim,ragged-right]
+withAlt =
+#(define-music-function
+     (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
+   #})
+
+\relative c' {
+  c2 \withAlt #0.5 { c4 c }
+  \withAlt #1.5 { c c } c2
+}
+@end lilypond
 
-Um diese Funktion zu bauen, wird folgendermaßen begonnen:
 
-@example
-(define (add-marcato event-chord)
-  "Add a marcato ArticulationEvent to the elements of `event-chord',
-  which is supposed to be an EventChord expression."
-  (let ((result-event-chord (ly:music-deep-copy event-chord)))
-    (set! (ly:music-property result-event-chord 'elements)
-          (cons (make-music 'ArticulationEvent
-                  'articulation-type "marcato")
-                (ly:music-property result-event-chord 'elements)))
-    result-event-chord))
-@end example
+@node Funktionen ohne Argumente
+@subsection Funktionen ohne Argumente
+@translationof Functions without arguments
 
-Die erste Zeile definiert eine Funktion in Scheme: Die Bezeichnung
-der Funktion ist @code{add-marcato} und sie hat eine Variable
-mit der Bezeichnung @code{event-chord}.  In Scheme geht der Typ
-einer Variable oft direkt aus der Bezeichnung hervor (das ist auch
-eine gute Methode für andere Programmiersprachen).
+In den meisten Fällen sollten Funktionen ohne Argumente mit einer
+Variable notiert werden:
 
 @example
-"Add a marcato..."
+dolce = \markup@{ \italic \bold dolce @}
 @end example
 
-@noindent
-ist eine (englische) Beschreibung, was diese Funktion tut.  Sie ist
-nicht unbedingt notwendig, aber genauso wie klare Variablen-Bezeichnungen
-ist auch das eine gute Methode.
+In einigen wenigen Fällen kann es aber auch sinnvoll sein, eine
+musikalische Funktion ohne Argumente zu erstellen:
 
 @example
-(let ((result-event-chord (ly:music-deep-copy event-chord)))
+displayBarNum =
+#(define-music-function
+     (parser location)
+     ()
+   (if (eq? #t (ly:get-option 'display-bar-numbers))
+       #@{ \once \override Score.BarNumber.break-visibility = ##f #@}
+       #@{#@}))
 @end example
 
-@code{let} wird benutzt, um die lokalen Variablen zu definieren.  Hier
-wird eine lokale Variable benutzt: @code{result-event-chord}.  Sie erhält
-den Wert @code{(ly:music-deep-copy event-chord)}.  @code{ly:music-deep-copy}
-ist eine LilyPond-spezifische Funktion, die wie alle Funktionen mit dem
-Präfix @code{ly:} versehen ist.  Sie wird benutzt, um eine Kopie eines
-musikalischen Ausdrucks anzufertigen.  Hier wird @code{event-chord}
-(der Parameter der Funktion) kopiert.  Die Funktion soll ja nur ein
-Artikulationszeichen an einen @code{EventChord} gehängt werden, deshalb ist es besser,
-den @code{EventChord}, der als Argument gegeben wurde, nicht zu
-verändern, weil er woanders benutzt werden könnte.
-
-Jetzt gibt es @code{result-event-chord}, wobei es sich um einen
-@code{NoteEventChord}-Ausdruck handelt, welcher gleichzeitig eine Kopie
-von @code{event-chord} ist.  Das Makro wird seiner Eigenschaftsliste
-hinzugefügt:
+Damit auch wirklich Taktzahlen angezeigt werden, wo die
+Funktion eingesetzt wurde, muss @command{lilypond} mit
+der Option
 
 @example
-(set! place new-value)
+lilypond -d display-bar-numbers Dateiname.ly
 @end example
 
-Was in diesem Fall @qq{gesetzt} werden soll (@qq{place}) ist die
-@q{elements}-Eigenschaft des @code{result-event-chord}-Ausdrucks.
+@noindent
+aufgerufen werden.
 
-@example
-(ly:music-property result-event-chord 'elements)
-@end example
 
-@code{ly:music-property} ist die Funktion, mit der musikalische
-Eigenschaften erreicht werden können (die @code{'elements},
-@code{'duration}, @code{'pitch} usw., die in der Ausgabe von
-@code{\displayMusic} weiter oben angezeigt werden).  Der neue
-Wert ist, was ehemals die Elementeigenschaft war, mit einem
-zusätzlichen Element: dem @code{ArticulationEvent}-Ausdruck,
-der aus der Ausgabe von
-@code{\displayMusic} kopiert werden kann:
+@node Leere musikalische Funktionen
+@subsection Leere musikalische Funktionen
+@translationof Void music functions
 
-@example
-(cons (make-music 'ArticulationEvent
-        'articulation-type "marcato")
-      (ly:music-property result-event-chord 'elements))
-@end example
+Eine musikalische Funktion muss einen musikalischen Ausdruck
+ausgeben.  Wenn man eine Funktion nur für ihre Nebeneffekte
+ausführt, sollte man @code{define-void-function} benützen.
+Es kann aber auch Fälle geben, in denen man teilweise eine
+musikalische Funktion erstellen will, teilweise aber nicht
+(wie im vorherigen Beispiel).  Indem man eine leere (@code{void})
+Funktion mit  @code{#@{ #@}} ausgibt, wird das erreicht.
 
-@code{cons} wird benutzt, um ein Element zu einer Liste hinzuzufügen,
-ohne dass die originale Liste verändert wird.  Das ist es, was die
-Funktion tun soll:  die gleiche Liste, aber mit dem neuen
-@code{ArticulationEvent}-Ausdruck.  Die Reihenfolge innerhalb
-der Elementeeigenschaft ist hier nicht relevant.
 
-Wenn schließlich die Marcato-Artikulation zu der entsprechenden
-@code{elements}-Eigenschaft hinzugefügt ist, kann
-@code{result-event-chord} ausgegeben werden, darum die letzte Zeile
-der Funktion.
+@node Ereignisfunktionen
+@section Ereignisfunktionen
+@translationof Event functions
 
-Jetzt wird die @code{add-marcato}-Funktion in eine musikalische
-Funktion umgewandelt:
+@funindex define-event-function
+@cindex Ereignisfunktionen
 
-@example
-addMarcato = #(define-music-function (parser location event-chord)
-                                     (ly:music?)
-    "Add a marcato ArticulationEvent to the elements of `event-chord',
-    which is supposed to be an EventChord expression."
-    (let ((result-event-chord (ly:music-deep-copy event-chord)))
-      (set! (ly:music-property result-event-chord 'elements)
-            (cons (make-music 'ArticulationEvent
-                    'articulation-type "marcato")
-                  (ly:music-property result-event-chord 'elements)))
-      result-event-chord))
-@end example
+Damit man eine musikalische Funktion anstelle eines Ereignisses benützen
+kann, muss man ihr einen Richtungsindikator voranstellen.  Manchmal
+entspricht dies jedoch nicht der Syntax der Konstruktionen, die man ersetzen
+will.  Dynamikbefehle beispielsweise werden normalerweise ohne Richtungsangabe
+angehängt, wie @code{c'\pp}.  Das Folgende ist eine Möglichkeit, beliebige
+Dynamikbefehle zu schreiben:
 
-Eine Überprüfung, dass die Funktion richtig arbeitet, geschieht
-folgendermaßen:
+@lilypond[quote,verbatim,ragged-right]
+dyn=#(define-event-function (parser location arg) (markup?)
+         (make-dynamic-script arg))
+\relative c' { c\dyn pfsss }
+@end lilypond
 
-@example
-\displayMusic \addMarcato c4
-@end example
+Man kann das Gleiche auch mit einer musikalischen Funktion erreichen, aber dann
+muss man immer einen Richtungsindikator voranstellen, wie @code{@w{c-\dyn pfsss}}.
 
 
-@node Programmierungsschnittstelle für Textbeschriftungen
-@section Programmierungsschnittstelle für Textbeschriftungen
-@translationof Markup programmer interface
+@node Textbeschriftungsfunktionen
+@section Textbeschriftungsfunktionen
+@translationof Markup functions
 
 Textbeschriftungselemente sind als besondere Scheme-Funktionen
-definiert, die ein Stencil-Objekt erstellen, dem eine Anzahl
+definiert, die ein @code{Stencil}-Objekt erstellen, dem eine Anzahl
 an Argumenten übergeben wird.
 
 @menu
 * Beschriftungskonstruktionen in Scheme::
 * Wie Beschriftungen intern funktionieren::
 * Neue Definitionen von Beschriftungsbefehlen::
-* Neue Definitionen von Beschriftungsbefehlen für Listen::
+* Neue Definitionen von Beschriftungslistenbefehlen::
 @end menu
 
 
@@ -945,14 +600,17 @@ ist
 identisch mit
 
 @example
-\markup \column @{ \line @{ \bold \italic "hello" \raise #0.4 "world" @}
-                  \larger \line @{ foo bar baz @} @}
+#@{ \markup \column @{ \line @{ \bold \italic "hello" \raise #0.4 "world" @}
+                  \larger \line @{ foo bar baz @} @} #@}
 @end example
 
 @noindent
 Dieses Beispiel zeigt die hauptsächlichen Übersetzungsregeln
 zwischen normaler Textbeschriftungssyntax von LilyPond und der
-Textbeschriftungssyntax in Scheme.
+Textbeschriftungssyntax in Scheme.  Es ist meistens der beste
+Weg, @code{#@{ @dots{} #@}} zur Eingabe von LilyPond-Syntax zu
+benützen, aber es soll auch erklärt werden, wie man das
+@code{markup}-Makro einsetzt, um eine Lösung nur in Scheme zu bekommen.
 
 @quotation
 @multitable @columnfractions .3 .3
@@ -960,11 +618,11 @@ Textbeschriftungssyntax in Scheme.
 @item @code{\markup Text1} @tab @code{(markup Text1)}
 @item @code{\markup @{ Text1 Text2 ... @}} @tab
         @code{(markup Text1 Text2 ... )}
-@item @code{\Befehl} @tab @code{#:Befehl}
+@item @code{\Beschriftungsbefehl} @tab @code{#:Beschriftungsbefehl}
 @item @code{\Variable} @tab @code{Variable}
 @item @code{\center-column @{ ... @}} @tab @code{#:center-column ( ... )}
 @item @code{Zeichenkette} @tab @code{"Zeichenkette"}
-@item @code{#scheme-arg} @tab @code{scheme-arg}
+@item @code{#scheme-Arg} @tab @code{scheme-Arg}
 @end multitable
 @end quotation
 
@@ -1030,232 +688,349 @@ Die @code{raise-markup}-Funktion erstellt zunächst den Stencil für die
 um 0.5 Notenlinienzwischenräume nach oben.  Das ist ein einfaches
 Beispiel.  Weitere, kompliziertere Beispiele finden sich nachfolgend
 in diesem Abschnitt und in der Datei
-@file{scm/@/define@/-markup@/-commands@/.scm}.
+@file{scm/define-markup-commands.scm}.
 
 
 @node Neue Definitionen von Beschriftungsbefehlen
 @subsection Neue Definitionen von Beschriftungsbefehlen
 @translationof New markup command definition
 
+Dieser Abschnitt behandelt die Definition von neuen Textbeschriftungsbefehlen.
+
+@menu
+* Syntax der Definition von Textbeschriftungsbefehlen::
+* Über Eigenschaften::
+* Ein vollständiges Bespiel::
+* Eingebaute Befehle anpassen::
+@end menu
+
+@node Syntax der Definition von Textbeschriftungsbefehlen
+@unnumberedsubsubsec Syntax der Definition von Textbeschriftungsbefehlen
+@translationof Markup command definition syntax
+
 Neue Textbeschriftungsbefehle können mit dem
 @code{define-markup-command}-Scheme-Makro definiert werden.
 
 @lisp
-(define-markup-command (@var{befehl-bezeichnung} @var{layout} @var{props} @var{arg1} @var{arg2} ...)
-            (@var{arg1-type?} @var{arg2-type?} ...)
+(define-markup-command (@var{befehl-bezeichnung} @var{layout} @var{props} @var{Arg1} @var{Arg2} ...)
+            (@var{Arg1-typ?} @var{Arg2-typ?} ...)
+    [ #:properties ((@var{Eigenschaft1} @var{Standard-Wert1})
+                    ...) ]
   ..Befehlkörper..)
 @end lisp
 
 Die Argumente sind:
 
 @table @var
-@item argi
-@var{i}te Befehlsargument
-@item argi-type?
-eine Eigenschaft für das @var{i}te Argument
-@item layout
+@item @var{befehl-bezeichnung}
+die Bezeichnung des Befehls
+
+@item @var{layout}
 die @q{layout}-Definition
+
 @item props
-eine Liste an alists, in der alle aktiven Eigenschaften enthalten sind
+eine Liste an  assoziativen Listen, in der alle aktiven Eigenschaften enthalten sind
+
+@item @var{argi}
+das @var{i}te Befehlsargument
+
+@item @var{argi-type?}
+eine Eigenschaft für das @var{i}te Argument
 @end table
 
-Als einfaches Beispiel soll gezeigt werden, wie man einen
-@code{\smallcaps}-Befehl hinzufügen kann, der die Kapitälchen
-für die Schriftzeichen auswählt.  Normalerweise würde man Kapitälchen
-folgendermaßen auswählen:
+Wenn der Befehl Eigenschaften des @code{props}-Arguments benutzt,
+kann das @code{#:properties}-Schlüsselwort benutzt werden um zu
+bestimmen, welche Eigenschaften mit welchen Standard-Werten benutzt
+werden.
 
-@example
-\markup @{ \override #'(font-shape . caps) Text-in-Kapitälchen @}
-@end example
+Argumente werden nach ihrem Typ unterschieden:
 
-@noindent
-Damit wird die Kapitälchenschriftart ausgewählt, indem die
-@code{font-shape}-Eigenschaft auf @code{#'caps} gesetzt wird,
-während @code{Text-in-caps} interpretiert wird.
+@itemize
+@item eine Textbeschriftung entspricht einem Typenprädikat @code{markup?};
+@item eine Textbeschriftungsliste entspricht einem Typenprädikat
+@code{markup-list?};
+@item jedes andere Scheme-Objekt entspricht Typenprädikaten wie etwa
+@code{list?}, @code{number?}, @code{boolean?}, usw.
+@end itemize
 
-Damit diese Funktion als @code{\smallcaps}-Befehl zur Verfügung
-gestellt werden kann, muss eine Funktion mit @code{define-markup-command}
-definiert werden.  Der Befehl braucht ein Argument vom Typ @code{markup}.
-Darum sollte der Beginn der Funktion lauten:
+Es gibt keine Einschränkung in der Reihenfolge der Argumente (nach
+den Standard-Argumenten @code{layout} und @code{props}).  Textbeschriftungsfunktionen,
+die als letztes Argument eine Textbeschriftung haben, haben die
+Besonderheit, dass sie auf Textbeschriftungslisten angewendet werden
+können, und das Resultat ist eine Textbeschriftungsliste, in der
+die Textbeschriftungsfuktion (mit den angegebenen Argumenten am Anfang)
+auf jedes Element der originalen Textbeschriftungsliste angewendet
+wurde.
 
-@example
-(define-markup-command (smallcaps layout props argument) (markup?)
-@end example
+Da das Wiederholen der Argumente am Anfang bei der Anwendung einer
+Textbeschriftungsfunktion auf eine Textbeschriftungsliste for allem
+für Scheme-Argumente sparsam ist, kann man Leistungseinbußen vermeiden,
+indem man nur Scheme-Argumente für die Argumente am Anfang einsetzt,
+wenn es sich um Textbeschriftungsfunktionen handelt, die eine Textbeschriftung
+als letztes Argument haben.
 
-@noindent
 
-Was jetzt folgt, ist der eigentliche Inhalt des Befehls: das
-@code{argument} soll als Beschriftung (markup) interpretiert werden,
-also:
+@node Über Eigenschaften
+@unnumberedsubsubsec Über Eigenschaften
+@translationof On properties
 
-@example
-(interpret-markup layout @dots{} argument)
-@end example
+Die @code{layout}- und @code{props}-Argumente der Textbeschriftungsbefehle
+bringen einen Kontext für die Interpretation der Beschriftung:
+Schriftgröße, Zeilenlänge usw.
 
-@noindent
-Diese Interpretation sollte @code{'(font-shape . caps)} zu den
-aktiven Eigenschaften hinzufügen, weshalb wir das Folgende anstelle
-der @dots{} in dem Beispiel einfügen:
+Das @code{layout}-Argument greift auf Eigenschaften zu, die in der
+@code{paper}-Umgebung definiert werden, indem man die @code{ly:output-def-lookup}-Funktion
+benutzt.  Beispielsweise liest man die Zeilenlänge (die gleiche, die auch in
+Partituren benutzt wird) aus mit:
 
 @example
-(cons (list '(font-shape . caps) ) props)
+(ly:output-def-lookup layout 'line-width)
 @end example
 
-@noindent
-Die Variable @code{props} ist eine Liste an alists, und mit @code{cons}
-wird ihr eine zusätzliche Einstellung hinzugefügt.
+Das @code{props}-Argument stellt einige Eigenschaften für die Textbeschriftungsbefehle
+zur Verfügung.  Beispielsweise wenn der Überschrifttext einer
+@code{book}-Umgebung interpretiert wird, werden alle Variablen, die
+in der @code{\header}-Umgebung definiert werden, automatisch zu @code{props}
+hinzugefügt, sodass die Beschriftung auf Titel, Komponist usw. der
+@code{book}-Umgebung zugreifen kann.  Das ist auch eine Möglichkeit, das
+Verhalten eines Beschriftungsbefehls zu konfigurieren: Wenn etwa ein
+Befehl die Schriftgröße während der Verarbeitung einsetzt, wird die
+Schriftgröße aus den @code{props} ausgelesen und nicht mit einem eigenen
+@code{font-size}-Argument definiert.  Beim Aufruf des Beschriftungsbefehls
+kann der Wert der Schriftgröße geändert werden, womit sich auch das Verhalten
+des Befehls verändert.  Benutzen Sie das @code{#:properties}-Schlüsselwort
+von @code{define-markup-command} um zu definieren, welche Eigenschaften aus den
+@code{props}-Argumenten ausgelesen werden sollen.
 
-Man könnte sich auch vorstellen, dass ein Rezitativ einer Oper
-gesetzt werden soll, und ein Befehl wäre sehr bequem, mit dem
-man die Namen der Charaktere auf eine eigene Art darstellen könnte.
-Namen sollen in Kapitälchen gesetzt werden und etwas nach links und
-oben verschoben werden.  Man kann also einen @code{\character}-Befehl
-definieren, der die nötige Verschiebung berücksichtigt und
-den neuen @code{\smallcaps}-Befehl einsetzt:
+Das Beispiel im nächsten Abschnitt illustriert, wie man auf Eigenschaften
+in einem Beschriftungsbefehl zugreifen und sie verändern kann.
 
-@example
-#(define-markup-command (character layout props name) (string?)
-  "Print the character name in small caps, translated to the left and
-  top.  Syntax: \\character #\"name\""
+
+@node Ein vollständiges Bespiel
+@unnumberedsubsubsec Ein vollständiges Bespiel
+@translationof A complete example
+
+Das folgende Beispiel definiert einen Beschriftungsbefehl, der einen
+doppelten Kasten um einen Text zeichnet.
+
+Zuerst wollen wir ein annäherndes Ergebnis mit Textbeschriftungen definieren.
+Nach Stöbern in @ruser{Textbeschriftungsbefehle} finden wir den Befehl
+@code{\box}:
+
+@lilypond[quote,verbatim,ragged-right]
+\markup \box \box HELLO
+@end lilypond
+
+Wir wollen aber etwas mehr Abstand (engl. padding) zwischen dem Text und dem Kasten.
+Nach der Dokumentation von @code{\box} hat der Befehl eine
+@code{box-padding}-Eigenschaft, die den Standardwert von 0.2 hat.  Die
+Dokumentation zeit auch, wir man den Wert verändert:
+
+@lilypond[quote,verbatim,ragged-right]
+\markup \box \override #'(box-padding . 0.6) \box A
+@end lilypond
+
+Auch der Abstand zwischen den zwei Kästen ist uns zu klein und soll auch
+vergrößert werden:
+
+@lilypond[quote,verbatim,ragged-right]
+\markup \override #'(box-padding . 0.4) \box
+    \override #'(box-padding . 0.6) \box A
+@end lilypond
+
+Diese lange Textbeschriftung immer wieder schreiben zu müssen, ist
+anstrengend.  Hier kömmt ein Textbeschriftungsbefehl ins Spiel.  Wir
+schreiben uns alle einen @code{double-box}-Beschriftungsbefehl, der
+ein Argument annimmt (den Text).  Er zeichnet zwei Kästen mit genügend Abstand:
+
+@lisp
+#(define-markup-command (double-box layout props text) (markup?)
+  "Draw a double box around text."
   (interpret-markup layout props
-   (markup #:hspace 0 #:translate (cons -3 1) #:smallcaps name)))
-@end example
+    #@{\markup \override #'(box-padding . 0.4) \box
+            \override #'(box-padding . 0.6) \box @{ #text @}#@}))
+@end lisp
 
-Hier ist eine Komplikation, die erklärt werden muss: Text über oder
-unter dem Notensystem wird vertikal verschoben um in einem bestimmten
-Abstand von dem System und den Noten zu sein (das wird als @qq{padding}
-bezeichnet).  Um sicherzugehen, dass dieser Mechanismus nicht die
-vertikale Verschiebung von @code{#:translate} annulliert, wird
-die leere Zeichenkette (@code{#:hspace 0}) vor den zu verschiebenden
-Text gesetzt.  Das @code{#:hspace 0} wird jetzt also über die Noten
-gesetzt und @code{name} dann relativ zu der leeren Zeichenkette
-verschoben.  Im Endeffekt wird der Text nach links oben verschoben.
+oder äquivalent
 
-Das Resultat sieht folgendermaßen aus:
+@lisp
+#(define-markup-command (double-box layout props text) (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)))
+@end lisp
+
+@code{text} ist die Bezeichnung des Arguments dieses Befehls,
+und @code{markup?} ist seine Art: hiermit wird der Befehl als
+Beschriftungsbefehl identifiziert.  Die @code{interpret-markup}-Funktion
+wird in den meisten Beschriftungsbefehlen benutzt: sie erstellt einen
+Stencil, wobei @code{layout}, @code{props} und eine Beschriftung benutzt
+werden.  Im zweiten Fall wird diese Beschriftung durch das
+@code{markup}-Scheme-Makro erstellt, siehe auche
+@ref{Beschriftungskonstruktionen in Scheme}.
+Die Transformation des @code{\markup}-Ausdrucks in einen
+Scheme-Beschriftungsausdruck geschieht durch Umschreiben des LilyPond-Codes
+in Scheme-Code.
+
+Der neue Befehl kann wie folgt benutzt werden:
 
 @example
-@{
-  c''^\markup \character #"Cleopatra"
-  e'^\markup \character #"Giulio Cesare"
-@}
+\markup \double-box A
 @end example
 
-@lilypond[quote,ragged-right]
-#(define-markup-command (smallcaps layout props str) (string?)
-  "Print the string argument in small caps.  Syntax: \\smallcaps #\"string\""
+Es wäre schön, den @code{double-box}-Befehl noch konfigurierbar zu gestalten:
+in unserem Fall sind die Werte von @code{box-padding} direkt definiert und
+können nicht mehr vom Benutzer verändert werden.  Es wäre auch besser, wenn
+der Abstand zwischen den beiden Kästen vom Abstand zwischen dem inneren Kasten
+und dem Text unterschieden werden könnte.  Eine neue Eigenschaft muss also
+definiert werden: @code{inter-box-padding} für den Abstand zwischen den Kästen.
+@code{box-padding} wird für den inneren Abstand benutzt.  Der neue Befehl wird
+so definiert:
+
+@lisp
+#(define-markup-command (double-box layout props text) (markup?)
+  #:properties ((inter-box-padding 0.4)
+                (box-padding 0.6))
+  "Draw a double box around text."
   (interpret-markup layout props
-   (make-line-markup
-    (map (lambda (s)
-          (if (= (string-length s) 0)
-              s
-              (markup #:large (string-upcase (substring s 0 1))
-                      #:translate (cons -0.6 0)
-                      #:tiny (string-upcase (substring s 1)))))
-         (string-split str #\Space)))))
-
-#(define-markup-command (character layout props name) (string?)
-  "Print the character name in small caps, translated to the left and
-  top.  Syntax: \\character #\"name\""
+    #@{\markup \override #`(box-padding . ,inter-box-padding) \box
+               \override #`(box-padding . ,box-padding) \box
+               @{ #text @} #@}))
+@end lisp
+
+Wiederum wäre die entsprechende Version mit dem @code{markup}-Makro
+so aussehen:
+
+@lisp
+#(define-markup-command (double-box layout props text) (markup?)
+  #:properties ((inter-box-padding 0.4)
+                (box-padding 0.6))
+  "Draw a double box around text."
   (interpret-markup layout props
-   (markup #:hspace 0 #:translate (cons -3 1) #:smallcaps name)))
+    (markup #:override `(box-padding . ,inter-box-padding) #:box
+            #:override `(box-padding . ,box-padding) #:box text)))
+@end lisp
 
-{
-  c''^\markup \character #"Cleopatra" c'' c'' c''
-  e'^\markup \character #"Giulio Cesare" e' e' e'
-}
-@end lilypond
+In diesem Code wird das @code{#:properties}-Schlüsselwort benutzt, sodass
+die Eigenschaften @code{inter-box-padding} und @code{box-padding} aus dem
+@code{props}-Argument ausgelesen werden, und Standardwerte werden gegeben,
+falls die Eigenschaften nicht definiert sein sollten.
 
-In diesen Befehlen wurden Kapitälchen eingesetzt, aber es kann
-vorkommen, dass die Schriftart keine Kapitälchen zur Verfügung
-stellt.  In diesem Fall können die Kapitälchen nachempfunden
-werden, indem man Großbuchstaben setzt, deren Anfangsbuchstabe
-etwas größer gesetzt wird:
+Dann werden diese Werte benutzt, um die @code{box-padding}-Eigenschaft
+zu verändert, die von beiden @code{\box}-Befehlen benutzt wird.  Beachten
+Sie Akzent und das Komma des @code{\override}-Arguments: hiermit kann man
+einen Variablenwert in einen wörtlichen Ausdruck überführen.
 
-@example
-#(define-markup-command (smallcaps layout props str) (string?)
-  "Print the string argument in small caps."
+Jetzt kann der Befehl in Beschriftungen benutzt werden und der Abstand
+der Kästen kann angepasst werden:
+
+@lilypond[quote,verbatim,ragged-right]
+#(define-markup-command (double-box layout props text) (markup?)
+  #:properties ((inter-box-padding 0.4)
+                (box-padding 0.6))
+  "Draw a double box around text."
   (interpret-markup layout props
-   (make-line-markup
-    (map (lambda (s)
-          (if (= (string-length s) 0)
-              s
-              (markup #:large (string-upcase (substring s 0 1))
-                      #:translate (cons -0.6 0)
-                      #:tiny (string-upcase (substring s 1)))))
-         (string-split str #\Space)))))
-@end example
+    #{\markup \override #`(box-padding . ,inter-box-padding) \box
+              \override #`(box-padding . ,box-padding) \box
+              { #text } #}))
 
-Der @code{smallcaps}-Befehl spaltet die Argumente zuerst in
-Einzelstücke auf, die von Leerzeichen getrennt sind
-(@code{(string-split str #\Space)}); für jedes Einzelstück
-wird dann eine Beschriftung aufgebaut, deren erster Buchstabe
-vergrößert wird und als Versalbuchstabe gesetzt wird
-(@code{#:large (string-upcase (substring s 0 1))}), und eine
-zweite Versalbuchstaben gesetzt werden
-(@code{#:tiny (string-upcase (substring s 1))}).  Wenn
-LilyPond ein Leerzeichen zwischen Beschriftungen einer Zeile
-entdeckt, wird die zweite Beschriftung nach links verschoben
-(@code{#:translate (cons -0.6 0) ...}).  Dann werden die
-Beschriftungen für jedes Einzelstück in eine Zeile gesetzt
-@code{(make-line-markup ...)}.  Schließlich wird die resultierende
-Beschriftung an die @code{interpret-markup}-Funktion zusammen
-mit den Argumenten @code{layout} und @code{props} weitergereicht.
-
-Achtung: ist gibt keinen internen Befehl @code{\smallCaps}, der
-benutzt werden kann, um Text in Kapitälchen zu setzen.  Siehe auch
-@ref{Text markup commands}.
+\markup \double-box A
+\markup \override #'(inter-box-padding . 0.8) \double-box A
+\markup \override #'(box-padding . 1.0) \double-box A
+@end lilypond
 
-@knownissues
+@node Eingebaute Befehle anpassen
+@unnumberedsubsubsec Eingebaute Befehle anpassen
+@translationof Adapting builtin commands
 
-Im Moment sind die möglichen Kombinationen von Argumenten (nach den
-Standardargumenten @var{layout} und @var{props}), die mit
-@code{define-markup-command} definiert werden, wie folgt
-limitiert:
-
-@table @asis
-@item (kein Argument)
-@itemx @var{list}
-@itemx @var{markup}
-@itemx @var{markup markup}
-@itemx @var{scm}
-@itemx @var{scm markup}
-@itemx @var{scm scm}
-@itemx @var{scm scm markup}
-@itemx @var{scm scm markup markup}
-@itemx @var{scm markup markup}
-@itemx @var{scm scm scm}
-@end table
+Ein guter Weg, einen neuen Beschriftungsbefehl zu schreiben, ist es, als Vorbild
+einen existierenden zu nehmen.  Die meisten Beschriftungsbefehle, die
+LilyPond mitbringt, finden sich in der Datei
+@file{scm/define-markup-commands.scm}.
 
-@noindent
-Hier stellt @var{scm} native Scheme-Datentypen dar wie
-@q{number} oder @q{string}.
+Man könnte beispielsweise den Befehl @code{\draw-line}, der eine Linie
+zeichnet, anpassen, sodass er eine Doppellinie zeichnet.  Der
+Befehl @code{\draw-line} ist wie folgend definiert (Dokumentation entfernt):
 
-Es ist beispielsweise nicht möglich, einen Beschriftungsbefehl
-@code{foo} mit vier Argumenten in folgender Weise zu nutzen:
+@lisp
+(define-markup-command (draw-line layout props dest)
+  (number-pair?)
+  #:category graphic
+  #:properties ((thickness 1))
+  "..documentation.."
+  (let ((th (* (ly:output-def-lookup layout 'line-thickness)
+               thickness))
+        (x (car dest))
+        (y (cdr dest)))
+    (make-line-stencil th 0 0 x y)))
+@end lisp
 
-@example
-#(define-markup-command (foo layout props
-                         num1    str1    num2    str2)
-                        (number? string? number? string?)
-  ...)
-@end example
+Um einen neuen Befehl, der auf einem existierenden basiert, zu definieren,
+wird die Befehlsdefinition kopiert und die Bezeichnung des Befehls
+geändert.  Das @code{#:category}-Schlagwort kann entfernt werden,
+weil es nur zur Erstellung der LilyPond-Dokumentation eingesetzt wird
+und keine Bedeutung für selbstdefinierte Befehle hat.
 
-@noindent
-Wenn es folgendermaßen eingesetzt wird:
+@lisp
+(define-markup-command (draw-double-line layout props dest)
+  (number-pair?)
+  #:properties ((thickness 1))
+  "..documentation.."
+  (let ((th (* (ly:output-def-lookup layout 'line-thickness)
+               thickness))
+        (x (car dest))
+        (y (cdr dest)))
+    (make-line-stencil th 0 0 x y)))
+@end lisp
 
-@example
-\markup \foo #1 #"bar" #2 #"baz"
-@end example
+Dann braucht man eine Eigenschaft, um den Abstand zwischen den zwei
+Linien zu definieren, als @code{line-gap} bezeichnet und etwa mit
+dem Standardwert 0.6:
+
+@lisp
+(define-markup-command (draw-double-line layout props dest)
+  (number-pair?)
+  #:properties ((thickness 1)
+                (line-gap 0.6))
+  "..documentation.."
+  ...
+@end lisp
+
+Schließlich wird der Code, der die zwei Linien zeichnet, hinzugefügt.
+Zwei Aufrufe an @code{make-line-stencil} werden benutzt, um beide Linien
+zu zeichnen, und die beiden sich daraus ergebenden Stencils werden mit
+@code{ly:stencil-add} kombiniert:
+
+@lilypond[quote,verbatim,ragged-right]
+#(define-markup-command (my-draw-line layout props dest)
+  (number-pair?)
+  #:properties ((thickness 1)
+                (line-gap 0.6))
+  "..documentation.."
+  (let* ((th (* (ly:output-def-lookup layout 'line-thickness)
+                thickness))
+         (dx (car dest))
+         (dy (cdr dest))
+         (w (/ line-gap 2.0))
+         (x (cond ((= dx 0) w)
+                  ((= dy 0) 0)
+                  (else (/ w (sqrt (+ 1 (* (/ dx dy) (/ dx dy))))))))
+         (y (* (if (< (* dx dy) 0) 1 -1)
+               (cond ((= dy 0) w)
+                     ((= dx 0) 0)
+                     (else (/ w (sqrt (+ 1 (* (/ dy dx) (/ dy dx))))))))))
+     (ly:stencil-add (make-line-stencil th x y (+ dx x) (+ dy y))
+                     (make-line-stencil th (- x) (- y) (- dx x) (- dy y)))))
+
+\markup \my-draw-line #'(4 . 3)
+\markup \override #'(line-gap . 1.2) \my-draw-line #'(4 . 3)
+@end lilypond
 
-@cindex Scheme signature
-@cindex Signatur, Scheme
-@noindent
-beschwert sich @command{lilypond}, dass @code{foo} wegen einer unbekannten
-Scheme Signatur nicht analysiert werden kann.
 
 
-@node Neue Definitionen von Beschriftungsbefehlen für Listen
-@subsection Neue Definitionen von Beschriftungsbefehlen für Listen
+@node Neue Definitionen von Beschriftungslistenbefehlen
+@subsection Neue Definitionen von Beschriftungslistenbefehlen
 @translationof New markup list command definition
 
 Beschriftungslistenbefehle können mit dem Scheme-Makro
@@ -1273,13 +1048,22 @@ denen die erste Zeile eingerückt ist.  Der Einzug wird aus dem
 
 @example
 #(define-markup-list-command (paragraph layout props args) (markup-list?)
-   (let ((indent (chain-assoc-get 'par-indent props 2)))
-     (interpret-markup-list layout props
-       (make-justified-lines-markup-list (cons (make-hspace-markup indent)
-                                               args)))))
+   #:properties ((par-indent 2))
+   (interpret-markup-list layout props
+     #@{\markuplist \justified-lines @{ \hspace #par-indent #args @} #@}))
+@end example
+
+Die Version nur in Scheme ist etwas komplexer:
+
+@example
+#(define-markup-list-command (paragraph layout props args) (markup-list?)
+   #:properties ((par-indent 2))
+   (interpret-markup-list layout props
+     (make-justified-lines-markup-list (cons (make-hspace-markup par-indent)
+                                             args))))
 @end example
 
-Neben den üblichen @code{layout} und @code{props}-Argumenten, nimmt der
+Neben den üblichen @code{layout} und @code{props}-Argumenten nimmt der
 @code{paragraph}-Beschriftungslistenbefehl als Argument eine Beschriftungsliste,
 die @code{args} genannt wird.  Das Prädikat für Beschriftungslisten ist
 @code{markup-list?}.
@@ -1288,17 +1072,17 @@ Zuerst errechnet die Funktion die Breite des Einzugs, eine Eigenschaft
 mit der Bezeichnung @code{par-indent} anhand der Eigenschaftsliste
 @code{props}.  Wenn die Eigenschaft nicht gefunden wird, ist der
 Standardwert @code{2}.  Danach wird eine Liste von Zeilen im Blocksatz
-erstellt, wobei die @code{make-justified-lines-markup-list}-Funktion
-eingesetzt wird, die verwandt ist mit dem eingebauten
-@code{\justified-lines}-Beschriftungslistenbefehl.  Horizontaler
-Platz wird zu Beginn eingefügt mit der @code{make-hspace-markup}-Funktion.
-Zuletzt wird die Beschriftungsliste ausgewertet durch die
-@code{interpret-markup-list}-Funktion.
+erstellt, wobei der eingebaute @code{\justified-lines}-Beschriftungslistenbefehl
+eingesetzt wird, der verwandt ist mit der
+@code{make-justified-lines-markup-list}-Funktion.  Horizontaler
+Platz wird zu Beginn eingefügt mit @code{\hspace} (oder der
+@code{make-hspace-markup}-Funktion).  Zuletzt wird die Beschriftungsliste
+ausgewertet durch die @code{interpret-markup-list}-Funktion.
 
 Dieser neue Beschriftungslistenbefehl kann wie folgt benutzt werden:
 
 @example
-\markuplines @{
+\markuplist @{
   \paragraph @{
     Die Kunst des Notensatzes wird auch als \italic @{Notenstich@} bezeichnet. Dieser
     Begriff stammt aus dem traditionellen Notendruck. Noch bis vor etwa
@@ -1307,7 +1091,7 @@ Dieser neue Beschriftungslistenbefehl kann wie folgt benutzt werden:
   @}
   \override-lines #'(par-indent . 4) \paragraph @{
     Diese Platte wurde dann mit Druckerschwärze versehen, so dass sie
-    in den geschnittenen und gestempelten Vertiefungen blieb. Diese 
+    in den geschnittenen und gestempelten Vertiefungen blieb. Diese
     Vertiefungen schwärzten dann ein auf die Platte gelegtes Papier.
     Das Gravieren wurde vollständig von Hand erledigt.
   @}
@@ -1315,7 +1099,6 @@ Dieser neue Beschriftungslistenbefehl kann wie folgt benutzt werden:
 @end example
 
 
-
 @node Kontexte für Programmierer
 @section Kontexte für Programmierer
 @translationof Contexts for programmers
@@ -1366,7 +1149,9 @@ während der Kompilation.
 @funindex \applyOutput
 
 Der vielfältigste Weg, ein Objekt zu beeinflussen, ist
-@code{\applyOutput}.  Die Syntax lautet:
+@code{\applyOutput}.  Das funktioniert, indem ein musikalisches
+Ereignis in den angegebenen Kontext eingefügt wird
+(@rinternals{ApplyOutputEvent}).  Die Syntax lautet:
 
 @example
 \applyOutput @var{Kontext} @var{proc}
@@ -1376,8 +1161,8 @@ Der vielfältigste Weg, ein Objekt zu beeinflussen, ist
 wobei @var{proc} eine Scheme-Funktion ist, die drei Argumente
 benötigt.
 
-Während der Interpretation wird die Funktion @var{proc} für
-jedes Layoutobjekt aufgerufen, dass im Kontext @var{Kontext}
+Während der Interpretation wird die Funktion @code{@var{proc}} für
+jedes Layoutobjekt aufgerufen, dass im Kontext @code{@var{Kontext}}
 vorgefunden wird, und zwar mit folgenden Argumenten:
 
 @itemize
@@ -1390,39 +1175,39 @@ Zusätzlich findet sich der Grund für das Layoutobjekt, etwa
 der musikalische Ausdruck oder das Objekt, das für seine Erstellung
 verantwortlich war, in der Objekteigenschaft @code{cause}.
 Für einen Notenkopf beispielsweise ist das ein
-@rinternals{NoteHead}-Ereignis, und für einen Notenhals
-(ein @rinternals{Stem}-Objekt) ist es ein @rinternals{NoteHead}-Objekt.
+@rinternals{NoteHead}-Ereignis, und für einen Notenhals ist es
+ein @rinternals{Stem}-Objekt.
 
 Hier ist eine Funktion, die mit @code{\applyOutput} benutzt
-werden kann; sie macht Notenköpfe auf der Mittellinie unsichtbar:
+werden kann; sie macht Notenköpfe auf und neben der Mittellinie unsichtbar:
 
 @lilypond[quote,verbatim,ragged-right]
 #(define (blanker grob grob-origin context)
    (if (and (memq 'note-head-interface (ly:grob-interfaces grob))
-            (eq? (ly:grob-property grob 'staff-position) 0))
+            (< (abs (ly:grob-property grob 'staff-position)) 2))
        (set! (ly:grob-property grob 'transparent) #t)))
 
-\relative {
-  e4 g8 \applyOutput #'Voice #blanker b d2
+\relative c' {
+  a'4 e8 <<\applyOutput #'Voice #blanker a c d>> b2
 }
 @end lilypond
 
 
-@node Scheme-Vorgänge als Eigenschaften
-@section Scheme-Vorgänge als Eigenschaften
-@translationof Scheme procedures as properties
+@node Callback-Funktionen
+@section Callback-Funktionen
+@translationof Callback functions
 
-Eigenschaften (wie Dicke, Richtung usw.) können mit
-@code{\override} auf feste Werte gesetzt werden, etwa:
+Eigenschaften (wie Dicke (@code{thickness}), Richtung (@code{direction})
+usw.) können mit @code{\override} auf feste Werte gesetzt werden, etwa:
 
 @example
-\override Stem #'thickness = #2.0
+\override Stem.thickness = #2.0
 @end example
 
 Eigenschaften können auch auf eine Scheme-Prozedur gesetzt werden:
 
 @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))
@@ -1485,17 +1270,35 @@ für @var{proc} zur Verfügung, das äußere stellt sicher, dass das
 Resultat der Funktion ausgegeben wird und nicht das
 @code{simple-closure}-Objekt.
 
+Aus dem Callback heraus kann man eine Beschriftung am einfachsten mit
+@code{grob-interpret-markup} auswerten.  Beispielsweise:
+
+@example
+mein-callback = #(lambda (grob)
+                 (grob-interpret-markup grob (markup "foo")))
+@end example
 
-@node Scheme-Code anstelle von \tweak verwenden
-@section Scheme-Code anstelle von @code{       weak} verwenden
-@translationof Using Scheme code instead of \tweak
+
+@node Scheme-Code innerhalb LilyPonds
+@section Scheme-Code innerhalb LilyPonds
+@translationof Inline Scheme code
+
+TODO: das Beispiel für diesen Abschnitt ist nicht gut gewähtl:
+
+@example
+F = -\tweak font-size #-3 -\flageolet
+@end example
+(beachte @samp{-}, was ein Nachereignis anzeigt) funktioniert
+für den geschilderten Zweck sehr gut.  Aber bis der Abschnitt
+neu geschrieben wird, nehmen wir einfach an, dass wir das nicht
+wissen.
 
 Der hauptsächliche Nachteil von @code{\tweak} ist seine
 syntaktische Inflexibilität.  Folgender Code beispielsweise
 ergibt einen Syntaxfehler:
 
 @example
-F = \tweak #'font-size #-3 -\flageolet
+F = \tweak font-size #-3 -\flageolet
 
 \relative c'' @{
   c4^\F c4_\F
@@ -1503,10 +1306,6 @@ F = \tweak #'font-size #-3 -\flageolet
 @end example
 
 @noindent
-Anders gesagt verhält sich @code{\tweak} nicht wie eine Artikulation
-und kann auch nicht deren Syntax verwenden: man kann es nicht
-mit @code{^} oder @code{_} anfügen.
-
 Durch die Verwendung von Scheme kann dieses Problem umgangen werden.
 Der Weg zum Resultat wird gezeigt in
 @ref{Artikulationszeichen zu Noten hinzufügen (Beispiel)}, insbesondere
@@ -1580,8 +1379,8 @@ wenn ja, wird @code{extra-offset} gesetzt.
 @end itemize
 
 Diese Funktion muss in @rinternals{Tie} (Bindebogen) installiert
-werden, und der letzte Teil eines gebrochenen Bindebogens wird
-nach oben verschoben.
+werden, damit der letzte Teil eines gebrochenen Bindebogens
+neu ausgerichtet wird.
 
 @lilypond[quote,verbatim,ragged-right]
 #(define (my-callback grob)
@@ -1598,7 +1397,7 @@ nach oben verschoben.
      (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
 }
@@ -1609,7 +1408,7 @@ Wenn man diesen Trick anwendet, sollte das neue @code{after-line-breaking}
 auch das alte @code{after-line-breaking}-Callback aufrufen,
 wenn es vorhanden ist.  Wenn diese Funktion etwa mit
 @code{Hairpin} (Crescendo-Klammer) eingesetzt wird, sollte auch
-@code{ly:hairpin::after-line-breaking} aufgerufen werden.
+@code{ly:spanner::kill-zero-spanned-time} aufgerufen werden.
 
 
 @item
@@ -1621,7 +1420,7 @@ und @code{PaperColumn}.  Sie können mit der
 
 @example
 \overrideProperty
-#"Score.NonMusicalPaperColumn"  % Grob-Bezeichnung
+Score.NonMusicalPaperColumn  % Grob-Bezeichnung
 #'line-break-system-details     % Eigenschaftsbezeichnung
 #'((next-padding . 20))         % Wert
 @end example
@@ -1631,3 +1430,15 @@ Es sollte angemerkt werden, dass @code{\override}, wenn man es auf
 innerhalb der @code{\context}-Umgebung funktioniert.
 
 @end itemize
+
+
+
+@node LilyPond Scheme-Schnittstellen
+@chapter LilyPond Scheme-Schnittstellen
+@translationof LilyPond Scheme interfaces
+
+Dieses Kapitel behandelt die verschiedenen Werkzeuge, die LilyPond als
+Hilfe für Scheme-Programmierer zur Verfügung stellt, um Information in
+den Musik-Stream zu senden und aus ihm herauszubekommen.
+
+TODO: was gehört hier eigentlich hin?