@c -*- coding: utf-8; mode: texinfo; -*-

@ignore
    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.17.6"

@c Translators: Till Paala

@node Schnittstellen für Programmierer
@chapter Schnittstellen für Programmierer
@translationof Interfaces for programmers

Fortgeschrittene Anpassungen können mithilfe der Programmiersprache
Scheme vorgenommen werden.  Wenn Sie Scheme nicht kennen, gibt
es eine grundlegende Einleitung in LilyPonds
@ref{Scheme-Übung}.

@menu
* LilyPond-Codeabschnitte::
* Scheme-Funktionen::
* Musikalische Funktionen::
* Ereignisfunktionen::
* Textbeschriftungsfunktionen::
* Kontexte für Programmierer::
* Callback-Funktionen::
* Scheme-Code innerhalb LilyPonds::
* Schwierige Korrekturen::
@end menu


@node LilyPond-Codeabschnitte
@section LilyPond-Codeabschnitte
@translationof Lilypond code blocks

Codeabschnitte in LilyPond sehen etwa so aus:

@example
  #@{ @var{Lilypond code} #@}
@end example

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.

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.

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.


@node Scheme-Funktionen
@section Scheme-Funktionen
@translationof Scheme functions

@cindex Scheme-Funktionen (LilyPond syntax)

@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.

@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

@funindex define-scheme-function

Die übliche Form zur Definition von Scheme-Funktionen ist:

@example
function =
#(define-scheme-function
     (parser location @var{Arg1} @var{Arg2} @dots{})
     (@var{Typ1?} @var{Typ2?} @dots{})
   @var{body})
@end example

@noindent
wobei

@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
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-void-function
     (parser location)
     ()
   (ly:set-option 'point-and-click #f))
...
\noPointAndClick   % Point and Click deaktivieren
@end example

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
\void #(hashq-set! eine-Tabelle ein-Schlüssel ein-Wert)
@end example

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

@cindex musikalische Funktionen

@emph{Musikalische Funktionen} sind Scheme-Prozeduren,
die musikalische Ausdrücke automatisch erstellen können und dadurch die
Eingabedatei maßgeblich vereinfachen können.

@menu
* Definition der musikalischen Funktionen::
* Benutzung von musikalischen Funktionen::
* Einfache Ersetzungsfunktionen::
* Mittlere Ersetzungsfunktionen::
* Mathematik in Funktionen::
* Funktionen ohne Argumente::
* Leere musikalische Funktionen::
@end menu


@node Definition der musikalischen Funktionen
@subsection Definition der musikalischen Funktionen
@translationof Music function definitions

Die allgemeine Form zur Definition musikalischer Funktionen ist:

@example
function =
#(define-music-function
     (parser location @var{Arg1} @var{Arg2} @dots{})
     (@var{Typ1?} @var{Typ2?} @dots{})
   @var{body})
@end example

@noindent
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}.

Eine Liste der möglichen Typenprädikate 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 musikalischen Funktionen
@subsection Benutzung von musikalischen Funktionen
@translationof Music function usage

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.

@itemize
@item
Auf höchster Ebene in einer musikalischen Funktion.  Keine Begrenzungen.

@item
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
s 1*0-\fun
@end example

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.

@item
Als Element eines Akkordes.  Der ausgegebene Ausdruck muss vom Typ
@code{rhythmic-event} sein, wahrscheinlich auch @code{NoteEvent}.

@end itemize

@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.


@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 Mittlere Ersetzungsfunktionen
@subsection Mittlere Ersetzungsfunktionen
@translationof Intermediate substitution functions

Mittlere Ersetzungsfunktionen setzen sich aus einer Mischung von
Scheme-Code und LilyPond-Code in der musikalischen Ausgabe-Funktion
zusammen.

Einige @code{\override}-Befehle benötigen ein Zahlenpaar
(als @code{cons}-Zelle in Scheme bezeichnet).

Das Paar kann direkt an die musikalische Funktion
mit der Variable @code{pair?} weitergeleitet werden:

@example
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

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 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
}

\relative c' {
  c2 \AltOn #0.5 c4 c
  \AltOn #1.5 c c \AltOff c2
}
@end lilypond

@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
   #})

