2 Commits

Author SHA1 Message Date
tux 5ee095b4e9 Skripte aus dem Bock repo 2023-07-16 19:26:29 +02:00
tux 036ddd2ef7 Initial commit 2023-07-16 18:39:46 +02:00
24 changed files with 789 additions and 1459 deletions
-63
View File
@@ -1,63 +0,0 @@
%%%%%%%%%%%%%%%%% 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
}
-86
View File
@@ -1,86 +0,0 @@
%% 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 {
\generalLayout
\context {
\Staff
\override RestCollision.positioning-done = #merge-rests-on-positioning
}
}
-98
View File
@@ -1,98 +0,0 @@
\language "deutsch"
\include "default_author_style.ly"
\include "styles.ly"
\include #(ly:format "styles/~a.ly" songStyle)
\include #(if (defined? 'customStyleOverridesFile) customStyleOverridesFile "void.ly")
#(set-default-paper-size songFormatAndSize)
#(set-global-staff-size globalSize)
\paper {
property-defaults.fonts.serif = \songChordFont
property-defaults.fonts.sans = \songLyricFont
%annotate-spacing = ##t
% spacing stuff
lyric-size = #lyricSize
two-sided = ##t
inner-margin = 1.5\cm
outer-margin = \songMargin
binding-offset = 0\cm
top-margin = \songMargin
bottom-margin = \songMargin
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))
}
generalLayout = \layout {
indent = #0
\context {
\Lyrics
\override LyricText.font-size = #lyricSize
\override StanzaNumber.font-size = #lyricSize
\override StanzaNumber.font-family = #'sans
\override LyricText.font-family = #'sans
\override LyricExtender.minimum-length = 0
}
\context {
\Staff
\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"
}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% 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
#})
% hübsche Wiederholungszeichen für den Liedtext
repStart = "𝄆"
repStop = "𝄇"
+20 -13
View File
@@ -121,7 +121,11 @@ includeSong =
\bookOutputName #filename \bookOutputName #filename
#} #}
(ly:parser-parse-string (if (< (list-ref (ly:version) 1) 19) (ly:parser-clone parser) (ly:parser-clone)) (ly:parser-parse-string (if (< (list-ref (ly:version) 1) 19) (ly:parser-clone parser) (ly:parser-clone))
(ly:format "\\include \"~a/~a/~a.ly\"" songPath filename filename)) (string-concatenate
(list
"HEADER = {} \nMUSIC = {}\nTEXT = \\markuplist {""}\nlyricSize = #1.6\n"
;"\\header { songfilename = \"" filename "\" }\n"
"\\include \"" "../../lieder/" filename "/" filename ".ly" "\"")))
(let ((label (gensym "index"))) (let ((label (gensym "index")))
(set! additional-page-switch-label-list (set! additional-page-switch-label-list
(acons label additional-page-numbers additional-page-switch-label-list)) (acons label additional-page-numbers additional-page-switch-label-list))
@@ -145,13 +149,6 @@ imagepage =
(acons 'xsize xsize (acons 'filename filename '())) (acons 'xsize xsize (acons 'filename filename '()))
song-list))) song-list)))
#(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)))
)))
songs = songs =
#(define-void-function (parser location) () #(define-void-function (parser location) ()
(for-each (lambda (songitems) (for-each (lambda (songitems)
@@ -162,7 +159,7 @@ songs =
#{ \bookpart { \markup { \null } } #} #{ \bookpart { \markup { \null } } #}
(if (eq? filename 'imagePage) (if (eq? filename 'imagePage)
(let ((xsize (assq-ref songvars 'xsize)) (let ((xsize (assq-ref songvars 'xsize))
(filename (ly:format "~a/~a" imagePagePath (assq-ref songvars 'filename)))) (filename (ly:format "boernel_images/~a" (assq-ref songvars 'filename))))
#{ \bookpart { #{ \bookpart {
\paper { \paper {
%{ %{
@@ -199,6 +196,16 @@ songs =
(reverse song-list) (reverse song-list)
)) ))
includeOnce =
#(define-void-function (parser location filename) (string?)
(if
(not (defined? (string->symbol filename)))
(begin
(ly:parser-include-string parser
(string-concatenate
(list "\\include \"" filename "\"")))
(primitive-eval (list 'define (string->symbol filename) #t)))))
#(define (boernel-stats) #(define (boernel-stats)
(let ( (let (
(songs (map (lambda (song) (symbol->string (car song))) (alist-delete 'emptyPage song-list))) (songs (map (lambda (song) (symbol->string (car song))) (alist-delete 'emptyPage song-list)))
@@ -209,7 +216,7 @@ songs =
;(string-join songs "\n") ;(string-join songs "\n")
"Nicht inkludiert:" "Nicht inkludiert:"
opticalline opticalline
(string-join (sort-list (lset-difference string=? (files-in-directory songPath) songs) string<?) "\n") (string-join (sort-list (lset-difference string=? (files-in-directory "../../lieder") songs) string<?) "\n")
opticalline opticalline
) "\n" ) ) "\n" )
))) )))
@@ -217,16 +224,16 @@ songs =
%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Include Images once and reference them: %% Include Images once and reference them:
#(define bbox-regexp #(define bbox-regexp
(ly:make-regex "%%BoundingBox:[ \t]+([0-9-]+)[ \t]+([0-9-]+)[ \t]+([0-9-]+)[ \t]+([0-9-]+)")) (make-regexp "%%BoundingBox:[ \t]+([0-9-]+)[ \t]+([0-9-]+)[ \t]+([0-9-]+)[ \t]+([0-9-]+)"))
#(define (get-postscript-bbox string) #(define (get-postscript-bbox string)
"Extract the bbox from STRING, or return #f if not present." "Extract the bbox from STRING, or return #f if not present."
(let* (let*
((match (ly:regex-exec bbox-regexp string))) ((match (regexp-exec bbox-regexp string)))
(if match (if match
(map (lambda (x) (map (lambda (x)
(string->number (ly:regex-match-substring match x))) (string->number (match:substring match x)))
(cdr (iota 5))) (cdr (iota 5)))
#f))) #f)))
-110
View File
@@ -1,110 +0,0 @@
% 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
#})
shiftChord = #(define-music-function (parser location xshift chord) (number? ly:music?)
#{
\once \override ChordName.extra-offset = #`(,xshift . 0)
$chord
#})
% 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 chordNameExceptions
(if (defined? 'customChordPrintings)
(sequential-music-to-chord-exceptions customChordPrintings #t)
'()))
generalLayout = \layout {
\generalLayout
\context {
\ChordNames
\semiGermanChords
\override ChordName.font-size = \songScoreChordFontSize
\override ChordName.font-series = \songChordFontSeries
\override ChordName.font-family = #'sans
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"
chordNameExceptions = \chordNameExceptions
% der baseline-skip der Akkorde beeinflusst, wie hoch die Hochstellung ist
\override ChordName.baseline-skip = #1.0
}
}
verseChordLayout = \layout {
\generalLayout
\context {
\ChordNames
\override ChordName.font-size = \songTextChordFontSize
}
}
% 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
}
}
}
#}))
-26
View File
@@ -1,26 +0,0 @@
\paper {
authorMarkup =
#(make-on-the-fly-markup
(lambda (layout props m)
(let ((name (chain-assoc-get 'author:name props #f))
(trail_name (chain-assoc-get 'author:trail_name props #f))
(birth_year (chain-assoc-get 'author:birth_year props #f))
(death_year (chain-assoc-get 'author:death_year props #f))
(organization (chain-assoc-get 'author:organization props #f)))
(interpret-markup layout props
(string-append
name
(if trail_name (ly:format " (~a)" trail_name) "")
(if (and birth_year death_year)
(ly:format ", (~a~a)" birth_year death_year)
(if birth_year
(ly:format ", (*~a)" birth_year)
(if death_year (ly:format ", (†~a)" death_year) "")))
(if organization (ly:format ", ~a" organization) "")
))))
(make-null-markup)
)
poetMarkup = \markup { "Worte:" \fromproperty #'author }
composerMarkup = \markup { "Weise:" \fromproperty #'author }
poetAndComposerEqualMarkup = \markup { "Worte und Weise:" \fromproperty #'author }
}
-18
View File
@@ -1,18 +0,0 @@
% songfilename auch im Markup 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 "~a/~a/~a" songPath songfilename filename))))
(if (file-exists? filepath)
(make-epsfile-markup Y ysize filepath)
(if defaultmarkup
defaultmarkup
(ly:format "file does not exist ~a" filepath))
))))
-93
View File
@@ -1,93 +0,0 @@
#(define-markup-command (print-songinfo layout props) ()
(define (songinfo-from songId key)
(let ((song (if (defined? 'SONG_DATA) (assoc-ref SONG_DATA songId) #f)))
(if song
(assoc-ref song key)
(ly:warning (ly:format "song with id ~a not found" songId)))))
(define (format-author authorId)
(let ((author (if (defined? 'AUTHOR_DATA) (assoc-ref AUTHOR_DATA authorId) #f)))
(if author
(markup
#:override (cons 'author:name (assoc-ref author "name"))
#:override (cons 'author:trail_name (assoc-ref author "trail_name"))
#:override (cons 'author:birth_year (assoc-ref author "birth_year"))
#:override (cons 'author:death_year (assoc-ref author "death_year"))
#:override (cons 'author:organization (assoc-ref author "organization"))
(ly:output-def-lookup layout 'authorMarkup))
(ly:warning (ly:format "author with id ~a not found" authorId)))))
(define (format-poet poetId)
(markup #:override (cons 'author (format-author poetId)) (ly:output-def-lookup layout 'poetMarkup)))
(define (format-composer composerId)
(markup #:override (cons 'author (format-author composerId)) (ly:output-def-lookup layout 'composerMarkup)))
(define (format-poet-and-composer authorId)
(markup #:override (cons 'author (format-author authorId)) (ly:output-def-lookup layout 'poetAndComposerEqualMarkup)))
(interpret-markup layout props
(if (chain-assoc-get 'page:is-bookpart-last-page props #f)
(let* ((songId (chain-assoc-get 'header:songId props #f))
(poetId (chain-assoc-get 'header:poetId props (if songId (songinfo-from songId "poet") #f)))
(composerId (chain-assoc-get 'header:composerId props (if songId (songinfo-from songId "composer") #f)))
(poet-and-composer-same (equal? poetId composerId)))
(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 (if poetId (if poet-and-composer-same (format-poet-and-composer poetId) (format-poet poetId)) #f)))
(composer (chain-assoc-get 'header:composer props (if (and composerId (not poet-and-composer-same)) (format-composer composerId) #f)))
(poet-and-composer-stacked (chain-assoc-get 'header:poet-and-composer-stacked props songInfoPoetAndComposerStacked))
(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)))
(markup #:override '(baseline-skip . 3.0) (
make-fontsize-markup songInfoFontSize
(make-sans-markup
;%\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)))
)
#(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)
)
))))
\paper {
print-first-page-number = ##t
first-page-number = #0
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 }
}
}
}
+736 -20
View File
@@ -1,28 +1,744 @@
\version "2.18" \version "2.18"
\language "deutsch"
#(ly:set-option 'relative-includes #t) #(ly:set-option 'relative-includes #t)
\include #(if (< (list-ref (ly:version) 1) 24) "legacy-lilypond-compatibility.ly" "void.ly") \include "../lilypond-custom-includes/categories.ly"
#(define noStandaloneOutput (if (defined? 'noStandaloneOutput) noStandaloneOutput #f)) 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
#(if (defined? 'LAYOUT) #f (load "json_parser.scm")) \include "./styles.ly"
#(use-modules (json parser))
\include "basic_format_and_style_settings.ly" #(define (lookup-var varsym default)
\include #(if (< (list-ref (ly:version) 1) 25) "legacy-lilypond-compatibility-pre-2.25.ly" "void.ly") (let ((value (assoc-ref (hash-map->list cons (struct-ref (current-module) 0)) varsym)))
\include "eps_file_from_song_dir.ly" (if value (variable-ref value) default)))
\include "title_with_category_images.ly"
\include "footer_with_songinfo.ly" globalSize = #(lookup-var 'globalSize 15)
\include "auto_rest_merging.ly" lyricSize = #(lookup-var 'lyricSize 1.6)
\include "chord_settings.ly" showCategoryImages = #(lookup-var 'showCategoryImages #t)
\include "transposition.ly"
\include "verses_with_chords.ly" % check if we have a StandAlone compile or if variable noStandaloneOutput is set
\include "arrows_in_scores.ly" #(define isStandAlone (not (lookup-var 'noStandaloneOutput #f)))
\include "swing_style.ly"
\include "inline_score.ly" #(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))
}
}
% reset important variables
LAYOUT = \layout { \generalLayout } LAYOUT = \layout { \generalLayout }
HEADER = {}
MUSIC = {} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
TEXT = \markuplist {""} %%% 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
}
-8
View File
@@ -1,8 +0,0 @@
INLINESCOREMUSIC = {}
inline-score =
#(define-music-function (music) (ly:music?)
(set! INLINESCOREMUSIC #{ \INLINESCOREMUSIC #music #})
#{
\transposable #music
#})
-482
View File
@@ -1,482 +0,0 @@
;;; (json parser) --- Guile JSON implementation.
;; Copyright (C) 2013-2020 Aleix Conchillo Flaque <aconchillo@gmail.com>
;;
;; This file is part of guile-json.
;;
;; guile-json is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3 of the License, or
;; (at your option) any later version.
;;
;; guile-json is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with guile-json. If not, see https://www.gnu.org/licenses/.
;;; Commentary:
;; JSON module for Guile
;;; Code:
(define-module (json parser)
#:use-module (ice-9 rdelim)
#:use-module (ice-9 streams)
#:use-module (rnrs io ports)
#:export (json->scm
json-string->scm
json-seq->scm
json-seq-string->scm))
;;
;; Miscellaneuos helpers
;;
(define (json-exception port)
(throw 'json-invalid port))
(define (digit? c)
(case c
((#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9) #t)
(else #f)))
(define (whitespace? c)
(case c
((#\sp #\ht #\lf #\cr) #t)
(else #f)))
(define (control-char? ch)
(<= (char->integer ch) #x1F))
(define (skip-whitespaces port)
(let ((ch (peek-char port)))
(cond
((whitespace? ch)
(read-char port)
(skip-whitespaces port))
(else *unspecified*))))
(define (expect-string port expected return)
(let loop ((n 0))
(cond
;; All characters match.
((= n (string-length expected)) return)
;; Go to next characters.
((eqv? (read-char port) (string-ref expected n))
(loop (+ n 1)))
;; Anything else is an error.
(else (json-exception port)))))
(define (expect-delimiter port delimiter)
(let ((ch (read-char port)))
(cond
((not (eqv? ch delimiter)) (json-exception port))
;; Unexpected EOF.
((eof-object? ch) (json-exception port)))))
(define (skip-record-separators port)
(when (eqv? #\rs (peek-char port))
(read-char port)
(skip-record-separators port)))
;;
;; Number parsing helpers
;;
(define (expect-digit port)
(let ((ch (peek-char port)))
(cond
((not (digit? ch)) (json-exception port))
;; Unexpected EOF.
((eof-object? ch) (json-exception port)))))
;; Read + or -, and return 1 or -1 respectively. If something different is
;; found, return 1.
(define (read-sign port)
(let ((ch (peek-char port)))
(cond
((eqv? ch #\+)
(read-char port)
1)
((eqv? ch #\-)
(read-char port)
-1)
(else 1))))
(define (read-digit-value port)
(let ((ch (read-char port)))
(cond
((eqv? ch #\0) 0)
((eqv? ch #\1) 1)
((eqv? ch #\2) 2)
((eqv? ch #\3) 3)
((eqv? ch #\4) 4)
((eqv? ch #\5) 5)
((eqv? ch #\6) 6)
((eqv? ch #\7) 7)
((eqv? ch #\8) 8)
((eqv? ch #\9) 9)
(else (json-exception port)))))
;; Read digits [0..9].
(define (read-digits port)
(expect-digit port)
(let loop ((ch (peek-char port)) (number 0))
(cond
((digit? ch)
(let ((value (read-digit-value port)))
(loop (peek-char port) (+ (* number 10) value))))
(else number))))
(define (read-digits-fraction port)
(expect-digit port)
(let loop ((ch (peek-char port)) (number 0) (length 0))
(cond
((digit? ch)
(let ((value (read-digit-value port)))
(loop (peek-char port) (+ (* number 10) value) (+ length 1))))
(else
(/ number (expt 10 length))))))
(define (read-exponent port)
(let ((ch (peek-char port)))
(cond
((or (eqv? ch #\e) (eqv? ch #\E))
(read-char port)
(let ((sign (read-sign port))
(digits (read-digits port)))
(if (<= digits 1000) ;; Some maximum exponent.
(expt 10 (* sign digits))
(json-exception port))))
(else 1))))
(define (read-fraction port)
(let ((ch (peek-char port)))
(cond
((eqv? ch #\.)
(read-char port)
(read-digits-fraction port))
(else 0))))
(define (read-positive-number port)
(let* ((number
(let ((ch (peek-char port)))
(cond
;; Numbers that start with 0 must be a fraction.
((eqv? ch #\0)
(read-char port)
0)
;; Otherwise read more digits.
(else (read-digits port)))))
(fraction (read-fraction port))
(exponent (read-exponent port))
(result (* (+ number fraction) exponent)))
(if (and (zero? fraction) (>= exponent 1))
result
(exact->inexact result))))
(define (json-read-number port)
(let ((ch (peek-char port)))
(cond
;; Negative numbers.
((eqv? ch #\-)
(read-char port)
(expect-digit port)
(* -1 (read-positive-number port)))
;; Positive numbers.
((digit? ch)
(read-positive-number port))
;; Anything else is an error.
(else (json-exception port)))))
;;
;; Object parsing helpers
;;
(define (read-pair port null ordered)
;; Read key.
(let ((key (json-read-string port)))
(skip-whitespaces port)
(let ((ch (peek-char port)))
(cond
;; Skip colon and read value.
((eqv? ch #\:)
(read-char port)
(cons key (json-read port null ordered)))
;; Anything other than colon is an error.
(else (json-exception port))))))
(define (json-read-object port null ordered)
(expect-delimiter port #\{)
(let loop ((pairs '()) (added #t))
(skip-whitespaces port)
(let ((ch (peek-char port)))
(cond
;; End of object.
((eqv? ch #\})
(read-char port)
(cond
(added (if ordered (reverse! pairs) pairs))
(else (json-exception port))))
;; Read one pair and continue.
((eqv? ch #\")
(let ((pair (read-pair port null ordered)))
(loop (cons pair pairs) #t)))
;; Skip comma and read more pairs.
((eqv? ch #\,)
(read-char port)
(cond
(added (loop pairs #f))
(else (json-exception port))))
;; Invalid object.
(else (json-exception port))))))
;;
;; Array parsing helpers
;;
(define (json-read-array port null ordered)
(expect-delimiter port #\[)
(skip-whitespaces port)
(cond
;; Special case when array is empty.
((eqv? (peek-char port) #\])
(read-char port)
#())
(else
;; Read first element in array.
(let loop ((values (list (json-read port null ordered))))
(skip-whitespaces port)
(let ((ch (peek-char port)))
(cond
;; Unexpected EOF.
((eof-object? ch) (json-exception port))
;; Handle comma (if there's a comma there should be another element).
((eqv? ch #\,)
(read-char port)
(loop (cons (json-read port null ordered) values)))
;; End of array.
((eqv? ch #\])
(read-char port)
(list->vector (reverse! values)))
;; Anything else other than comma and end of array is wrong.
(else (json-exception port))))))))
;;
;; String parsing helpers
;;
(define (read-hex-digit->integer port)
(let ((ch (read-char port)))
(cond
((eqv? ch #\0) 0)
((eqv? ch #\1) 1)
((eqv? ch #\2) 2)
((eqv? ch #\3) 3)
((eqv? ch #\4) 4)
((eqv? ch #\5) 5)
((eqv? ch #\6) 6)
((eqv? ch #\7) 7)
((eqv? ch #\8) 8)
((eqv? ch #\9) 9)
((or (eqv? ch #\A) (eqv? ch #\a)) 10)
((or (eqv? ch #\B) (eqv? ch #\b)) 11)
((or (eqv? ch #\C) (eqv? ch #\c)) 12)
((or (eqv? ch #\D) (eqv? ch #\d)) 13)
((or (eqv? ch #\E) (eqv? ch #\e)) 14)
((or (eqv? ch #\F) (eqv? ch #\f)) 15)
(else (json-exception port)))))
(define (read-unicode-value port)
(+ (* 4096 (read-hex-digit->integer port))
(* 256 (read-hex-digit->integer port))
(* 16 (read-hex-digit->integer port))
(read-hex-digit->integer port)))
;; Unicode codepoint with surrogates is:
;; 10000 + (high - D800) + (low - DC00)
;; which is equivalent to:
;; (high << 10) + low - 35FDC00
;; see
;; https://github.com/aconchillo/guile-json/issues/58#issuecomment-662744070
(define (json-surrogate-pair->unicode high low)
(+ (* high #x400) low #x-35FDC00))
(define (read-unicode-char port)
(let ((codepoint (read-unicode-value port)))
(cond
;; Surrogate pairs. `codepoint` already contains the higher surrogate
;; (between D800 and DC00) . At this point we are expecting another
;; \uXXXX that holds the lower surrogate (between DC00 and DFFF).
((and (>= codepoint #xD800) (< codepoint #xDC00))
(expect-string port "\\u" #f)
(let ((low-surrogate (read-unicode-value port)))
(if (and (>= low-surrogate #xDC00) (< low-surrogate #xE000))
(integer->char (json-surrogate-pair->unicode codepoint low-surrogate))
(json-exception port))))
;; Reserved for surrogates (we just need to check starting from the low
;; surrogates).
((and (>= codepoint #xDC00) (< codepoint #xE000))
(json-exception port))
(else (integer->char codepoint)))))
(define (read-control-char port)
(let ((ch (read-char port)))
(cond
((eqv? ch #\") #\")
((eqv? ch #\\) #\\)
((eqv? ch #\/) #\/)
((eqv? ch #\b) #\bs)
((eqv? ch #\f) #\ff)
((eqv? ch #\n) #\lf)
((eqv? ch #\r) #\cr)
((eqv? ch #\t) #\ht)
((eqv? ch #\u) (read-unicode-char port))
(else (json-exception port)))))
(define (json-read-string port)
(expect-delimiter port #\")
(let loop ((chars '()) (ch (read-char port)))
(cond
;; Unexpected EOF.
((eof-object? ch) (json-exception port))
;; Unescaped control characters are not allowed.
((control-char? ch) (json-exception port))
;; End of string.
((eqv? ch #\") (reverse-list->string chars))
;; Escaped characters.
((eqv? ch #\\)
(loop (cons (read-control-char port) chars) (read-char port)))
;; All other characters.
(else
(loop (cons ch chars) (read-char port))))))
;;
;; Booleans and null parsing helpers
;;
(define (json-read-true port)
(expect-string port "true" #t))
(define (json-read-false port)
(expect-string port "false" #f))
(define (json-read-null port null)
(expect-string port "null" null))
;;
;; Main parser functions
;;
(define (json-read port null ordered)
(skip-whitespaces port)
(let ((ch (peek-char port)))
(cond
;; Unexpected EOF.
((eof-object? ch) (json-exception port))
;; Read JSON values.
((eqv? ch #\t) (json-read-true port))
((eqv? ch #\f) (json-read-false port))
((eqv? ch #\n) (json-read-null port null))
((eqv? ch #\{) (json-read-object port null ordered))
((eqv? ch #\[) (json-read-array port null ordered))
((eqv? ch #\") (json-read-string port))
;; Anything else should be a number.
(else (json-read-number port)))))
;;
;; Public procedures
;;
(define* (json->scm #:optional (port (current-input-port))
#:key (null 'null) (ordered #f) (concatenated #f))
"Parse a JSON document into native. Takes one optional argument,
@var{port}, which defaults to the current input port from where the JSON
document is read. It also takes a few of keyword arguments: @{null}: value for
JSON's null, it defaults to the 'null symbol, @{ordered} to indicate whether
JSON objects order should be preserved or not (the default) and @{concatenated}
which can be used to tell the parser that more JSON documents might come after a
properly parsed document."
(let loop ((value (json-read port null ordered)))
;; Skip any trailing whitespaces.
(skip-whitespaces port)
(cond
;; If we reach the end the parsing succeeded.
((eof-object? (peek-char port)) value)
;; If there's anything else other than the end, check if user wants to keep
;; parsing concatenated valid JSON documents, otherwise parser fails.
(else
(cond (concatenated value)
(else (json-exception port)))))))
(define* (json-string->scm str #:key (null 'null) (ordered #f))
"Parse a JSON document into native. Takes a string argument,
@var{str}, that contains the JSON document. It also takes a couple of keyword
argument: @{null}: value for JSON's null, it defaults to the 'null symbol and
@{ordered} to indicate whether JSON objects order should be preserved or
not (the default)."
(call-with-input-string str (lambda (p) (json->scm p #:null null #:ordered ordered))))
(define* (json-seq->scm #:optional (port (current-input-port))
#:key (null 'null) (ordered #f)
(handle-truncate 'skip) (truncated-object 'truncated))
"Lazy parse a JSON text sequence from the port @var{port}.
This procedure returns a stream of parsed documents. The optional argument
@var{port} defines the port to read from and defaults to the current input
port. It also takes a few keyword arguments: @{null}: value for JSON's null
(defaults to the 'null symbol), @{ordered} to indicate whether JSON objects
order should be preserved or not (the default), @{handle-truncate}: defines how
to handle data loss, @{truncated-object}: used to replace unparsable
objects. Allowed values for @{handle-truncate} argument are 'throw (throw an
exception), 'stop (stop parsing and end the stream), 'skip (default, skip
corrupted fragment and return the next entry), 'replace (skip corrupted fragment
and return @{truncated-object} instead)."
(letrec ((handle-truncation
(case handle-truncate
((throw) json-exception)
((stop) (const (eof-object)))
((skip)
(lambda (port)
(read-delimited "\x1e" port 'peek)
(read-entry port)))
((replace)
(lambda (port)
(read-delimited "\x1e" port 'peek)
truncated-object))))
(read-entry
(lambda (port)
(let ((ch (read-char port)))
(cond
((eof-object? ch) ch)
((not (eqv? ch #\rs))
(handle-truncation port))
(else
(skip-record-separators port)
(catch 'json-invalid
(lambda ()
(let ((next (json-read port null ordered)))
(if (eqv? #\lf (peek-char port))
(begin
(read-char port)
next)
(handle-truncation port))))
(lambda (_ port)
(handle-truncation port)))))))))
(port->stream port read-entry)))
(define* (json-seq-string->scm str #:key (null 'null) (ordered #f)
(handle-truncate 'skip) (truncated-object 'truncated))
"Lazy parse a JSON text sequence from the string @var{str}.
This procedure returns a stream of parsed documents and also takes the same
keyword arguments as @code{json-seq->scm}."
(call-with-input-string str
(lambda (p)
(json-seq->scm p #:null null #:ordered ordered
#:handle-truncate handle-truncate
#:truncated-object truncated-object))))
;;; (json parser) ends here
-22
View File
@@ -1,22 +0,0 @@
% guile regular expressions aktivieren:
#(use-modules (ice-9 regex))
#(define ly:make-regex make-regexp)
#(define ly:regex-exec regexp-exec)
#(define ly:regex-match-substring match:substring)
#(define (ly:regex-replace pattern text . replacements)
(apply regexp-substitute/global #f pattern text 'pre (append replacements (list 'post))))
% old font handling
#(define (default-pango size)
(make-pango-font-tree
songChordFont
songLyricFont
"Luxi Mono"
(/ size 20)))
\paper {
#(define fonts (default-pango globalSize))
}
-39
View File
@@ -1,39 +0,0 @@
% set the speed of the midi music
#(define midiQuarterNoteSpeed (if (defined? 'midiQuarterNoteSpeed) midiQuarterNoteSpeed 90))
MUSIC = { \transposable \MUSIC }
% nur Output wenn noStandaloneOutput auf false steht
output = #(if (not noStandaloneOutput)
#{
\bookpart {
\HEADER
\score {
\MUSIC
\layout { \LAYOUT }
}
\TEXT
\score {
\unfoldRepeats { \MUSIC \INLINESCOREMUSIC }
\midi {
\context {
\Score
% Tempo des midi files
tempoWholesPerMinute = #(ly:make-moment midiQuarterNoteSpeed 4)
}
}
}
}
#}
)
% if we don't want a standalone output, cause we compile a book, we just have an empty output here,
% so lilypond does not generate output for this song
\book {
\bookpart { \output }
}
+10 -10
View File
@@ -1,16 +1,16 @@
#(define bookStyle #(define book-style
(if (not (defined? 'bookStyle)) (if (not (defined? 'book-style))
#f #f
bookStyle)) book-style))
#(define songStyle #(define song-style
(if (not (defined? 'songStyle)) (if (not (defined? 'song-style))
(if (not (defined? 'defaultSongStyle)) 'börnel defaultSongStyle) 'bock
songStyle)) song-style))
#(if (not (boolean? bookStyle)) #(if (not (boolean? book-style))
(set! songStyle bookStyle)) (set! song-style book-style))
#(define (bock-style layout props) #(define (bock-style layout props)
"Whether we have bockstyle or not" "Whether we have bockstyle or not"
(eq? songStyle 'bock)) (eq? song-style 'bock))
-15
View File
@@ -1,15 +0,0 @@
songFormatAndSize = "a6landscape"
songMargin = 8
songInfoFontSize = -1.5
songTitleFont = "Britannic T. custom"
songChordFont = "TimesNewRomanPS"
songLyricFont = "Arial"
songChordFontSeries = #'normal
songTextChordAlignment = #'left
songScoreChordFontSize = 3
songTextChordFontSize = 2
songTextLineHeigth = 5.5
songInfoPoetAndComposerStacked = ##f
songTocColumns = 3
globalSize = 15
lyricSize = 1.6
-15
View File
@@ -1,15 +0,0 @@
songFormatAndSize = "b6landscape"
songMargin = 5
songInfoFontSize = -3.5
songTitleFont = "Oregano"
songChordFont = "TeX Gyre Heros"
songLyricFont = "Liberation Sans"
songChordFontSeries = #'bold
songTextChordAlignment = #'center
songScoreChordFontSize = 0
songTextChordFontSize = \songScoreChordFontSize
songTextLineHeigth = 5
songInfoPoetAndComposerStacked = ##f
songTocColumns = 3
globalSize = 15
lyricSize = 1.6
-15
View File
@@ -1,15 +0,0 @@
songFormatAndSize = "a5"
songMargin = 5
songInfoFontSize = 0
songTitleFont = "Fontin Bold"
songChordFont = "Fontin"
songLyricFont = "FontinSans"
songChordFontSeries = #'bold
songTextChordAlignment = #'left
songScoreChordFontSize = 2
songTextChordFontSize = 2
songTextLineHeigth = 5.3
songInfoPoetAndComposerStacked = ##t
songTocColumns = 2
globalSize = 14
lyricSize = 1.6
-48
View File
@@ -1,48 +0,0 @@
swing = \mark \markup {
\line \general-align #Y #DOWN {
\score {
\new Staff \with {
fontSize = #-2
\override StaffSymbol.line-count = #0
% \override VerticalAxisGroup.Y-extent = #'(0 . 0)
}
\relative {
\stemUp
\override Score.SpacingSpanner.common-shortest-duration = #(ly:make-moment 3 16)
\override Beam.positions = #'(2 . 2)
h'8[ h8]
}
\layout {
ragged-right= ##t
indent = 0
\context {
\Staff \remove "Clef_engraver"
\remove "Time_signature_engraver"
}
}
}
" ="
\score {
\new Staff \with {
fontSize = #-2
\override StaffSymbol.line-count = #0
% \override VerticalAxisGroup.Y-extent = #'(0 . 0)
}
\relative {
\stemUp
\override Score.SpacingSpanner.common-shortest-duration = #(ly:make-moment 3 16)
\override Stem.length = #4.5
\tuplet 3/2 { h'4 h8 }
}
\layout {
ragged-right= ##t
indent = 0
\context {
\Staff
\remove "Clef_engraver"
\remove "Time_signature_engraver"
}
}
}
}
}
-71
View File
@@ -1,71 +0,0 @@
#(define-markup-command (bookTitleMarkupCustom layout props)()
(interpret-markup layout
(prepend-alist-chain 'defaultmarkup #{
\markup {
\override #'(baseline-skip . 3.5)
\center-column {
\override #`(font-name . ,songTitleFont) { \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 noStandaloneOutput
(make-epsfileref-markup Y size
(category-image-path category))
(make-epsfile-markup Y size
(category-image-path category)))))
#(define showCategoryImages (if (defined? 'showCategoryImages) showCategoryImages #t))
#(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 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" (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 { " " } #})
)))
\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 }
}
+22 -21
View File
@@ -1,5 +1,3 @@
\include "../lilypond-custom-includes/toc_config.ly"
% embed all category images in postscript once % embed all category images in postscript once
#(define-markup-list-command (embed-category-images layout props)() #(define-markup-list-command (embed-category-images layout props)()
(map (lambda (category) (map (lambda (category)
@@ -21,20 +19,13 @@
(map (lambda (foo) (map (lambda (foo)
(make-general-align-markup Y UP (make-override-markup '(baseline-skip . 1) (make-column-markup (make-general-align-markup Y UP (make-override-markup '(baseline-skip . 1) (make-column-markup
(let add-to-col ((lines restlines) (height-left height)) (let add-to-col ((lines restlines) (height-left height))
(set! restlines lines) (let* ((finished (null? lines))
(if (null? lines) (linestencil (if (not finished) (interpret-markup layout (cons (list (cons 'line-width line-width) (cons 'baseline-skip 1)) props) (markup #:center-align (car lines)))))
'() (calc-height (- height-left (if finished 0 (interval-length (ly:stencil-extent linestencil Y))))))
(let* ((line-to-stencil (lambda (line) (interpret-markup layout (cons (list (cons 'line-width line-width) (cons 'baseline-skip 1)) props) (markup line)))) (set! restlines lines)
(stencil-height (lambda (stencil) (interval-length (ly:stencil-extent stencil Y)))) (if (or (< calc-height 0) (null? lines))
(linestencil (line-to-stencil (car lines))) (list)
(current-line-height (stencil-height linestencil)) (cons (markup #:stencil linestencil) (add-to-col (cdr lines) calc-height)))))))))
(new-height-left (- height-left current-line-height))
(next-line-height (if (null? (cdr lines)) current-line-height (stencil-height (line-to-stencil (cadr lines)))))
(no-space-for-next-line (and (< next-line-height current-line-height) (< new-height-left next-line-height)))
)
(if (or (< new-height-left 0) no-space-for-next-line)
'()
(cons (markup #:stencil linestencil) (add-to-col (cdr lines) new-height-left))))))))))
(make-list cols)))) (make-list cols))))
(if (null? restlines) (if (null? restlines)
(list) (list)
@@ -173,7 +164,17 @@
(cdr revlist))))))))) (cdr revlist)))))))))
\paper { \paper {
indexTitleMarkup = \tocSubtitleText indexTitleMarkup = \markup \column {
\fontsize #5 \sans \bold \fill-line { \null \fromproperty #'index:text \null }
\vspace #.5
\justify {
Da die allermeisten Lieder unter verschiedenen Namen bekannt sind,
wollen wir euch ein Inhaltsverzeichnis an die Hand geben, mit dem ihr hoffentlich auf verschiedene Arten fündig werdet.
Die Liedtitel, die auch die Überschriften sind, findet ihr normal gedruckt.
Alle weiteren Alternativtitel oder Liedanfänge sind zur Unterscheidung kursiv gedruckt.
}
\vspace #1
}
categoryTitleMarkup = \markup \column { categoryTitleMarkup = \markup \column {
\fontsize #5 \sans \bold \fill-line { \null \fromproperty #'index:text \null } \fontsize #5 \sans \bold \fill-line { \null \fromproperty #'index:text \null }
\vspace #1 \vspace #1
@@ -181,8 +182,8 @@
indexItemMarkup = \markup \with-link-symbol-ref #'index:label { indexItemMarkup = \markup \with-link-symbol-ref #'index:label {
\index-item-with-pattern \index-item-with-pattern
} }
indexSectionMarkup = \markup \override #'(baseline-skip . 1.5) \left-column { indexSectionMarkup = \markup \override #'(baseline-skip . 1.5) \column {
\sans \bold \fontsize #3 \fromproperty #'index:text \fill-line { \sans \bold \fontsize #3 \fromproperty #'index:text \null }
\null \null
} }
indexCategoryMarkup = \markup \override #'(baseline-skip . 1.5) \column { indexCategoryMarkup = \markup \override #'(baseline-skip . 1.5) \column {
@@ -235,7 +236,7 @@
(ly:output-def-lookup layout 'indexTitleMarkup)))) (ly:output-def-lookup layout 'indexTitleMarkup))))
(cons title (cons title
(interpret-markup-list layout props (interpret-markup-list layout props
(make-columnlayout-markup-list songTocColumns 2 (make-columnlayout-markup-list 3 2
(let ((h (- (ly:output-def-lookup layout 'paper-height) 12))) (let ((h (- (ly:output-def-lookup layout 'paper-height) 12)))
(cons (- h (interval-length (ly:stencil-extent title Y))) h)) (cons (- h (interval-length (ly:stencil-extent title Y))) h))
(prepare-item-markup index-items layout)))))) (prepare-item-markup index-items layout))))))
@@ -248,7 +249,7 @@
(ly:output-def-lookup layout 'categoryTitleMarkup)))) (ly:output-def-lookup layout 'categoryTitleMarkup))))
(cons title (cons title
(interpret-markup-list layout props (interpret-markup-list layout props
(make-columnlayout-markup-list songTocColumns 2 (make-columnlayout-markup-list 3 2
(let ((h (- (ly:output-def-lookup layout 'paper-height) 12))) (let ((h (- (ly:output-def-lookup layout 'paper-height) 12)))
(cons (- h (interval-length (ly:stencil-extent title Y))) h)) (cons (- h (interval-length (ly:stencil-extent title Y))) h))
(prepare-item-markup category-index-items layout))))))) (prepare-item-markup category-index-items layout)))))))
-13
View File
@@ -1,13 +0,0 @@
TRANSPOSITION = ##f
transposeGlobal =
#(define-void-function (from to) (ly:pitch? ly:pitch?)
(set! TRANSPOSITION (cons from to)))
transposable =
#(define-music-function (music) (ly:music?)
(if TRANSPOSITION
#{
\transpose #(car TRANSPOSITION) #(cdr TRANSPOSITION) #music
#}
music))
-167
View File
@@ -1,167 +0,0 @@
% 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 { "
(ly:regex-replace (ly:make-regex "\n") text " } \\line { ")
" \\size-box-to-box ##f ##t \"\" \"Agj\" }" )))
(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 songTextChordAlignment
((center) (make-size-box-to-box-markup use-x use-y abox bbox))
((left) (make-size-box-to-box-left-aligned-markup use-x use-y abox bbox)))))
% 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 songTextChordAlignment
((center) (make-center-align-markup chord-with-text))
((left) (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?)
#:properties ((intraverse-vspace 0))
"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 . ,(+ intraverse-vspace songTextLineHeigth)) #:anchor-x-between #:stanza stanza
(make-wrap-newline-markup
(ly:regex-replace (ly:make-regex "\\(( *)([^,()]*)( *),([^)]*)\\)")
(ly:regex-replace (ly:make-regex "(([^ \n]*\\([^()]*,[^()]+\\)[^ \n(]*)+)") verse " \\concat { " 1 " } ")
"\\textup \\line { \"" 1 "\" " 2 " \"" 3 "\" } \\score { \\transposable " transp " \\chords { s4 " 4 " } \\layout { \\verseChordLayout } }")
)
))))
% Kompletter Vers aus dem Akkorde entfernt werden
#(define-markup-command (nochordverse layout props stanza verse) (markup? string?)
#:properties ((intraverse-vspace 0))
"Vers ohne Akkorde"
(interpret-markup layout props
(markup #:override `(baseline-skip . ,(+ intraverse-vspace 3.0)) #:anchor-x-between #:stanza stanza
#:wrap-newline (ly:regex-replace (ly:make-regex "\\(([^,]*),([^)]*)\\)") verse 1)
)
)
)
#(define-markup-command (verseformat layout props verse) (markup?)
"Textformatierung für Strophen"
(interpret-markup layout props
(make-sans-markup (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))))))
-5
View File
@@ -1,5 +0,0 @@
% this is just an empty dummy file to make conditional includes work so that relative pathes could be used
% this is working if #(ly:set-option 'relative-includes #t) was set:
% \include #(if condition relative/path/to/file.ly void.ly)
% but this does not work:
% #(if condition (ly:parser-include-string "\\include \"relative/path/to/file.ly\""))