Hallo Lilypond-Fans,
und hier kommt die zweite Iteration. Ausdrucken und Nachmessen hatte noch zu einer interessanten Erkenntnis geführt. Auch wenn der Spaltenabstand richtig mit ly:cm angegeben worden war, im Ausdruck wurde deutlich mehr Platz dazwischen gestellt. Es erwies sich, dass der Ausdruck um das 1,6-fache breiter war als gewünscht.
Bezüglich der Ursache tappe ich noch etwas im Nebel. Ich habe Indizien gefunden, dass es mit der Standard-Maß-Eigenschaft stretchability von space zusammen hängt. Dieser Spur werde ich separat nachgehen. Diesem Effekt wird vorläufig durch einen Korrekturfaktor Rechnung getragen, s.u.
Harms Anregung Properties für die Breite des Spaltenzwischenraums habe ich aufgegriffen. Nun kann man diesen Wert individuell einstellen, damit lässt sich columns auch wieder getrennt vom eigentlichen Lilypond-Dokument ablegen.
Hier nun die aktualisierte Fassung:
#(define-markup-command (columns layout props args) (markup-list?)
#:properties ((column-separator (ly:mm 5)) ; default value
(separator-min-width 0.6)) ; minimum value
(let* ((n (length args)) ; number of arguments is number of columns
(eff-cs (/ column-separator 1.58)) ; workaround, compensate stretching
(w (- eff-cs separator-min-width)) ; w idth of additional horizontal space between columns
(line-width (/ (- (chain-assoc-get 'line-width props
(ly:output-def-lookup layout 'line-width))
(* (if (<= w 0.0) separator-min-width eff-cs) (- n 1)))
n))
)
(ly:debug (format #f "markup command columns w=~s" w))
(interpret-markup layout props
(make-line-markup
((lambda (between list)
(letrec ((p (lambda (b l)
(if (null? (cdr l)) (cons b l)
(cons b (cons (car l) (p b (cdr l))))))))
; check cases
(cond
((and (list? between) (null? between)) list)
((or (null? between) (null? list)) list)
; list contains only one element
((null? (cdr list)) list)
; process list and skip first between
(else (cdr (p between list)))
) ; cond
) ; letrec
) (if (<= w 0.0) '() (markup #:hspace w))
(map (lambda (line)
(markup #:pad-to-box `(0 . ,line-width) '(0 . 0)
#:override `(line-width . ,line-width)
line))
args))))))
Und hier ein kompilierbares Beispiel, zwei Seiten, einmal mit sieben Spalten, einmal mit zwei. Die erste Seite mit Standardzwischenraum 0,5cm und im zweiten abweichend 1cm.
\version "2.16.2"
#(set-global-staff-size 18)
#(set-default-paper-size "a4" 'landscape)
#(ly:set-option 'point-and-click #f)
% Inspiriert von http://lsr.di.unimi.it/LSR/Snippet?id=464
% Mit eigenen Ergänzungen: Abstand zwischen den Spalten, um zu verhindern, dass
% der Text "aneinander klebt".
#(define-markup-command (columns layout props args) (markup-list?)
#:properties ((column-separator (ly:mm 5)) ; default value
(separator-min-width 0.6)) ; minimum value
(let* ((n (length args)) ; number of arguments is number of columns
(eff-cs (/ column-separator 1.58)) ; workaround, compensate stretching
(w (- eff-cs separator-min-width)) ; w idth of additional horizontal space between columns
(line-width (/ (- (chain-assoc-get 'line-width props
(ly:output-def-lookup layout 'line-width))
(* (if (<= w 0.0) separator-min-width eff-cs) (- n 1)))
n))
)
(ly:debug (format #f "markup command columns w=~s" w))
(interpret-markup layout props
(make-line-markup
((lambda (between list)
(letrec ((p (lambda (b l)
(if (null? (cdr l)) (cons b l)
(cons b (cons (car l) (p b (cdr l))))))))
; check cases
(cond
((and (list? between) (null? between)) list)
((or (null? between) (null? list)) list)
; list contains only one element
((null? (cdr list)) list)
; process list and skip first between
(else (cdr (p between list)))
) ; cond
) ; letrec
) (if (<= w 0.0) '() (markup #:hspace w))
(map (lambda (line)
(markup #:pad-to-box `(0 . ,line-width) '(0 . 0)
#:override `(line-width . ,line-width)
line))
args))))))
TXTK = \markup { \justify { Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea
rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum
dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed
diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. }
}
TXTL = \markup { \justify { Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea
rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum
dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed
diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit
amet.
}
}
\book {
\bookpart {
\TXTK
\markup {
\columns {
\column {
\fill-line \huge { \null Lorem \null }
\vspace #1
\TXTL
}
\column {
\fill-line \huge { \null ipsum \null }
\vspace #1
\TXTL
}
\column {
\fill-line \huge { \null dolor \null }
\vspace #1
\TXTL
}
\column {
\fill-line \huge { \null sit \null }
\vspace #1
\TXTL
}
\column {
\fill-line \huge { \null amet \null }
\vspace #1
\TXTL
}
\column {
\fill-line \huge { \null consetutur \null }
\vspace #1
\TXTL
}
\column {
\fill-line \huge { \null sadipscing \null }
\vspace #1
\TXTL
}
}
}
\pageBreak
\TXTK
\markup {
\override #(cons 'column-separator (ly:cm 1))
\columns {
\column {
\fill-line \huge { \null ipsum \null }
\vspace #1
\TXTL
}
\column {
\fill-line \huge { \null dolor \null }
\vspace #1
\TXTL
}
}
}
\paper {
annotate-spacing = ##f
oddHeaderMarkup = \markup { \null }
evenHeaderMarkup = \markup { \null }
oddFooterMarkup = \markup { \null }
evenFooterMarkup = \markup { \null }
}
}
}
Und hier noch das Ergebnis als PDF.
Grüße
Martin