\relative c' {
  c2 \withAlt #0.5 { c4 c }
  \withAlt #1.5 { c c } c2
}
@end lilypond


@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:

@example
dolce = \markup@{ \italic \bold dolce @}
@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 Leere musikalische Funktionen
@subsection Leere musikalische Funktionen
@translationof Void music functions

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.


@node Ereignisfunktionen
@section Ereignisfunktionen
@translationof Event functions

@funindex define-event-function
@cindex Ereignisfunktionen

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:

@lilypond[quote,verbatim,ragged-right]
dyn=#(define-event-function (parser location arg) (markup?)
         (make-dynamic-script arg))
\relative c' { c\dyn pfsss }
@end lilypond

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 Textbeschriftungsfunktionen
@section Textbeschriftungsfunktionen
@translationof Markup functions

Textbeschriftungselemente sind als besondere Scheme-Funktionen
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 Beschriftungslistenbefehlen::
@end menu


@node Beschriftungskonstruktionen in Scheme
@subsection Beschriftungskonstruktionen in Scheme
@translationof Markup construction in Scheme

@cindex Textbeschriftungsbefehle, definieren
@cindex Textbeschriftung, eigene Befehle
@cindex eigene Befehle, Textbeschriftung
@cindex markup, eigene Befehle
@cindex Befehle definieren, Textbeschriftung

Das @code{markup}-(Textbeschriftungs)Makro erstellt Textbeschriftungs-Ausdrücke
in Scheme, wobei eine LilyPond-artige Syntax benutzt wird.  Beispielsweise
ist

@example
(markup #:column (#:line (#:bold #:italic "hello" #:raise 0.4 "world")
                  #:larger #:line ("foo" "bar" "baz")))
@end example

@noindent
identisch mit

@example
#@{ \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.  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
@item @b{LilyPond} @tab @b{Scheme}
@item @code{\markup Text1} @tab @code{(markup Text1)}
@item @code{\markup @{ Text1 Text2 ... @}} @tab
        @code{(markup Text1 Text2 ... )}
@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}
@end multitable
@end quotation

Die gesamte Scheme-Sprache ist innerhalb des @code{markup}-Makros
zugänglich.  Man kann also beispielsweise Funktionen innerhalb
eines @code{markup} aufrufen, um Zeichenketten zu manipulieren.
Das ist nützlich, wenn neue Beschriftungsbefehle definiert werden
sollen (siehe auch
@ref{Neue Definitionen von Beschriftungsbefehlen}).


@knownissues

Das Beschriftungslistenargument von Befehlen wie @code{#:line},
@code{#:center} und @code{#:column} kann keine Variable oder
das Resultat eines Funktionsaufrufen sein.

@lisp
(markup #:line (Funktion-die-Textbeschriftung-ausgibt))
@end lisp

@noindent
ist ungültig.  Man sollte anstatt dessen die Funktionen
@code{make-line-markup}, @code{make-center-markup} oder
@code{make-column-markup} benutzen:

@lisp
(markup (make-line-markup (Funktion-die-Textbeschriftung-ausgibt)))
@end lisp


@node Wie Beschriftungen intern funktionieren
@subsection Wie Beschriftungen intern funktionieren
@translationof How markups work internally

In einer Textbeschriftung wie

@example
\raise #0.5 "Textbeispiel"
@end example

@noindent
ist @code{\raise} unter der Haube durch die @code{raise-markup}-Funktion
repräsentiert.  Der Beschriftungsausdruck wird gespeichert als

@example
(list raise-markup 0.5 (list simple-markup "Textbeispiel"))
@end example

Wenn die Beschriftung in druckbare Objekte (Stencils) umgewandelt ist,
wir die @code{raise-markup}-Funktion folgendermaßen aufgerufen:

@example
(apply raise-markup
       @var{\layout object}
       @var{Liste der Eigenschafts-alists}
       0.5
       @var{die "Textbeispiel"-Beschriftung})
@end example

Die @code{raise-markup}-Funktion erstellt zunächst den Stencil für die
@code{Textbeispiel}-Beschriftung und verschiebt dann diesen Stencil
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}.


@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-typ?} @var{Arg2-typ?} ...)
    [ #:properties ((@var{Eigenschaft1} @var{Standard-Wert1})
                    ...) ]
  ..Befehlkörper..)
