10 Commits

Author SHA1 Message Date
tux
36f1e8c0fd new engraver for spacing in chordlyrics 2025-06-12 22:29:58 +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
10 changed files with 221 additions and 29 deletions

View File

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

View File

@ -225,9 +225,9 @@ cue =
#{
\tag #'cues {
\tweak self-alignment-X #LEFT
\mark
\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

@ -114,7 +114,7 @@ width may require additional tweaking.)"
includeSong =
#(define-void-function (parser location textproc filename) ((procedure?) string?)
#(define-void-function (parser location filename) (string?)
#{
\bookOutputName #filename
#}
@ -125,7 +125,15 @@ includeSong =
(acons label additional-page-numbers additional-page-switch-label-list))
(set! song-list
(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))
))
@ -184,14 +192,14 @@ songs =
;(header (assq-ref songvars 'header))
(music (assq-ref songvars 'music))
(layout (assq-ref songvars 'layout))
(text (assq-ref songvars 'text))
(text-pages (assq-ref songvars 'text-pages))
(label (assq-ref songvars 'label)))
#{
\bookpart {
$header
\headerToTOC #header #label
\score { $music \layout { $layout } }
$text
$(add-text-pages text-pages)
}
#}))))))
(reverse song-list)

View File

@ -68,6 +68,18 @@ altChord =
#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
#(define (note-name->german-markup-nosym pitch lowercase?)
(define (pitch-alteration-semitones pitch) (inexact->exact (round (* (ly:pitch-alteration pitch) 2))))

View File

@ -2,6 +2,7 @@
poetPrefix = "Worte:"
composerPrefix = "Weise:"
compositionPrefix = "Satz:"
adaptionPrefix = "Bearbeitung:"
poetAndComposerEqualPrefix = "Worte und Weise:"
voicePrefix = "Stimme:"
versePrefix = "Strophe:"

View File

@ -102,14 +102,16 @@
(verseComposerData (find-author-id-with-part-numbers 'meloverse authors))
(voiceComposerData (find-author-id-with-part-numbers 'voice authors))
(compositionIds (find-author-ids-by 'composition authors))
(adaptionIds (find-author-ids-by 'adaption authors))
(bridgeIds (find-author-ids-by 'bridge authors))
(interludeIds (find-author-ids-by 'interlude authors))
(year_text (chain-assoc-get 'header:year_text props #f))
(year_translation (chain-assoc-get 'header:year_translation props #f))
(year_melody (chain-assoc-get 'header:year_melody 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
(join-present (list
(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
(ly:output-def-lookup layout 'composerPrefix)
" "
@ -148,6 +150,10 @@
(render-contribution-group (ly:output-def-lookup layout 'compositionPrefix) compositionIds)
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 'interludePrefix) interludeIds)
) "; ")

7
include_from_song.ily Normal file
View File

@ -0,0 +1,7 @@
includeFromSong =
#(define-void-function (filename) (string?)
(let ((noDefaultOutputBackup noDefaultOutput))
(set! noDefaultOutput #t)
(ly:parser-parse-string (ly:parser-clone)
(ly:format "\\include \"~a\"" filename))
(set! noDefaultOutput noDefaultOutputBackup)))

View File

@ -26,6 +26,34 @@ TEXT = \markuplist {
\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)
(begin
(let ((header (ly:book-header HEADER)) (paper (ly:book-paper HEADER)))
@ -37,7 +65,7 @@ TEXT = \markuplist {
\MUSIC
\layout { \LAYOUT }
}#})
(add-score TEXT)
(add-text-pages TEXT_PAGES)
(add-score #{
\score {
\unfoldRepeats { \MUSIC \INLINESCOREMUSIC }

View File

@ -67,13 +67,14 @@
(ly:string-substitute "…" ""
(ly:string-substitute "Č" "C"
(ly:string-substitute "Đ" "D"
(ly:string-substitute "Š" "S"
(ly:string-substitute "Т" "T"
(ly:string-substitute "Ä" "Ae"
(ly:string-substitute "ä" "ae"
(ly:string-substitute "Ö" "O"
(ly:string-substitute "ö" "oe"
(ly:string-substitute "Ü" "U"
(ly:string-substitute "ü" "ue" sorttext))))))))))))
(ly:string-substitute "ü" "ue" sorttext)))))))))))))
index-item-list))
(make-music 'EventChord
'page-marker #t
@ -279,10 +280,11 @@ headerToTOC = #(define-music-function (parser location header label) (ly:book? s
(verseComposerData (find-author-id-with-part-numbers 'meloverse authors))
(voiceComposerData (find-author-id-with-part-numbers 'voice authors))
(compositionIds (find-author-ids-by 'composition authors))
(adaptionIds (find-author-ids-by 'adaption authors))
(bridgeIds (find-author-ids-by 'bridge authors))
(interludeIds (find-author-ids-by 'interlude authors)))
(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*
(
@ -358,7 +360,7 @@ headerToTOC = #(define-music-function (parser location header label) (ly:book? s
(songvars (cdr song))
(page-number (number->string (assoc-get (assq-ref songvars 'label) labelPageTable)))
(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)
(let ((extracted (assq-ref extractedheadervars varsym)))
(if extracted extracted ""))))
@ -370,6 +372,7 @@ headerToTOC = #(define-music-function (parser location header label) (ly:book? s
(verseComposerData (find-author-id-with-part-numbers 'meloverse authors))
(voiceComposerData (find-author-id-with-part-numbers 'voice authors))
(compositionIds (find-author-ids-by 'composition authors))
(adaptionIds (find-author-ids-by 'adaption authors))
(bridgeIds (find-author-ids-by 'bridge authors))
(interludeIds (find-author-ids-by 'interlude authors)))
(map csv-escape
@ -387,11 +390,12 @@ headerToTOC = #(define-music-function (parser location header label) (ly:book? s
(headervar-or-empty 'categories)
(format-authors (append poetIds (map car versePoetData)))
(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_melody)
(headervar-or-empty 'year_translation)
(headervar-or-empty 'year_composition)
(headervar-or-empty 'year_adaption)
(headervar-or-empty 'copyright)
(headervar-or-empty 'source)
(format-info-paragraphs (headervar-or-empty 'infotext))
@ -416,6 +420,7 @@ headerToTOC = #(define-music-function (parser location header label) (ly:book? s
"year_melody"
"year_translation"
"year_composition"
"year_adaption"
"copyright"
"source"
"infotext"

View File

@ -221,14 +221,28 @@
(cons (car x) (+ (cdr x) amount))
y)))
#(define-markup-command (score-equal-height layout props reference-height lines)
(number? markup-list?)
#(define-markup-command (score-equal-height-with-indents layout props lines)
(markup-list?)
#:category music
#:properties ((baseline-skip))
(stack-stencils Y DOWN baseline-skip
(map
(lambda (line) (ly:make-stencil (ly:stencil-expr line) (ly:stencil-extent line X) `(,(/ reference-height -2.0) . ,(/ reference-height 2.0))))
(interpret-markup-list layout props lines))))
#:properties ((intraverse-vspace 0)
(verse-line-height songTextLineHeigth)
(line-indents '()))
(let ((indents-max-index (- (length line-indents) 1)))
(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)
"Allow interpretation of tildes as lyric tieing marks."
@ -239,24 +253,128 @@
(make-pad-right-markup -0.1 (make-tied-lyric-markup text))
text))))
Chord_lyrics_spacing_engraver =
#(lambda (ctx)
(let ((last-note-head #f)
(note-head-extended #f)
(last-lyric-syllable-width 0)
(lyric-width-since-last-chord 0)
(notes-on-syllable-count 0)
(last-chord-name #f)
(remaining-chord-width 0)
(last-rest #f)
(rest-count 0)
(multi-measure-rest-count 0)
(stanza-shift 0))
(make-engraver
(listeners
((multi-measure-rest-event engraver event)
(set! multi-measure-rest-count (+ multi-measure-rest-count 1))
)
((break-event engraver event)
(set! last-note-head #f)
(set! note-head-extended #f)
(set! last-lyric-syllable-width 0)
(set! lyric-width-since-last-chord 0)
(set! notes-on-syllable-count 0)
(set! last-chord-name #f)
(set! remaining-chord-width 0)
(set! last-rest #f)
(set! rest-count 0)
(set! multi-measure-rest-count 0)
(set! stanza-shift 0)
))
(acknowledgers
((note-head-interface this-engraver grob source-engraver)
(if (and (> rest-count 0) (not last-note-head))
(let ((rest-spacing-on-line-start 1.2))
(ly:grob-set-property! grob 'minimum-X-extent (cons (- rest-spacing-on-line-start) 0))
(set! stanza-shift rest-spacing-on-line-start)
))
(set! notes-on-syllable-count (+ 1 notes-on-syllable-count))
(set! last-note-head grob)
(set! note-head-extended #f)
(set! last-rest #f)
(set! rest-count 0)
(set! multi-measure-rest-count 0)
)
((lyric-syllable-interface this-engraver grob source-engraver)
(set! remaining-chord-width (max 0 (- remaining-chord-width lyric-width-since-last-chord)))
(set! last-lyric-syllable-width (- (cdr (ly:grob-extent grob grob X)) 0.2))
(set! lyric-width-since-last-chord (+ lyric-width-since-last-chord last-lyric-syllable-width))
(if last-note-head (set! notes-on-syllable-count 1))
)
((chord-name-interface this-engraver grob source-engraver)
(if (not (and
(boolean? (ly:grob-property grob 'begin-of-line-visible))
(ly:grob-property grob 'begin-of-line-visible)))
(let ((on-a-rest (> rest-count 0)))
(if (not on-a-rest)
(set! notes-on-syllable-count (- notes-on-syllable-count 1)))
(if (and last-chord-name (= multi-measure-rest-count 1) (> lyric-width-since-last-chord remaining-chord-width))
(ly:grob-set-property! last-chord-name 'extra-spacing-width (cons -0.1 (+ 0.1 (- lyric-width-since-last-chord remaining-chord-width)))))
(if last-note-head
(let* ((last-note-min-x-extent (ly:grob-property last-note-head 'minimum-X-extent))
(last-note-min-x-lower (if (pair? last-note-min-x-extent) (car last-note-min-x-extent) 0))
(last-note-min-x-upper (if (pair? last-note-min-x-extent) (cdr last-note-min-x-extent) 0)))
(if on-a-rest
(begin
(if (not note-head-extended)
(begin
(ly:grob-set-property! last-note-head 'minimum-X-extent
(cons last-note-min-x-lower (- last-lyric-syllable-width -2 (* 2.2 rest-count))))
(set! note-head-extended #t)
))
(ly:grob-set-property! last-rest 'minimum-X-extent (cons 0 2))
)
(if (and (> lyric-width-since-last-chord 0)
(> remaining-chord-width lyric-width-since-last-chord))
(ly:grob-set-property! last-note-head 'minimum-X-extent
(cons (- -1.2 (- remaining-chord-width lyric-width-since-last-chord)) last-note-min-x-upper))
(let* ((width-per-note-head 0.5)
(note-width-since-last-chord (* width-per-note-head notes-on-syllable-count)))
(if (> remaining-chord-width note-width-since-last-chord)
(ly:grob-set-property! last-note-head 'minimum-X-extent
(cons (- note-width-since-last-chord remaining-chord-width) last-note-min-x-upper))
)
)
)
)))
(set! last-chord-name grob)
(set! remaining-chord-width
(if (and on-a-rest (equal? (ly:prob-property (ly:grob-property grob 'cause) 'duration) (ly:prob-property (ly:grob-property last-rest 'cause) 'duration)))
0
(cdr (ly:grob-extent grob grob X))))
(set! lyric-width-since-last-chord 0)
(set! notes-on-syllable-count (if on-a-rest 0 1))
))
)
((rest-interface this-engraver grob source-engraver)
(set! rest-count (+ 1 rest-count))
(set! last-rest grob)
(set! multi-measure-rest-count 0)
)
((stanza-number-interface this-engraver grob source-engraver)
(ly:grob-set-property! grob 'padding (+ 1 stanza-shift)))
))))
%#(ly:set-option 'debug-skylines #t)
#(define-markup-command (chordlyrics layout props lyrics) (ly:music?)
#:properties ((verse-chords #{#})
(verse-reference-voice #{#})
(verse-break-voice #{#})
(verse-line-height songTextLineHeigth)
(verse-text-chord-distance songTextChordDistance)
(intraverse-vspace 0)
(transposition (cons #f #f))
(verselayout generalLayout))
"Vers mit Akkorden"
(interpret-markup layout props
#{
\markup {
\override #`(baseline-skip . ,intraverse-vspace)
\score-equal-height #verse-line-height \score-lines {
\score-equal-height-with-indents \score-lines {
<<
\new Devnull { #verse-break-voice }
\new NullVoice = "dummyvoice" { #verse-reference-voice }
\new Devnull { #(music-clone verse-break-voice) }
\new NullVoice = "dummyvoice" { #(music-clone verse-reference-voice) }
\transposable #transposition #(music-clone verse-chords)
\new Lyrics \lyricsto "dummyvoice" { #lyrics }
>>
@ -287,11 +405,14 @@
% \override SpacingSpanner.strict-note-spacing = ##t
\override SpacingSpanner.uniform-stretching = ##t
\override SpacingSpanner.spacing-increment = 0
%\override SpacingSpanner.packed-spacing = ##t
\consists \Chord_lyrics_spacing_engraver
\remove Bar_number_engraver
\remove Mark_engraver
\remove Jump_engraver
\remove Volta_engraver
\remove Parenthesis_engraver
\remove Metronome_mark_engraver
}
\context {
\Staff
@ -318,8 +439,10 @@
\NullVoice
\consists Rest_engraver
\omit Rest
% \undo \omit NoteHead
% \hide NoteHead
\override Rest.X-extent = #'(0 . 0)
\undo \omit NoteHead
\hide NoteHead
\override NoteHead.X-extent = #'(0 . 0.5)
}
}
}