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

@ignore
    Translation of GIT committish: 7b70644b95f383b4281e9ffa146d315d2ada11d3

    When revising a translation, copy the HEAD committish of the
    version that you are working on.  See TRANSLATION for details.
@end ignore

@c \version "2.12.0"

@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
@rlearning{Scheme-Übung}.

@menu
* Musikalische Funktionen::
* Schnittstelle für Programmierer::
* Komplizierte Funktionen erstellen::
* Programmierungsschnittstelle für Textbeschriftungen::
* Kontexte für Programmierer::
* Scheme-Vorgänge als Eigenschaften::
* Scheme-Code anstelle von \tweak verwenden::
* 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

Es ist einfach, eine Funktion zu erstellen, die Variablen
im LilyPond-Code ersetzt.  Die allgemeine Form derartiger
Funktionen ist

@example
function =
#(define-music-function (parser location @var{var1} @var{var2}...@var{vari}... )
                        (@var{var1-type?} @var{var2-type?}...@var{vari-type?}...)
  #@{
    @emph{...Noten...}
  #@})
@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

Die folgenden Eingabetypen können als Variablen in einer musikalischen
Funktion benutzt werden.  Diese Liste ist nicht vollständig -- siehe
auch andere Dokumentationen überScheme für weitere Variablenarten.

@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

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 Einfache Ersetzungsfunktionen
@subsection Einfache Ersetzungsfunktionen
@translationof Simple substitution functions

Hier ist ein einfaches Beispiel:

@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


@node Paarige Ersetzungsfunktionen
@subsection Paarige Ersetzungsfunktionen
@translationof Paired substitution functions

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.

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

