\version "2.18" \language "deutsch" #(ly:set-option 'relative-includes #t) \include "../lilypond-custom-includes/categories.ly" compatibilityMode = #(define-void-function (parser location) () (if (< (list-ref (ly:version) 1) 24) (ly:parser-parse-string (if (< (list-ref (ly:version) 1) 19) (ly:parser-clone parser) (ly:parser-clone)) (string-concatenate (list "\\include \"" "./legacy-lilypond-compatibility.ly" "\""))))) \compatibilityMode \include "./styles.ly" #(define (lookup-var varsym default) (let ((value (assoc-ref (hash-map->list cons (struct-ref (current-module) 0)) varsym))) (if value (variable-ref value) default))) globalSize = #(lookup-var 'globalSize 15) lyricSize = #(lookup-var 'lyricSize 1.6) showCategoryImages = #(lookup-var 'showCategoryImages #t) % check if we have a StandAlone compile or if variable noStandaloneOutput is set #(define isStandAlone (not (lookup-var 'noStandaloneOutput #f))) #(if (< (list-ref (ly:version) 1) 19) (case song-style ((börnel) (set-default-paper-size "b6" 'landscape)) ((bock) (set-default-paper-size "a6" 'landscape))) (case song-style ((börnel) (set-default-paper-size "b6landscape")) ((bock) (set-default-paper-size "a6landscape"))) ) #(set-global-staff-size globalSize) #(define-markup-command (print-songinfo layout props) () (interpret-markup layout props (let ( (blockwidth (* (chain-assoc-get 'header:songinfo-size-factor props 0.9) (ly:output-def-lookup layout 'line-width))) (infotext (chain-assoc-get 'header:songinfo props #f)) (poet (chain-assoc-get 'header:poet props #f)) (composer (chain-assoc-get 'header:composer props #f)) (poet-and-composer-stacked (chain-assoc-get 'header:poet-and-composer-stacked props #f)) (between-poet-and-composer-markup (chain-assoc-get 'header:between-poet-and-composer-markup props (make-hspace-markup 3))) (copyright (chain-assoc-get 'header:copyright props #f))) (if (chain-assoc-get 'page:is-bookpart-last-page props #f) (markup #:override '(baseline-skip . 3.0) ( make-fontsize-markup (case song-style ((börnel) -3.5) ((bock) -1.5)) ;(symbol->keyword (case song-style ((börnel) 'roman) ((bock) 'sans))) ((lambda (m) (case song-style ((börnel) (make-roman-markup m)) ((bock) (make-sans-markup m)))) ;%\override #'(line-width . 92) \wordwrap-field #symbol (make-column-markup (list (make-line-markup (list (if (and poet (not (and (string? poet) (string-null? poet)))) (markup poet between-poet-and-composer-markup) "") (if (and composer (not poet-and-composer-stacked)) composer "")) ) (if (and composer poet-and-composer-stacked) (make-line-markup (list composer)) "") (make-override-markup `(line-width . ,blockwidth) (make-justify-string-markup (string-append (if (and copyright (not (and (string? copyright) (string-null? copyright)))) (ly:format "© ~a\n\n" copyright) "") (if infotext infotext "") ))) ))) ) ) (make-null-markup)))) ) % songfilename verfügbar machen #(define-markup-list-command (setsongfilename layout props songfilename markuplist) (string? markup-list?) (interpret-markup-list layout (prepend-alist-chain 'songfilename songfilename props) markuplist)) #(define-markup-command (customEps layout props ysize filename)(number? string?) #:properties ((songfilename "") (defaultmarkup #f)) (interpret-markup layout props (let ((filepath (if (string-null? songfilename) filename (ly:format "../../lieder/~a/~a" songfilename filename)))) (if (file-exists? filepath) (make-epsfile-markup Y ysize filepath) (if defaultmarkup defaultmarkup (ly:format "file does not exist ~a" filepath)) )))) #(define-markup-command (bookTitleMarkupCustom layout props)() (interpret-markup layout (prepend-alist-chain 'defaultmarkup #{ \markup { \override #'(baseline-skip . 3.5) \center-column { \override #`(font-name . ,(case song-style ((börnel) "Oregano") ((bock) "Britannic T. custom"))) { \fontsize #6 \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 (list (make-vspace-markup (chain-assoc-get 'header:titletopspace props 0)) (make-customEps-markup (chain-assoc-get 'header:titlesize props 3.5) "titel.eps") )) )) #(define-markup-command (category-image layout props size category)(number? string?) (interpret-markup layout props (if isStandAlone (make-epsfile-markup Y size (category-image-path category)) (make-epsfileref-markup Y size (category-image-path category))))) #(define-markup-command (category-images layout props)() (interpret-markup layout props (if showCategoryImages (make-line-markup (map (lambda (category) (make-category-image-markup 5 category)) (string-tokenize (chain-assoc-get 'header:categories props "")))) (make-null-markup)))) #(define-markup-command (pagecenter layout props stuff)(markup?) (interpret-markup layout props (let ((halfpaperheight (/ (ly:output-def-lookup layout 'paper-height) 2)) (halfstuffheight (/ (interval-length (ly:stencil-extent (interpret-markup layout props stuff) Y)) 2))) (make-fill-line-markup (list (make-pad-to-box-markup '(0 . 0) (cons (- (- halfpaperheight halfstuffheight)) (+ halfpaperheight halfstuffheight)) stuff))) ))) #(define-markup-command (print-pagenumber layout props)() (let ((label (chain-assoc-get 'header:myindexlabel props #f))) (interpret-markup layout props (markup #:large #:bold (if label (make-custom-page-number-markup label (chain-assoc-get 'page:page-number props 0)) (make-fromproperty-markup 'page:page-number-string) ) )))) #(define pdf-encode (if (< (list-ref (ly:version) 1) 24) ly:encode-string-for-pdf (@@ (lily framework-ps) pdf-encode))) % PDF tags #(define-markup-command (title-to-pdf-toc layout props title) (string?) (ly:make-stencil (list 'embedded-ps (ly:format "[/Action /GoTo /View [/Fit] /Title <~a> /OUT pdfmark" (fold (lambda (ch hexout) (string-append hexout (format #f "~2,'0x" (char->integer ch)))) "" (string->list (pdf-encode title))))) empty-interval empty-interval ;'(0 . 0) '(0 . 0) )) #(define-markup-command (title-with-category-images layout props right)(boolean?) (interpret-markup layout props (let* ((title (chain-assoc-get 'header:title props #f)) (pdfbookmark (chain-assoc-get 'header:songfilename props title))) (if title ;(if (chain-assoc-get 'header:categories props #f) (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 \fill-line \general-align #Y #UP { \null \bookTitleMarkupCustom \null } #}) ;(make-null-markup)) #{ \markup { " " } #}) ))) #(define (default-pango size) (case song-style ((börnel) (make-pango-font-tree ;"FreeSans" ;"Spectral" "Liberation Sans" "TeX Gyre Heros" "Luxi Mono" (/ size 20))) ((bock) (make-pango-font-tree ;"FreeSans" ;"Spectral" "TimesNewRomanPS" "Arial" "Luxi Mono" (/ size 20))))) \paper { #(define fonts (default-pango globalSize)) %annotate-spacing = ##t % spacing stuff lyric-size = #lyricSize two-sided = ##t inner-margin = 1.5\cm outer-margin = #(case song-style ((börnel) 5) ((bock) 8)) binding-offset = 0\cm top-margin = #(case song-style ((börnel) 5) ((bock) 8)) bottom-margin = #(case song-style ((börnel) 5) ((bock) 8)) system-system-spacing = #'((basic-distance . 10) (padding . 1.5)) markup-system-spacing = #'((basic-distance . 1)) score-markup-spacing = #'((padding . 2)) top-markup-spacing = #'((basic-distance . 0) (minimum-distance . 0) (padding . 0)) % top-system-spacing = #'((basic-distance . 0) (minimum-distance . 0) (padding . -3)) %top-system-spacing #'stretchability = #30 % last-bottom-spacing #'stretchability = #0 print-first-page-number = ##t first-page-number = #0 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 } oddFooterMarkup = \markup { \fill-line { \line { \null } \line { \general-align #Y #DOWN \print-songinfo } \line { \if \should-print-page-number \print-pagenumber } } } evenFooterMarkup = \markup { \fill-line { \line { \if \should-print-page-number \print-pagenumber } \line { \general-align #Y #DOWN \print-songinfo } \line { \null } } } } % Akkorde können auch geklammert sein #(define (parenthesis-ignatzek-chord-names in-pitches bass inversion context) (markup #:line ( "(" (ignatzek-chord-names in-pitches bass inversion context) ")" ))) klamm = #(define-music-function (parser location chords) (ly:music?) #{ \set chordNameFunction = #parenthesis-ignatzek-chord-names $chords \set chordNameFunction = #ignatzek-chord-names #}) bchord = #(define-music-function (parser location chords) (ly:music?) #{ \override ChordName.font-series = #'bold $chords \revert ChordName.font-series #}) % 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)) %% http://lsr.dsi.unimi.it/LSR/Item?id=336 %% see also http://code.google.com/p/lilypond/issues/detail?id=1228 %% Usage: %% \new Staff \with { %% \override RestCollision.positioning-done = #merge-rests-on-positioning %% } << \somevoice \\ \othervoice >> %% or (globally): %% \layout { %% \context { %% \Staff %% \override RestCollision.positioning-done = #merge-rests-on-positioning %% } %% } %% %% Limitations: %% - only handles two voices %% - does not handle multi-measure/whole-measure rests #(define (rest-score r) (let ((score 0) (yoff (ly:grob-property-data r 'Y-offset)) (sp (ly:grob-property-data r 'staff-position))) (if (number? yoff) (set! score (+ score 2)) (if (eq? yoff 'calculation-in-progress) (set! score (- score 3)))) (and (number? sp) (<= 0 2 sp) (set! score (+ score 2)) (set! score (- score (abs (- 1 sp))))) score)) #(define (merge-rests-on-positioning grob) (let* ((can-merge #f) (elts (ly:grob-object grob 'elements)) (num-elts (and (ly:grob-array? elts) (ly:grob-array-length elts))) (two-voice? (= num-elts 2))) (if two-voice? (let* ((v1-grob (ly:grob-array-ref elts 0)) (v2-grob (ly:grob-array-ref elts 1)) (v1-rest (ly:grob-object v1-grob 'rest)) (v2-rest (ly:grob-object v2-grob 'rest))) (and (ly:grob? v1-rest) (ly:grob? v2-rest) (let* ((v1-duration-log (ly:grob-property v1-rest 'duration-log)) (v2-duration-log (ly:grob-property v2-rest 'duration-log)) (v1-dot (ly:grob-object v1-rest 'dot)) (v2-dot (ly:grob-object v2-rest 'dot)) (v1-dot-count (and (ly:grob? v1-dot) (ly:grob-property v1-dot 'dot-count -1))) (v2-dot-count (and (ly:grob? v2-dot) (ly:grob-property v2-dot 'dot-count -1)))) (set! can-merge (and (number? v1-duration-log) (number? v2-duration-log) (= v1-duration-log v2-duration-log) (eq? v1-dot-count v2-dot-count))) (if can-merge ;; keep the rest that looks best: (let* ((keep-v1? (>= (rest-score v1-rest) (rest-score v2-rest))) (rest-to-keep (if keep-v1? v1-rest v2-rest)) (dot-to-kill (if keep-v1? v2-dot v1-dot))) ;; uncomment if you're curious of which rest was chosen: ;;(ly:grob-set-property! v1-rest 'color green) ;;(ly:grob-set-property! v2-rest 'color blue) (ly:grob-suicide! (if keep-v1? v2-rest v1-rest)) (if (ly:grob? dot-to-kill) (ly:grob-suicide! dot-to-kill)) (ly:grob-set-property! rest-to-keep 'direction 0) (ly:rest::y-offset-callback rest-to-keep))))))) (if can-merge #t (ly:rest-collision::calc-positioning-done grob)))) generalLayout = \layout { indent = #0 % Akkordeinstellungen \context { \ChordNames \semiGermanChords \override ChordName.font-size = #(case song-style ((börnel) 0) ((bock) 3)) \override ChordName.font-series = #(case song-style ((börnel) 'bold) ((bock) 'normal)) \override ChordName.font-family = #(case song-style ((börnel) 'sans) ((bock) 'roman)) chordNameLowercaseMinor = ##t chordChanges = ##t % eigenen chordRootNamer damit F# = Fis und Gb = Ges (also alteration ausgeschrieben) chordRootNamer = #note-name->german-markup-nosym chordNoteNamer = #bassnote-name->german-markup-nosym majorSevenSymbol = "maj7" % der baseline-skip der Akkorde beeinflusst, wie hoch die Hochstellung ist \override ChordName.baseline-skip = #1.0 } \context { \Lyrics \override LyricText.font-size = #lyricSize \override StanzaNumber.font-size = #lyricSize \override StanzaNumber.font-family = #(case song-style ((börnel) 'roman) ((bock) 'sans)) \override LyricText.font-family = #(case song-style ((börnel) 'roman) ((bock) 'sans)) \override LyricExtender.minimum-length = 0 } \context { \Staff \override RestCollision.positioning-done = #merge-rests-on-positioning \accidentalStyle modern } \context { \Score \remove "Bar_number_engraver" \RemoveEmptyStaves \override VerticalAxisGroup.remove-first = ##t \overrideTimeSignatureSettings 4/4 % timeSignatureFraction 1/4 % baseMomentFraction #'(1 1 1 1) % beatStructure #'() % beamExceptions \overrideTimeSignatureSettings 3/4 % timeSignatureFraction 1/4 % baseMomentFraction #'(1 1 1 1) % beatStructure #'() % beamExceptions } \context { \Voice % ich will lines breaken wie ich will! \remove "Forbid_line_break_engraver" } } verseChordLayout = \layout { \generalLayout \context { \ChordNames \override ChordName.font-size = #(case song-style ((börnel) 0) ((bock) 2)) } } LAYOUT = \layout { \generalLayout } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% kleine Helferlein: textp = \lyricmode { \markup { \raise #1 \musicglyph #"rests.3" } } % zweite Stimme alles grau secondVoiceStyle = { \override NoteHead.color = #grey \override Stem.color = #grey \override Flag.color = #grey \override Beam.color = #grey } firstVoiceStyle = { \override NoteHead.color = #black \override Stem.color = #black \override Flag.color = #black \override Beam.color = #black } % einzelne Noten innerhalb von \secondVoiceStyle mit schwarzem statt grauem Kopf schwarzkopf = #(define-music-function (parser location noten) (ly:music?) #{ \revert NoteHead.color $noten \override NoteHead.color = #grey #}) % guile regular expressions aktivieren: #(use-modules (ice-9 regex)) %{ % parsing line by line #(define-markup-command (wrap-newline layout props text) (string?) "Text Zeile für Zeile parsen" (interpret-markup layout props (ly:parse-string-expression (if (< (list-ref (ly:version) 1) 19) (ly:parser-clone parser) (ly:parser-clone)) (string-append "\\markup { \\column { \\line {" (regexp-substitute/global #f "\n" text 'pre "} \\line {" 'post ) "} } }" )) ) ) %} % parsing line by line #(define-markup-command (wrap-newline layout props text) (string?) "Text Zeile für Zeile parsen" (interpret-markup layout props #{ \markup { \column { $(let ((verse-markup-string (string-append "\\line { " (regexp-substitute/global #f "\n" text 'pre " } \\line { " 'post ) " \\size-box-to-box ##f ##t \"\" \"Agj\" }" ))) ;(ly:parse-string-expression (if (< (list-ref (ly:version) 1) 19) (ly:parser-clone parser) (ly:parser-clone)) verse-markup-string)) (if (< (list-ref (ly:version) 1) 19) (ly:parser-include-string parser verse-markup-string) (ly:parser-include-string verse-markup-string))) }}#} ) ) #(define-markup-command (size-box-to-box layout props use-x use-y abox bbox) (boolean? boolean? markup? markup?) (let* ((ma (interpret-markup layout props abox)) (mb (interpret-markup layout props bbox)) (ax (ly:stencil-extent ma X)) (ay (ly:stencil-extent ma Y)) (bx (ly:stencil-extent mb X)) (by (ly:stencil-extent mb Y)) (halfdiffabx (* (- (interval-length bx) (interval-length ax)) 0.5))) (ly:stencil-translate (ly:make-stencil (ly:stencil-expr ma) (if use-x (if (< halfdiffabx 0) (cons (- (interval-bound ax DOWN) halfdiffabx) (+ (interval-bound ax UP) halfdiffabx)) bx) ax) (if use-y by ay)) (cons (if (and use-x (< halfdiffabx 0)) halfdiffabx 0) 0) ))) #(define-markup-command (size-box-to-box-left-aligned layout props use-x use-y abox bbox) (boolean? boolean? markup? markup?) (let* ((ma (interpret-markup layout props abox)) (mb (interpret-markup layout props bbox)) (ax (ly:stencil-extent ma X)) (ay (ly:stencil-extent ma Y)) (bx (ly:stencil-extent mb X)) (by (ly:stencil-extent mb Y))) (ly:make-stencil (ly:stencil-expr ma) (if use-x bx ax) (if use-y by ay)) )) #(define-markup-command (size-box-to-box-style-dependent layout props use-x use-y abox bbox) (boolean? boolean? markup? markup?) (interpret-markup layout props (case song-style ((börnel) (make-size-box-to-box-markup use-x use-y abox bbox)) ((bock) (make-size-box-to-box-left-aligned-markup use-x use-y abox bbox))))) % Akkord mit Bunddiagramm anzeigen #(define-markup-command (fret-chord layout props fret chord) (string? string?) (interpret-markup layout props #{ \markup { \override #'(baseline-skip . 2) \center-column { \score { \new ChordNames { #(if (< (list-ref (ly:version) 1) 19) (ly:parser-include-string parser (string-append "\\chordmode { s4 " chord " }")) (ly:parser-include-string (string-append "\\chordmode { s4 " chord " }")) ) } \layout { \generalLayout } } \override #'(fret-diagram-details . ( (barre-type . straight))) { \fret-diagram-terse #fret } } } #})) % Akkorde in Strophen transponieren #(define-markup-list-command (transpose layout props from to markuplist) (markup? markup? markup-list?) (interpret-markup-list layout (prepend-alist-chain 'transposition (cons from to) props) markuplist)) #(define-markup-command (chord-alignment-style-dependent layout props chord-with-text) (markup?) (interpret-markup layout props (case song-style ((börnel) (make-center-align-markup chord-with-text)) ((bock) (make-left-align-markup chord-with-text))))) % Text über Text mittig darstellen #(define-markup-command (textup layout props text uptext) (markup? markup?) "Markup über Text mittig darstellen." (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 { \generalLayout } } } #text } #} )) #(define-markup-command (anchor-x-between layout props arga argb) (markup? markup?) (let* ((la (interval-length (ly:stencil-extent (interpret-markup layout props arga) X))) (m (interpret-markup layout props (markup #:general-align Y DOWN arga argb (make-size-box-to-box-markup #t #t (markup #:null) arga)))) (l (interval-length (ly:stencil-extent m X)))) (ly:stencil-aligned-to m X (- (/ (* la 2) l) 1)) )) #(define-markup-command (stanza-raw layout props arg) (markup?) (interpret-markup layout props (if (and (string? arg) (string-null? arg)) " " #{\markup \score { \new Lyrics { \lyricmode { \set stanza = #arg "" } } \layout { \generalLayout } } #} ))) #(define-markup-command (stanza layout props arg) (markup?) (interpret-markup layout props (make-size-box-to-box-markup #f #t (make-stanza-raw-markup arg) (make-stanza-raw-markup "x")))) % Kompletten Vers mit Akkorden #(define-markup-command (chordverse layout props stanza verse) (markup? string?) "Vers mit Akkorden" (let* ((fromto (chain-assoc-get 'transposition props #f)) (transp (if fromto (string-append "\\transpose " (car fromto) " " (cdr fromto)) ""))) (interpret-markup layout props (markup #:override `(baseline-skip . ,(case song-style ((börnel) 5.0) ((bock) 5.5))) #:anchor-x-between #:stanza stanza (make-wrap-newline-markup (regexp-substitute/global #f "\\(( *)([^,()]*)( *),([^)]*)\\)" (regexp-substitute/global #f "(([^ \n]*\\([^()]*\\)[^ \n]*)+)" verse 'pre " \\concat { " 1 " } " 'post) 'pre "\\textup \\line { \"" 1 "\" " 2 " \"" 3 "\" } \\score { " transp " \\chords { s4 " 4 " } \\layout { \\verseChordLayout } }" 'post)) )))) % Kompletter Vers aus dem Akkorde entfernt werden #(define-markup-command (nochordverse layout props stanza verse) (markup? string?) "Vers ohne Akkorde" (interpret-markup layout props (markup #:override '(baseline-skip . 3.0) #:anchor-x-between #:stanza stanza #:wrap-newline (regexp-substitute/global #f "\\(([^,]*),([^)]*)\\)" verse 'pre 1 'post ) ) ) ) % hübsche Wiederholungszeichen für den Liedtext repStart = "𝄆" repStop = "𝄇" %{ repStart = \markup { \raise #0.75 \override #'(word-space . 0.2) { \wordwrap { \vcenter { \override #'(word-space . 0.2) { \wordwrap { \filled-box #'(0 . 0.3) #'(0 . 2.5) #0 \filled-box #'(0 . 0.15) #'(0 . 2.5) #0 } } %\override #'(baseline-skip . 1.3) \fontsize #-5 \column { "•" "•" } \override #'(baseline-skip . 1.0) \column { \draw-circle #0.2 #0 ##t \draw-circle #0.2 #0 ##t } } } } } repStop = \markup { \rotate #180 \repStart } %} #(define-markup-command (verseformat layout props verse) (markup?) "Textformatierung für Strophen" (interpret-markup layout props ((lambda (m) (case song-style ((börnel) (make-roman-markup m)) ((bock) (make-sans-markup m)))) (make-fontsize-markup (ly:output-def-lookup layout 'lyric-size) verse)) ) ) #(define-markup-command (group-verses layout props versegroup) (markup-list?) #:properties ((verse-cols 1) (verse-vspace 1) (verse-hspace 1) (verse-ordering-horizontal #f)) "Gruppiere Strophen in einem Markup auf Wunsch spaltenweise" (let ((h (make-hash-table verse-cols)) (index 0) (column-item-count (ceiling (/ (length versegroup) verse-cols)))) (for-each (lambda (el) (let ((i (if verse-ordering-horizontal (modulo index verse-cols) (floor (/ index column-item-count))))) (hashv-set! h i (cons el (hashv-ref h i (list)))) (set! index (+ index 1)))) versegroup) (interpret-markup layout props (make-fill-line-markup (cons (make-verseformat-markup (make-line-markup (reverse (hash-fold (lambda (key value l) (cons (make-column-markup (fold (lambda (v verses) (cons v (if (null? verses) verses (cons (make-vspace-markup verse-vspace) verses)))) (list) value)) (if (null-list? l) l (cons (make-hspace-markup verse-hspace) l)))) (list) h)))) (list)))))) %%%%%%%%%%%%%%%%% Pfeilezeugs % http://lilypond.org/doc/v2.19/Documentation/snippets/vocal-music #(define-markup-command (arrow-at-angle layout props angle-deg length fill) (number? number? boolean?) (let* ( (PI-OVER-180 (/ (atan 1 1) 34)) (degrees->radians (lambda (degrees) (* degrees PI-OVER-180))) (angle-rad (degrees->radians angle-deg)) (target-x (* length (cos angle-rad))) (target-y (* length (sin angle-rad)))) (interpret-markup layout props (markup #:translate (cons (/ target-x 2) (/ target-y 2)) #:rotate angle-deg #:translate (cons (/ length -2) 0) #:concat (#:draw-line (cons length 0) #:arrow-head X RIGHT fill))))) splitStaffBarLineMarkup = \markup \with-dimensions #'(0 . 0) #'(0 . 0) { \combine \arrow-at-angle #45 #(sqrt 8) ##t \arrow-at-angle #-45 #(sqrt 8) ##t } splitStaffBarLine = { \once \override Staff.BarLine.stencil = #(lambda (grob) (ly:stencil-combine-at-edge (ly:bar-line::print grob) X RIGHT (grob-interpret-markup grob splitStaffBarLineMarkup) 0)) \break } convDownStaffBarLine = { \once \override Staff.BarLine.stencil = #(lambda (grob) (ly:stencil-combine-at-edge (ly:bar-line::print grob) X RIGHT (grob-interpret-markup grob #{ \markup\with-dimensions #'(0 . 0) #'(0 . 0) { \translate #'(0 . -.13)\arrow-at-angle #-45 #(sqrt 8) ##t }#}) 0)) \break } convUpStaffBarLine = { \once \override Staff.BarLine.stencil = #(lambda (grob) (ly:stencil-combine-at-edge (ly:bar-line::print grob) X RIGHT (grob-interpret-markup grob #{ \markup\with-dimensions #'(0 . 0) #'(0 . 0) { \translate #'(0 . .14)\arrow-at-angle #45 #(sqrt 8) ##t }#}) 0)) \break }