Hi,
zunächst möchte ich mich für die Unterstützung ganz herzlich bedanken, allen voran bei harm und fugenkomponist.
Wie ich
hier berichtete, arbeite ich an einem Liederbuch. Da ich mich nicht in LaTeX einfuchsen wollte, habe ich versucht, das gesamte Unternehmen ausschließlich in Lilypond zu realisieren. Vielleicht helfen meine Erfahrungen auch anderen, daher dieser Thread (und außerdem ein kleines Code-Repository, falls ich meine Daten auf der Festplatte wieder einmal nicht finde

).
Die für mich am meisten überraschende Erkenntnis war die, dass Lilypond-Variablendefinition der Art
firstvoice=
\relative c'' {
c
}
niemals innerhalb geschwungener Klammern stehen dürfen. Das bedeutet, dass ich diesen Code nicht mit \include in einen bookpart-einfügen kann. Wie beispielsweise
diese Diskussion in der Mailliste zeigt, bin ich nicht die Einzige, die über diesen Umstand gestolpert ist. Möglicherweise bin ich einfach zu blöd gewesen, um es zu begreifen, aber aus der Dokumentation geht dieser außerordentlich wichtige Umstand zumindest für mich nicht klar hervor.
Ich habe verschiedene Herangehensweisen probiert. Zunächst bastelte ich eine große Datei, wobei die Schwierigkeit darin bestand, Variablennamen zu erzeugen. Bekanntlich dürfen Lilypond-Variablen nur Buchstaben enthalten, weder Ziffern noch Sonderzeichen, nicht einmal Bindestriche oder Underscores. Ich fand einen Workaround (der noch immer unapproved im Repository steht), dies kombiniert mit einem anderen "Trick" aus dem Forum ergab folgendes:
myTitel="Die lustigen Hammerschmiegsölln"
%% Variablen für 1. und 2. Stimmen
#(ly:parser-include-string (string-append "\"m" myTitel "1\"")) =
\relative c'' { c }
#(ly:parser-include-string (string-append "\"m" myTitel "2\"")) =
\relative c' { c }
%% Variable für Akkordbezeichnungen
#(ly:parser-include-string (string-append "\"c" myTitel "\"")) =
\chordmode { c }
%% Texte für Strophen 1+2
#(ly:parser-include-string (string-append "\"l" myTitel "1\"")) = \lyricmode {
\set stanza = #"1. "
Strophe I
}
#(ly:parser-include-string (string-append "\"l" myTitel "2\"")) = \lyricmode {
\set stanza = #"1. "
Strophe II
}
\score
{
<<
\new Staff="leadsheet" \with {
}
<<
\tocItem \markup #myTitel
<<
\context Voice="melody" {
#(ly:parser-include-string (string-append "\\\"m" myTitel "1\""))
}
\context Voice="sndvoice"
{ #(ly:parser-include-string (string-append "\\\"m" myTitel "2\"")) }
>>
\new Lyrics \lyricsto "melody" {
#(ly:parser-include-string (string-append "\\\"l" myTitel "1\""))
}
\new Lyrics \lyricsto "melody" {
#(ly:parser-include-string (string-append "\\\"l" myTitel "2\""))
}
>>
\context ChordNames
{ #(ly:parser-include-string (string-append "\\\"c" myTitel "\"")) }
>>
\header {
title = #myTitel
poet = ""
composer = \markup {
\override #'(baseline-skip . 1)
\right-column {
"Text: Volkslied"
"Melodie: Volksweise"
}
}
piece = ##f
opus = ##f
}
}
%% ... und dann noch der Liedtext als Markup
Der Nachteil dieser Variante: bereits nach wenigen Liedern wurde die 1000-Zeile Grenze für den Code überschritten, die Reihenfolge der Lieder lässt sich nur mit Aufwand wieder ändern.
Also änderte ich meine Vorgangsweise und lagerte den Code für jedes Lied in eine eigene Datei aus. Das hatte den Vorteil, dass ich die Variablen in allen einzelnen Lieddateien gleich nennen konnte und somit die Struktur der Lieddateien klarer und übersichtlicher wurde.
Ich bastelte mir eine Vorlagendatei in dieser Art
\language "deutsch"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%% Lied Muster
%%%%%%%% Anfang
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
myTitel="LiedTitel"
%% Voice 1
firstvoice =
\relative c'' {
c
}
%% Voice 2
secondvoice =
\relative c' {
s4
}
%% Chords
songchords =
\chordmode {
c
}
%% Song Lyrics
firstverse = \lyricmode {
\set stanza = #"1. "
1. Strophe
}
secondverse = \lyricmode {
\set stanza = #"2. "
Strophe xx
}
thirdverse = \lyricmode {
\set stanza = #"3. "
Strophe xxx
}
fourthverse = \lyricmode {
\set stanza = #"4. "
Strophe xxxx
}
fifthverse = \lyricmode {
\set stanza = #"5. "
Strophe xxxxx
}
\score
{
<<
\new Staff="leadsheet"
<<
\tocItem \markup #myTitel
\context FirstVoice="melody" \firstvoice
\context SecondVoice="sndvoice" \secondvoice
>>
\new Lyrics \lyricsto "melody" \firstverse
\new AltLyrics \lyricsto "melody" \secondverse
\new Lyrics \lyricsto "melody" \thirdverse
\new AltLyrics \lyricsto "melody" \fourthverse
\new Lyrics \lyricsto "melody" \fifthverse
\context ChordNames \songchords
>>
\header {
title = #myTitel
poet = ##f
composer = \markup {
\override #'(baseline-skip . 1)
\right-column {
"Text: Volkslied"
"Melodie: Volksweise"
}
}
piece = ##f
opus = ##f
}
}
%% Songtext
\markup {
\column {
\fill-line {
\hspace #0.1 % moves the column off the left margin;
% can be removed if space on the page is tight
\column {
\line {
\bold "2."
\column {
"This is verse two."
"It has two lines."
}
}
\vspace #Absatz
\line {
\bold "3."
\column {
"This is verse three."
"It has two lines."
}
}
}
\hspace #0.1 % adds horizontal spacing between columns;
\column {
\line {
\bold "4."
\column {
"This is verse four."
"It has two lines."
}
}
\vspace #Absatz
\line {
\bold "5."
\column {
"This is verse five."
"It has two lines."
}
}
}
\hspace #0.1 % gives some extra space on the right margin;
% can be removed if page space is tight
}
\vspace #Absatz
\fill-line
{
\line {
\bold "6."
\column {
"This is a single verse five."
"centered in the line."
}
}
}
}
}Die Formatierung lagerte ich in eine eigene Datei aus, wo ich die Contexte FirstVoice, SecondVoice und AltLyrics definierte.
\layout {
\context {
\Voice
\name FirstVoice
\alias Voice
autoBeaming = ##f
\override NoteCollision.merge-differently-dotted = ##t
\override NoteCollision.merge-differently-headed = ##t
\override Stem.direction = #UP
\override Slur.direction = #UP
\override Tie.direction = #UP
\override NoteColumn.horizontal-shift = #0
}
\context {
\Voice
\name SecondVoice
\alias Voice
\remove "Slur_engraver"
\remove "Tuplet_engraver"
\remove "Rest_engraver"
\remove "Multi_measure_rest_engraver"
% alignBelowContext = #"firstvoice"
autoBeaming = ##f
\override NoteCollision.merge-differently-dotted = ##t
\override NoteCollision.merge-differently-headed = ##t
\override NoteHead.font-size = #smallerNoteHead
\override Stem.direction = #DOWN
\override Tie.direction = #DOWN
\override NoteColumn.horizontal-shift = #0
}
\context {
\Staff
\accepts FirstVoice
\accepts SecondVoice
}
\context {
\StaffGroup
\accepts AltLyrics
}
\context {
\Lyrics
\override LyricText.font-size =#1
}
\context {
\Lyrics
\name AltLyrics
\alias Lyrics
\override StanzaNumber.font-series = #'bold
\override LyricText.font-shape = #'italic
}
\context {
\Score
\remove System_start_delimiter_engraver
\remove "Bar_number_engraver"
beamExceptions = #'()
}
\context {
\ChordNames
chordNameLowercaseMinor = ##f
majorSevenSymbol = \markup { maj7 }
chordChanges = ##f
alignAboveContext = #"leadsheet"
}
\context {
\Voice
\override NoteCollision.merge-differently-dotted = ##t
\override NoteCollision.merge-differently-headed = ##t
beamExceptions = #'()
autoBeaming = ##f
\override BreathingSign.text =
\markup { \musicglyph #"scripts.lvarcomma" }
}
}Wie im zuerst erwähnten Thread beschrieben, bereitete mir das Inhaltsverzeichnis ein Problem, weil ich zu viele überflüssige Definitionen in die Paper-Umgebung eingebaut hatte. Das Inhaltsverzeichnis musste ich in einen eigenen Bookpart auslagern:
\bookpart {
\paper {
top-margin = 15\mm
ragged-right = ##f
ragged-bottom = ##t
ragged-last-bottom = ##t
bottom-margin = 10\mm
indent = #0
line-width = 120\mm
#(include-special-characters)
print-page-number = ##t
first-page-number = #1
print-first-page-number = ##t
tocItemMarkup = \tocItemWithDotsMarkup
tocActMarkup = \markup \fontsize #1 \column {
\hspace #1
\line { \italic \fromproperty #'toc:text \null }
\hspace #1
}
tocTitleMarkup = \markup \column {
\fontsize #4 \sans \bold \fill-line { \null "Liederverzeichnis" \null }
\hspace #1
}
}
\markuplist \table-of-contents
}Der Versuch, das gleiche mit den Include-Statements durchzuführen, scheiterte an dem eingangs erwähnte Umstand. Woraufhin ich begann, die Vorlage umzuschreiben. Die Änderung der Lilypond-Variablendefinition in eine Scheme-eigene umgeht dieses Problem nämlich, es heißt dann
#(define firstvoice #{ \relative c'' { c } #} )Was zwar nicht besonders schön zu lesen, aber praktikabel war. Bis ich auf den entscheidenden Nachteil dieser Konstruktion stieß. Ich verwende nämlich Frescobaldi als Editor. Dieser hat die schöne Eigenschaft, dass ich durch Anklicken einer Note im PDF sofort zur passenden Stelle im Lilypond-Code springen kann. Durch die eben beschriebene Änderung der Variablendefinition geht diese für mich unverzichtbare Eigenschaft verloren. Somit definiere ich wieder die Variablen in Lilypond-Manier und vermeide es, die \include-Statements in einem bookpart zu verwenden.
Meine Steuerdatei schaut jetzt also etwa folgendermaßen aus
\version "2.19.37"
\language "deutsch"
#(set-global-staff-size 18)
FootLeft = #(string-append "" )
FootCenter = #(string-append "")
FootLeft = #(string-append "gesetzt mit LILYPOND " (lilypond-version) " am " (strftime "%d.%m.%Y %H:%M:%S" (localtime (current-time))))
tocAct = #(define-music-function (text) (markup?)
(add-toc-item! 'tocActMarkup text))
%% ... dann kommen die Definitionen für das Inhaltsverzeichnis, hier weggelassen
\bookpart {
\paper {
%% .... Definitionen für das Inhaltsverzeichnis
}
\markuplist \table-of-contents
}
\layout {
\context {
\Voice
}
%% alle Kontexte
}
}
\paper {
top-margin = 15\mm
ragged-right = ##f
ragged-bottom = ##t
ragged-last-bottom = ##t
bottom-margin = 10\mm
indent = #0
line-width = 150\mm
print-all-headers = ##t
#(include-special-characters)
%print-all-headers = ##t
page-number-type = #'arabic
print-page-number = ##t
first-page-number = #1
print-first-page-number = ##t
%% Abstand von Liedtext zu nachfolgender Überschrift
markup-markup-spacing = #'((basic-distance . 12)
(minimum-distance . 5)
(padding . 5)
(stretchability . 40))
%% Abstand eines Liedes ohne nachfolgenden Liedtext zu nachfolgender Überschrift
score-markup-spacing = #'((basic-distance . 12)
(minimum-distance . 5)
(padding . 5)
(stretchability . 40))
}
\tocAct \markup "Morgen- und Abendlieder" %% Kapitelüberschrift
%% Liste der Lieder
\include "__/gutenabend.ly"
\include "__\mond.ly"
\include "__\abendstille.ly"
\include "__\adezur.ly"
%% uswPS: weitere Threads zum Thema:
Alphabetisch sortierter IndexAlphabetisch sortierter Index