{ c'2 \AltOn #0.5 c'4 c'
  \AltOn #1.5 c' c' \AltOff c'2 }
@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 #})

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

@example
noPointAndClick =
#(define-music-function (parser location) ()
   (ly:set-option 'point-and-click #f)
   (make-music 'SequentialMusic 'void #t))
...
\noPointAndClick   % disable point and click
@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:

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



@node Schnittstelle für Programmierer
@section Schnittstelle für Programmierer
@translationof Programmer interfaces

Dieser Abschnitt zeigt, wie LilyPond und
Scheme gemischt werden können.

@menu
* Eingabevariablen und Scheme::
* Interne Repräsentation der Musik::
@end menu


@node Eingabevariablen und Scheme
@subsection Eingabevariablen und Scheme
@translationof Input variables and Scheme

Das Eingabeformat unterstützt die Notation von Variablen: im
folgenden Beispiel wird ein musikalischer Ausdruck einer Variable
mit der Bezeichnung @code{traLaLa} zugewiesen:

@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 Geltunsbereich 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{... }'})
@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 Schme
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}-Devinition 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

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:

@example
#(define (nopc)
  (ly:set-option 'point-and-click #f))

...
#(nopc)
@{ c'4 @}
@end example

@knownissues

Scheme- und LilyPond-Variablen können im LilyPond-Modus mit der
@code{--safe}-Option nicht vermischt werden.


@node Interne Repräsentation der Musik
@subsection Interne Repräsentation der Musik
@translationof Internal music representation

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.

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

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

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

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

@example
#(display-scheme-music
   (ly:music-property (first (ly:music-property someNote 'elements))
                      'pitch))
===>
(ly:make-pitch 0 0 0)
@end example

Die Tonhöhe einer Note kann geändert werden, indem man diese
@code{'pitch}-Eigenschaft umdefiniert:

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

@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

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.

Jetzt folgt eine Betrachtung der Eingabe:

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


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

Eine @code{$variable} innerhalb von @code{#@{...#@}} ist das
gleiche wie die normale Befehlsform @code{\variable} in
üblicher LilyPond-Notation.  Es ist bekannt dass

@example
@{ \music -. -> @}
@end example

@noindent
in LilyPond nicht funktioniert.  Das Problem könnte vermieden
werden, indem das Artikulationszeichen an eine Pseudonote
gehängtwird:

@example
@{ << \music s1*0-.-> @}
@end example

@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

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}-Ausdrcuk zu der Elementeigenschaft
des @code{EventChord}-Ausdrucks hinzugefügt werden.

Um diese Funktion zu bauen, wird folgerndermaß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

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

@example
"Add a marcato..."
@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.

@example
(let ((result-event-chord (ly:music-deep-copy event-chord)))
@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 gleichzeigt eine Kopie
von @code{event-chord} ist.  Das Makro wird seiner Eigenschaftsliste
hinzugefügt:

@example
(set! place new-value)
@end example

Was in diesem Fall @qq{gesetzt} werden soll (@qq{place}) ist die
@q{elements}-Eigenschaft des @code{result-event-chord}-Ausdrucks.

@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 Elemtneigenschaft war, mit einem
zusätzlichen Element: dem @code{ArticulationEvent}-Ausdruck,
der aus der Ausgabe von
@code{\displayMusic} kopiert werden kann:

@example
(cons (make-music 'ArticulationEvent
        'articulation-type "marcato")
      (ly:music-property result-event-chord 'elements))
@end example

@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 hinzuzugefügt ist, kann
@code{result-event-chord} ausgegeben werden, darum die letzte Zeile
der Funktion.

Jetzt wird die @code{add-marcato}-Funktion in eine musikalische
Funktion umgewandelt:

@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

Eine Überprüfung, dass die Funktion richtig arbeitet, geschieht
folgendermaßen:

@example
\displayMusic \addMarcato c4
@end example


@node Programmierungsschnittstelle für Textbeschriftungen
@section Programmierungsschnittstelle für Textbeschriftungen
@translationof Markup programmer interface

Textbeschriftungselemente sind als besondere Scheme-Funktionen
definiert, die ein 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::
@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.

@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{\Befehl} @tab @code{#:Befehl}
@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ächt 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

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?} ...)
  ..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
die @q{layout}-Definition
@item props
eine Liste an alists, in der alle aktiven Eigenschaften enthalten sind
@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:

@example
\markup @{ \override #'(font-shape . caps) Text-in-Kapitälchen @}
@end example

@noindent
Damit wird die Kapitälchenschriftart ausgewählt, indem die
@code{font-shape}-Eigesnchaft auf @code{#'caps} gesetzt wird,
während @code{Text-in-caps} interpretiert wird.

Damit diese Funkion 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:

@example
(define-markup-command (smallcaps layout props argument) (markup?)
@end example

@noindent

Was jetzt folgt, ist der eigentliche Inhalt des Befehls: das
@code{argument} soll als Beschriftung (markup) interpretiert werden,
also:

@example
(interpret-markup layout @dots{} argument)
@end example

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

@example
(cons (list '(font-shape . caps) ) props)
@end example

@noindent
Die Variable @code{props} ist eine Liste an alists, und mit @code{cons}
wird ihr eine zusätzliche Einstellung hinzugefügt.

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:

@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\""
  (interpret-markup layout props
   (markup #:hspace 0 #:translate (cons -3 1) #:smallcaps name)))
@end example

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.

Das Resultat sieht folgendermaßen aus:

@example
@{
  c''^\markup \character #"Cleopatra"
  e'^\markup \character #"Giulio Cesare"
@}
@end example

@lilypond[quote,ragged-right]
#(define-markup-command (smallcaps layout props str) (string?)
  "Print the string argument in small caps.  Syntax: \\smallcaps #\"string\""
  (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\""
  (interpret-markup layout props
   (markup #:hspace 0 #:translate (cons -3 1) #:smallcaps name)))

{
  c''^\markup \character #"Cleopatra" c'' c'' c''
  e'^\markup \character #"Giulio Cesare" e' e' e'
}
@end lilypond

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:

@example
#(define-markup-command (smallcaps layout props str) (string?)
  "Print the string argument in small caps."
  (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

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

@knownissues

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

@noindent
Hier stellt @var{scm} native Scheme-Datentypen dar wie
@q{number} oder @q{string}.

Es ist beispielsweise nicht möglich, einen Beschriftungsbefehl
@code{foo} mit vier Argumenten in folgender Weise zu nutzen:

@example
#(define-markup-command (foo layout props
                         num1    str1    num2    str2)
                        (number? string? number? string?)
  ...)
@end example

@noindent
Wenn es folgendermaßen eingesetzt wird:

@example
\markup \foo #1 #"bar" #2 #"baz"
@end example

@cindex Scheme signature
@cindex Signatur, Scheme
@noindent
beschwert sich @command{lilypond}, dass @code{foo} wegen einer ungekannten
Scheme Signatur nicht analysiert werden kann.


@node Neue Definitionen von Beschriftungsbefehlen für Listen
@subsection Neue Definitionen von Beschriftungsbefehlen für Listen
@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
Stecils 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?)
   (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)))))
@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 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.

Dieser neue Beschriftungslistenbefehl kann wie folgt benutzt werden:

@example
\markuplines @{
  \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 Taktzahlshould 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}.  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 @var{proc} für
jedes Layoutobjekt aufgerufen, dass im Kontext @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
(ein @rinternals{Stem}-Objekt) ist es ein @rinternals{NoteHead}-Objekt.

Hier ist eine Funktion, die mit @code{\applyOutput} benutzt
werden kann; sie macht Notenköpfe auf 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))
       (set! (ly:grob-property grob 'transparent) #t)))

\relative {
  e4 g8 \applyOutput #'Voice #blanker b d2
}
@end lilypond


@node Scheme-Vorgänge als Eigenschaften
@section Scheme-Vorgänge als Eigenschaften
@translationof Scheme procedures as properties

Eigenschaften (wie Dicke, Richtung 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, sobal der Wert der
Eigenschaft während das Formatierungsprozesses angefordert wird.

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

@table @code
@item stencil
  Die Druckfunktion, die eine Ausgabe des Symbols ervorruft
@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.


@node Scheme-Code anstelle von \tweak verwenden
@section Scheme-Code anstelle von @code{	weak} verwenden
@translationof Using Scheme code instead of \tweak

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
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
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, und der letzte Teil eines gebrochenen Bindebogens wird
nach oben verschoben.

@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:hairpin::after-line-breaking} 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, immernoch
innerhalb der @code{\context}-Umgebung funktioniert.

@end itemize
