28 Commits

Author SHA1 Message Date
tux
19f6046333 fix includeFromSong 2025-06-17 09:01:24 +02:00
tux
a288248da3 Refactor toc code 2025-06-15 13:38:06 +02:00
tux
7a65d056d6 refactor title markup and allow songnumbers 2025-06-14 16:37:27 +02:00
tux
53c41bf5dc add transliteration to toc 2025-06-10 07:33:09 +02:00
c49dba89f7 include adaptions/editings in author system 2025-06-07 16:27:32 +02:00
tux
195110923a include another song without outputting anything 2025-06-06 18:13:22 +02:00
tux
8d0ddcee06 introduce TEXT_PAGES 2025-05-19 22:14:08 +02:00
tux
c47ceb443e fix some chord spacing 2025-05-11 17:59:56 +02:00
tux
377beeab57 refactor and fix tagging bug 2025-05-11 11:39:19 +02:00
tux
cb4b74d4f7 indents for verse lines 2025-05-10 15:13:47 +02:00
616034baca Remove Metronome_mark_engraver 2025-05-08 23:28:08 +04:00
tux
34c9c5a932 capoTranspose eingebaut 2025-04-30 17:31:01 +02:00
57bcf94167 add default chordName exceptions 2025-04-27 14:37:07 +02:00
9a9ef8e8df fix transpositions for verses 2025-04-27 12:15:32 +04:00
tux
531e459af1 fix files-in-directory 2025-04-27 01:47:53 +02:00
tux
fc1bc74b10 fix altChord transposition again 2025-04-27 01:21:13 +02:00
tux
d47ae1a66d interpret songinfo with markups 2025-04-26 21:29:06 +02:00
37ee497f89 make cues configurable 2025-04-26 23:26:12 +04:00
41bd881014 remove Jump_engraver 2025-04-26 21:40:05 +04:00
tux
00a7b0ebc8 pseudoIndents for custom layouting 2025-04-21 19:48:30 +02:00
tux
760ca71ba7 melisOff and melisOn 2025-04-21 19:11:05 +02:00
tux
17074e2db6 secondVoiceStyle for Accidentals 2025-04-19 22:33:54 +02:00
tux
654f619fba sort contributions 2025-04-19 19:08:13 +02:00
tux
cc4fc9f297 fix altChord for SVG Output 2025-04-19 17:03:20 +02:00
d2dbf3448a change accidentalStyle to modern-voice-cautionary 2025-04-17 22:52:36 +04:00
tux
140bc611d1 fix altChord transposition 2025-04-17 20:22:21 +02:00
tux
eccd9b8730 fill-midi 2025-04-05 14:31:19 +02:00
900f4e1d06 workaround popen trouble on windows 2025-03-28 11:01:55 +01:00
16 changed files with 457 additions and 138 deletions

View File

@ -28,12 +28,15 @@
\include "arrows_in_scores.ly" \include "arrows_in_scores.ly"
\include "swing_style.ly" \include "swing_style.ly"
\include "inline_score.ly" \include "inline_score.ly"
\include "custom_indentation.ily"
\include "include_from_song.ily"
% reset important variables % reset important variables
LAYOUT = \layout { \generalLayout } LAYOUT = \layout { \generalLayout }
HEADER = {} HEADER = {}
MUSIC = {} MUSIC = {}
TEXT = \markuplist {""} TEXT = \markuplist {}
TEXT_PAGES = #f
verseChords = {} verseChords = {}
firstVoice = {} firstVoice = {}

View File

@ -43,7 +43,7 @@ generalLayout = \layout {
} }
\context { \context {
\Staff \Staff
\accidentalStyle modern \accidentalStyle modern-voice-cautionary
\consists Merge_rests_engraver \consists Merge_rests_engraver
} }
\context { \context {
@ -71,6 +71,7 @@ generalLayout = \layout {
\override Stem.layer = 2 \override Stem.layer = 2
\override Flag.layer = 2 \override Flag.layer = 2
\override Beam.layer = 2 \override Beam.layer = 2
\override Accidental.layer = 2
} }
} }
@ -86,11 +87,13 @@ secondVoiceStyle = {
\override Stem.color = #grey \override Stem.color = #grey
\override Flag.color = #grey \override Flag.color = #grey
\override Beam.color = #grey \override Beam.color = #grey
\override Accidental.color = #grey
\override NoteHead.layer = 1 \override NoteHead.layer = 1
\override Dots.layer = 1 \override Dots.layer = 1
\override Stem.layer = 1 \override Stem.layer = 1
\override Flag.layer = 1 \override Flag.layer = 1
\override Beam.layer = 1 \override Beam.layer = 1
\override Accidental.layer = 1
} }
firstVoiceStyle = { firstVoiceStyle = {
@ -99,6 +102,7 @@ firstVoiceStyle = {
\override Stem.color = #black \override Stem.color = #black
\override Flag.color = #black \override Flag.color = #black
\override Beam.color = #black \override Beam.color = #black
\override Accidental.color = #black
} }
% Deprecated: einzelne Noten innerhalb von \secondVoiceStyle mit schwarzem statt grauem Kopf % Deprecated: einzelne Noten innerhalb von \secondVoiceStyle mit schwarzem statt grauem Kopf
@ -212,3 +216,18 @@ dottedExtender = {
(cons (cdr x-ext) 0)) (cons (cdr x-ext) 0))
grob)))) grob))))
} }
melisOff = \set ignoreMelismata = ##t
melisOn = \unset ignoreMelismata
cue =
#(define-music-function (zahlen) (number-list?)
#{
\tag #'cues {
\tweak self-alignment-X #LEFT
\mark
#(make-on-the-fly-markup
(lambda (layout props m) (interpret-markup layout (prepend-alist-chain 'cues zahlen props) (ly:output-def-lookup layout 'cueMarkup)))
(make-null-markup))
}
#})

View File

