Hallo Ingmar,
so, jetzt versuche ich die Erklärung und ein funktionierendes Beispiel nachzureichen.
Wer sich die Mühe macht, die Lilypond-Dokumentation zu studieren, wird recht bald damit konfrontiert, dass Lilypond und die Programmiersprache Scheme ganz eng verkoppelt sind. Scheme ist eine Sprache, die keine Strenge Trennung zwischen Programmtext und Daten kennt.
Was macht nun Lilypond? Vereinfacht gesagt, es nimmt die .ly-Dateien, macht Scheme-Code daraus und wirft das dem Scheme-Interpreter "vor die Füße".
Irgendwo steht sinngemäß: "Musikalische Ausdrücke sind Scheme-Ausdrücke." Das ist auch der Grund warum man beides Mischen kann.
Die Übersetzung der Lilypond-Dateien ist möglich, weil es eine Syntax für Lilypond gibt. Die Syntax sieht vor, dass man Variablen verwenden kann. Die einfach Schreibweise
<platzhalter>=<inhalt>
ist aber nur auf der "untersten" Ebene (außerhalb der geschweiften Klammern) möglich, denn "drüber" ist alles schon "in der Scheme"-Welt. (Anmerkung: mir ist bewusst, dass das extrem vereinfacht ist, aber manchmal heiligt der Zweck die Mittel ...)
Diese Erkenntnis ist schon die halbe Miete. Wenn man also innerhalb eines book-Blocks ist, kann man die einfache Variablenschreibweise nicht verwenden und muss auf die Scheme-Syntax ausweichen. Die sieht dann so aus: Aus <platzhalter>=<inhalt> wird (define <platzhalter> <inhalt>). Zusätzlich, da es ja eine Lilypond-Datei ist, die vom Lilypond-Parser verarbeitet wird, müssen wir noch ein # vor die öffnende runde Klammer stellen. Fertig ist die Laube.
Damit sieht der ursprüngliche Code so aus, stellt den Lilypond-Interpreter zufrieden und liefert das erwartete Ergebnis:
\version "2.16.2"
\markuplist \table-of-contents
\bookpart {
#(define TT "Erstes")
\tocItem \markup \TT
\score { { c' d' e' f' g' } }
\header { piece = \TT }
}
\bookpart {
#(define TT "Zweites")
\tocItem \markup \TT
\score { { c'' b' a' g' f' } }
\header { piece = \TT }
}
Grüße und schönes Wochenende
Martin