20 Commits

Author SHA1 Message Date
603b25831a Chordpro export 2026-04-07 08:31:02 +02:00
71c8c0385c switch swingStyle to textMark 2026-03-31 18:55:12 +02:00
f075946777 use right translationAuthorPrefix in authorContributionFormat 2026-03-12 22:25:50 +01:00
a0de02126c no "add" as additionalPitchPrefix 2026-03-10 19:17:40 +01:00
7ece3b9c10 underline for LyricText 2026-03-09 17:01:21 +01:00
7fc99e8883 use new chords and page references of LilyPond 2.25.35 2026-03-08 13:37:31 +01:00
b3feb3aa6d padding for stop tags and refactoring 2026-02-22 20:33:18 +01:00
7b166f6fc3 pad left for stanzas to have a minimum distance to SystemStartBar 2026-02-22 13:22:45 +01:00
9c437d0f06 reset tag groups for each song 2026-02-10 17:18:52 +01:00
a52f993678 more flexible titeling 2026-02-01 01:45:10 +01:00
bbd6d44455 Autorensystem flexibilisiert 2026-01-11 20:03:31 +01:00
f68e2f10ae implement default bridge style 2025-12-29 18:06:00 +01:00
463d61fbd9 fix customize layout sizing 2025-12-22 11:29:32 +01:00
tux
2d14a5b632 new engraver for spacing in chordlyrics 2025-12-15 21:41:45 +01:00
368a1b96aa rework stanza handler 2025-12-15 11:49:30 +01:00
f57b1c4ec3 customize text chord distance in old system, too 2025-12-15 01:47:05 +01:00
e530bdf090 make verselayout really work 2025-12-15 01:26:19 +01:00
c97c856b05 Use \tempo command for midi speed
* Remove Metronome mark engraver
* Remove midiQuarterNoteSpeed
2025-12-13 12:50:01 +01:00
76b81a9968 no breaks in toc after section title 2025-11-24 20:45:00 +01:00
3ff5a36106 better load song include data in windows 2025-11-24 16:47:13 +01:00
14 changed files with 1491 additions and 265 deletions

2
.gitignore vendored
View File

@@ -1,8 +1,8 @@
# ---> Lilypond
*.pdf
*.cho
*.ps
*.midi
*.mid
*.log
*~

View File

@@ -21,14 +21,24 @@
)))))
(scm-load "resolve_inherits.scm")
(scm-load "yaml_parser.scm")))
#(define AUTHOR_DATA (if (defined? 'AUTHOR_DATA) AUTHOR_DATA (parse-yml-file "../../lilypond-song-includes/data/authors.yml")))
#(define SONG_DATA (if (defined? 'SONG_DATA) SONG_DATA (parse-yml-file "../../lilypond-song-includes/data/songs.yml")))
#(define (song-includes-data-path filename)
(string-join
(list
(dirname (dirname (dirname (dirname (current-filename)))))
"lilypond-song-includes"
"data"
filename)
file-name-separator-string))
#(define AUTHOR_DATA (if (defined? 'AUTHOR_DATA) AUTHOR_DATA (parse-yml-file (song-includes-data-path "authors.yml"))))
#(define SONG_DATA (if (defined? 'SONG_DATA) SONG_DATA (parse-yml-file (song-includes-data-path "songs.yml"))))
\include "merge_rests_engraver_override.ily"
\include "basic_format_and_style_settings.ily"
\include "eps_file_from_song_dir.ily"
\include "title_with_category_images.ily"
\include "chord_settings.ily"
\include "chordpro.ily"
\include "transposition.ily"
\include "verses_with_chords.ily"
\include "arrows_in_scores.ily"
@@ -47,3 +57,5 @@ TEXT_PAGES = #f
verseChords = {}
firstVoice = {}
global = {}
\resetTagGroups

View File

