Ein vollständiges Bespiel (LilyPond erweitern)

#### Ein vollständiges Bespiel

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 Textbeschriftungsbefehle finden wir den Befehl `\box`:

>     \markup \box \box HELLO

Wir wollen aber etwas mehr Abstand (engl. padding) zwischen dem Text und dem Kasten. Nach der Dokumentation von `\box` hat der Befehl eine `box-padding`-Eigenschaft, die den Standardwert von 0.2 hat. Die Dokumentation zeit auch, wir man den Wert verändert:

>     \markup \box \override #'(box-padding . 0.6) \box A

Auch der Abstand zwischen den zwei Kästen ist uns zu klein und soll auch vergrößert werden:

>     \markup \override #'(box-padding . 0.4) \box
>         \override #'(box-padding . 0.6) \box A

Diese lange Textbeschriftung immer wieder schreiben zu müssen, ist anstrengend. Hier kömmt ein Textbeschriftungsbefehl ins Spiel. Wir schreiben uns alle einen `double-box`-Beschriftungsbefehl, der ein Argument annimmt (den Text). Er zeichnet zwei Kästen mit genügend Abstand:

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

oder äquivalent

    #(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)))

`text` ist die Bezeichnung des Arguments dieses Befehls, und `markup?` ist seine Art: hiermit wird der Befehl als Beschriftungsbefehl identifiziert. Die `interpret-markup`-Funktion wird in den meisten Beschriftungsbefehlen benutzt: sie erstellt einen Stencil, wobei `layout`, `props` und eine Beschriftung benutzt werden. Im zweiten Fall wird diese Beschriftung durch das `markup`-Scheme-Makro erstellt, siehe auche Beschriftungskonstruktionen in Scheme. Die Transformation des `\markup`-Ausdrucks in einen Scheme-Beschriftungsausdruck geschieht durch Umschreiben des LilyPond-Codes in Scheme-Code.

Der neue Befehl kann wie folgt benutzt werden:

    \markup \double-box A

Es wäre schön, den `double-box`-Befehl noch konfigurierbar zu gestalten: in unserem Fall sind die Werte von `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: `inter-box-padding` für den Abstand zwischen den Kästen. `box-padding` wird für den inneren Abstand benutzt. Der neue Befehl wird so definiert:

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

Wiederum wäre die entsprechende Version mit dem `markup`-Makro so aussehen:

    #(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)))

In diesem Code wird das `#:properties`-Schlüsselwort benutzt, sodass die Eigenschaften `inter-box-padding` und `box-padding` aus dem `props`-Argument ausgelesen werden, und Standardwerte werden gegeben, falls die Eigenschaften nicht definiert sein sollten.

Dann werden diese Werte benutzt, um die `box-padding`-Eigenschaft zu verändert, die von beiden `\box`-Befehlen benutzt wird. Beachten Sie Akzent und das Komma des `\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:

>     #(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

#### LilyPond erweitern v2.26.0 (stable-branch).

- 1 Scheme-Tutorium
  - 1.1 Einleitung in Scheme
    - 1.1.1 Scheme-Sandkasten
    - 1.1.2 Scheme-Variablen
    - 1.1.3 Einfache Scheme-Datentypen
    - 1.1.4 Zusammengesetzte Scheme-Datentypen
    - 1.1.5 Berechnungen in Scheme
    - 1.1.6 Scheme-Prozeduren
    - 1.1.7 Scheme-Konditionale
  - 1.2 Scheme in LilyPond
    - 1.2.1 LilyPond Scheme-Syntax
    - 1.2.2 LilyPond-Variablen
    - 1.2.3 Eingabe-Variablen und Scheme
    - 1.2.4 Scheme in LilyPond importieren
    - 1.2.5 Objekteigenschaften
    - 1.2.6 Zusammengesetzte LilyPond-Variablen
    - 1.2.7 Interne musikalische Repräsentation
  - 1.3 Komplizierte Funktionen erstellen
    - 1.3.1 Musikalische Funktionen darstellen
    - 1.3.2 Eigenschaften von Musikobjekten
    - 1.3.3 Verdoppelung einer Note mit Bindebögen (Beispiel)
    - 1.3.4 Artikulationszeichen zu Noten hinzufügen (Beispiel)
- 2 Schnittstellen für Programmierer
  - 2.1 LilyPond-Codeabschnitte
  - 2.2 Scheme-Funktionen
    - 2.2.1 Definition von Scheme-Funktionen
    - 2.2.2 Benutzung von Scheme-Funktionen
    - 2.2.3 Leere Scheme-Funktionen
  - 2.3 Musikalische Funktionen
    - 2.3.1 Definition der musikalischen Funktionen
    - 2.3.2 Benutzung von musikalischen Funktionen
    - 2.3.3 Einfache Ersetzungsfunktionen
    - 2.3.4 Mittlere Ersetzungsfunktionen
    - 2.3.5 Mathematik in Funktionen
    - 2.3.6 Funktionen ohne Argumente
    - 2.3.7 Leere musikalische Funktionen
  - 2.4 Ereignisfunktionen
  - 2.5 Textbeschriftungsfunktionen
    - 2.5.1 Beschriftungskonstruktionen in Scheme
    - 2.5.2 Wie Beschriftungen intern funktionieren
    - 2.5.3 Neue Definitionen von Beschriftungsbefehlen
      - Syntax der Definition von Textbeschriftungsbefehlen
      - Über Eigenschaften
      - Ein vollständiges Bespiel
      - Eingebaute Befehle anpassen
    - 2.5.4 Neue Definitionen von Beschriftungslistenbefehlen
  - 2.6 Kontexte für Programmierer
    - 2.6.1 Kontextauswertung
    - 2.6.2 Eine Funktion auf alle Layout-Objekte anwenden
  - 2.7 Callback-Funktionen
  - 2.8 Scheme-Code innerhalb LilyPonds
  - 2.9 Schwierige Korrekturen
- 3 LilyPond Scheme-Schnittstellen
- Appendix A GNU Free Documentation License
- Appendix B Register