@end lisp

Die Argumente sind:

@table @var
@item @var{befehl-bezeichnung}
die Bezeichnung des Befehls

@item @var{layout}
die @q{layout}-Definition

@item props
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

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.

Argumente werden nach ihrem Typ unterschieden:

@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

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.

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.


@node Über Eigenschaften
@unnumberedsubsubsec Über Eigenschaften
@translationof On properties

Die @code{layout}- und @code{props}-Argumente der Textbeschriftungsbefehle
bringen einen Kontext für die Interpretation der Beschriftung:
Schriftgröße, Zeilenlänge usw.

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
(ly:output-def-lookup layout 'line-width)
@end example

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.

Das Beispiel im nächsten Abschnitt illustriert, wie man auf Eigenschaften
in einem Beschriftungsbefehl zugreifen und sie verändern kann.


@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 \override #'(box-padding . 0.4) \box
            \override #'(box-padding . 0.6) \box @{ #text @}#@}))
@end lisp

oder äquivalent

@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
\markup \double-box A
@end example

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
    #@{\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 #:override `(box-padding . ,inter-box-padding) #:box
            #:override `(box-padding . ,box-padding) #:box text)))
@end lisp

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.

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.

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
    #{\markup \override #`(box-padding . ,inter-box-padding) \box
              \override #`(box-padding . ,box-padding) \box
              { #text } #}))

\markup \double-box A
\markup \override #'(inter-box-padding . 0.8) \double-box A
\markup \override #'(box-padding . 1.0) \double-box A
@end lilypond

@node Eingebaute Befehle anpassen
@unnumberedsubsubsec Eingebaute Befehle anpassen
@translationof Adapting builtin commands

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}.

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):

@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

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.

@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

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



@node Neue Definitionen von Beschriftungslistenbefehlen
@subsection Neue Definitionen von Beschriftungslistenbefehlen
@translationof New markup list command definition

Beschriftungslistenbefehle können mit dem Scheme-Makro
@code{define-markup-list-command} definiert werden, welches
sich ähnlich verhält wie das
@code{define-markup-command}-Makro, das schon beschrieben
wurde in @ref{Neue Definitionen von Beschriftungsbefehlen}.  Ein Unterschied
ist, dass bei diesem Listen-Makro eine ganze Liste an
Stencils ausgegeben wird.

Im folgenden Beispiel wird ein @code{\paragraph}-Beschriftungslistenbefehl
definiert, welcher eine Liste von Zeilen im Blocksatz ausgibt, von
denen die erste Zeile eingerückt ist.  Der Einzug wird aus dem
@code{props}-Argument entnommen.

@example
#(define-markup-list-command (paragraph layout props args) (markup-list?)
   #: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
@code{paragraph}-Beschriftungslistenbefehl als Argument eine Beschriftungsliste,
die @code{args} genannt wird.  Das Prädikat für Beschriftungslisten ist
@code{markup-list?}.

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 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
\markuplist @{
  \paragraph @{
    Die Kunst des Notensatzes wird auch als \italic @{Notenstich@} bezeichnet. Dieser
    Begriff stammt aus dem traditionellen Notendruck. Noch bis vor etwa
    20 Jahren wurden Noten erstellt, indem man sie in eine Zink- oder
    Zinnplatte schnitt oder mit Stempeln schlug.
  @}
  \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
    Vertiefungen schwärzten dann ein auf die Platte gelegtes Papier.
    Das Gravieren wurde vollständig von Hand erledigt.
  @}
@}
@end example


@node Kontexte für Programmierer
@section Kontexte für Programmierer
@translationof Contexts for programmers

@menu
* Kontextauswertung::
* Eine Funktion auf alle Layout-Objekte anwenden::
@end menu

@node Kontextauswertung
@subsection Kontextauswertung
@translationof Context evaluation

@cindex Aufrufen von Code während der Interpretation
@cindex On-the-fly Code ausführen

@funindex \applyContext

Kontexte können während ihrer Interpretation mit Scheme-Code
modifiziert werden.  Die Syntax hierfür ist

@example
\applyContext @var{function}
@end example