@@ -29,6 +29,11 @@
(if (null? stanzanumbers)
refString
(ly:format refStringWithNumbers (string-join (map (lambda (stanzanumber) (ly:format "~a" stanzanumber)) stanzanumbers) ", ")))))
bridgeMarkupFormatter = #(lambda (layout props stanzanumbers)
(interpret-markup layout props
(if (null? stanzanumbers)
bridgeString
(ly:format bridgeStringWithNumbers (string-join (map (lambda (stanzanumber) (ly:format "~a" stanzanumber)) stanzanumbers) ", ")))))
}
generalLayout = \layout {
@@ -49,6 +54,7 @@ generalLayout = \layout {
\context {
\Score
\remove "Bar_number_engraver"
\remove "Metronome_mark_engraver"
\RemoveEmptyStaves
\override VerticalAxisGroup.remove-first = ##t
\overrideTimeSignatureSettings
@@ -78,6 +84,11 @@ generalLayout = \layout {
}
}
#(define (customized-layout base-layout)
(let
((custom-size (ly:output-def-lookup base-layout 'size #f)))
(if custom-size (layout-set-staff-size custom-size))))
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% kleine Helferlein:
@@ -133,18 +144,26 @@ override-stanza =
#}
)
#(define (handle-stanza-numbers context numbers number-formater)
(let* ((stanzanumbers (ly:assoc-get 'custom-stanzanumber-override (ly:assoc-get 'details (ly:context-grob-definition context 'StanzaNumber) '()) numbers))
(stanza-style (ly:assoc-get 'style (ly:context-grob-definition context 'StanzaNumber)))
(roman-format (lambda (stanzanumber) (format #f "~@r" stanzanumber))))
(ly:context-set-property! context 'stanza
(make-pad-left-markup 1
(number-formater
(if (eq? stanza-style 'roman)
(map roman-format stanzanumbers)
stanzanumbers))))))
#(define (stanza . stanzanumbers)
#{
\once \override StanzaNumber.details.custom-realstanza = ##t % set this to signal that there is a real stanza and no repeat signs
\once \override StanzaNumber.details.custom-stanza-type = #'verse
\once \override StanzaNumber.details.custom-stanza-numbers = #stanzanumbers
\applyContext
#(lambda (context)
(let* ((stanzanumbers-override (ly:assoc-get 'custom-stanzanumber-override (ly:assoc-get 'details (ly:context-grob-definition context 'StanzaNumber) '()) #f))
(stanza-style (ly:assoc-get 'style (ly:context-grob-definition context 'StanzaNumber)))
(stanza-format (lambda (stanzanumber) (format #f (if (eq? stanza-style 'roman) romanStanzaFormat stanzaFormat) stanzanumber))))
(ly:context-set-property! context 'stanza
(string-join (map stanza-format
(if stanzanumbers-override stanzanumbers-override stanzanumbers))
", "))))
(handle-stanza-numbers context stanzanumbers
(lambda (numbers) (string-join (map (lambda (n) (format #f stanzaFormat n)) numbers) ", "))))
#}
)
@@ -152,7 +171,35 @@ ref =
#(define-music-function (stanzanumbers lyrics) ((number-list? (list)) ly:music?)
#{ \lyricmode {
\once \override StanzaNumber.details.custom-realstanza = ##t % set this to signal that there is a real stanza and no repeat signs
\set stanza = #(make-on-the-fly-markup (lambda (layout props m) ((ly:output-def-lookup layout 'refMarkupFormatter) layout props stanzanumbers)) (make-null-markup))
\once \override StanzaNumber.details.custom-stanza-type = #'ref
\once \override StanzaNumber.details.custom-stanza-numbers = #stanzanumbers
\applyContext
#(lambda (context)
(handle-stanza-numbers context stanzanumbers
(lambda (numbers)
(make-on-the-fly-markup
(lambda (layout props m)
((ly:output-def-lookup layout 'refMarkupFormatter) layout props numbers))
(make-null-markup)))))
#lyrics
}
#}
)
bridge =
#(define-music-function (stanzanumbers lyrics) ((number-list? (list)) ly:music?)
#{ \lyricmode {
\once \override StanzaNumber.details.custom-realstanza = ##t % set this to signal that there is a real stanza and no repeat signs
\once \override StanzaNumber.details.custom-stanza-type = #'bridge
\once \override StanzaNumber.details.custom-stanza-numbers = #stanzanumbers
\applyContext
#(lambda (context)
(handle-stanza-numbers context stanzanumbers
(lambda (numbers)
(make-on-the-fly-markup
(lambda (layout props m)
((ly:output-def-lookup layout 'bridgeMarkupFormatter) layout props numbers))
(make-null-markup)))))
#lyrics
}
#}
@@ -160,8 +207,11 @@ ref =
% prints a repStart Sign as stanza if the tag 'repeats is kept.
% if there was a stanza already set by the stanza function with StanzaNumber.details.custom-realstanza = ##t we set that also as stanza.
% Sets custom-inline-text for ChordPro export so it can collect the repeat sign separately
repStartWithTag = \lyricmode {
\tag #'repeats {
\once \override StanzaNumber.details.custom-inline-text = \repStart
\once \override StanzaNumber.details.custom-inline-direction = #LEFT
\applyContext
#(lambda (context)
(let ((lastStanza (ly:context-property context 'stanza))
@@ -179,9 +229,11 @@ repStartWithTag = \lyricmode {
repStopWithTag = \lyricmode {
\tag #'repeats {
\once \override StanzaNumber.details.custom-inline-text = \repStop
\once \override StanzaNumber.details.custom-inline-direction = #RIGHT
\once \override StanzaNumber.font-series = #'normal
\once \override StanzaNumber.direction = 1
\set stanza = \markup { \repStop }
\set stanza = \markup { \pad-x-right #1 \repStop }
}
}
@@ -265,3 +317,17 @@ rufWithMarkup =
ruf =
#(define-music-function (text) (string?)
(rufWithMarkup (make-ruf-style-markup text)))
underlineOn =
#(define-music-function () ()
#{
\override LyricText.stencil =
#(lambda (grob)
(grob-interpret-markup grob (make-underline-markup (ly:grob-property grob 'text))))
#})
underlineOff =
#(define-music-function () ()
#{
\revert LyricText.stencil
#})

View File

@@ -40,34 +40,19 @@ shiftChords = #(define-music-function (parser location xshift chords) (number? l
altChord =
#(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 {
\translate #'(-0.5 . 0)
\score {
\chords { \transposable #(cons (car (music-pitches mainchord)) (car in-pitches)) { #(music-clone mainchord) \klamm #(music-clone altchord) } }
\layout {
\LAYOUT
\context {
\ChordNames
\override ChordName.extra-spacing-width = #'(0 . 0.3)
\override ChordName.stencil = #remove-point-and-click
}
\context {
\Score
\override SpacingSpanner.spacing-increment = 0
}
}
}
}#})))
(let* ((chord-name (lambda (in-pitches bass inversion context)
(make-line-markup (list
(ignatzek-chord-names in-pitches bass inversion context)
(make-hspace-markup 0.3)
(parenthesis-ignatzek-chord-names (music-pitches (transposable (cons (car (music-pitches mainchord)) (car in-pitches)) (music-clone altchord))) '() '() context)
))
)))
#{
\once \set chordNameFunction = #chord-name
#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?)
@@ -80,41 +65,8 @@ capoTranspose =
(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))))
(define (accidental->markup alteration name)
(if (= alteration 0)
(make-line-markup (list empty-markup))
(if (= alteration FLAT)
(if (equal? name "B")
""
; (make-line-markup (list (make-hspace-markup 0.2)
; (make-tiny-markup (make-raise-markup 1.2
; (make-musicglyph-markup (assoc-get alteration standard-alteration-glyph-name-alist ""))))
; ))
(if (or (equal? name "E") (equal? name "A")) "s" "es"))
"is")
))
(define (conditional-string-downcase str condition)
(if condition (string-downcase str) str))
(let* ((name (ly:pitch-notename pitch))
(alt-semitones (pitch-alteration-semitones pitch))
(n-a (if (member (cons name alt-semitones) `((6 . -1) (6 . -2)))
(cons 7 (+ 0 alt-semitones))
(cons name alt-semitones))))
(make-line-markup
(list
(make-simple-markup
(conditional-string-downcase
(vector-ref #("C" "D" "E" "F" "G" "A" "H" "B") (car n-a))
lowercase?))
(accidental->markup (/ (cdr n-a) 2) (vector-ref #("C" "D" "E" "F" "G" "A" "H" "B") (car n-a)) ))))
)
% 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?)((chord-name:name-markup 'deutsch) pitch #f))
defaultChordPrintings = {
<c g>-\markup { \super "5" }
@@ -157,15 +109,15 @@ generalLayout = \layout {
\generalLayout
\context {
\ChordNames
\semiGermanChords
\override ChordName.font-size = \songScoreChordFontSize
\override ChordName.font-series = \songChordFontSeries
\override ChordName.font-family = #'serif
chordNameLowercaseMinor = ##t
chordChanges = ##t
% eigenen chordRootNamer damit F# = Fis und Gb = Ges (also alteration ausgeschrieben)
chordRootNamer = #note-name->german-markup-nosym
chordRootNamer = #(chord-name:name-markup 'deutsch)
chordNoteNamer = #bassnote-name->german-markup-nosym
additionalPitchPrefix = ""
majorSevenSymbol = "maj7"
chordNameExceptions = \chordNameExceptions
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,8 +2,8 @@
poetPrefix = "Worte:"
composerPrefix = "Weise:"
compositionPrefix = "Satz:"
adaptionTextPrefix = "Bearbeitung Text:"
adaptionMusicPrefix = "Bearbeitung Musik:"
adaptionTextPrefix = "Bearbeitung:"
adaptionMusicPrefix = "Bearbeitung:"
poetAndComposerEqualPrefix = "Worte und Weise:"
voicePrefix = "Stimme:"
versePrefix = "Strophe:"
@@ -12,6 +12,7 @@
pronunciationPrefix = "Aussprache:"
interludePrefix = "Zwischenspiel:"
bridgePrefix = "Bridge:"
author-joiner = #(lambda (author-list) (string-join author-list ", "))
authorFormat =
#(lambda (noDetails name trail_name birth_year death_year organization)
@@ -31,6 +32,105 @@
""
)))
authorContributionFormat =
#(lambda* (render-contribution-group render-partial-contribution-group #:key
(poetIds '())
(translatorIds '())
(versePoetData '())
(composerIds '())
(verseComposerData '())
(voiceComposerData '())
(compositionIds '())
(adaptionTextIds '())
(adaptionMusicIds '())
(bridgeIds '())
(interludeIds '())
(year_text #f)
(year_translation #f)
(year_melody #f)
(year_composition #f)
(year_adaption_text #f)
(year_adaption_music #f)
(poetAndComposerEqualPrefix "")
(poetPrefix "")
(composerPrefix "")
(translationAuthorPrefix "")
(pronunciationPrefix "")
(compositionPrefix "")
(adaptionTextPrefix "")
(adaptionMusicPrefix "")
(bridgePrefix "")
(interludePrefix ""))
(if (and
(equal? poetIds composerIds)
(null? translatorIds)
(null? versePoetData)
(null? verseComposerData)
(null? voiceComposerData)
(null? compositionIds)
(null? adaptionTextIds)
(null? adaptionMusicIds)
(null? bridgeIds)
(null? interludeIds))
(list
(join-present (list
(render-contribution-group poetAndComposerEqualPrefix poetIds)
(if (equal? year_text year_melody) year_text (join-present (list year_text year_melody) "/"))
) ", ")
#f)
(list
(if (and (null? poetIds) (null? versePoetData) (null? translatorIds)) #f
(string-append
poetPrefix
" "
(join-present (list
(join-present (list
(render-contribution-group "" poetIds)
year_text
) ", ")
(render-partial-contribution-group 'versePrefix versePoetData)
(join-present (list
(render-contribution-group adaptionTextPrefix adaptionTextIds)
year_adaption_text
) ", ")
(join-present (list
(render-contribution-group translationAuthorPrefix translatorIds)
year_translation
) ", ")
) "; ")
))
(if (and
(null? composerIds)
(null? compositionIds)
(null? adaptionMusicIds)
(null? verseComposerData)
(null? voiceComposerData)
(null? bridgeIds)
(null? interludeIds)) #f
(string-append
composerPrefix
" "
(join-present (list
(join-present (list
(render-contribution-group "" composerIds)
year_melody
) ", ")
(render-partial-contribution-group 'versePrefix verseComposerData)
(render-partial-contribution-group 'voicePrefix voiceComposerData)
(join-present (list
(render-contribution-group compositionPrefix compositionIds)
year_composition
) ", ")
(join-present (list
(render-contribution-group adaptionMusicPrefix adaptionMusicIds)
year_adaption_music
) ", ")
(render-contribution-group bridgePrefix bridgeIds)
(render-contribution-group interludePrefix interludeIds)
) "; ")
)))))
songinfoMarkup =
#(make-on-the-fly-markup
(lambda (layout props m)
@@ -45,13 +145,15 @@
(year_melody (chain-assoc-get 'songinfo:year_melody props #f))
(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))
(concat-markupped-strings (lambda (text)
(ly:regex-replace (ly:make-regex "(\\S+)(\\\\\\w+(?:\\s+\\[^\\{\\s]*|\\s*\\{[^\\}]*\\}))(\\S*)") text "\\concat {" 1 "\\line {" 2 "}" 3 "}")))
(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) } #}))
#{ \markuplist { $(ly:parser-include-string (concat-markupped-strings paragraph)) } #}))
(ly:regex-split (ly:make-regex "\r?\n[ \t\r\n]*\n[ \t\r\n]*") (string-append prefix text))))
'())))
(poet-and-composer-markup-list

View File

@@ -16,9 +16,10 @@ songTocColumns = 3
globalSize = 15
lyricSize = 1.6
stanzaFormat = "~a."
romanStanzaFormat = "~@r."
refString = "Ref.:"
refStringWithNumbers = "Ref. ~a:"
bridgeString = "Bridge:"
bridgeStringWithNumbers = "Bridge ~a:"
% hübsche Wiederholungszeichen für den Liedtext
repStart = "𝄆"
repStop = "𝄇"

View File

@@ -30,6 +30,9 @@
(lambda (a b) (< (cadr a) (cadr b))))
(list)))
#(define (join-present items joiner)
(string-join (filter (lambda (item) (and (string? item) (not (string-null? (string-trim-both item))))) items) joiner))
#(define-markup-command (print-songinfo layout props) ()
(define (songinfo-from songId key)
(let ((song (if (defined? 'SONG_DATA) (assoc-ref SONG_DATA songId) #f)))
@@ -74,11 +77,7 @@
(define (render-contribution-group contributionPrefix authorIds)
(if (null? 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)
(string-append contributionPrefix " " ((ly:output-def-lookup layout 'author-joiner) (format-authors authorIds))))
)
(define (render-partial-contribution-group prefixLookup authorData)
@@ -94,93 +93,37 @@
(define (poet-and-composer-from-authors authors)
(if authors
(let (
(poetIds (find-author-ids-by 'text authors))
(translatorIds (find-author-ids-by 'translation authors))
(versePoetData (find-author-id-with-part-numbers 'verse authors))
(composerIds (find-author-ids-by 'melody authors))
(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))
(adaptionTextIds (find-author-ids-by 'adaption_text authors))
(adaptionMusicIds (find-author-ids-by 'adaption_music 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_text (chain-assoc-get 'header:year_adaption_text props #f))
(year_adaption_music (chain-assoc-get 'header:year_adaption_music props #f))
((ly:output-def-lookup layout 'authorContributionFormat)
render-contribution-group
render-partial-contribution-group
#:poetIds (find-author-ids-by 'text authors)
#:translatorIds (find-author-ids-by 'translation authors)
#:versePoetData (find-author-id-with-part-numbers 'verse authors)
#:composerIds (find-author-ids-by 'melody authors)
#: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)
#:adaptionTextIds (find-author-ids-by 'adaption_text authors)
#:adaptionMusicIds (find-author-ids-by 'adaption_music 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_text (chain-assoc-get 'header:year_adaption_text props #f)
#:year_adaption_music (chain-assoc-get 'header:year_adaption_music props #f)
#:poetAndComposerEqualPrefix (ly:output-def-lookup layout 'poetAndComposerEqualPrefix)
#:poetPrefix (ly:output-def-lookup layout 'poetPrefix)
#:composerPrefix (ly:output-def-lookup layout 'composerPrefix)
#:translationAuthorPrefix (ly:output-def-lookup layout 'translationAuthorPrefix)
#:pronunciationPrefix (ly:output-def-lookup layout 'pronunciationPrefix)
#:compositionPrefix (ly:output-def-lookup layout 'compositionPrefix)
#:adaptionTextPrefix (ly:output-def-lookup layout 'adaptionTextPrefix)
#:adaptionMusicPrefix (ly:output-def-lookup layout 'adaptionMusicPrefix)
#:bridgePrefix (ly:output-def-lookup layout 'bridgePrefix)
#:interludePrefix (ly:output-def-lookup layout 'interludePrefix)
)
(if (and
(equal? poetIds composerIds)
(null? translatorIds)
(null? versePoetData)
(null? verseComposerData)
(null? voiceComposerData)
(null? compositionIds)
(null? adaptionTextIds)
(null? adaptionMusicIds)
(null? bridgeIds)
(null? interludeIds))
(list
(join-present (list
(render-contribution-group (ly:output-def-lookup layout 'poetAndComposerEqualPrefix) poetIds)
(if (equal? year_text year_melody) year_text (join-present (list year_text year_melody) "/"))
) ", ")
#f)
(list
(if (and (null? poetIds) (null? versePoetData) (null? translatorIds)) #f
(string-append
(ly:output-def-lookup layout 'poetPrefix)
" "
(join-present (list
(join-present (list
(render-contribution-group "" poetIds)
year_text
) ", ")
(render-partial-contribution-group 'versePrefix versePoetData)
(join-present (list
(render-contribution-group (ly:output-def-lookup layout 'translationAuthorPrefix) translatorIds)
year_translation
) ", ")
(join-present (list
(render-contribution-group (ly:output-def-lookup layout 'adaptionTextPrefix) adaptionTextIds)
year_adaption_text
) ", ")
) "; ")
))
(if (and
(null? composerIds)
(null? compositionIds)
(null? adaptionMusicIds)
(null? verseComposerData)
(null? voiceComposerData)
(null? bridgeIds)
(null? interludeIds)) #f
(string-append
(ly:output-def-lookup layout 'composerPrefix)
" "
(join-present (list
(join-present (list
(render-contribution-group "" composerIds)
year_melody
) ", ")
(render-partial-contribution-group 'versePrefix verseComposerData)
(render-partial-contribution-group 'voicePrefix voiceComposerData)
(join-present (list
(render-contribution-group (ly:output-def-lookup layout 'compositionPrefix) compositionIds)
year_composition
) ", ")
(join-present (list
(render-contribution-group (ly:output-def-lookup layout 'adaptionMusicPrefix) adaptionMusicIds)
year_adaption_music
) ", ")
(render-contribution-group (ly:output-def-lookup layout 'bridgePrefix) bridgeIds)
(render-contribution-group (ly:output-def-lookup layout 'interludePrefix) interludeIds)
) "; ")
)))))
(list #f #f)
)
)

View File

@@ -1,4 +1,4 @@
swing = \mark \markup {
swing = \textMark \markup {
\line \general-align #Y #DOWN {
\score {
\new Staff \with {
@@ -47,7 +47,7 @@ swing = \mark \markup {
}
}
swingOff = \mark \markup {
swingOff = \textMark \markup {
\line \general-align #Y #DOWN {
\score {
\new Staff \with {
@@ -99,7 +99,7 @@ swingOff = \mark \markup {
\include "swing.ly"
swingMusic =
#(define-music-function (parser location music) (ly:music?)
#(define-music-function (music) (ly:music?)
(define (partial-duration-length m)
(let ((name (ly:music-property m 'name))
(es (ly:music-property m 'elements))

View File

@@ -1,6 +1,5 @@
#(define-markup-command (bookTitleMarkupCustom layout props)()
(interpret-markup layout
(prepend-alist-chain 'songfilename (chain-assoc-get 'header:songfilename props "") props)
(interpret-markup layout props
(make-column-markup
(list
(make-vspace-markup (chain-assoc-get 'header:titletopspace props 0))
@@ -38,23 +37,24 @@
;'(0 . 0) '(0 . 0)
)))
#(define-markup-command (title-with-category-images layout props right)(boolean?)
(interpret-markup layout props
#(define-markup-command (build-full-title layout props right)(boolean?)
(interpret-markup layout (prepend-alist-chain 'songfilename (chain-assoc-get 'header:songfilename props "") props)
(let* ((title (chain-assoc-get 'header:title props ""))
(starttext (chain-assoc-get 'header:starttext props #f))
(pdfbookmark (if starttext (string-append starttext " | " title) title)))
(pdfbookmark (if starttext (string-append starttext " | " title) title))
(title-markup (ly:output-def-lookup layout (if right 'oddTitleLineMarkup 'evenTitleLineMarkup))))
(if title
(if right
#{\markup { \title-to-pdf-toc #pdfbookmark \fill-line \general-align #Y #UP { \null \bookTitleMarkupCustom \category-images } } #}
#{\markup { \title-to-pdf-toc #pdfbookmark \fill-line \general-align #Y #UP { \category-images \bookTitleMarkupCustom \null } } #})
#{ \markup { " " } #})
(markup #:title-to-pdf-toc pdfbookmark title-markup)
make-null-markup)
)))
\paper {
bookTitleMarkup = \markup \null
scoreTitleMarkup = \markup \null
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 }
oddHeaderMarkup = \markup { \if \on-first-page-of-part \build-full-title ##t }
evenHeaderMarkup = \markup { \if \on-first-page-of-part \build-full-title ##f }
oddTitleLineMarkup = \markup { \fill-line \general-align #Y #UP { \null \bookTitleMarkupCustom \category-images } }
evenTitleLineMarkup = \markup { \fill-line \general-align #Y #UP { \category-images \bookTitleMarkupCustom \null } }
defaultTitleMarkup = \markup {
\override #'(baseline-skip . 3.5)
\center-column {

View File

@@ -60,19 +60,20 @@
% Text über Text mittig darstellen
#(define-markup-command (textup layout props text uptext) (markup? markup?)
#:properties ((verselayout generalLayout)
(verse-text-chord-distance songTextChordDistance))
"Markup über Text mittig darstellen."
(let ((verselayout (chain-assoc-get 'verselayout props generalLayout)))
(interpret-markup layout props
#{\markup {
\size-box-to-box-style-dependent ##t ##f
\general-align #X #LEFT \override #`(direction . ,UP) \override #'(baseline-skip . 1.0) \dir-column \chord-alignment-style-dependent {
\pad-to-box #'(0 . 0) #'(0 . 2.0) { #text }
\size-box-to-box ##f ##t #uptext \score { \chords { g4:m a } \layout { \verselayout } }
\general-align #X #LEFT \override #`(direction . ,UP) \override #'(baseline-skip . 1) \dir-column \chord-alignment-style-dependent {
\pad-to-box #'(0 . 0) #`(0 . ,(- verse-text-chord-distance 0.8)) { #text }
\size-box-to-box ##f ##t #uptext \score { \chords { g4:m a } \layout { $verselayout #(customized-layout verselayout) } }
}
#text
}
#}
)))
))
#(define-markup-command (anchor-x-between layout props arga argb)
(markup? markup?)
@@ -82,16 +83,15 @@
(ly:stencil-aligned-to m X (- (/ (* la 2) l) 1))
))
#(define-markup-command (stanza-raw layout props arg)
(string-or-music?)
(let ((verselayout (chain-assoc-get 'verselayout props generalLayout)))
#(define-markup-command (stanza-raw layout props arg) (string-or-music?)
#:properties ((verselayout generalLayout))
(interpret-markup layout props
(if (and (string? arg) (string-null? arg))
" "
#{\markup
\score { \new Lyrics { \lyricmode { #(if (ly:music? arg) arg #{ \set stanza = #arg #}) "" } } \layout { \verselayout } }
\score { \new Lyrics { \lyricmode { #(if (ly:music? arg) arg #{ \set stanza = #arg #}) "" } } \layout { $verselayout #(customized-layout verselayout) } }
#}
))))
)))
#(define-markup-command (stanza layout props arg)
(string-or-music?)
@@ -141,7 +141,7 @@
(make-wrap-newline-markup
(ly:regex-replace (ly:make-regex "\\(( *)([^,()]*)( *),([^)]*)\\)")
(ly:regex-replace (ly:make-regex "(([^ \n]*\\([^()]*,[^()]+\\)[^ \n(]*)+)") (handle-custom-newlines custom-verse-breaks verse) " \\concat { " 1 " } ")
"\\textup \\line { \"" 1 "\" " 2 " \"" 3 "\" } \\score { " transp " \\chords { s4 " 4 " } \\layout { \\verselayout } }")
"\\textup \\line { \"" 1 "\" " 2 " \"" 3 "\" } \\score { " transp " \\chords { s4 " 4 " } \\layout { $verselayout #(customized-layout verselayout) } }")
)
))))
@@ -203,23 +203,9 @@
#(define-markup-command (pad-left layout props amount arg)
(number? markup?)
(let* ((m (interpret-markup layout props arg))
(x (ly:stencil-extent m X))
(y (ly:stencil-extent m Y)))
(ly:stencil-translate
(ly:make-stencil (ly:stencil-expr m)
(cons (- (car x) amount) (cdr x))
y)
`(,amount . 0))))
#(define-markup-command (pad-right layout props amount arg)
(number? markup?)
(let* ((m (interpret-markup layout props arg))
(x (ly:stencil-extent m X))
(y (ly:stencil-extent m Y)))
(ly:make-stencil (ly:stencil-expr m)
(cons (car x) (+ (cdr x) amount))
y)))
(interpret-markup layout props (make-pad-x-left-markup amount arg))
`(,amount . 0)))
#(define-markup-command (score-equal-height-with-indents layout props lines)
(markup-list?)
@@ -250,9 +236,103 @@
(let ((text (ly:grob-property grob 'text)))
(grob-interpret-markup grob (if (string? text)
(make-pad-right-markup -0.1 (make-tied-lyric-markup text))
(make-pad-x-right-markup -0.1 (make-tied-lyric-markup text))
text))))
Chord_lyrics_spacing_engraver =
#(lambda (ctx)
(let ((last-lyric-syllable #f)
(lyric-width-since-last-chord 0)
(music-columns-for-last-syllable 0)
(last-printed-chord #f)
(chord-width-since-last-lyric 0)
(lyrics-seen-since-break #f)
(have-a-rest #f)
(stanza #f)
(place-at-right-edge
(lambda (grob anchor padding)
(let ((anchor-width (interval-length (ly:grob-extent anchor anchor X))))
(ly:grob-set-parent! grob X anchor)
(ly:grob-set-property! grob 'X-offset (+ padding anchor-width))
))))
(make-engraver
(listeners
((multi-measure-rest-event engraver event)
(set! have-a-rest #t)
)
((rest-event engraver event)
(set! have-a-rest #t)
)
((lyric-event engraver event)
(set! have-a-rest #f)
(set! music-columns-for-last-syllable 0)
)
((break-event engraver event)
(set! last-lyric-syllable #f)
(set! lyric-width-since-last-chord 0)
(set! music-columns-for-last-syllable 0)
(set! last-printed-chord #f)
(set! chord-width-since-last-lyric 0)
(set! lyrics-seen-since-break #f)
))
(acknowledgers
((musical-paper-column-interface this-engraver grob source-engraver)
(set! music-columns-for-last-syllable (+ 1 music-columns-for-last-syllable))
)
((lyric-syllable-interface this-engraver grob source-engraver)
(let ((syllable-width (interval-length (ly:grob-extent grob grob X))))
(set! lyric-width-since-last-chord (+ lyric-width-since-last-chord syllable-width))
)
(if (> chord-width-since-last-lyric 0)
(if lyrics-seen-since-break
(ly:grob-set-property! grob 'extra-spacing-width
(cons (- chord-width-since-last-lyric) (cdr (ly:grob-property grob 'extra-spacing-width '(0 . 0)))))
(if last-printed-chord
(let ((gap-for-starting-rest 2.0))
(if stanza (ly:grob-set-property! stanza 'padding (+ 1 gap-for-starting-rest)))
(ly:grob-set-parent! grob X last-printed-chord)
(ly:grob-set-property! grob 'X-offset gap-for-starting-rest)
)))
)
(set! last-lyric-syllable grob)
(set! chord-width-since-last-lyric 0)
(set! lyrics-seen-since-break #t)
)
((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)
lyrics-seen-since-break))
(let* ((last-printed-chord-width (if last-printed-chord (interval-length (ly:grob-extent last-printed-chord last-printed-chord X)) 0))
(chord-overwidth (- last-printed-chord-width lyric-width-since-last-chord))
(chord-gap 0.5))
(if have-a-rest
(let ((chord-width (interval-length (ly:grob-extent grob grob X))))
(if last-lyric-syllable
(if (and last-printed-chord (> chord-overwidth 0))
(place-at-right-edge grob last-printed-chord chord-gap)
(place-at-right-edge grob last-lyric-syllable 0))
(if last-printed-chord
(place-at-right-edge grob last-printed-chord chord-gap)))
(set! chord-width-since-last-lyric (+ chord-width-since-last-lyric chord-width chord-gap))
))
(if (and last-lyric-syllable last-printed-chord (> chord-overwidth 0))
(ly:grob-set-property! last-lyric-syllable 'extra-spacing-width
(cons (car (ly:grob-property last-lyric-syllable 'extra-spacing-width '(0 . 0))) (+ chord-gap chord-overwidth)))
)
(set! lyric-width-since-last-chord (* (if last-lyric-syllable (interval-length (ly:grob-extent last-lyric-syllable last-lyric-syllable X)) 0) (- 1 (/ 1.0 music-columns-for-last-syllable))))
(set! last-printed-chord grob)
(set! last-lyric-syllable #f)
)
(ly:grob-set-property! grob 'X-extent '(+inf.0 . -inf.0))
)
)
((stanza-number-interface this-engraver grob source-engraver)
(set! stanza grob)
)
)
)))
#(define-markup-command (chordlyrics layout props lyrics) (ly:music?)
#:properties ((verse-chords #{#})
(verse-reference-voice #{#})
@@ -272,10 +352,8 @@
\new Lyrics \lyricsto "dummyvoice" { #lyrics }
>>
\layout {
\verselayout
#(let
((custom-size (ly:output-def-lookup verselayout 'size #f)))
(if custom-size (layout-set-staff-size custom-size)))
$verselayout
#(customized-layout verselayout)
ragged-right = ##t
\context {
\Lyrics
@@ -299,12 +377,17 @@
% \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
% ChordPro engraver in Score context to collect all data
\consists \ChordPro_score_collector
\remove Bar_number_engraver
\remove Mark_engraver
\remove Jump_engraver
\remove Volta_engraver
\remove Parenthesis_engraver
\remove Metronome_mark_engraver
\remove Text_mark_engraver
}
\context {
\Staff
@@ -328,14 +411,6 @@
\remove Note_heads_engraver
\remove Script_engraver
}
\context {
\NullVoice
\consists Rest_engraver
\omit Rest
\undo \omit NoteHead
\hide NoteHead
\override NoteHead.X-extent = #'(0 . 0)
}
}
}
}

View File

@@ -90,7 +90,7 @@
(for-each (lambda (category)
(let* ((catsym (string->symbol category))
(catlist (hashq-ref category-index-hash catsym
(list (list label 'indexCategoryMarkup `(((rawtext . ,category))))))))
(list (list label 'indexCategoryMarkup `(((combine-with-next . #t) (rawtext . ,category))))))))
(if (assq catsym category-names)
(hashq-set! category-index-hash catsym
(cons (list label markup-symbol textoptions) catlist))
@@ -114,7 +114,7 @@
(for-each (lambda (authorID)
(let* ((authorsym (string->symbol authorID))
(authorlist (hashq-ref author-index-hash authorsym
(list (list label 'indexAuthorMarkup `(((rawtext . ,authorID))))))))
(list (list label 'indexAuthorMarkup `(((combine-with-next . #t) (rawtext . ,authorID))))))))
(hashq-set! author-index-hash authorsym
(cons (list label markup-symbol textoptions) authorlist))
))
@@ -218,7 +218,7 @@
}
#(define (prepare-item-markup items layout)
(map (lambda (index-item)
(define (single-item-markup index-item)
(let* ((label (car index-item))
(index-markup (cadr index-item))
(textoptions (caddr index-item))
@@ -231,7 +231,16 @@
#:override (cons 'index:alternative alternative)
#:override (cons 'index:songnumber songnumber)
(ly:output-def-lookup layout index-markup))))
(items)))
(if (null? items)
items
(let* ((index-item (car items))
(combine-with-next (chain-assoc-get 'combine-with-next (caddr index-item) #f))
(restitems (cdr items))
(item-markup (single-item-markup index-item)))
(if (and combine-with-next (not (null? restitems)))
(cons (make-column-markup (list item-markup (single-item-markup (car restitems)))) (prepare-item-markup (cdr restitems) layout))
(cons item-markup (prepare-item-markup restitems layout))))
))
#(define-markup-list-command (index-in-columns-with-title layout props index-type title-markup) (symbol? markup?)
( _i "Outputs index alphabetical sorted or in categories" )
@@ -245,7 +254,7 @@
(make-columnlayout-markup-list songTocColumns 2
(let ((h (- (ly:output-def-lookup layout 'paper-height) 12)))
(cons (- h (interval-length (ly:stencil-extent title Y))) h))
(prepare-item-markup items layout))))))
(prepare-item-markup (items) layout))))))
indexItem =
#(define-music-function (parser location sorttext text) (string? markup?)
@@ -255,7 +264,7 @@ indexItem =
indexSection =
#(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-index-item! 'indexSectionMarkup (prepend-alist-chain 'rawtext text '()) sorttext))
(add-index-item! 'indexSectionMarkup (prepend-alist-chain 'combine-with-next #t (prepend-alist-chain 'rawtext text '())) sorttext))
#(define (extract-and-check-vars-from-header bookheader varlist)
(let* ((headervars (hash-map->list cons (struct-ref (ly:book-header bookheader) 0)))
@@ -432,6 +441,6 @@ headerToTOC = #(define-music-function (parser location header label) (ly:book? s
; we use a delayed stencil to have all the page references available
(ly:make-stencil
`(delay-stencil-evaluation
,(delay (let* ((table (ly:output-def-lookup layout 'label-page-table)))
,(delay (let* ((table (ly:output-def-lookup layout 'label-absolute-page-table)))
(generate-toc-csv (if (list? table) table '()))
empty-stencil)))))

View File

@@ -1,8 +1,10 @@
% set the speed of the midi music
#(define midiQuarterNoteSpeed (if (defined? 'midiQuarterNoteSpeed) midiQuarterNoteSpeed 90))
MUSIC = { \transposable #TRANSPOSITION \MUSIC }
LAYOUT = \layout {
\LAYOUT
#(customized-layout LAYOUT)
}
verselayout = \layout {
\LAYOUT
\context {
@@ -11,13 +13,6 @@ verselayout = \layout {
}
}
LAYOUT = \layout {
\LAYOUT
#(let
((custom-size (ly:output-def-lookup LAYOUT 'size #f)))
(if custom-size (layout-set-staff-size custom-size)))
}
TEXT = \markuplist {
\override #`(transposition . ,TRANSPOSITION)
\override #`(verselayout . ,verselayout)
@@ -44,6 +39,20 @@ TEXT = \markuplist {
TEXT_PAGES
(list TEXT))))
%% Add invisible ChordPro write trigger to last TEXT_PAGES markuplist
#(when (and (defined? 'chordpro-export-enabled) chordpro-export-enabled (pair? TEXT_PAGES))
(let* ((last-index (- (length TEXT_PAGES) 1))
(last-page (list-ref TEXT_PAGES last-index))
(modified-last-page #{
\markuplist {
#last-page
\chordpro-delayed-write
}
#}))
(set! TEXT_PAGES
(append (list-head TEXT_PAGES last-index)
(list modified-last-page)))))
#(define (add-text-pages text-pages)
(if (pair? text-pages)
(begin
@@ -60,21 +69,38 @@ TEXT = \markuplist {
(if header (set! $defaultheader header))
(if paper (set! $defaultpaper paper))
)
;; ChordPro export: Store filename and extract metadata from basicSongInfo FIRST
(when (and (defined? 'chordpro-export-enabled) chordpro-export-enabled)
;; Use ly:parser-output-name which returns the output basename
;; This will write relative to current working directory (same as PDF)
(let ((output-name (ly:parser-output-name)))
(set! chordpro-current-filename output-name))
;; Try to extract metadata from basicSongInfo \header block
(when (defined? 'basicSongInfo)
(let* ((header-alist (ly:module->alist basicSongInfo))
(title (assoc-ref header-alist 'title))
(authors (assoc-ref header-alist 'authors)))
(when title
(set! chordpro-header-title
(if (markup? title)
(markup->string title)
(if (string? title) title "Untitled"))))
(when authors
(set! chordpro-header-authors authors)))))
(add-score #{
\score {
\MUSIC
\layout { \LAYOUT }
}#})
(add-text-pages TEXT_PAGES)
(add-score #{
\score {
\unfoldRepeats { \MUSIC \INLINESCOREMUSIC }
\midi {
\context {
\Score
% Tempo des midi files
tempoWholesPerMinute = #(/ midiQuarterNoteSpeed 4)
}
\context {
\Staff
\remove "Staff_performer"