@ -1,4 +1,5 @@
#(define song-list '()) #(define song-list '())
#(define song-number 0)
#(define (files-in-directory dirname) #(define (files-in-directory dirname)
;;; Generate list containing filenames ;;; Generate list containing filenames
@ -9,7 +10,7 @@
(closedir dir) (closedir dir)
files) files)
(else (else
(next (readdir dir) (if (string-match "^(0|\\.)" f) files (cons f files)))))))) (next (readdir dir) (if (ly:regex-match? (ly:regex-exec (ly:make-regex "^(0|\\.)") f)) files (cons f files))))))))
#(define (file-to-stats filename) #(define (file-to-stats filename)
(set! song-list (cons filename song-list))) (set! song-list (cons filename song-list)))
@ -114,7 +115,7 @@ width may require additional tweaking.)"
includeSong = includeSong =
#(define-void-function (parser location textproc filename) ((procedure?) string?) #(define-void-function (parser location filename) (string?)
#{ #{
\bookOutputName #filename \bookOutputName #filename
#} #}
@ -125,7 +126,15 @@ includeSong =
(acons label additional-page-numbers additional-page-switch-label-list)) (acons label additional-page-numbers additional-page-switch-label-list))
(set! song-list (set! song-list
(acons (string->symbol filename) (acons (string->symbol filename)
(acons 'label label (acons 'header HEADER (acons 'music MUSIC (acons 'layout LAYOUT (acons 'text #{ \markuplist \setsongfilename $filename $(if textproc (textproc TEXT) TEXT) #} '()))))) (acons 'label label
(acons 'header HEADER
(acons 'music MUSIC
(acons 'layout LAYOUT
(acons 'text-pages
(map (lambda (text)
#{ \markuplist \setsongfilename $filename $text #})
TEXT_PAGES)
'())))))
song-list)) song-list))
)) ))
@ -177,21 +186,23 @@ songs =
\markup { \pagecenter { \epsfile #X #xsize #filename } } \markup { \pagecenter { \epsfile #X #xsize #filename } }
} #} } #}
) )
(let ((header #{ \bookpart { $(assq-ref songvars 'header) \header { (let* ((newnumber (+ 1 song-number))
(header #{ \bookpart { $(assq-ref songvars 'header) \header {
songfilename = $(symbol->string filename) songfilename = $(symbol->string filename)
myindexlabel = #(assq-ref songvars 'label) myindexlabel = #(assq-ref songvars 'label)
songnumber = #(number->string newnumber)
} } #}) } } #})
;(header (assq-ref songvars 'header))
(music (assq-ref songvars 'music)) (music (assq-ref songvars 'music))
(layout (assq-ref songvars 'layout)) (layout (assq-ref songvars 'layout))
(text (assq-ref songvars 'text)) (text-pages (assq-ref songvars 'text-pages))
(label (assq-ref songvars 'label))) (label (assq-ref songvars 'label)))
(set! song-number newnumber)
#{ #{
\bookpart { \bookpart {
$header $header
\headerToTOC #header #label \headerToTOC #header #label
\score { $music \layout { $layout } } \score { $music \layout { $layout } }
$text $(add-text-pages text-pages)
} }
#})))))) #}))))))
(reverse song-list) (reverse song-list)

View File

@ -38,18 +38,23 @@ shiftChords = #(define-music-function (parser location xshift chords) (number? l
$chords $chords
#}) #})
altChord = #(define-music-function (parser location mainchord altchord) (ly:music? ly:music?) altChord =
(define (chord-namer in-pitches bass inversion context) #(define-music-function (parser location mainchord altchord) (ly:music? ly:music?)
#{ (let* ((remove-point-and-click
(lambda (grob)
(ly:grob-set-property! grob 'cause #f)
(ly:text-interface::print grob)))
(chord-name (lambda (in-pitches bass inversion context) #{
\markup { \markup {
\translate #'(-0.5 . 0) \translate #'(-0.5 . 0)
\score { \score {
\chords { #mainchord \klamm #altchord } \chords { \transposable #(cons (car (music-pitches mainchord)) (car in-pitches)) { #(music-clone mainchord) \klamm #(music-clone altchord) } }
\layout { \layout {
\LAYOUT \LAYOUT
\context { \context {
\ChordNames \ChordNames
\override ChordName.extra-spacing-width = #'(0 . 0.3) \override ChordName.extra-spacing-width = #'(0 . 0.3)
\override ChordName.stencil = #remove-point-and-click
} }
\context { \context {
\Score \Score
@ -57,12 +62,23 @@ altChord = #(define-music-function (parser location mainchord altchord) (ly:musi
} }
} }
} }
} }#})))
#}) #{
#{ \once \set chordNameFunction = #chord-name
\once \set chordNameFunction = #chord-namer
#mainchord #mainchord
#}) #}))
% Akkorde werden so transponiert, dass sie passen, wenn man mit Kapo im angegebenen Bund spielt
capoTranspose =
#(define-music-function (fret chords) (number? ly:music?)
(define semi->pitch
(make-semitone->pitch
(music-pitches
#{ h b a gis g fis f e es d cis c #})))
(transpose
(ly:pitch-transpose (semi->pitch fret) (ly:make-pitch 0 0))
(ly:make-pitch 0 0)
chords))
% kleine Mollakkorde und Alteration ausgeschrieben % kleine Mollakkorde und Alteration ausgeschrieben
#(define (note-name->german-markup-nosym pitch lowercase?) #(define (note-name->german-markup-nosym pitch lowercase?)
@ -100,11 +116,42 @@ altChord = #(define-music-function (parser location mainchord altchord) (ly:musi
% additional bass notes should get uppercased % additional bass notes should get uppercased
#(define (bassnote-name->german-markup-nosym pitch lowercase?)(note-name->german-markup-nosym pitch #f)) #(define (bassnote-name->german-markup-nosym pitch lowercase?)(note-name->german-markup-nosym pitch #f))
defaultChordPrintings = {
<c g>-\markup { \super "5" }
%% Dur
<c e g a>-\markup { \super "6" } %Standardverhalten
<c e a >-\markup { \super "6(no5)" }
<c e g a d'>-\markup { \super "6/9" }
<c e g b d'>-\markup { \super "9" } %Standardverhalten
<c e g b d' f'>-\markup { \super "11" } %Standardverhalten
<c e g b d' a'>-\markup { \super "13" }
%add chords
<c e g d'>-\markup { \super "add9" }
<c e g f'>-\markup { \super "add11" }
<c e g a'>-\markup { \super "add13" }
%major chords
<c e g h d'>-\markup { \super "maj9" }
%% Moll
<c es g a>-\markup { \super "6" } %Standardverhalten
<c es a >-\markup { \super "6(no5)" }
<c es g a d'>-\markup { \super "6/9" }
<c es g b d'>-\markup { \super "9" } %Standardverhalten
<c es g b d' f'>-\markup { \super "11" } %Standardverhalten
<c es g b d' a'>-\markup { \super "13" }
%add chords
<c es g d'>-\markup { \super "add9" }
<c es g f'>-\markup { \super "add11" }
<c es g a'>-\markup { \super "add13" }
%major chords
<c es g h d'>-\markup { \super "maj9" }
}
#(define chordNameExceptions #(define chordNameExceptions
(append
(if (defined? 'customChordPrintings) (if (defined? 'customChordPrintings)
(sequential-music-to-chord-exceptions customChordPrintings #t) (sequential-music-to-chord-exceptions customChordPrintings #t)
'())) '())
(sequential-music-to-chord-exceptions defaultChordPrintings #t)))
generalLayout = \layout { generalLayout = \layout {
\generalLayout \generalLayout

135
custom_indentation.ily Normal file
View File

@ -0,0 +1,135 @@
% https://lsr.di.unimi.it/LSR/Snippet?id=1098
%%%%%%%% HEADER %%%%%%%%
%
% this code was prompted by
% https://lists.gnu.org/archive/html/lilypond-user/2019-07/msg00139.html
% and offers a pseudoIndent hack suitable for general use
% keywords:
% indent short-indent indentation system line
% mid-score temporarily arbitrary individual single just only once
% coda margin
% mouse's tale acrostic mesostic spine
%%%%%%%% PSEUDOINDENT FUNCTIONS %%%%%%%%
% these two functions are for indenting individual systems
% - to left-indent a system, apply \pseudoIndent before the music continues
% - \pseudoIndents is similar, but lets you also indent on the right
% - both provide an option for changing that system's instrument names
% N.B. these functions
% - assume application to non-ragged lines (generally the default)
% - include a manual \break to ensure application at line start
% - misbehave if called more than once at the same line start
% the parameters of the (full) pseudoIndents function are:
% 1: name-tweaks
% usually omitted; accepts replacement \markup for instrument names
% as an ordered list; starred elements leave their i-names unchanged.
% 2: left-indent
% additional left-indentation, in staff-space units; can be negative,
% but avoid a total indentation which implies (unsupported) stretching.
% 3: right-indent
% amount of right-indentation, in staff-space units; can be negative.
% - not offered by the (reduced) pseudoIndent function
pseudoIndents = % inline alternative to a new \score, also with right-indent
#(define-music-function (name-tweaks left-indent right-indent)
((markup-list? '()) number? number?)
(define (warn-stretched p1 p2) (ly:input-warning (*location*) (G_
" pseudoIndents ~s ~s is stretching staff; expect distorted layout") p1 p2))
(let* (
(narrowing (+ left-indent right-indent)) ; of staff implied by args
(set-staffsymbol! (lambda (staffsymbol-grob) ; change staff to new width
(let* (
(left-bound (ly:spanner-bound staffsymbol-grob LEFT))
(left-moment (ly:grob-property left-bound 'when))
(capo? (moment<=? left-moment ZERO-MOMENT)) ; in first system of score
(layout (ly:grob-layout staffsymbol-grob))
(lw (ly:output-def-lookup layout 'line-width)) ; debugging info
(indent (ly:output-def-lookup layout (if capo? 'indent 'short-indent)))
(old-stil (ly:staff-symbol::print staffsymbol-grob))
(staffsymbol-x-ext (ly:stencil-extent old-stil X))
;; >=2.19.16's first system has old-stil already narrowed [2]
;; compensate for this (ie being not pristine) when calculating
;; - old leftmost-x (its value is needed when setting so-called 'width)
;; - the new width and position (via local variable narrowing_)
(ss-t (ly:staff-symbol-line-thickness staffsymbol-grob))
(pristine? (<= 0 (car staffsymbol-x-ext) ss-t)) ; would expect half
(leftmost-x (+ indent (if pristine? 0 narrowing)))
(narrowing_ (if pristine? narrowing 0)) ; uses 0 if already narrowed
(old-width (+ (interval-length staffsymbol-x-ext) ss-t))
(new-width (- old-width narrowing_))
(new-rightmost-x (+ leftmost-x new-width)) ; and set! this immediately
(junk (ly:grob-set-property! staffsymbol-grob 'width new-rightmost-x))
(in-situ-stil (ly:staff-symbol::print staffsymbol-grob))
(new-stil (ly:stencil-translate-axis in-situ-stil narrowing_ X))
;(new-stil (stencil-with-color new-stil red)) ; for when debugging
(new-x-ext (ly:stencil-extent new-stil X)))
(ly:grob-set-property! staffsymbol-grob 'stencil new-stil)
(ly:grob-set-property! staffsymbol-grob 'X-extent new-x-ext)
)))
(set-X-offset! (lambda (margin-grob) ; move grob across to line start
(let* (
(old (ly:grob-property-data margin-grob 'X-offset))
(new (lambda (grob) (+ (if (procedure? old) (old grob) old) narrowing))))
(ly:grob-set-property! margin-grob 'X-offset new))))
(tweak-text! (lambda (i-name-grob mkup) ; tweak both instrumentname texts
(if (and (markup? mkup) (not (string=? (markup->string mkup) "*")))
(begin
(ly:grob-set-property! i-name-grob 'long-text mkup)
(ly:grob-set-property! i-name-grob 'text mkup)
)))) ; else retain existing text
(install-narrowing (lambda (leftedge-grob) ; on staves, + adapt left margin
(let* (
(sys (ly:grob-system leftedge-grob))
(all-grobs (ly:grob-array->list (ly:grob-object sys 'all-elements)))
(grobs-named (lambda (name)
(filter (lambda (x) (eq? name (grob::name x))) all-grobs)))
(first-leftedge-grob (list-ref (grobs-named 'LeftEdge) 0))
(relsys-x-of (lambda (g) (ly:grob-relative-coordinate g sys X)))
(leftedge-x (relsys-x-of first-leftedge-grob))
(leftedged? (lambda (g) (= (relsys-x-of g) leftedge-x)))
(leftedged-ss (filter leftedged? (grobs-named 'StaffSymbol))))
(if (eq? leftedge-grob first-leftedge-grob) ; ignore other leftedges [1]
(begin
(for-each set-staffsymbol! leftedged-ss)
(for-each set-X-offset! (grobs-named 'SystemStartBar))
(for-each set-X-offset! (grobs-named 'InstrumentName))
(for-each tweak-text! (grobs-named 'InstrumentName) name-tweaks)
))))))
(if (negative? narrowing) (warn-stretched left-indent right-indent))
#{ % and continue anyway
% ensure that these overrides are applied only at begin-of-line
\break % (but this does not exclude unsupported multiple application)
% give the spacing engine notice regarding the loss of width for music
\once \override Score.LeftEdge.X-extent = #(cons narrowing narrowing)
% discard line start region of staff and reassemble left-margin elements
\once \override Score.LeftEdge.after-line-breaking = #install-narrowing
% shift the system to partition the narrowing between left and right
\overrideProperty Score.NonMusicalPaperColumn.line-break-system-details
.X-offset #(- right-indent)
% prevent a leftmost barnumber entering a stretched staff
\once \override Score.BarNumber.horizon-padding = #(max 1 (- 1 narrowing))
#}))
pseudoIndent = % for changing just left-indent
#(define-music-function (name-tweaks left-indent)
((markup-list? '()) number?)
#{
\pseudoIndents $name-tweaks $left-indent 0
#})
% [1] versions <2.19.1 can have end-of-line leftedges too
% - these were eliminated in issue 3761
% [2] versions >=2.19.16: the first system behaves differently from the rest
% - a side effect of issue 660 ?
% [3] versions >=2.23.0: LeftEdge's position may well differ in Y (but not in X)
% - a side effect of issue 6084 ?

View File

@ -2,6 +2,7 @@
poetPrefix = "Worte:" poetPrefix = "Worte:"
composerPrefix = "Weise:" composerPrefix = "Weise:"
compositionPrefix = "Satz:" compositionPrefix = "Satz:"
adaptionPrefix = "Bearbeitung:"
poetAndComposerEqualPrefix = "Worte und Weise:" poetAndComposerEqualPrefix = "Worte und Weise:"
voicePrefix = "Stimme:" voicePrefix = "Stimme:"
versePrefix = "Strophe:" versePrefix = "Strophe:"
@ -42,7 +43,16 @@
(poet-with-year (if (and poet-maybe-with-composer year_text) (string-append poet-maybe-with-composer ", " year_text) poet-maybe-with-composer)) (poet-with-year (if (and poet-maybe-with-composer year_text) (string-append poet-maybe-with-composer ", " year_text) poet-maybe-with-composer))
(composer-with-year (if (and composer year_melody) (string-append composer ", " year_melody) composer)) (composer-with-year (if (and composer year_melody) (string-append composer ", " year_melody) composer))
(poet-and-composer-oneliner (if (and poet-with-year composer-with-year) (markup poet-with-year between-poet-and-composer-markup composer-with-year) #f)) (poet-and-composer-oneliner (if (and poet-with-year composer-with-year) (markup poet-with-year between-poet-and-composer-markup composer-with-year) #f))
(current-line-width (chain-assoc-get 'line-width props (ly:output-def-lookup layout 'line-width)))) (current-line-width (chain-assoc-get 'line-width props (ly:output-def-lookup layout 'line-width)))
(string-with-paragraphs->markuplist (lambda (prefix text)
(if text
(apply append
(map
(lambda (paragraph)
(make-wordwrap-internal-markup-list #t
#{ \markuplist { $(ly:parser-include-string paragraph) } #}))
(ly:regex-split (ly:make-regex "\n[ \t\n]*\n[ \t\n]*") text)))
'()))))
(stack-lines DOWN 0.0 (chain-assoc-get 'baseline-skip props) (stack-lines DOWN 0.0 (chain-assoc-get 'baseline-skip props)
(interpret-markup-list layout props (interpret-markup-list layout props
(append (append
@ -53,10 +63,11 @@
(if composer-with-year (string-append "\n\n" composer-with-year) "") (if composer-with-year (string-append "\n\n" composer-with-year) "")
))) )))
(make-wordwrap-string-internal-markup-list #t (string-append (make-wordwrap-string-internal-markup-list #t (string-append
(if copyright (string-append "\n\n© " copyright) "") (if copyright (string-append "\n\n© " copyright) "")))
(if infotext (string-append "\n\n" infotext) "") (string-with-paragraphs->markuplist "" infotext)
(if translation (string-append "\n\nÜbersetzung: " translation) "") (string-with-paragraphs->markuplist "Übersetzung: " translation)
(if pronunciation (string-append "\n\nAussprache: " pronunciation) "")))))))) (string-with-paragraphs->markuplist "Aussprache: " pronunciation)
)))))
(make-null-markup) (make-null-markup)
) )
} }

View File

@ -22,3 +22,14 @@ refStringWithNumbers = "Ref. ~a:"
% hübsche Wiederholungszeichen für den Liedtext % hübsche Wiederholungszeichen für den Liedtext
repStart = "𝄆" repStart = "𝄆"
repStop = "𝄇" repStop = "𝄇"
customChordPrintings = {}
\paper {
cueMarkup = \markup {
\italic
#(make-on-the-fly-markup (lambda (layout props m)
(interpret-markup layout props
(string-join (map (lambda (n) (format #f "~@r." n)) (chain-assoc-get 'cues props)) ", ")))
(make-null-markup))
}
}

View File

@ -4,15 +4,15 @@
(interpret-markup-list layout (prepend-alist-chain 'songfilename songfilename props) markuplist)) (interpret-markup-list layout (prepend-alist-chain 'songfilename songfilename props) markuplist))
#(define-markup-command (customEps layout props ysize filename)(number? string?) #(define-markup-command (customEps layout props ysize filename)(number? string?)
#:properties ((songfilename "") #:properties ((songfilename ""))
(defaultmarkup #f))
(interpret-markup layout props (interpret-markup layout props
(let ((filepath (if (string-null? songfilename) (let ((defaulttitlemarkup (ly:output-def-lookup layout 'defaultTitleMarkup))
(filepath (if (string-null? songfilename)
filename filename
(ly:format "~a/~a/~a" songPath songfilename filename)))) (ly:format "~a/~a/~a" songPath songfilename filename))))
(if (file-exists? filepath) (if (file-exists? filepath)
(make-epsfile-markup Y ysize filepath) (make-epsfile-markup Y ysize filepath)
(if defaultmarkup (if defaulttitlemarkup
defaultmarkup defaulttitlemarkup
(ly:format "file does not exist ~a" filepath)) (ly:format "file does not exist ~a" filepath))
)))) ))))

View File

@ -21,11 +21,13 @@
#(define (find-author-id-with-part-numbers contributionType authors) #(define (find-author-id-with-part-numbers contributionType authors)
(if authors (if authors
(sort-list
(filter-map (lambda (authordata) (filter-map (lambda (authordata)
(let ((contributionNumbers (filter-map (lambda (contribution) (if (and (list? contribution) (equal? contributionType (car contribution))) (cadr contribution) #f)) (cdr authordata))) (let ((contributionNumbers (filter-map (lambda (contribution) (if (and (list? contribution) (equal? contributionType (car contribution))) (cadr contribution) #f)) (cdr authordata)))
(authorId (car authordata))) (authorId (car authordata)))
(if (null? contributionNumbers) #f (cons authorId contributionNumbers)) (if (null? contributionNumbers) #f (cons authorId (sort-list contributionNumbers <)))
)) authors) )) authors)
(lambda (a b) (< (cadr a) (cadr b))))
(list))) (list)))
#(define-markup-command (print-songinfo layout props) () #(define-markup-command (print-songinfo layout props) ()
@ -75,22 +77,20 @@
(string-append contributionPrefix " " (string-join (format-authors authorIds) ", "))) (string-append contributionPrefix " " (string-join (format-authors authorIds) ", ")))
) )
(define (join-present items joiner)
(string-join (filter (lambda (item) (and (string? item) (not (string-null? (string-trim-both item))))) items) joiner)
)
(define (render-partial-contribution-group prefixLookup authorData) (define (render-partial-contribution-group prefixLookup authorData)
(if (null? authorData) (if (null? authorData)
"" ""
(let ((firstAuthorContributions (cdar authorData))) (let ((firstAuthorContributions (cdar authorData)))
(receive (authorDataSame authorDataOther) (receive (authorDataSame authorDataOther)
(partition (lambda (authorEntry) (equal? (cdr authorEntry) firstAuthorContributions)) authorData) (partition (lambda (authorEntry) (equal? (cdr authorEntry) firstAuthorContributions)) authorData)
(string-append (join-present (list
(render-contribution-group (numbered-contribution-prefix firstAuthorContributions prefixLookup) (map car authorDataSame)) (render-contribution-group (numbered-contribution-prefix firstAuthorContributions prefixLookup) (map car authorDataSame))
" "
(render-partial-contribution-group prefixLookup authorDataOther) (render-partial-contribution-group prefixLookup authorDataOther)
)))) ) " ")))))
)
(define (join-present items joiner)
(string-join (filter (lambda (item) (and (string? item) (not (string-null? (string-trim-both item))))) items) joiner)
)
(define (poet-and-composer-from-authors authors) (define (poet-and-composer-from-authors authors)
(if authors (if authors
@ -102,14 +102,16 @@
(verseComposerData (find-author-id-with-part-numbers 'meloverse authors)) (verseComposerData (find-author-id-with-part-numbers 'meloverse authors))
(voiceComposerData (find-author-id-with-part-numbers 'voice authors)) (voiceComposerData (find-author-id-with-part-numbers 'voice authors))
(compositionIds (find-author-ids-by 'composition authors)) (compositionIds (find-author-ids-by 'composition authors))
(adaptionIds (find-author-ids-by 'adaption authors))
(bridgeIds (find-author-ids-by 'bridge authors)) (bridgeIds (find-author-ids-by 'bridge authors))
(interludeIds (find-author-ids-by 'interlude authors)) (interludeIds (find-author-ids-by 'interlude authors))
(year_text (chain-assoc-get 'header:year_text props #f)) (year_text (chain-assoc-get 'header:year_text props #f))
(year_translation (chain-assoc-get 'header:year_translation props #f)) (year_translation (chain-assoc-get 'header:year_translation props #f))
(year_melody (chain-assoc-get 'header:year_melody props #f)) (year_melody (chain-assoc-get 'header:year_melody props #f))
(year_composition (chain-assoc-get 'header:year_composition props #f)) (year_composition (chain-assoc-get 'header:year_composition props #f))
(year_adaption (chain-assoc-get 'header:year_adaption props #f))
) )
(if (and (equal? poetIds composerIds) (null? translatorIds) (null? versePoetData) (null? verseComposerData) (null? voiceComposerData) (null? compositionIds) (null? bridgeIds) (null? interludeIds)) (if (and (equal? poetIds composerIds) (null? translatorIds) (null? versePoetData) (null? verseComposerData) (null? voiceComposerData) (null? compositionIds) (null? adaptionIds) (null? bridgeIds) (null? interludeIds))
(list (list
(join-present (list (join-present (list
(render-contribution-group (ly:output-def-lookup layout 'poetAndComposerEqualPrefix) poetIds) (render-contribution-group (ly:output-def-lookup layout 'poetAndComposerEqualPrefix) poetIds)
@ -133,7 +135,7 @@
) ", ") ) ", ")
) "; ") ) "; ")
)) ))
(if (and (null? composerIds) (null? compositionIds) (null? verseComposerData) (null? voiceComposerData) (null? bridgeIds) (null? interludeIds)) #f (if (and (null? composerIds) (null? compositionIds) (null? adaptionIds) (null? verseComposerData) (null? voiceComposerData) (null? bridgeIds) (null? interludeIds)) #f
(string-append (string-append
(ly:output-def-lookup layout 'composerPrefix) (ly:output-def-lookup layout 'composerPrefix)
" " " "
@ -148,6 +150,10 @@
(render-contribution-group (ly:output-def-lookup layout 'compositionPrefix) compositionIds) (render-contribution-group (ly:output-def-lookup layout 'compositionPrefix) compositionIds)
year_composition year_composition
) ", ") ) ", ")
(join-present (list
(render-contribution-group (ly:output-def-lookup layout 'adaptionPrefix) adaptionIds)
year_adaption
) ", ")
(render-contribution-group (ly:output-def-lookup layout 'bridgePrefix) bridgeIds) (render-contribution-group (ly:output-def-lookup layout 'bridgePrefix) bridgeIds)
(render-contribution-group (ly:output-def-lookup layout 'interludePrefix) interludeIds) (render-contribution-group (ly:output-def-lookup layout 'interludePrefix) interludeIds)
) "; ") ) "; ")

15
include_from_song.ily Normal file
View File

@ -0,0 +1,15 @@
includeFromSong =
#(define-void-function (filename) (string?)
(let ((noDefaultOutputBackup noDefaultOutput))
(set! noDefaultOutput #t)
(ly:parser-parse-string (ly:parser-clone)
(ly:format "\\include \"~a\""
(string-append
(dirname (dirname (current-filename)))
file-name-separator-string
"lilypond-song-includes"
file-name-separator-string
"liedbausteine"
file-name-separator-string
filename)))
(set! noDefaultOutput noDefaultOutputBackup)))

View File

@ -6,3 +6,8 @@ inline-score =
#{ #{
\transposable #TRANSPOSITION #music \transposable #TRANSPOSITION #music
#}) #})
fill-midi =
#(define-void-function (music) (ly:music?)
(set! INLINESCOREMUSIC #{ \INLINESCOREMUSIC #music #})
)

View File

@ -1,20 +1,23 @@
(if (not windows?) (use-modules (ice-9 popen))) (if (not windows?) (use-modules (ice-9 popen)))
(use-modules (ice-9 textual-ports) (json parser)) (use-modules (ice-9 textual-ports) (json parser))
; We use Python to convert the data yamls like the authors.yml to json, that we can parse in scheme.
; Windows does not like Pipes, so we use a tmpfile instead.
; Be sure you have PyYAML installed. On Windows that could be done for example like "py -m pip install PyYAML"
(define (yml-file->scm filename) (define (yml-file->scm filename)
(if windows? (if windows?
(let* ((tmpdir (or (getenv "TMPDIR") (getenv "TEMP") "/tmp")) (let* ((port (make-tmpfile #f))
(port (mkstemp (string-append tmpdir "\\" (basename filename) "-XXXXXX") "r"))
(tmpfilepath (port-filename port)) (tmpfilepath (port-filename port))
(python_code (string-append "import sys, yaml, json; f = open('" tmpfilepath "', 'w'); f.write(json.dumps(yaml.safe_load(open('" filename "')))); f.close()")) (ignore (close-port port))
(status (system (string-append "py -X utf8 -c \"" python_code "\""))) (python_code (string-append "import sys, yaml, json; f = open(r'" tmpfilepath "', 'w'); f.write(json.dumps(yaml.safe_load(open(r'" filename "')))); f.close()"))
(json (get-string-all port))) (status (system (string-append (search-executable '("python3" "python" "py")) " -X utf8 -c \"" python_code "\"")))
(readport (open-file tmpfilepath "r" #:encoding "UTF-8"))
(json (get-string-all readport)))
(close-port readport)
(delete-file tmpfilepath) (delete-file tmpfilepath)
(json-string->scm (if (status:exit-val status) json "{}"))) (json-string->scm (if (status:exit-val status) json "{}")))
(let* ((python_code (string-append "import sys, yaml, json; print(json.dumps(yaml.safe_load(open('" filename "'))))")) (let* ((python_code (string-append "import sys, yaml, json; print(json.dumps(yaml.safe_load(open(r'" filename "'))))"))
; WTF? On Windows there is "py" and we need to specify the encoding, on linux there is "python3" or "python" (pipe (open-pipe (string-append "PYTHONHOME='' " (search-executable '("python3" "python" "py")) " -X utf8 -c \"" python_code "\"") OPEN_READ))
; but "python3" seems to work better. Be sure you have PyYAML installed.
(pipe (open-pipe (string-append "PYTHONHOME='' " (if windows? "py" "python3") " -X utf8 -c \"" python_code "\"") OPEN_READ))
(json (get-string-all pipe))) (json (get-string-all pipe)))
(close-pipe pipe) (close-pipe pipe)
(json-string->scm json)))) (json-string->scm json))))

View File

@ -26,6 +26,34 @@ TEXT = \markuplist {
\TEXT \TEXT
} }
#(define TEXT_PAGES
(map
(lambda (text) #{
\markuplist {
\override #`(transposition . ,TRANSPOSITION)
\override #`(verselayout . ,verselayout)
\override #`(verse-chords . ,#{ \chords { \verseChords } #})
\override #`(verse-reference-voice . ,#{ \global \firstVoice #})
#text
}
#})
(if
(and
(defined? 'TEXT_PAGES)
(pair? TEXT_PAGES))
TEXT_PAGES
(list TEXT))))
#(define (add-text-pages text-pages)
(if (pair? text-pages)
(begin
(add-score (car text-pages))
(for-each
(lambda (text)
(add-music (pageBreak))
(add-score text))
(cdr text-pages)))))
#(if (not noStandaloneOutput) #(if (not noStandaloneOutput)
(begin (begin
(let ((header (ly:book-header HEADER)) (paper (ly:book-paper HEADER))) (let ((header (ly:book-header HEADER)) (paper (ly:book-paper HEADER)))
@ -37,7 +65,7 @@ TEXT = \markuplist {
\MUSIC \MUSIC
\layout { \LAYOUT } \layout { \LAYOUT }
}#}) }#})
(add-score TEXT) (add-text-pages TEXT_PAGES)
(add-score #{ (add-score #{
\score { \score {
\unfoldRepeats { \MUSIC \INLINESCOREMUSIC } \unfoldRepeats { \MUSIC \INLINESCOREMUSIC }

View File

@ -1,16 +1,6 @@
#(define-markup-command (bookTitleMarkupCustom layout props)() #(define-markup-command (bookTitleMarkupCustom layout props)()
(interpret-markup layout (interpret-markup layout
(prepend-alist-chain 'defaultmarkup #{ (prepend-alist-chain 'songfilename (chain-assoc-get 'header:songfilename props "") props)
\markup {
\override #'(baseline-skip . 3.5)
\center-column {
\override #`(font-name . ,songTitleFont) { \fontsize #songTitleSize \fromproperty #'header:title }
\large \bold \fromproperty #'header:subtitle
\smaller \bold \fromproperty #'header:subsubtitle
}
}
#}
(prepend-alist-chain 'songfilename (chain-assoc-get 'header:songfilename props "") props))
(make-column-markup (make-column-markup
(list (list
(make-vspace-markup (chain-assoc-get 'header:titletopspace props 0)) (make-vspace-markup (chain-assoc-get 'header:titletopspace props 0))
@ -63,4 +53,12 @@
scoreTitleMarkup = \markup \null scoreTitleMarkup = \markup \null
oddHeaderMarkup = \markup { \if \on-first-page-of-part \title-with-category-images ##t } oddHeaderMarkup = \markup { \if \on-first-page-of-part \title-with-category-images ##t }
evenHeaderMarkup = \markup { \if \on-first-page-of-part \title-with-category-images ##f } evenHeaderMarkup = \markup { \if \on-first-page-of-part \title-with-category-images ##f }
defaultTitleMarkup = \markup {
\override #'(baseline-skip . 3.5)
\center-column {
\override #`(font-name . ,songTitleFont) { \fontsize #songTitleSize \fromproperty #'header:title }
\large \bold \fromproperty #'header:subtitle
\smaller \bold \fromproperty #'header:subsubtitle
}
}
} }

View File

@ -67,13 +67,14 @@
(ly:string-substitute "…" "" (ly:string-substitute "…" ""
(ly:string-substitute "Č" "C" (ly:string-substitute "Č" "C"
(ly:string-substitute "Đ" "D" (ly:string-substitute "Đ" "D"
(ly:string-substitute "Š" "S"
(ly:string-substitute "Т" "T" (ly:string-substitute "Т" "T"
(ly:string-substitute "Ä" "Ae" (ly:string-substitute "Ä" "Ae"
(ly:string-substitute "ä" "ae" (ly:string-substitute "ä" "ae"
(ly:string-substitute "Ö" "O" (ly:string-substitute "Ö" "O"
(ly:string-substitute "ö" "oe" (ly:string-substitute "ö" "oe"
(ly:string-substitute "Ü" "U" (ly:string-substitute "Ü" "U"
(ly:string-substitute "ü" "ue" sorttext)))))))))))) (ly:string-substitute "ü" "ue" sorttext)))))))))))))
index-item-list)) index-item-list))
(make-music 'EventChord (make-music 'EventChord
'page-marker #t 'page-marker #t
@ -166,22 +167,24 @@
(markup #:override (cons 'baseline-skip 3.5) (if catname (make-left-column-markup (string-split (cadr catname) #\newline)) category))))) (markup #:override (cons 'baseline-skip 3.5) (if catname (make-left-column-markup (string-split (cadr catname) #\newline)) category)))))
#(define-markup-command (index-item-with-pattern layout props)() #(define-markup-command (index-item-with-pattern layout props)()
#:properties ((index:text "")
(index:alternative #f)
(index:page #f)
(line-width))
(let* ( (let* (
(text (chain-assoc-get 'index:text props))
(page (chain-assoc-get 'index:page props))
(width (- (width (-
(chain-assoc-get 'line-width props) line-width
(interval-length (ly:stencil-extent (interpret-markup layout props "XXXX") X)))) (interval-length (ly:stencil-extent (interpret-markup layout props "XXXX") X))))
(lines-reversed (lines-reversed
(if (markup? text)
(list text)
(reverse (map (lambda (stil) (markup #:stencil stil)) (reverse (map (lambda (stil) (markup #:stencil stil))
(wordwrap-string-internal-markup-list layout (wordwrap-string-internal-markup-list layout
(cons (if (chain-assoc-get 'alternative text) (prepend-alist-chain 'line-width width
(list (cons 'line-width width) (cons 'font-shape 'italic)) (if index:alternative
(list (cons 'line-width width))) props) #f (prepend-alist-chain 'font-shape 'italic props)
(chain-assoc-get 'rawtext text)))))) props))
(last-line-with-dots (make-fill-with-pattern-markup 1 RIGHT "." (car lines-reversed) page)) #f
index:text))))
(last-line-with-dots (make-fill-with-pattern-markup 1 RIGHT "." (car lines-reversed) index:page))
(lines-without-dots (cdr lines-reversed)) (lines-without-dots (cdr lines-reversed))
(target-line-size-markup (target-line-size-markup
(make-column-markup (make-column-markup
@ -203,7 +206,7 @@
\paper { \paper {
indexItemMarkup = \markup { indexItemMarkup = \markup {
\index-item-with-pattern \sans \index-item-with-pattern
} }
indexSectionMarkup = \markup \override #'(baseline-skip . 1.5) \left-column { indexSectionMarkup = \markup \override #'(baseline-skip . 1.5) \left-column {
\sans \bold \fontsize #3 \fromproperty #'index:text \sans \bold \fontsize #3 \fromproperty #'index:text
@ -227,12 +230,17 @@
#(define (prepare-item-markup items layout) #(define (prepare-item-markup items layout)
(map (lambda (index-item) (map (lambda (index-item)
(let ((label (car index-item)) (let* ((label (car index-item))
(index-markup (cadr index-item)) (index-markup (cadr index-item))
(text (caddr index-item))) (textoptions (caddr index-item))
(text (chain-assoc-get 'rawtext textoptions))
(alternative (chain-assoc-get 'alternative textoptions))
(songnumber (chain-assoc-get 'songnumber textoptions)))
(markup #:override (cons 'index:label label) (markup #:override (cons 'index:label label)
#:override (cons 'index:page (markup #:custom-page-number label -1)) #:override (cons 'index:page (markup #:custom-page-number label -1))
#:override (cons 'index:text text) #:override (cons 'index:text text)
#:override (cons 'index:alternative alternative)
#:override (cons 'index:songnumber songnumber)
(ly:output-def-lookup layout index-markup)))) (ly:output-def-lookup layout index-markup))))
(items))) (items)))
@ -253,12 +261,12 @@
indexItem = indexItem =
#(define-music-function (parser location sorttext text) (string? markup?) #(define-music-function (parser location sorttext text) (string? markup?)
"Add a line to the alphabetical index, using the @code{indexItemMarkup} paper variable markup." "Add a line to the alphabetical index, using the @code{indexItemMarkup} paper variable markup."
(add-index-item! 'indexItemMarkup text sorttext)) (add-index-item! 'indexItemMarkup (prepend-alist-chain 'rawtext text '()) sorttext))
indexSection = indexSection =
#(define-music-function (parser location sorttext text) (string? markup?) #(define-music-function (parser location sorttext text) (string? markup?)
"Add a section line to the alphabetical index, using @code{indexSectionMarkup} paper variable markup. This can be used to divide the alphabetical index into different sections, for example one section for each first letter." "Add a section line to the alphabetical index, using @code{indexSectionMarkup} paper variable markup. This can be used to divide the alphabetical index into different sections, for example one section for each first letter."
(add-index-item! 'indexSectionMarkup text sorttext)) (add-index-item! 'indexSectionMarkup (prepend-alist-chain 'rawtext text '()) sorttext))
#(define (extract-and-check-vars-from-header bookheader varlist) #(define (extract-and-check-vars-from-header bookheader varlist)
(let* ((headervars (hash-map->list cons (struct-ref (ly:book-header bookheader) 0))) (let* ((headervars (hash-map->list cons (struct-ref (ly:book-header bookheader) 0)))
@ -279,33 +287,36 @@ headerToTOC = #(define-music-function (parser location header label) (ly:book? s
(verseComposerData (find-author-id-with-part-numbers 'meloverse authors)) (verseComposerData (find-author-id-with-part-numbers 'meloverse authors))
(voiceComposerData (find-author-id-with-part-numbers 'voice authors)) (voiceComposerData (find-author-id-with-part-numbers 'voice authors))
(compositionIds (find-author-ids-by 'composition authors)) (compositionIds (find-author-ids-by 'composition authors))
(adaptionIds (find-author-ids-by 'adaption authors))
(bridgeIds (find-author-ids-by 'bridge authors)) (bridgeIds (find-author-ids-by 'bridge authors))
(interludeIds (find-author-ids-by 'interlude authors))) (interludeIds (find-author-ids-by 'interlude authors)))
(delete-duplicates (delete-duplicates
(append poetIds translatorIds (map car versePoetData) composerIds (map car verseComposerData) (map car voiceComposerData) compositionIds bridgeIds interludeIds)) (append poetIds translatorIds (map car versePoetData) composerIds (map car verseComposerData) (map car voiceComposerData) compositionIds adaptionIds bridgeIds interludeIds))
)) ))
(let* (let*
( (
(extractedheadervars (extract-and-check-vars-from-header header '(title starttext alttitle categorytitle categories authors))) (extractedheadervars (extract-and-check-vars-from-header header '(title starttext alttitle categorytitle categories authors songnumber)))
(title (assq-ref extractedheadervars 'title)) (title (assq-ref extractedheadervars 'title))
(starttext (assq-ref extractedheadervars 'starttext)) (starttext (assq-ref extractedheadervars 'starttext))
(alttitle (assq-ref extractedheadervars 'alttitle)) (alttitle (assq-ref extractedheadervars 'alttitle))
(categorytitle (assq-ref extractedheadervars 'categorytitle)) (categorytitle (assq-ref extractedheadervars 'categorytitle))
(categories (assq-ref extractedheadervars 'categories)) (categories (assq-ref extractedheadervars 'categories))
(authors (assq-ref extractedheadervars 'authors)) (authors (assq-ref extractedheadervars 'authors))
(add-to-toc! (lambda (toctitle tocmarkup) (songnumber (assq-ref extractedheadervars 'songnumber))
(add-index-item! 'indexItemMarkup tocmarkup toctitle label))) (textoptions (lambda (text alternative) `(((rawtext . ,text) (alternative . ,alternative) (songnumber . ,songnumber)))))
(add-to-toc! (lambda (toctitle alternative)
(add-index-item! 'indexItemMarkup (textoptions toctitle alternative) toctitle label)))
) )
(if categories (add-category-index-item! (string-tokenize categories) 'indexItemMarkup (cons (list (cons 'rawtext (if categorytitle categorytitle title))) '()) label)) (if categories (add-category-index-item! (string-tokenize categories) 'indexItemMarkup (textoptions (if categorytitle categorytitle title) #f) label))
(if authors (add-author-index-item! (all-author-ids authors) 'indexItemMarkup (cons (list (cons 'rawtext (if categorytitle categorytitle title))) '()) label)) (if authors (add-author-index-item! (all-author-ids authors) 'indexItemMarkup (textoptions (if categorytitle categorytitle title) #f) label))
(if starttext (add-to-toc! starttext (cons (list (cons 'rawtext starttext) (cons 'alternative #t)) '()))) (if starttext (add-to-toc! starttext #t))
(if alttitle (if alttitle
(if (list? alttitle) (if (list? alttitle)
(for-each (lambda (alt) (for-each (lambda (alt)
(add-to-toc! alt (cons (list (cons 'rawtext alt) (cons 'alternative #t)) '()))) (add-to-toc! alt #t))
alttitle) alttitle)
(add-to-toc! alttitle (cons (list (cons 'rawtext alttitle) (cons 'alternative #t)) '())))) (add-to-toc! alttitle #t)))
(if title (add-to-toc! title (cons (list (cons 'rawtext title)) '())) #{ #}) (if title (add-to-toc! title #f) #{ #})
)) ))
@ -358,7 +369,7 @@ headerToTOC = #(define-music-function (parser location header label) (ly:book? s
(songvars (cdr song)) (songvars (cdr song))
(page-number (number->string (assoc-get (assq-ref songvars 'label) labelPageTable))) (page-number (number->string (assoc-get (assq-ref songvars 'label) labelPageTable)))
(extractedheadervars (extract-and-check-vars-from-header (assq-ref songvars 'header) (extractedheadervars (extract-and-check-vars-from-header (assq-ref songvars 'header)
'(title starttext alttitle categorytitle categories authors year_text year_melody year_translation year_composition infotext translation pronunciation copyright source))) '(title starttext alttitle categorytitle categories authors year_text year_melody year_translation year_composition year_adaption infotext translation pronunciation copyright source)))
(headervar-or-empty (lambda (varsym) (headervar-or-empty (lambda (varsym)
(let ((extracted (assq-ref extractedheadervars varsym))) (let ((extracted (assq-ref extractedheadervars varsym)))
(if extracted extracted "")))) (if extracted extracted ""))))
@ -370,6 +381,7 @@ headerToTOC = #(define-music-function (parser location header label) (ly:book? s
(verseComposerData (find-author-id-with-part-numbers 'meloverse authors)) (verseComposerData (find-author-id-with-part-numbers 'meloverse authors))
(voiceComposerData (find-author-id-with-part-numbers 'voice authors)) (voiceComposerData (find-author-id-with-part-numbers 'voice authors))
(compositionIds (find-author-ids-by 'composition authors)) (compositionIds (find-author-ids-by 'composition authors))
(adaptionIds (find-author-ids-by 'adaption authors))
(bridgeIds (find-author-ids-by 'bridge authors)) (bridgeIds (find-author-ids-by 'bridge authors))
(interludeIds (find-author-ids-by 'interlude authors))) (interludeIds (find-author-ids-by 'interlude authors)))
(map csv-escape (map csv-escape
@ -387,11 +399,12 @@ headerToTOC = #(define-music-function (parser location header label) (ly:book? s
(headervar-or-empty 'categories) (headervar-or-empty 'categories)
(format-authors (append poetIds (map car versePoetData))) (format-authors (append poetIds (map car versePoetData)))
(format-authors translatorIds) (format-authors translatorIds)
(format-authors (append composerIds compositionIds bridgeIds interludeIds (map car voiceComposerData) (map car verseComposerData))) (format-authors (append composerIds compositionIds adaptionIds bridgeIds interludeIds (map car voiceComposerData) (map car verseComposerData)))
(headervar-or-empty 'year_text) (headervar-or-empty 'year_text)
(headervar-or-empty 'year_melody) (headervar-or-empty 'year_melody)
(headervar-or-empty 'year_translation) (headervar-or-empty 'year_translation)
(headervar-or-empty 'year_composition) (headervar-or-empty 'year_composition)
(headervar-or-empty 'year_adaption)
(headervar-or-empty 'copyright) (headervar-or-empty 'copyright)
(headervar-or-empty 'source) (headervar-or-empty 'source)
(format-info-paragraphs (headervar-or-empty 'infotext)) (format-info-paragraphs (headervar-or-empty 'infotext))
@ -416,6 +429,7 @@ headerToTOC = #(define-music-function (parser location header label) (ly:book? s
"year_melody" "year_melody"
"year_translation" "year_translation"
"year_composition" "year_composition"
"year_adaption"
"copyright" "copyright"
"source" "source"
"infotext" "infotext"

View File

@ -221,14 +221,28 @@
(cons (car x) (+ (cdr x) amount)) (cons (car x) (+ (cdr x) amount))
y))) y)))
#(define-markup-command (score-equal-height layout props reference-height lines) #(define-markup-command (score-equal-height-with-indents layout props lines)
(number? markup-list?) (markup-list?)
#:category music #:category music
#:properties ((baseline-skip)) #:properties ((intraverse-vspace 0)
(stack-stencils Y DOWN baseline-skip (verse-line-height songTextLineHeigth)
(map (line-indents '()))
(lambda (line) (ly:make-stencil (ly:stencil-expr line) (ly:stencil-extent line X) `(,(/ reference-height -2.0) . ,(/ reference-height 2.0)))) (let ((indents-max-index (- (length line-indents) 1)))
(interpret-markup-list layout props lines)))) (stack-stencils Y DOWN intraverse-vspace
(index-map
(lambda (index line)
(let ((stil
(ly:make-stencil
(ly:stencil-expr line)
(ly:stencil-extent line X)
`(,(/ verse-line-height -2.0) . ,(/ verse-line-height 2.0)))))
(if (<= index indents-max-index)
(ly:stencil-translate-axis
stil
(list-ref line-indents index)
X)
stil)))
(interpret-markup-list layout props lines)))))
#(define-public (custom-lyric-text::print grob) #(define-public (custom-lyric-text::print grob)
"Allow interpretation of tildes as lyric tieing marks." "Allow interpretation of tildes as lyric tieing marks."
@ -243,22 +257,18 @@
#:properties ((verse-chords #{#}) #:properties ((verse-chords #{#})
(verse-reference-voice #{#}) (verse-reference-voice #{#})
(verse-break-voice #{#}) (verse-break-voice #{#})
(verse-line-height songTextLineHeigth)
(verse-text-chord-distance songTextChordDistance) (verse-text-chord-distance songTextChordDistance)
(intraverse-vspace 0)
(transposition (cons #f #f)) (transposition (cons #f #f))
(verselayout generalLayout)) (verselayout generalLayout))
"Vers mit Akkorden" "Vers mit Akkorden"
(interpret-markup layout props (interpret-markup layout props
#{ #{
\markup { \markup {
\override #`(baseline-skip . ,intraverse-vspace) \score-equal-height-with-indents \score-lines {
\score-equal-height #verse-line-height \score-lines {
\transposable #transposition
<< <<
\new Devnull { #verse-break-voice } \new Devnull { #(music-clone verse-break-voice) }
\new NullVoice = "dummyvoice" { #verse-reference-voice } \new NullVoice = "dummyvoice" { #(music-clone verse-reference-voice) }
#(music-clone verse-chords) \transposable #transposition #(music-clone verse-chords)
\new Lyrics \lyricsto "dummyvoice" { #lyrics } \new Lyrics \lyricsto "dummyvoice" { #lyrics }
>> >>
\layout { \layout {
@ -290,8 +300,10 @@
\override SpacingSpanner.spacing-increment = 0 \override SpacingSpanner.spacing-increment = 0
\remove Bar_number_engraver \remove Bar_number_engraver
\remove Mark_engraver \remove Mark_engraver
\remove Jump_engraver
\remove Volta_engraver \remove Volta_engraver
\remove Parenthesis_engraver \remove Parenthesis_engraver
\remove Metronome_mark_engraver
} }
\context { \context {
\Staff \Staff
@ -318,8 +330,9 @@
\NullVoice \NullVoice
\consists Rest_engraver \consists Rest_engraver
\omit Rest \omit Rest
% \undo \omit NoteHead \undo \omit NoteHead
% \hide NoteHead \hide NoteHead
\override NoteHead.X-extent = #'(0 . 0)
} }
} }
} }