@var{function} sollte eine Scheme-Funktion sein, die ein
einziges Argument braucht, welches der Kontext ist, auf den
sie ausgeführt werden soll.  Der folgende Code schreibt
die aktuelle Taktzahl in die Standardausgabe
während der Kompilation.

@example
\applyContext
  #(lambda (x)
    (format #t "\nWe were called in barnumber ~a.\n"
     (ly:context-property x 'currentBarNumber)))
@end example



@node Eine Funktion auf alle Layout-Objekte anwenden
@subsection Eine Funktion auf alle Layout-Objekte anwenden
@translationof Running a function on all layout objects


@cindex Aufruf von Code für Layoutobjekte

@funindex \applyOutput

Der vielfältigste Weg, ein Objekt zu beeinflussen, ist
@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}
@end example

@noindent
wobei @var{proc} eine Scheme-Funktion ist, die drei Argumente
benötigt.

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
@item dem Layoutobjekt
@item dem Kontext, in dem das Objekt erstellt wurde
@item dem Kontext, in welchem @code{\applyOutput} bearbeitet wird.
@end itemize

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 ist es
ein @rinternals{Stem}-Objekt.

Hier ist eine Funktion, die mit @code{\applyOutput} benutzt
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))
            (< (abs (ly:grob-property grob 'staff-position)) 2))
       (set! (ly:grob-property grob 'transparent) #t)))

\relative c' {
  a'4 e8 <<\applyOutput #'Voice #blanker a c d>> b2
}
@end lilypond


@node Callback-Funktionen
@section Callback-Funktionen
@translationof Callback functions

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
@end example

Eigenschaften können auch auf eine Scheme-Prozedur gesetzt werden:

@lilypond[fragment,verbatim,quote,relative=2]
\override Stem.thickness = #(lambda (grob)
    (if (= UP (ly:grob-property grob 'direction))
        2.0
        7.0))
c b a g b a g b
@end lilypond

@noindent
In diesem Fall wird die Prozedur ausgeführt, sobald der Wert der
Eigenschaft während das Formatierungsprozesses angefordert wird.

Der größte Teil der Satzmaschinierie funktioniert mit derartigen
Callbacks.  Eigenschaften, die üblicherweise Callbacks
benutzen, sind u. A.:

@table @code
@item stencil
  Die Druckfunktion, die eine Ausgabe des Symbols hervorruft
@item X-offset
  Die Funktion, die die horizontale Position setzt
@item X-extent
  Die Funktion, die die Breite eines Objekts errechnet
@end table

Die Funktionen brauchen immer ein einziges Argument, das der
Grob ist.

Wenn Funktionen mit mehreren Argumenten aufgerufen werden müssen,
kann der aktuelle Grob mit einer Grob-Einschließung
eingefügt werden.  Hier eine Einstellung aus
@code{AccidentalSuggestion}:

@example
(X-offset .
  ,(ly:make-simple-closure
    `(,+
        ,(ly:make-simple-closure
           (list ly:self-alignment-interface::centered-on-x-parent))
      ,(ly:make-simple-closure
           (list ly:self-alignment-interface::x-aligned-on-self)))))
@end example

@noindent
In diesem Beispiel werden sowohl @code{ly:self-alignment-interface::x-aligned-on-self}
als auch @code{ly:self-alignment-interface::centered-on-x-parent}
mit dem Grob als Argument aufgerufen.  Die Resultate werden mit der
@code{+}-Funktion addiert.  Um sicherzugehen, dass die Addition
richtig ausgeführt wird, wird das ganze Konstrukt in
@code{ly:make-simple-closure} eingeschlossen.

In der Tat ist die Benutzung einer einzelnen Funktion als
Eigenschaftswert äquivalent zu

@example
(ly:make-simple-closure (ly:make-simple-closure (list @var{proc})))
@end example

@noindent
Das innere @code{ly:make-simple-closure} stellt den Grob als Argument
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 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

\relative c'' @{
  c4^\F c4_\F
@}
@end example

@noindent
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
wie @code{\displayMusic} benutzt wird, hilft hier weiter.

@example
F = #(let ((m (make-music 'ArticulationEvent
                          'articulation-type "flageolet")))
       (set! (ly:music-property m 'tweaks)
             (acons 'font-size -3
                    (ly:music-property m 'tweaks)))
       m)

\relative c'' @{
  c4^\F c4_\F
@}
@end example

@noindent
In diesem Beispiel werden die @code{tweaks}-Eigenschaften
des Flageolet-Objekts @code{m} (mit @code{make-music} erstellt)
werden mit @code{ly:music-property} ausgelesen, ein neues
Schlüssel-Wert-Paar, um die Schriftgröße zu ändern, wird
der Eigenschaftenliste mithilfe der @code{acons}-Schemefunktion
vorangestellt, und das Resultat wird schließlich mit
@code{set!} zurückgeschrieben.  Das letzte Element des
@code{let}-Blocks ist der Wiedergabewert, @code{m}.



@node Schwierige Korrekturen
@section Schwierige Korrekturen
@translationof Difficult tweaks

Hier finden sich einige Klassen an schwierigeren Anpassungen.

@itemize

@item
Ein Typ der schwierigen Anpassungen ist die Erscheinung von
Strecker-Objekten wie Binde- oder Legatobögen.  Zunächst wird
nur eins dieser Objekte erstellt, und sie können mit dem
normalen Mechanismus verändert werden.  In einigen Fällen
reichen die Strecker jedoch über Zeilenumbrüche.  Wenn das
geschieht, werden diese Objekte geklont.  Ein eigenes
Objekt wird für jedes System erstellt, in dem es sich befindet.
Sie sind Klone des originalen Objektes und erben alle
Eigenschaften, auch @code{\override}-Befehle.

Anders gesagt wirkt sich ein @code{\override} immer auf alle
Stücke eines geteilten Streckers aus.  Um nur einen Teil eines
Streckers bei einem Zeilenumbruch zu verändern, ist es notwendig,
in den Formatierungsprozess einzugreifen.  Das Callback
@code{after-line-breaking} enthält die Schemefunktion, die
aufgerufen wird, nachdem Zeilenumbrüche errechnet worden sind
und die Layout-Objekte über die unterschiedlichen Systeme verteilt
wurden.

Im folgenden Beispiel wird die Funktion
@code{my-callback} definiert.  Diese Funktion

@itemize
@item
bestimmt, ob das Objekt durch Zeilenumbrüche geteilt ist,
@item
wenn ja, ruft sie alle geteilten Objekte auf,
@item
testet, ob es sich um das letzte der geteilten Objekte handelt,
@item
wenn ja, wird @code{extra-offset} gesetzt.
@end itemize

Diese Funktion muss in @rinternals{Tie} (Bindebogen) installiert
werden, damit der letzte Teil eines gebrochenen Bindebogens
neu ausgerichtet wird.

@lilypond[quote,verbatim,ragged-right]
#(define (my-callback grob)
  (let* (
         ; have we been split?
         (orig (ly:grob-original grob))

         ; if yes, get the split pieces (our siblings)
         (siblings (if (ly:grob? orig)
                     (ly:spanner-broken-into orig) '() )))

   (if (and (>= (length siblings) 2)
             (eq? (car (last-pair siblings)) grob))
     (ly:grob-set-property! grob 'extra-offset '(-2 . 5)))))

\relative c'' {
  \override Tie.after-line-breaking =
  #my-callback
  c1 ~ \break c2 ~ c
}
@end lilypond

@noindent
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:spanner::kill-zero-spanned-time} aufgerufen werden.


@item
Manche Objekte können aus technischen Gründen nicht mit @code{\override}
verändert werden.  Beispiele hiervon sind @code{NonMusicalPaperColumn}
und @code{PaperColumn}.  Sie können mit der
@code{\overrideProperty}-Funktion geändert werden, die ähnlich wie
@code{\once \override} funktioniert, aber eine andere Syntax einsetzt.

@example
\overrideProperty
Score.NonMusicalPaperColumn  % Grob-Bezeichnung
#'line-break-system-details     % Eigenschaftsbezeichnung
#'((next-padding . 20))         % Wert
@end example

Es sollte angemerkt werden, dass @code{\override}, wenn man es auf
@code{NonMusicalPaperColumn} und @code{PaperColumn} anwendet, immer noch
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?
