Compare commits
	
		
			124 Commits
		
	
	
		
			tocSubtitl
			...
			5364f93db4
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 5364f93db4 | |||
| aa0e3816d0 | |||
| 3b0c320839 | |||
| 12abf0a5f7 | |||
| a01e95f31d | |||
| 90feb6dfbb | |||
| ede5568962 | |||
| 66b5c37755 | |||
| cd5e38aabc | |||
| ca129eec79 | |||
| f824b23311 | |||
| 5ef4ee78ae | |||
| 45e751fa24 | |||
| 9fb2d96765 | |||
| 8ce3af93c7 | |||
| 19f6046333 | |||
| a288248da3 | |||
| 7a65d056d6 | |||
| 53c41bf5dc | |||
| c49dba89f7 | |||
| 195110923a | |||
| 8d0ddcee06 | |||
| c47ceb443e | |||
| 377beeab57 | |||
| cb4b74d4f7 | |||
| 616034baca | |||
| 34c9c5a932 | |||
| 57bcf94167 | |||
| 9a9ef8e8df | |||
| 531e459af1 | |||
| fc1bc74b10 | |||
| d47ae1a66d | |||
| 37ee497f89 | |||
| 41bd881014 | |||
| 00a7b0ebc8 | |||
| 760ca71ba7 | |||
| 17074e2db6 | |||
| 654f619fba | |||
| cc4fc9f297 | |||
| d2dbf3448a | |||
| 140bc611d1 | |||
| eccd9b8730 | |||
| 900f4e1d06 | |||
| 7d01bd769c | |||
| a0e70b4c4b | |||
| 04a01d3b3f | |||
| 07b598db06 | |||
| a61becaf5e | |||
| f0f4b0c180 | |||
| b6bead747d | |||
| 4dbdb72d30 | |||
| aa8b9526fa | |||
| 3cb0e00e8f | |||
| 152d56fe3f | |||
| 883c32701c | |||
| 7b97e04fab | |||
| e4b65aafcb | |||
| bf7e959100 | |||
| ddd4888041 | |||
| a368a3c589 | |||
| e6725b84d4 | |||
|  | b41e2a62a4 | ||
| 15c27c271f | |||
| eca352b6d0 | |||
| ed30b34df2 | |||
| a558a0b02f | |||
| c4f3a3c196 | |||
| db26306b5b | |||
| 487bf457fb | |||
| 47bb7991b8 | |||
| d94703547c | |||
| f0ffd3f630 | |||
| 8dfbc5ef25 | |||
| 8800341e18 | |||
| d56c11c5ff | |||
| 754682afcf | |||
| 88f0dc9f8f | |||
| e9b904c32c | |||
| fd14138d0b | |||
| a1bc48b824 | |||
| b4690f63bc | |||
| 958efca6aa | |||
| 81a5676965 | |||
| 5ee1a7b6be | |||
| 162d32c53d | |||
| a3c3a67b33 | |||
| 09d3bb7fa1 | |||
| bab581042a | |||
| 3b87476549 | |||
| c4bfc17b89 | |||
| e388559f23 | |||
| e17c544763 | |||
| 3c2f27b477 | |||
| b3d46ff607 | |||
| 0df95f6441 | |||
| 201a54f60a | |||
| 0199813a81 | |||
| bce9ffe763 | |||
| 86943b9316 | |||
| 5884ab9d2c | |||
| 199f515be9 | |||
| 8c7386807b | |||
| 7f7cac99f4 | |||
| 395e959432 | |||
| e72efbd156 | |||
| a0f60bc1c7 | |||
| f5d5e1b020 | |||
| 4f43791541 | |||
|  | 2f906344de | ||
| b23ba5c0dc | |||
| bc769f0831 | |||
| 6975cb1713 | |||
| fbaf7a2c86 | |||
| 8b0fc2d7c9 | |||
| 14e01900c2 | |||
| bf596edb2c | |||
| d6774670f3 | |||
| 260664462d | |||
| 9de2869750 | |||
| f0010c7746 | |||
| bedb2c0e22 | |||
| 33c3d47504 | |||
| 15f37accaa | |||
| c26fddd963 | 
| @@ -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 |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -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 = "𝄇" |  | ||||||
| @@ -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 |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|      #})) |  | ||||||
| @@ -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 } |  | ||||||
| } |  | ||||||
| @@ -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 } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,28 +0,0 @@ | |||||||
| \version "2.18" |  | ||||||
|  |  | ||||||
| #(ly:set-option 'relative-includes #t) |  | ||||||
|  |  | ||||||
| \include #(if (< (list-ref (ly:version) 1) 24) "legacy-lilypond-compatibility.ly" "void.ly") |  | ||||||
|  |  | ||||||
| #(define noStandaloneOutput (if (defined? 'noStandaloneOutput) noStandaloneOutput #f)) |  | ||||||
|  |  | ||||||
| #(if (defined? 'LAYOUT) #f (load "json_parser.scm")) |  | ||||||
| #(use-modules (json parser)) |  | ||||||
| \include "basic_format_and_style_settings.ly" |  | ||||||
| \include #(if (< (list-ref (ly:version) 1) 25) "legacy-lilypond-compatibility-pre-2.25.ly" "void.ly") |  | ||||||
| \include "eps_file_from_song_dir.ly" |  | ||||||
| \include "title_with_category_images.ly" |  | ||||||
| \include "footer_with_songinfo.ly" |  | ||||||
| \include "auto_rest_merging.ly" |  | ||||||
| \include "chord_settings.ly" |  | ||||||
| \include "transposition.ly" |  | ||||||
| \include "verses_with_chords.ly" |  | ||||||
| \include "arrows_in_scores.ly" |  | ||||||
| \include "swing_style.ly" |  | ||||||
| \include "inline_score.ly" |  | ||||||
|  |  | ||||||
| % reset important variables |  | ||||||
| LAYOUT = \layout { \generalLayout } |  | ||||||
| HEADER = {} |  | ||||||
| MUSIC = {} |  | ||||||
| TEXT = \markuplist {""} |  | ||||||
| @@ -1,8 +0,0 @@ | |||||||
| INLINESCOREMUSIC = {} |  | ||||||
|  |  | ||||||
| inline-score = |  | ||||||
| #(define-music-function (music) (ly:music?) |  | ||||||
|    (set! INLINESCOREMUSIC #{ \INLINESCOREMUSIC #music #}) |  | ||||||
|     #{ |  | ||||||
|       \transposable #music |  | ||||||
|     #}) |  | ||||||
							
								
								
									
										482
									
								
								json_parser.scm
									
									
									
									
									
								
							
							
						
						
									
										482
									
								
								json_parser.scm
									
									
									
									
									
								
							| @@ -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 |  | ||||||
| @@ -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)) |  | ||||||
| } |  | ||||||
| @@ -1,27 +0,0 @@ | |||||||
| % this is to be compatible to older lilypond versions |  | ||||||
| \version "2.18.0" |  | ||||||
|  |  | ||||||
| #(define (on-first-page layout props) |  | ||||||
|   "Whether the markup is printed on the first page of the book." |  | ||||||
|   (= (chain-assoc-get 'page:page-number props -1) |  | ||||||
|      (book-first-page layout props))) |  | ||||||
|  |  | ||||||
| #(define-markup-command (if layout props condition? argument) |  | ||||||
|   (procedure? markup?) |  | ||||||
|   #:category conditionals |  | ||||||
|   (if (condition? layout props) |  | ||||||
|       (interpret-markup layout props argument) |  | ||||||
|       empty-stencil)) |  | ||||||
|  |  | ||||||
| #(define (on-first-page-of-part layout props) |  | ||||||
|   "Whether the markup is printed on the first page of the book part." |  | ||||||
|   (= (chain-assoc-get 'page:page-number props -1) |  | ||||||
|      (ly:output-def-lookup layout 'first-page-number))) |  | ||||||
|  |  | ||||||
| #(define (should-print-page-number layout props) |  | ||||||
|   "Whether the page number should be printed on this page.  This depends |  | ||||||
| on the settings @code{print-@/page-@/numbers} and |  | ||||||
| @code{print-@/first-@/page-@/number} of the @code{\\paper} block." |  | ||||||
|   (and (eq? #t (ly:output-def-lookup layout 'print-page-number)) |  | ||||||
|        (or (not (on-first-page layout props)) |  | ||||||
|            (eq? #t (ly:output-def-lookup layout 'print-first-page-number))))) |  | ||||||
							
								
								
									
										49
									
								
								private_includes/base/all.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								private_includes/base/all.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | |||||||
|  | #(define include_dir_not_added? (if (defined? 'include_dir_not_added?) include_dir_not_added? #t)) | ||||||
|  | #(if include_dir_not_added? | ||||||
|  |    (let* ((common-include-dir (dirname (dirname (dirname (current-filename)))))) | ||||||
|  |       (ly:parser-append-to-include-path common-include-dir) | ||||||
|  |       (set! include_dir_not_added? #f))) | ||||||
|  |  | ||||||
|  | #(define noStandaloneOutput (if (defined? 'noStandaloneOutput) noStandaloneOutput #f)) | ||||||
|  |  | ||||||
|  | #(define windows? (string-prefix-ci? "windows" (utsname:sysname (uname)))) | ||||||
|  |  | ||||||
|  | #(if (defined? 'LAYOUT) #f | ||||||
|  |   (let ((scm-load (lambda (filename) (load ( | ||||||
|  |     string-append | ||||||
|  |       ; on windows the detection of absolute pathes is broken (cause they start with a drive letter and not with a /) | ||||||
|  |       ; so we have to use relative pathes for load. That works in frescobaldi, but not if you call lilypond from command line, | ||||||
|  |       ; with a relative path to the .ly file, so we use absolute pathes on posix systems, where it works. | ||||||
|  |       (if windows? | ||||||
|  |         "" | ||||||
|  |         (string-append (dirname (current-filename)) file-name-separator-string)) | ||||||
|  |       "scm" file-name-separator-string filename | ||||||
|  |     ))))) | ||||||
|  |     (scm-load "resolve_inherits.scm") | ||||||
|  |     (scm-load "yaml_parser.scm"))) | ||||||
|  | #(define AUTHOR_DATA (if (defined? 'AUTHOR_DATA) AUTHOR_DATA (parse-yml-file "../../lilypond-song-includes/data/authors.yml"))) | ||||||
|  | #(define SONG_DATA (if (defined? 'SONG_DATA) SONG_DATA (parse-yml-file "../../lilypond-song-includes/data/songs.yml"))) | ||||||
|  |  | ||||||
|  | \include "merge_rests_engraver_override.ily" | ||||||
|  | \include "basic_format_and_style_settings.ily" | ||||||
|  | \include "eps_file_from_song_dir.ily" | ||||||
|  | \include "title_with_category_images.ily" | ||||||
|  | \include "chord_settings.ily" | ||||||
|  | \include "transposition.ily" | ||||||
|  | \include "verses_with_chords.ily" | ||||||
|  | \include "arrows_in_scores.ily" | ||||||
|  | \include "swing_style.ily" | ||||||
|  | \include "inline_score.ily" | ||||||
|  | \include "custom_indentation.ily" | ||||||
|  | \include "include_from_song.ily" | ||||||
|  |  | ||||||
|  | % reset important variables | ||||||
|  | LAYOUT = \layout { \generalLayout } | ||||||
|  | HEADER = {} | ||||||
|  | MUSIC = {} | ||||||
|  | TEXT = \markuplist {} | ||||||
|  | TEXT_PAGES = #f | ||||||
|  |  | ||||||
|  | verseChords = {} | ||||||
|  | firstVoice = {} | ||||||
|  | global = {} | ||||||
							
								
								
									
										259
									
								
								private_includes/base/basic_format_and_style_settings.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										259
									
								
								private_includes/base/basic_format_and_style_settings.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,259 @@ | |||||||
|  | \language "deutsch" | ||||||
|  |  | ||||||
|  | \include "default_style.ily" | ||||||
|  | \include "default_songinfo_style.ily" | ||||||
|  | \include "footer_with_songinfo.ily" | ||||||
|  |  | ||||||
|  | \include #(if (defined? 'customStyleOverridesFile) customStyleOverridesFile "../void.ily") | ||||||
|  |  | ||||||
|  | #(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 | ||||||
|  |   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)) | ||||||
|  |   refMarkupFormatter = #(lambda (layout props stanzanumbers) | ||||||
|  |     (interpret-markup layout props | ||||||
|  |     (if (null? stanzanumbers) | ||||||
|  |         refString | ||||||
|  |         (ly:format refStringWithNumbers (string-join (map (lambda (stanzanumber) (ly:format "~a" stanzanumber)) stanzanumbers) ", "))))) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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-voice-cautionary | ||||||
|  |     \consists \Better_Merge_rests_engraver | ||||||
|  |   } | ||||||
|  |   \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" | ||||||
|  |     \override NoteHead.layer = 2 | ||||||
|  |     \override Rest.layer = 2 | ||||||
|  |     \override Dots.layer = 2 | ||||||
|  |     \override Stem.layer = 2 | ||||||
|  |     \override Flag.layer = 2 | ||||||
|  |     \override Beam.layer = 2 | ||||||
|  |     \override Accidental.layer = 2 | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||||||
|  | %%% kleine Helferlein: | ||||||
|  |  | ||||||
|  | textp = \lyricmode { \markup { \raise #1 \musicglyph #"rests.3" } } | ||||||
|  |  | ||||||
|  | % zweite Stimme alles grau | ||||||
|  | secondVoiceStyle = { | ||||||
|  |   \override NoteHead.color = #grey | ||||||
|  |   \override Rest.color = #grey | ||||||
|  |   \override Dots.color = #grey | ||||||
|  |   \override Stem.color = #grey | ||||||
|  |   \override Flag.color = #grey | ||||||
|  |   \override Beam.color = #grey | ||||||
|  |   \override Accidental.color = #grey | ||||||
|  |   \override NoteHead.layer = 1 | ||||||
|  |   \override Rest.layer = 1 | ||||||
|  |   \override Dots.layer = 1 | ||||||
|  |   \override Stem.layer = 1 | ||||||
|  |   \override Flag.layer = 1 | ||||||
|  |   \override Beam.layer = 1 | ||||||
|  |   \override Accidental.layer = 1 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | firstVoiceStyle = { | ||||||
|  |   \override NoteHead.color = #black | ||||||
|  |   \override Rest.color = #black | ||||||
|  |   \override Dots.color = #black | ||||||
|  |   \override Stem.color = #black | ||||||
|  |   \override Flag.color = #black | ||||||
|  |   \override Beam.color = #black | ||||||
|  |   \override Accidental.color = #black | ||||||
|  | } | ||||||
|  |  | ||||||
|  | % Deprecated: einzelne Noten innerhalb von \secondVoiceStyle mit schwarzem statt grauem Kopf | ||||||
|  | schwarzkopf = | ||||||
|  |   #(define-music-function (parser location noten) (ly:music?) | ||||||
|  |     (begin (ly:warning "\\schwarzkopf brauchts nicht mehr, das kann ersatzlos weg!") noten)) | ||||||
|  |  | ||||||
|  | romanStanza = | ||||||
|  |   #(define-music-function (parser location) () | ||||||
|  |   #{ \override StanzaNumber.style = #'roman #}) | ||||||
|  |  | ||||||
|  | override-stanza = | ||||||
|  | #(define-music-function (parser location stanzanumber) (number?) | ||||||
|  | #{ | ||||||
|  |   \once \override StanzaNumber.forced-spacing = #stanzanumber % misuse property "forced-spacing" to override the stanzanumber | ||||||
|  | #} | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | #(define (stanza . stanzanumbers) | ||||||
|  | #{ | ||||||
|  |   \once \override StanzaNumber.layer = 23 % set this to signal that there is a real stanza and no repeat signs | ||||||
|  |   \applyContext | ||||||
|  |   #(lambda (context) | ||||||
|  |     (let* ((stanzanumber-override (ly:assoc-get 'forced-spacing (ly:context-grob-definition context 'StanzaNumber) #f)) | ||||||
|  |            (stanza-style (ly:assoc-get 'style (ly:context-grob-definition context 'StanzaNumber))) | ||||||
|  |            (stanza-format (lambda (stanzanumber) (format #f (if (eq? stanza-style 'roman) romanStanzaFormat stanzaFormat) stanzanumber)))) | ||||||
|  |         (ly:context-set-property! context 'stanza | ||||||
|  |           (string-join (map stanza-format | ||||||
|  |                             (if stanzanumber-override (list stanzanumber-override) stanzanumbers)) | ||||||
|  |                         ", ")))) | ||||||
|  | #} | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | ref = | ||||||
|  | #(define-music-function (stanzanumbers lyrics) ((number-list? (list)) ly:music?) | ||||||
|  | #{ \lyricmode { | ||||||
|  |     \once \override StanzaNumber.layer = 23 % set this to signal that there is a real stanza and no repeat signs | ||||||
|  |     \set stanza = #(make-on-the-fly-markup (lambda (layout props m) ((ly:output-def-lookup layout 'refMarkupFormatter) layout props stanzanumbers)) (make-null-markup)) | ||||||
|  |     #lyrics | ||||||
|  |   } | ||||||
|  | #} | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | % prints a repStart Sign as stanza if the tag 'repeats is kept. | ||||||
|  | % if there was a stanza already set by the stanza function with StanzaNumber.layer = 23 we set that also as stanza. | ||||||
|  | repStartWithTag = \lyricmode { | ||||||
|  |   \tag #'repeats { | ||||||
|  |     \applyContext | ||||||
|  |     #(lambda (context) | ||||||
|  |       (let ((lastStanza (ly:context-property context 'stanza)) | ||||||
|  |             (printLastStanza (= (ly:assoc-get 'layer (ly:context-grob-definition context 'StanzaNumber) 0) 23)) | ||||||
|  |             (stanzaFontSeries (ly:assoc-get 'font-series (ly:context-grob-definition context 'StanzaNumber) 'normal))) | ||||||
|  |       (ly:context-set-property! context 'stanza | ||||||
|  |         (make-concat-markup | ||||||
|  |           (if printLastStanza | ||||||
|  |             (list (make-override-markup `(font-series . ,stanzaFontSeries) lastStanza) (make-hspace-markup 1) repStart) | ||||||
|  |             (list repStart) | ||||||
|  |             ))))) | ||||||
|  |     \once \override StanzaNumber.font-series = #'normal | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | repStopWithTag = \lyricmode { | ||||||
|  |   \tag #'repeats { | ||||||
|  |     \once \override StanzaNumber.font-series = #'normal | ||||||
|  |     \once \override StanzaNumber.direction = 1 | ||||||
|  |     \set stanza = \markup { \repStop } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | rightHyphen = \lyricmode { | ||||||
|  |   \once \override StanzaNumber.font-series = #'normal | ||||||
|  |   \once \override StanzaNumber.direction = 1 | ||||||
|  |   \set stanza = "-" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | leftHyphen = \lyricmode { | ||||||
|  |   \once \override StanzaNumber.font-series = #'normal | ||||||
|  |   \set stanza = "-" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | multiVerseSkips = | ||||||
|  | #(define-music-function (parser location skips) (number?) | ||||||
|  |   #{ \tag #'multiVerse { \repeat unfold #skips { \skip4 } } #}) | ||||||
|  |  | ||||||
|  | alt = | ||||||
|  | #(define-music-function (parser location a b) (ly:music? ly:music?) | ||||||
|  |   #{ \tag #'firstVerse { #a } \tag #'multiVerse { #b } #}) | ||||||
|  |  | ||||||
|  | updown = | ||||||
|  | #(define-music-function (parser location word) (string?) | ||||||
|  | (let ((first-char (string-take word 1)) | ||||||
|  |       (rest (substring word 1 (string-length word)))) | ||||||
|  | #{ | ||||||
|  |   \lyricmode { | ||||||
|  |     \markup { | ||||||
|  |       \tag #'up #(string-append (string-capitalize first-char) rest) | ||||||
|  |       \tag #'down #(string-append (string-downcase first-char) rest) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | #})) | ||||||
|  |  | ||||||
|  | dottedExtender = { | ||||||
|  |   \override LyricExtender.style = #'dotted-line | ||||||
|  |   \override LyricExtender.thickness = 2 | ||||||
|  |   \override LyricExtender.Y-offset = 0.1 | ||||||
|  |   \override LyricExtender.stencil = | ||||||
|  |     #(lambda (grob) | ||||||
|  |       (let* ((stil (ly:lyric-extender::print grob)) | ||||||
|  |              (nostil (null? stil)) | ||||||
|  |              (x-ext (if nostil 0 (ly:stencil-extent stil X)))) | ||||||
|  |          (if nostil | ||||||
|  |            stil | ||||||
|  |            (make-connected-line | ||||||
|  |              (list | ||||||
|  |                (cons (car x-ext) 0) | ||||||
|  |                (cons (cdr x-ext) 0)) | ||||||
|  |              grob)))) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | melisOff = \set ignoreMelismata = ##t | ||||||
|  | melisOn = \unset ignoreMelismata | ||||||
|  |  | ||||||
|  | cue = | ||||||
|  | #(define-music-function (zahlen) (number-list?) | ||||||
|  |   #{ | ||||||
|  |       \tag #'cues { | ||||||
|  |         \tweak self-alignment-X #LEFT | ||||||
|  |         \mark | ||||||
|  |           #(make-on-the-fly-markup | ||||||
|  |             (lambda (layout props m) (interpret-markup layout (prepend-alist-chain 'cues zahlen props) (ly:output-def-lookup layout 'cueMarkup))) | ||||||
|  |             (make-null-markup)) | ||||||
|  |       } | ||||||
|  |   #}) | ||||||
|  |  | ||||||
|  | #(define-markup-command (ruf-style layout props text) (string?) | ||||||
|  |    (interpret-markup layout props | ||||||
|  |                      (markup #:italic (string-append "(" text ")")))) | ||||||
|  | rufWithMarkup = | ||||||
|  | #(define-music-function (text) (markup?) | ||||||
|  |    #{ | ||||||
|  |      \lyricmode { | ||||||
|  |        \once \override StanzaNumber.font-series = #'normal | ||||||
|  |        \once \override StanzaNumber.direction = 1 | ||||||
|  |        \set stanza = #text | ||||||
|  |      } | ||||||
|  |    #}) | ||||||
|  | ruf = | ||||||
|  | #(define-music-function (text) (string?) | ||||||
|  |    (rufWithMarkup (make-ruf-style-markup text))) | ||||||
							
								
								
									
										217
									
								
								private_includes/base/chord_settings.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								private_includes/base/chord_settings.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,217 @@ | |||||||
|  | % 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 | ||||||
|  | #}) | ||||||
|  |  | ||||||
|  | repeats-around-chords = | ||||||
|  | #(define-music-function (parser location chords) (ly:music?) | ||||||
|  | #{ | ||||||
|  |   \once \set noChordSymbol = \markup { \normal-text \repStart } | ||||||
|  |   r4 | ||||||
|  | 	$chords | ||||||
|  |   \once \set noChordSymbol = \markup { \normal-text \repStop } | ||||||
|  |   r4 | ||||||
|  | #}) | ||||||
|  |  | ||||||
|  | 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 | ||||||
|  | #}) | ||||||
|  |  | ||||||
|  | shiftChords = #(define-music-function (parser location xshift chords) (number? ly:music?) | ||||||
|  | #{ | ||||||
|  | 	\override ChordName.extra-offset = #`(,xshift . 0) | ||||||
|  | 	$chords | ||||||
|  | #}) | ||||||
|  |  | ||||||
|  | altChord = | ||||||
|  | #(define-music-function (parser location mainchord altchord) (ly:music? ly:music?) | ||||||
|  |   (let* ((remove-point-and-click | ||||||
|  |            (lambda (grob) | ||||||
|  |              (ly:grob-set-property! grob 'cause #f) | ||||||
|  |              (ly:text-interface::print grob))) | ||||||
|  |          (chord-name (lambda (in-pitches bass inversion context) #{ | ||||||
|  |            \markup { | ||||||
|  |              \translate #'(-0.5 . 0) | ||||||
|  |              \score { | ||||||
|  |                \chords { \transposable #(cons (car (music-pitches mainchord)) (car in-pitches)) { #(music-clone mainchord) \klamm #(music-clone altchord) } } | ||||||
|  |                \layout { | ||||||
|  |                  \LAYOUT | ||||||
|  |                  \context { | ||||||
|  |                    \ChordNames | ||||||
|  |                    \override ChordName.extra-spacing-width = #'(0 . 0.3) | ||||||
|  |                    \override ChordName.stencil = #remove-point-and-click | ||||||
|  |                  } | ||||||
|  |                  \context { | ||||||
|  |                    \Score | ||||||
|  |                    \override SpacingSpanner.spacing-increment = 0 | ||||||
|  |                  } | ||||||
|  |                } | ||||||
|  |              } | ||||||
|  |            }#}))) | ||||||
|  |     #{ | ||||||
|  |       \once \set chordNameFunction = #chord-name | ||||||
|  |       #mainchord | ||||||
|  |     #})) | ||||||
|  |  | ||||||
|  | % Akkorde werden so transponiert, dass sie passen, wenn man mit Kapo im angegebenen Bund spielt | ||||||
|  | capoTranspose = | ||||||
|  | #(define-music-function (fret chords) (number? ly:music?) | ||||||
|  |   (define semi->pitch | ||||||
|  |     (make-semitone->pitch | ||||||
|  |       (music-pitches | ||||||
|  |         #{ h b a gis g fis f e es d cis c #}))) | ||||||
|  |   (transpose | ||||||
|  |     (ly:pitch-transpose (semi->pitch fret) (ly:make-pitch 0 0)) | ||||||
|  |     (ly:make-pitch 0 0) | ||||||
|  |     chords)) | ||||||
|  |  | ||||||
|  | % kleine Mollakkorde und Alteration ausgeschrieben | ||||||
|  | #(define (note-name->german-markup-nosym pitch lowercase?) | ||||||
|  |    (define (pitch-alteration-semitones pitch) (inexact->exact (round (* (ly:pitch-alteration pitch) 2)))) | ||||||
|  |    (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)) | ||||||
|  |  | ||||||
|  | defaultChordPrintings = { | ||||||
|  |   <c g>-\markup { \super "5" } | ||||||
|  |   %% Dur | ||||||
|  |   <c e g a>-\markup { \super "6" } %Standardverhalten | ||||||
|  |   <c e a >-\markup { \super "6(no5)" } | ||||||
|  |   <c e g a d'>-\markup { \super "6/9" } | ||||||
|  |   <c e g b d'>-\markup { \super "9" } %Standardverhalten | ||||||
|  |   <c e g b d' f'>-\markup { \super "11" } %Standardverhalten | ||||||
|  |   <c e g b d' a'>-\markup { \super "13" } | ||||||
|  |   %add chords | ||||||
|  |   <c e g d'>-\markup { \super "add9" } | ||||||
|  |   <c e g f'>-\markup { \super "add11" } | ||||||
|  |   <c e g a'>-\markup { \super "add13" } | ||||||
|  |   %major chords | ||||||
|  |   <c e g h d'>-\markup { \super "maj9" } | ||||||
|  |   %% Moll | ||||||
|  |   <c es g a>-\markup { \super "6" } %Standardverhalten | ||||||
|  |   <c es a >-\markup { \super "6(no5)" } | ||||||
|  |   <c es g a d'>-\markup { \super "6/9" } | ||||||
|  |   <c es g b d'>-\markup { \super "9" } %Standardverhalten | ||||||
|  |   <c es g b d' f'>-\markup { \super "11" } %Standardverhalten | ||||||
|  |   <c es g b d' a'>-\markup { \super "13" } | ||||||
|  |   %add chords | ||||||
|  |   <c es g d'>-\markup { \super "add9" } | ||||||
|  |   <c es g f'>-\markup { \super "add11" } | ||||||
|  |   <c es g a'>-\markup { \super "add13" } | ||||||
|  |   %major chords | ||||||
|  |   <c es g h d'>-\markup { \super "maj9" } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #(define chordNameExceptions | ||||||
|  |   (append | ||||||
|  |     (if (defined? 'customChordPrintings) | ||||||
|  |       (sequential-music-to-chord-exceptions customChordPrintings #t) | ||||||
|  |       '()) | ||||||
|  |     (sequential-music-to-chord-exceptions defaultChordPrintings #t))) | ||||||
|  |  | ||||||
|  | generalLayout = \layout { | ||||||
|  |   \generalLayout | ||||||
|  |   \context { | ||||||
|  |     \ChordNames | ||||||
|  |     \semiGermanChords | ||||||
|  |     \override ChordName.font-size = \songScoreChordFontSize | ||||||
|  |     \override ChordName.font-series = \songChordFontSeries | ||||||
|  |     \override ChordName.font-family = #'serif | ||||||
|  |     chordNameLowercaseMinor = ##t | ||||||
|  |     chordChanges = ##t | ||||||
|  |     % eigenen chordRootNamer damit F# = Fis und Gb = Ges (also alteration ausgeschrieben) | ||||||
|  |     chordRootNamer = #note-name->german-markup-nosym | ||||||
|  |     chordNoteNamer = #bassnote-name->german-markup-nosym | ||||||
|  |     majorSevenSymbol = "maj7" | ||||||
|  |     chordNameExceptions = \chordNameExceptions | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | % 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 { | ||||||
|  |               #(ly:parser-include-string (string-append "\\chordmode { s4 " chord " }")) | ||||||
|  |             } \layout { \generalLayout } } | ||||||
|  |             \override #'(fret-diagram-details . ((barre-type . straight))) { | ||||||
|  |               \fret-diagram-terse #fret | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |      #})) | ||||||
|  |  | ||||||
|  | % If you add this engraver to ChordNames Context chords get only printed on chordchanges and if its the first chord after line break. | ||||||
|  | Ensure_first_chord_after_line_break_printed_engraver = | ||||||
|  |   #(lambda (ctx) | ||||||
|  |      (define last-system-column-rank 0) | ||||||
|  |      (make-engraver | ||||||
|  |       (acknowledgers | ||||||
|  |        ((chord-name-interface this-engraver grob source-engraver) | ||||||
|  |           (ly:grob-set-property! grob 'after-line-breaking | ||||||
|  |             (lambda (grob) | ||||||
|  |               (let ((current-system-column-rank (car (ly:grob-spanned-column-rank-interval (ly:grob-system grob))))) | ||||||
|  |                 (if (and | ||||||
|  |                        (ly:context-property ctx 'chordChanges #f) | ||||||
|  |                        (ly:grob-property grob 'begin-of-line-visible #f) | ||||||
|  |                        (not (= last-system-column-rank current-system-column-rank))) | ||||||
|  |                   ; the current chord handling implementation in lilypond uses 'begin-of-line-visible to mark repeated chords | ||||||
|  |                   (ly:grob-set-property! grob 'begin-of-line-visible #f)) | ||||||
|  |                 (set! last-system-column-rank current-system-column-rank) | ||||||
|  |                 (ly:chord-name::after-line-breaking grob) | ||||||
|  |                 ))))))) | ||||||
|  |  | ||||||
|  | % If you add this engraver to ChordNames Context chords get only printed on chordchanges and not at newline. | ||||||
|  | Ignoring_newline_chord_changes_engraver = | ||||||
|  |   #(lambda (ctx) | ||||||
|  |      (make-engraver | ||||||
|  |       (acknowledgers | ||||||
|  |        ((chord-name-interface this-engraver grob source-engraver) | ||||||
|  |          (when (and (ly:context-property ctx 'chordChanges #f) (ly:grob-property grob 'begin-of-line-visible #f)) | ||||||
|  |                   (ly:grob-suicide! grob) | ||||||
|  |                 ))))) | ||||||
							
								
								
									
										135
									
								
								private_includes/base/custom_indentation.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								private_includes/base/custom_indentation.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,135 @@ | |||||||
|  | % https://lsr.di.unimi.it/LSR/Snippet?id=1098 | ||||||
|  | %%%%%%%% HEADER %%%%%%%% | ||||||
|  | % | ||||||
|  | % this code was prompted by | ||||||
|  | % https://lists.gnu.org/archive/html/lilypond-user/2019-07/msg00139.html | ||||||
|  | % and offers a pseudoIndent hack suitable for general use | ||||||
|  |  | ||||||
|  | % keywords: | ||||||
|  | % indent short-indent indentation system line | ||||||
|  | % mid-score temporarily arbitrary individual single just only once | ||||||
|  | % coda margin | ||||||
|  | % mouse's tale acrostic mesostic spine | ||||||
|  |  | ||||||
|  | %%%%%%%% PSEUDOINDENT FUNCTIONS %%%%%%%% | ||||||
|  |  | ||||||
|  | % these two functions are for indenting individual systems | ||||||
|  | % - to left-indent a system, apply \pseudoIndent before the music continues | ||||||
|  | % - \pseudoIndents is similar, but lets you also indent on the right | ||||||
|  | % - both provide an option for changing that system's instrument names | ||||||
|  |  | ||||||
|  | % N.B. these functions | ||||||
|  | % - assume application to non-ragged lines (generally the default) | ||||||
|  | % - include a manual \break to ensure application at line start | ||||||
|  | % - misbehave if called more than once at the same line start | ||||||
|  |  | ||||||
|  | % the parameters of the (full) pseudoIndents function are: | ||||||
|  | % 1: name-tweaks | ||||||
|  | %      usually omitted; accepts replacement \markup for instrument names | ||||||
|  | %      as an ordered list; starred elements leave their i-names unchanged. | ||||||
|  | % 2: left-indent | ||||||
|  | %      additional left-indentation, in staff-space units; can be negative, | ||||||
|  | %      but avoid a total indentation which implies (unsupported) stretching. | ||||||
|  | % 3: right-indent | ||||||
|  | %      amount of right-indentation, in staff-space units; can be negative. | ||||||
|  | %      - not offered by the (reduced) pseudoIndent function | ||||||
|  |  | ||||||
|  |  | ||||||
|  | pseudoIndents = % inline alternative to a new \score, also with right-indent | ||||||
|  | #(define-music-function (name-tweaks left-indent right-indent) | ||||||
|  |   ((markup-list? '()) number? number?) | ||||||
|  |   (define (warn-stretched p1 p2) (ly:input-warning (*location*) (G_ | ||||||
|  |     " pseudoIndents ~s ~s is stretching staff; expect distorted layout") p1 p2)) | ||||||
|  |   (let* ( | ||||||
|  |     (narrowing (+ left-indent right-indent)) ; of staff implied by args | ||||||
|  |  | ||||||
|  |     (set-staffsymbol! (lambda (staffsymbol-grob) ; change staff to new width | ||||||
|  |       (let* ( | ||||||
|  |         (left-bound (ly:spanner-bound staffsymbol-grob LEFT)) | ||||||
|  |         (left-moment (ly:grob-property left-bound 'when)) | ||||||
|  |         (capo? (moment<=? left-moment ZERO-MOMENT)) ; in first system of score | ||||||
|  |         (layout (ly:grob-layout staffsymbol-grob)) | ||||||
|  |         (lw (ly:output-def-lookup layout 'line-width)) ; debugging info | ||||||
|  |         (indent (ly:output-def-lookup layout (if capo? 'indent 'short-indent))) | ||||||
|  |         (old-stil (ly:staff-symbol::print staffsymbol-grob)) | ||||||
|  |         (staffsymbol-x-ext (ly:stencil-extent old-stil X)) | ||||||
|  |         ;; >=2.19.16's first system has old-stil already narrowed [2] | ||||||
|  |         ;; compensate for this (ie being not pristine) when calculating | ||||||
|  |         ;; - old leftmost-x (its value is needed when setting so-called 'width) | ||||||
|  |         ;; - the new width and position (via local variable narrowing_) | ||||||
|  |         (ss-t (ly:staff-symbol-line-thickness staffsymbol-grob)) | ||||||
|  |         (pristine? (<= 0 (car staffsymbol-x-ext) ss-t)) ; would expect half | ||||||
|  |         (leftmost-x (+ indent (if pristine? 0 narrowing))) | ||||||
|  |         (narrowing_ (if pristine? narrowing 0)) ; uses 0 if already narrowed | ||||||
|  |         (old-width (+ (interval-length staffsymbol-x-ext) ss-t)) | ||||||
|  |         (new-width (- old-width narrowing_)) | ||||||
|  |         (new-rightmost-x (+ leftmost-x new-width)) ; and set! this immediately | ||||||
|  |         (junk (ly:grob-set-property! staffsymbol-grob 'width new-rightmost-x)) | ||||||
|  |         (in-situ-stil (ly:staff-symbol::print staffsymbol-grob)) | ||||||
|  |         (new-stil (ly:stencil-translate-axis in-situ-stil narrowing_ X)) | ||||||
|  |        ;(new-stil (stencil-with-color new-stil red)) ; for when debugging | ||||||
|  |         (new-x-ext (ly:stencil-extent new-stil X))) | ||||||
|  |       (ly:grob-set-property! staffsymbol-grob 'stencil new-stil) | ||||||
|  |       (ly:grob-set-property! staffsymbol-grob 'X-extent new-x-ext) | ||||||
|  |       ))) | ||||||
|  |  | ||||||
|  |     (set-X-offset! (lambda (margin-grob) ; move grob across to line start | ||||||
|  |       (let* ( | ||||||
|  |         (old (ly:grob-property-data margin-grob 'X-offset)) | ||||||
|  |         (new (lambda (grob) (+ (if (procedure? old) (old grob) old) narrowing)))) | ||||||
|  |       (ly:grob-set-property! margin-grob 'X-offset new)))) | ||||||
|  |  | ||||||
|  |     (tweak-text! (lambda (i-name-grob mkup) ; tweak both instrumentname texts | ||||||
|  |       (if (and (markup? mkup) (not (string=? (markup->string mkup) "*"))) | ||||||
|  |       (begin | ||||||
|  |         (ly:grob-set-property! i-name-grob 'long-text mkup) | ||||||
|  |         (ly:grob-set-property! i-name-grob 'text mkup) | ||||||
|  |         )))) ; else retain existing text | ||||||
|  |  | ||||||
|  |     (install-narrowing (lambda (leftedge-grob) ; on staves, + adapt left margin | ||||||
|  |       (let* ( | ||||||
|  |         (sys (ly:grob-system leftedge-grob)) | ||||||
|  |         (all-grobs (ly:grob-array->list (ly:grob-object sys 'all-elements))) | ||||||
|  |         (grobs-named (lambda (name) | ||||||
|  |           (filter (lambda (x) (eq? name (grob::name x))) all-grobs))) | ||||||
|  |         (first-leftedge-grob (list-ref (grobs-named 'LeftEdge) 0)) | ||||||
|  |         (relsys-x-of (lambda (g) (ly:grob-relative-coordinate g sys X))) | ||||||
|  |         (leftedge-x (relsys-x-of first-leftedge-grob)) | ||||||
|  |         (leftedged? (lambda (g) (= (relsys-x-of g) leftedge-x))) | ||||||
|  |         (leftedged-ss (filter leftedged? (grobs-named 'StaffSymbol)))) | ||||||
|  |       (if (eq? leftedge-grob first-leftedge-grob) ; ignore other leftedges [1] | ||||||
|  |        (begin | ||||||
|  |          (for-each set-staffsymbol! leftedged-ss) | ||||||
|  |          (for-each set-X-offset! (grobs-named 'SystemStartBar)) | ||||||
|  |          (for-each set-X-offset! (grobs-named 'InstrumentName)) | ||||||
|  |          (for-each tweak-text! (grobs-named 'InstrumentName) name-tweaks) | ||||||
|  |        )))))) | ||||||
|  |  | ||||||
|  |   (if (negative? narrowing) (warn-stretched left-indent right-indent)) | ||||||
|  |   #{ % and continue anyway | ||||||
|  |     % ensure that these overrides are applied only at begin-of-line | ||||||
|  |     \break % (but this does not exclude unsupported multiple application) | ||||||
|  |     % give the spacing engine notice regarding the loss of width for music | ||||||
|  |     \once \override Score.LeftEdge.X-extent = #(cons narrowing narrowing) | ||||||
|  |     % discard line start region of staff and reassemble left-margin elements | ||||||
|  |     \once \override Score.LeftEdge.after-line-breaking = #install-narrowing | ||||||
|  |     % shift the system to partition the narrowing between left and right | ||||||
|  |     \overrideProperty Score.NonMusicalPaperColumn.line-break-system-details | ||||||
|  |     .X-offset #(- right-indent) | ||||||
|  |     % prevent a leftmost barnumber entering a stretched staff | ||||||
|  |     \once \override Score.BarNumber.horizon-padding = #(max 1 (- 1 narrowing)) | ||||||
|  |   #})) | ||||||
|  |  | ||||||
|  | pseudoIndent = % for changing just left-indent | ||||||
|  | #(define-music-function (name-tweaks left-indent) | ||||||
|  |   ((markup-list? '()) number?) | ||||||
|  |   #{ | ||||||
|  |     \pseudoIndents $name-tweaks $left-indent 0 | ||||||
|  |   #}) | ||||||
|  |  | ||||||
|  | % [1] versions <2.19.1 can have end-of-line leftedges too | ||||||
|  | %     - these were eliminated in issue 3761 | ||||||
|  | % [2] versions >=2.19.16: the first system behaves differently from the rest | ||||||
|  | %     - a side effect of issue 660 ? | ||||||
|  | % [3] versions >=2.23.0: LeftEdge's position may well differ in Y (but not in X) | ||||||
|  | %     - a side effect of issue 6084 ? | ||||||
							
								
								
									
										78
									
								
								private_includes/base/default_songinfo_style.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								private_includes/base/default_songinfo_style.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | |||||||
|  | \paper { | ||||||
|  |   poetPrefix = "Worte:" | ||||||
|  |   composerPrefix = "Weise:" | ||||||
|  |   compositionPrefix = "Satz:" | ||||||
|  |   adaptionTextPrefix = "Bearbeitung Text:" | ||||||
|  |   adaptionMusicPrefix = "Bearbeitung Musik:" | ||||||
|  |   poetAndComposerEqualPrefix = "Worte und Weise:" | ||||||
|  |   voicePrefix = "Stimme:" | ||||||
|  |   versePrefix = "Strophe:" | ||||||
|  |   translationAuthorPrefix = "Übersetzung:" | ||||||
|  |   translationPrefix = "Übersetzung:" | ||||||
|  |   pronunciationPrefix = "Aussprache:" | ||||||
|  |   interludePrefix = "Zwischenspiel:" | ||||||
|  |   bridgePrefix = "Bridge:" | ||||||
|  |  | ||||||
|  |   authorFormat = | ||||||
|  |     #(lambda (noDetails name trail_name birth_year death_year organization) | ||||||
|  |         (let ((string-present (lambda (str) (and str (not (and (string? str) (string-null? str)))))) | ||||||
|  |               (render_informations (lambda (infolist) (string-append (car infolist) (if (or noDetails (null? (cdr infolist))) "" (string-append " (" (string-join (cdr infolist) ", ") ")")))))) | ||||||
|  |             (if (or (string-present trail_name) (string-present name)) | ||||||
|  |               (render_informations (filter string-present (list | ||||||
|  |                 trail_name | ||||||
|  |                 name | ||||||
|  |                 (if (and (string-present birth_year) (string-present death_year)) | ||||||
|  |                   (ly:format "~a‒~a" birth_year death_year) | ||||||
|  |                   (if (string-present birth_year) | ||||||
|  |                     (ly:format "*~a" birth_year) | ||||||
|  |                     (if (string-present death_year) (ly:format "†~a" death_year) ""))) | ||||||
|  |                 organization | ||||||
|  |               ))) | ||||||
|  |               "" | ||||||
|  |           ))) | ||||||
|  |  | ||||||
|  |   songinfoMarkup = | ||||||
|  |     #(make-on-the-fly-markup | ||||||
|  |       (lambda (layout props m) | ||||||
|  |         (let* ((between-poet-and-composer-markup (chain-assoc-get 'header:between-poet-and-composer-markup props (make-hspace-markup 3))) | ||||||
|  |               (poet-maybe-with-composer (chain-assoc-get 'songinfo:poet-maybe-with-composer props #f)) | ||||||
|  |               (composer (chain-assoc-get 'songinfo:composer props #f)) | ||||||
|  |               (copyright (chain-assoc-get 'songinfo:copyright props #f)) | ||||||
|  |               (infotext (chain-assoc-get 'songinfo:infotext props #f)) | ||||||
|  |               (translation (chain-assoc-get 'songinfo:translation props #f)) | ||||||
|  |               (pronunciation (chain-assoc-get 'songinfo:pronunciation props #f)) | ||||||
|  |               (year_text (chain-assoc-get 'songinfo:year_text props #f)) | ||||||
|  |               (year_melody (chain-assoc-get 'songinfo:year_melody props #f)) | ||||||
|  |               (poet-with-year (if (and poet-maybe-with-composer year_text) (string-append poet-maybe-with-composer ", " year_text) poet-maybe-with-composer)) | ||||||
|  |               (composer-with-year (if (and composer year_melody) (string-append composer ", " year_melody) composer)) | ||||||
|  |               (string-with-paragraphs->markuplist (lambda (prefix text) | ||||||
|  |                 (if text | ||||||
|  |                   (apply append | ||||||
|  |                     (map | ||||||
|  |                       (lambda (paragraph) | ||||||
|  |                         (make-wordwrap-internal-markup-list #t | ||||||
|  |                           #{ \markuplist { $(ly:parser-include-string paragraph) } #})) | ||||||
|  |                       (ly:regex-split (ly:make-regex "\n[ \t\n]*\n[ \t\n]*") (string-append prefix text)))) | ||||||
|  |                   '()))) | ||||||
|  |               (poet-and-composer-markup-list | ||||||
|  |                 (string-with-paragraphs->markuplist "" (string-append | ||||||
|  |                   (if poet-with-year (string-append "\n\n" poet-with-year) "") | ||||||
|  |                   (if composer-with-year (string-append "\n\n" composer-with-year) "") | ||||||
|  |                 ))) | ||||||
|  |               (poet-and-composer-oneliner (if (and poet-with-year composer-with-year) (make-line-markup (cons (cadr poet-and-composer-markup-list) (cons between-poet-and-composer-markup (cddr poet-and-composer-markup-list)))) #f)) | ||||||
|  |               (current-line-width (chain-assoc-get 'line-width props (ly:output-def-lookup layout 'line-width)))) | ||||||
|  |           (stack-lines DOWN 0.0 (chain-assoc-get 'baseline-skip props) | ||||||
|  |             (interpret-markup-list layout props | ||||||
|  |               (append | ||||||
|  |                 (if (and poet-and-composer-oneliner (< (interval-length (ly:stencil-extent (interpret-markup layout props poet-and-composer-oneliner) X)) current-line-width)) | ||||||
|  |                   (list poet-and-composer-oneliner) | ||||||
|  |                   poet-and-composer-markup-list) | ||||||
|  |                 (string-with-paragraphs->markuplist "" (string-append | ||||||
|  |                   (if copyright (string-append "\n\n© " copyright) ""))) | ||||||
|  |                 (string-with-paragraphs->markuplist "" infotext) | ||||||
|  |                 (string-with-paragraphs->markuplist (string-append (ly:output-def-lookup layout 'translationPrefix) " ") translation) | ||||||
|  |                 (string-with-paragraphs->markuplist (string-append (ly:output-def-lookup layout 'pronunciationPrefix) " ") pronunciation) | ||||||
|  |                   ))))) | ||||||
|  |       (make-null-markup) | ||||||
|  |     ) | ||||||
|  | } | ||||||
							
								
								
									
										35
									
								
								private_includes/base/default_style.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								private_includes/base/default_style.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | songFormatAndSize = "a5" | ||||||
|  | songMargin = 5 | ||||||
|  | songInfoFontSize = 0 | ||||||
|  | songInfoLineWidthFraction = 0.9 | ||||||
|  | songTitleSize = 6 | ||||||
|  | songTitleFont = "Liberation Sans" | ||||||
|  | songChordFont = "Liberation Sans" | ||||||
|  | songLyricFont = "Liberation Sans" | ||||||
|  | songChordFontSeries = #'bold | ||||||
|  | songTextChordAlignment = #'left | ||||||
|  | songScoreChordFontSize = 2 | ||||||
|  | songTextChordFontSize = \songScoreChordFontSize | ||||||
|  | songTextChordDistance = 2.8 | ||||||
|  | songTextLineHeigth = 5.8 | ||||||
|  | songTocColumns = 3 | ||||||
|  | globalSize = 15 | ||||||
|  | lyricSize = 1.6 | ||||||
|  | stanzaFormat = "~a." | ||||||
|  | romanStanzaFormat = "~@r." | ||||||
|  | refString = "Ref.:" | ||||||
|  | refStringWithNumbers = "Ref. ~a:" | ||||||
|  | % hübsche Wiederholungszeichen für den Liedtext | ||||||
|  | repStart = "𝄆" | ||||||
|  | repStop = "𝄇" | ||||||
|  | customChordPrintings = {} | ||||||
|  |  | ||||||
|  | \paper { | ||||||
|  |   cueMarkup = \markup { | ||||||
|  |     \italic | ||||||
|  |       #(make-on-the-fly-markup (lambda (layout props m) | ||||||
|  |         (interpret-markup layout props | ||||||
|  |           (string-join (map (lambda (n) (format #f "~@r." n)) (chain-assoc-get 'cues props)) ", "))) | ||||||
|  |         (make-null-markup)) | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -4,15 +4,15 @@ | |||||||
|   (interpret-markup-list layout (prepend-alist-chain 'songfilename songfilename props) markuplist)) |   (interpret-markup-list layout (prepend-alist-chain 'songfilename songfilename props) markuplist)) | ||||||
| 
 | 
 | ||||||
| #(define-markup-command (customEps layout props ysize filename)(number? string?) | #(define-markup-command (customEps layout props ysize filename)(number? string?) | ||||||
|    #:properties ((songfilename "") |    #:properties ((songfilename "")) | ||||||
|                  (defaultmarkup #f)) |  | ||||||
|    (interpret-markup layout props |    (interpret-markup layout props | ||||||
|      (let ((filepath (if (string-null? songfilename) |      (let ((defaulttitlemarkup (ly:output-def-lookup layout 'defaultTitleMarkup)) | ||||||
|  |            (filepath (if (string-null? songfilename) | ||||||
|                           filename |                           filename | ||||||
|                           (ly:format "~a/~a/~a" songPath songfilename filename)))) |                           (ly:format "~a/~a/~a" songPath songfilename filename)))) | ||||||
|        (if (file-exists? filepath) |        (if (file-exists? filepath) | ||||||
|              (make-epsfile-markup Y ysize filepath) |              (make-epsfile-markup Y ysize filepath) | ||||||
|              (if defaultmarkup |              (if defaulttitlemarkup | ||||||
|                  defaultmarkup |                  defaulttitlemarkup | ||||||
|                  (ly:format "file does not exist ~a" filepath)) |                  (ly:format "file does not exist ~a" filepath)) | ||||||
| )))) | )))) | ||||||
							
								
								
									
										273
									
								
								private_includes/base/footer_with_songinfo.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										273
									
								
								private_includes/base/footer_with_songinfo.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,273 @@ | |||||||
|  | #(use-modules (ice-9 receive)) | ||||||
|  | #(define (format-author author-format-function authorId noDetails) | ||||||
|  |   (let ((author (if (defined? 'AUTHOR_DATA) (assoc-ref AUTHOR_DATA authorId) #f))) | ||||||
|  |     (if author | ||||||
|  |       (author-format-function | ||||||
|  |         noDetails | ||||||
|  |         (assoc-ref author "name") | ||||||
|  |         (assoc-ref author "trail_name") | ||||||
|  |         (assoc-ref author "birth_year") | ||||||
|  |         (assoc-ref author "death_year") | ||||||
|  |         (assoc-ref author "organization") | ||||||
|  |       ) | ||||||
|  |       (if (string-null? authorId) | ||||||
|  |           "unbekannt" | ||||||
|  |           authorId)))) | ||||||
|  |  | ||||||
|  | #(define (find-author-ids-by contributionType authors) | ||||||
|  |   (if authors | ||||||
|  |     (filter-map (lambda (authordata) (if (member contributionType (cdr authordata)) (car authordata) #f)) authors) | ||||||
|  |     (list))) | ||||||
|  |  | ||||||
|  | #(define (find-author-id-with-part-numbers contributionType authors) | ||||||
|  |   (if authors | ||||||
|  |     (sort-list | ||||||
|  |       (filter-map (lambda (authordata) | ||||||
|  |         (let ((contributionNumbers (filter-map (lambda (contribution) (if (and (list? contribution) (equal? contributionType (car contribution))) (cadr contribution) #f)) (cdr authordata))) | ||||||
|  |               (authorId (car authordata))) | ||||||
|  |           (if (null? contributionNumbers) #f (cons authorId (sort-list contributionNumbers <))) | ||||||
|  |         )) authors) | ||||||
|  |       (lambda (a b) (< (cadr a) (cadr b)))) | ||||||
|  |     (list))) | ||||||
|  |  | ||||||
|  | #(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* (default-author-format authorId #:optional (noDetails #f)) | ||||||
|  |     (format-author (ly:output-def-lookup layout 'authorFormat) authorId noDetails)) | ||||||
|  |  | ||||||
|  |   (define (format-poet poetId) | ||||||
|  |     (string-append (ly:output-def-lookup layout 'poetPrefix) " " (default-author-format poetId))) | ||||||
|  |  | ||||||
|  |   (define (format-composer composerId) | ||||||
|  |     (string-append (ly:output-def-lookup layout 'composerPrefix) " " (default-author-format composerId))) | ||||||
|  |  | ||||||
|  |   (define (format-poet-and-composer authorId) | ||||||
|  |     (string-append (ly:output-def-lookup layout 'poetAndComposerEqualPrefix) " " (default-author-format authorId))) | ||||||
|  |  | ||||||
|  |   (define (numbered-contribution-prefix contributionNumbers prefixLookup) | ||||||
|  |     (string-append | ||||||
|  |       (string-join (map (lambda (contributionNumber) (ly:format "~a." contributionNumber)) contributionNumbers) ", ") | ||||||
|  |       " " | ||||||
|  |       (ly:output-def-lookup layout prefixLookup) | ||||||
|  |     ) | ||||||
|  |   ) | ||||||
|  |  | ||||||
|  |   (define referencedAuthors '()) | ||||||
|  |  | ||||||
|  |   (define (format-authors authorIds) | ||||||
|  |     (map (lambda (authorId) | ||||||
|  |       (default-author-format | ||||||
|  |         authorId | ||||||
|  |         (if (member authorId referencedAuthors) | ||||||
|  |           #t | ||||||
|  |           (begin | ||||||
|  |             (set! referencedAuthors (cons authorId referencedAuthors)) | ||||||
|  |             #f))) | ||||||
|  |     ) authorIds) | ||||||
|  |   ) | ||||||
|  |  | ||||||
|  |   (define (render-contribution-group contributionPrefix authorIds) | ||||||
|  |     (if (null? authorIds) | ||||||
|  |       "" | ||||||
|  |       (string-append contributionPrefix " " (string-join (format-authors authorIds) ", "))) | ||||||
|  |   ) | ||||||
|  |  | ||||||
|  |   (define (join-present items joiner) | ||||||
|  |     (string-join (filter (lambda (item) (and (string? item) (not (string-null? (string-trim-both item))))) items) joiner) | ||||||
|  |   ) | ||||||
|  |  | ||||||
|  |   (define (render-partial-contribution-group prefixLookup authorData) | ||||||
|  |     (if (null? authorData) | ||||||
|  |       "" | ||||||
|  |       (let ((firstAuthorContributions (cdar authorData))) | ||||||
|  |         (receive (authorDataSame authorDataOther) | ||||||
|  |             (partition (lambda (authorEntry) (equal? (cdr authorEntry) firstAuthorContributions)) authorData) | ||||||
|  |           (join-present (list | ||||||
|  |             (render-contribution-group (numbered-contribution-prefix firstAuthorContributions prefixLookup) (map car authorDataSame)) | ||||||
|  |             (render-partial-contribution-group prefixLookup authorDataOther) | ||||||
|  |             ) " "))))) | ||||||
|  |  | ||||||
|  |   (define (poet-and-composer-from-authors authors) | ||||||
|  |     (if authors | ||||||
|  |       (let ( | ||||||
|  |             (poetIds (find-author-ids-by 'text authors)) | ||||||
|  |             (translatorIds (find-author-ids-by 'translation authors)) | ||||||
|  |             (versePoetData (find-author-id-with-part-numbers 'verse authors)) | ||||||
|  |             (composerIds (find-author-ids-by 'melody authors)) | ||||||
|  |             (verseComposerData (find-author-id-with-part-numbers 'meloverse authors)) | ||||||
|  |             (voiceComposerData (find-author-id-with-part-numbers 'voice authors)) | ||||||
|  |             (compositionIds (find-author-ids-by 'composition authors)) | ||||||
|  |             (adaptionTextIds (find-author-ids-by 'adaption_text authors)) | ||||||
|  |             (adaptionMusicIds (find-author-ids-by 'adaption_music authors)) | ||||||
|  |             (bridgeIds (find-author-ids-by 'bridge authors)) | ||||||
|  |             (interludeIds (find-author-ids-by 'interlude authors)) | ||||||
|  |             (year_text (chain-assoc-get 'header:year_text props #f)) | ||||||
|  |             (year_translation (chain-assoc-get 'header:year_translation props #f)) | ||||||
|  |             (year_melody (chain-assoc-get 'header:year_melody props #f)) | ||||||
|  |             (year_composition (chain-assoc-get 'header:year_composition props #f)) | ||||||
|  |             (year_adaption_text (chain-assoc-get 'header:year_adaption_text props #f)) | ||||||
|  |             (year_adaption_music (chain-assoc-get 'header:year_adaption_music props #f)) | ||||||
|  |             ) | ||||||
|  |         (if (and | ||||||
|  |               (equal? poetIds composerIds) | ||||||
|  |               (null? translatorIds) | ||||||
|  |               (null? versePoetData) | ||||||
|  |               (null? verseComposerData) | ||||||
|  |               (null? voiceComposerData) | ||||||
|  |               (null? compositionIds) | ||||||
|  |               (null? adaptionTextIds) | ||||||
|  |               (null? adaptionMusicIds) | ||||||
|  |               (null? bridgeIds) | ||||||
|  |               (null? interludeIds)) | ||||||
|  |           (list | ||||||
|  |             (join-present (list | ||||||
|  |               (render-contribution-group (ly:output-def-lookup layout 'poetAndComposerEqualPrefix) poetIds) | ||||||
|  |               (if (equal? year_text year_melody) year_text (join-present (list year_text year_melody) "/")) | ||||||
|  |             ) ", ") | ||||||
|  |             #f) | ||||||
|  |           (list | ||||||
|  |             (if (and (null? poetIds) (null? versePoetData) (null? translatorIds)) #f | ||||||
|  |               (string-append | ||||||
|  |                 (ly:output-def-lookup layout 'poetPrefix) | ||||||
|  |                 " " | ||||||
|  |                 (join-present (list | ||||||
|  |                   (join-present (list | ||||||
|  |                     (render-contribution-group "" poetIds) | ||||||
|  |                     year_text | ||||||
|  |                   ) ", ") | ||||||
|  |                   (render-partial-contribution-group 'versePrefix versePoetData) | ||||||
|  |                   (join-present (list | ||||||
|  |                     (render-contribution-group (ly:output-def-lookup layout 'translationAuthorPrefix) translatorIds) | ||||||
|  |                     year_translation | ||||||
|  |                   ) ", ") | ||||||
|  |                   (join-present (list | ||||||
|  |                     (render-contribution-group (ly:output-def-lookup layout 'adaptionTextPrefix) adaptionTextIds) | ||||||
|  |                     year_adaption_text | ||||||
|  |                   ) ", ") | ||||||
|  |                 ) "; ") | ||||||
|  |               )) | ||||||
|  |             (if (and | ||||||
|  |                   (null? composerIds) | ||||||
|  |                   (null? compositionIds) | ||||||
|  |                   (null? adaptionMusicIds) | ||||||
|  |                   (null? verseComposerData) | ||||||
|  |                   (null? voiceComposerData) | ||||||
|  |                   (null? bridgeIds) | ||||||
|  |                   (null? interludeIds)) #f | ||||||
|  |               (string-append | ||||||
|  |                 (ly:output-def-lookup layout 'composerPrefix) | ||||||
|  |                 " " | ||||||
|  |                 (join-present (list | ||||||
|  |                   (join-present (list | ||||||
|  |                     (render-contribution-group "" composerIds) | ||||||
|  |                     year_melody | ||||||
|  |                   ) ", ") | ||||||
|  |                   (render-partial-contribution-group 'versePrefix verseComposerData) | ||||||
|  |                   (render-partial-contribution-group 'voicePrefix voiceComposerData) | ||||||
|  |                   (join-present (list | ||||||
|  |                     (render-contribution-group (ly:output-def-lookup layout 'compositionPrefix) compositionIds) | ||||||
|  |                     year_composition | ||||||
|  |                   ) ", ") | ||||||
|  |                   (join-present (list | ||||||
|  |                     (render-contribution-group (ly:output-def-lookup layout 'adaptionMusicPrefix) adaptionMusicIds) | ||||||
|  |                     year_adaption_music | ||||||
|  |                   ) ", ") | ||||||
|  |                   (render-contribution-group (ly:output-def-lookup layout 'bridgePrefix) bridgeIds) | ||||||
|  |                   (render-contribution-group (ly:output-def-lookup layout 'interludePrefix) interludeIds) | ||||||
|  |                 ) "; ") | ||||||
|  |               ))))) | ||||||
|  |       (list #f #f) | ||||||
|  |     ) | ||||||
|  |   ) | ||||||
|  |  | ||||||
|  |   (interpret-markup layout props | ||||||
|  |     (if (chain-assoc-get 'page:is-bookpart-last-page props #f) | ||||||
|  |     (let* ((authors (chain-assoc-get 'header:authors props #f)) | ||||||
|  |            (poet-and-composers (poet-and-composer-from-authors authors)) | ||||||
|  |            (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 ((infotext (chain-assoc-get 'header:infotext props (chain-assoc-get 'header:songinfo props #f))) | ||||||
|  |             (poet-maybe-with-composer (chain-assoc-get 'header:poet props (if poetId (if poet-and-composer-same (format-poet-and-composer poetId) (format-poet poetId)) (car poet-and-composers)))) | ||||||
|  |             (composer (chain-assoc-get 'header:composer props (if (and composerId (not poet-and-composer-same)) (format-composer composerId) (cadr poet-and-composers)))) | ||||||
|  |             (copyright (chain-assoc-get 'header:copyright props #f)) | ||||||
|  |             (translation (chain-assoc-get 'header:translation props #f)) | ||||||
|  |             (pronunciation (chain-assoc-get 'header:pronunciation props #f)) | ||||||
|  |             (year_text (if (string? (car poet-and-composers)) #f (chain-assoc-get 'header:year_text props #f))) | ||||||
|  |             (year_melody (if (string? (car poet-and-composers)) #f (chain-assoc-get 'header:year_melody props #f)))) | ||||||
|  |             (markup | ||||||
|  |               #:override (cons 'songinfo:poet-maybe-with-composer | ||||||
|  |                 (if (and poet-maybe-with-composer (not (and (string? poet-maybe-with-composer) (string-null? poet-maybe-with-composer)))) poet-maybe-with-composer #f)) | ||||||
|  |               #:override (cons 'songinfo:composer | ||||||
|  |                 (if (and composer (not (and (string? composer) (string-null? composer)))) composer #f)) | ||||||
|  |               #:override (cons 'songinfo:copyright | ||||||
|  |                 (if (and copyright (not (and (string? copyright) (string-null? copyright)))) copyright #f)) | ||||||
|  |               #:override (cons 'songinfo:infotext | ||||||
|  |                 (if (and infotext (not (and (string? infotext) (string-null? infotext)))) infotext #f)) | ||||||
|  |               #:override (cons 'songinfo:translation | ||||||
|  |                 (if (and translation (not (and (string? translation) (string-null? translation)))) translation #f)) | ||||||
|  |               #:override (cons 'songinfo:pronunciation | ||||||
|  |                 (if (and pronunciation (not (and (string? pronunciation) (string-null? pronunciation)))) pronunciation #f)) | ||||||
|  |               #:override (cons 'songinfo:year_text | ||||||
|  |                 (if (and year_text (not (and (string? year_text) (string-null? year_text)))) year_text #f)) | ||||||
|  |               #:override (cons 'songinfo:year_melody | ||||||
|  |                 (if (and year_melody (not (and (string? year_melody) (string-null? year_melody)))) year_melody #f)) | ||||||
|  |               #:override '(baseline-skip . 3.0) | ||||||
|  |               #:fontsize songInfoFontSize | ||||||
|  |               #:sans | ||||||
|  |               (ly:output-def-lookup layout 'songinfoMarkup) | ||||||
|  |             ))) | ||||||
|  |       (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) | ||||||
|  |         ) | ||||||
|  |    )))) | ||||||
|  |  | ||||||
|  | #(define-markup-command (fractional-line-width layout props arg)(markup?) | ||||||
|  |   (interpret-markup layout props | ||||||
|  |     (make-override-markup | ||||||
|  |       `(line-width . ,(* (chain-assoc-get 'header:songinfo-size-factor props songInfoLineWidthFraction) (ly:output-def-lookup layout 'line-width))) | ||||||
|  |       arg))) | ||||||
|  |  | ||||||
|  | #(define pdf-encode (@@ (lily framework-ps) pdf-encode)) | ||||||
|  | % PDF tags | ||||||
|  | #(define-markup-command (page-number-to-pdf-label layout props) () | ||||||
|  |      (ly:make-stencil | ||||||
|  |       (list 'embedded-ps | ||||||
|  |              (ly:format | ||||||
|  |               "[ /Label (~a) /PAGELABEL pdfmark\n" (pdf-encode (chain-assoc-get 'page:page-number-string props "?")))) | ||||||
|  |       empty-interval empty-interval | ||||||
|  |       )) | ||||||
|  |  | ||||||
|  | \paper { | ||||||
|  |   print-first-page-number = ##t | ||||||
|  |   first-page-number = #0 | ||||||
|  |  | ||||||
|  |   oddFooterMarkup = \markup { | ||||||
|  |     \fill-line { | ||||||
|  |       \line { \page-number-to-pdf-label \null } | ||||||
|  |       \line { \if \on-last-page-of-part \general-align #Y #DOWN \fractional-line-width \print-songinfo } | ||||||
|  |       \line { \if \should-print-page-number \print-pagenumber } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   evenFooterMarkup  = \markup { | ||||||
|  |     \fill-line { | ||||||
|  |       \line { \if \should-print-page-number \print-pagenumber } | ||||||
|  |       \line { \if \on-last-page-of-part \general-align #Y #DOWN \fractional-line-width \print-songinfo } | ||||||
|  |       \line { \page-number-to-pdf-label \null } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								private_includes/base/include_from_song.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								private_includes/base/include_from_song.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | includeFromSong = | ||||||
|  | #(define-void-function (filename) (string?) | ||||||
|  |   (let ((noDefaultOutputBackup noDefaultOutput)) | ||||||
|  |     (set! noDefaultOutput #t) | ||||||
|  |     (ly:parser-parse-string (ly:parser-clone) | ||||||
|  |       (ly:format "\\include \"~a\"" | ||||||
|  |       (string-append | ||||||
|  |         (dirname (dirname (dirname (dirname (current-filename))))) | ||||||
|  |         file-name-separator-string | ||||||
|  |         "lilypond-song-includes" | ||||||
|  |         file-name-separator-string | ||||||
|  |         "liedbausteine" | ||||||
|  |         file-name-separator-string | ||||||
|  |         filename))) | ||||||
|  |     (set! noDefaultOutput noDefaultOutputBackup))) | ||||||
							
								
								
									
										13
									
								
								private_includes/base/inline_score.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								private_includes/base/inline_score.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | INLINESCOREMUSIC = {} | ||||||
|  |  | ||||||
|  | inline-score = | ||||||
|  | #(define-music-function (music) (ly:music?) | ||||||
|  |    (set! INLINESCOREMUSIC #{ \INLINESCOREMUSIC #music #}) | ||||||
|  |     #{ | ||||||
|  |       \transposable #TRANSPOSITION #music | ||||||
|  |     #}) | ||||||
|  |  | ||||||
|  | fill-midi = | ||||||
|  | #(define-void-function (music) (ly:music?) | ||||||
|  |    (set! INLINESCOREMUSIC #{ \INLINESCOREMUSIC #music #}) | ||||||
|  | ) | ||||||
							
								
								
									
										86
									
								
								private_includes/base/merge_rests_engraver_override.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								private_includes/base/merge_rests_engraver_override.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | |||||||
|  | Better_Merge_rests_engraver = | ||||||
|  | #(lambda (context) | ||||||
|  |   (define (has-one-or-less? lst) (or (null? lst) (null? (cdr lst)))) | ||||||
|  |   (define (has-at-least-two? lst) (not (has-one-or-less? lst))) | ||||||
|  |   (define (all-equal? lst pred) | ||||||
|  |     (or (has-one-or-less? lst) | ||||||
|  |         (and (pred (car lst) (cadr lst)) (all-equal? (cdr lst) pred)))) | ||||||
|  |   (define (measure-count-eqv? a b) | ||||||
|  |     (eqv? | ||||||
|  |      (ly:grob-property a 'measure-count) | ||||||
|  |      (ly:grob-property b 'measure-count))) | ||||||
|  |  | ||||||
|  |   (define (rests-all-unpitched? rests) | ||||||
|  |     "Returns true when all rests do not override the staff-position grob | ||||||
|  |     property. When a rest has a position set we do not want to merge rests at | ||||||
|  |     that position." | ||||||
|  |     (every (lambda (rest) (null? (ly:grob-property rest 'staff-position))) rests)) | ||||||
|  |  | ||||||
|  |   (define (less-by-layer a b) | ||||||
|  |     (< | ||||||
|  |       (ly:grob-property b 'layer 0) | ||||||
|  |       (ly:grob-property a 'layer 0))) | ||||||
|  |  | ||||||
|  |   (define (merge-mmrests mmrests) | ||||||
|  |     "Move all multimeasure rests to the single voice location." | ||||||
|  |     (if (all-equal? mmrests measure-count-eqv?) | ||||||
|  |         (begin | ||||||
|  |           (for-each | ||||||
|  |            (lambda (rest) (ly:grob-set-property! rest 'direction CENTER)) | ||||||
|  |            mmrests) | ||||||
|  |           (for-each | ||||||
|  |            (lambda (rest) (ly:grob-set-property! rest 'transparent #t)) | ||||||
|  |            (cdr (sort mmrests less-by-layer)))))) | ||||||
|  |  | ||||||
|  |   (define (merge-rests rests) | ||||||
|  |     (for-each | ||||||
|  |      (lambda (rest) (ly:grob-set-property! rest 'staff-position 0)) | ||||||
|  |      rests) | ||||||
|  |     (for-each | ||||||
|  |      (lambda (rest) (ly:grob-set-property! rest 'transparent #t)) | ||||||
|  |      (cdr (sort rests less-by-layer)))) | ||||||
|  |  | ||||||
|  |   (let ((mmrests '()) | ||||||
|  |         (rests '()) | ||||||
|  |         (dots '())) | ||||||
|  |     (make-engraver | ||||||
|  |      ((start-translation-timestep translator) | ||||||
|  |       (set! rests '()) | ||||||
|  |       (set! mmrests '()) | ||||||
|  |       (set! dots '())) | ||||||
|  |      (acknowledgers | ||||||
|  |       ((dot-column-interface engraver grob source-engraver) | ||||||
|  |        (if (not (ly:context-property context 'suspendRestMerging #f)) | ||||||
|  |            (set! | ||||||
|  |             dots | ||||||
|  |             (append (ly:grob-array->list (ly:grob-object grob 'dots)) | ||||||
|  |                     dots)))) | ||||||
|  |       ((rest-interface engraver grob source-engraver) | ||||||
|  |        (cond | ||||||
|  |         ((ly:context-property context 'suspendRestMerging #f) | ||||||
|  |          #f) | ||||||
|  |         ((grob::has-interface grob 'multi-measure-rest-interface) | ||||||
|  |          (set! mmrests (cons grob mmrests))) | ||||||
|  |         (else | ||||||
|  |          (set! rests (cons grob rests)))))) | ||||||
|  |      ((stop-translation-timestep translator) | ||||||
|  |       (let (;; get a list of the rests 'duration-lengths, 'duration-log does | ||||||
|  |             ;; not take dots into account | ||||||
|  |             (durs | ||||||
|  |              (map | ||||||
|  |               (lambda (g) | ||||||
|  |                 (ly:duration->moment | ||||||
|  |                  (ly:prob-property | ||||||
|  |                   (ly:grob-property g 'cause) | ||||||
|  |                   'duration))) | ||||||
|  |               rests))) | ||||||
|  |         (if (and | ||||||
|  |              (has-at-least-two? rests) | ||||||
|  |              (all-equal? durs equal?) | ||||||
|  |              (rests-all-unpitched? rests)) | ||||||
|  |             (begin | ||||||
|  |               (merge-rests rests) | ||||||
|  |               ;; ly:grob-suicide! works nicely for dots, as opposed to rests. | ||||||
|  |               (if (pair? dots) (for-each ly:grob-suicide! (cdr dots))))) | ||||||
|  |         (if (has-at-least-two? mmrests) | ||||||
|  |             (merge-mmrests mmrests))))))) | ||||||
							
								
								
									
										22
									
								
								private_includes/base/scm/resolve_inherits.scm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								private_includes/base/scm/resolve_inherits.scm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | (define (resolve-inherit-entry-in-list alist entry) | ||||||
|  |   (let* ((key (car entry)) | ||||||
|  |         (attributes (cdr entry)) | ||||||
|  |         (inherits (assoc-ref attributes "inherits"))) | ||||||
|  |     (if inherits | ||||||
|  |       (let* ((alist-without-entry (alist-delete key alist)) | ||||||
|  |             (inherit-entry (assoc inherits alist-without-entry)) | ||||||
|  |             (inherits-attributes (if inherit-entry (alist-copy (cdr (resolve-inherit-entry-in-list alist-without-entry inherit-entry))))) | ||||||
|  |             (override-attributes (alist-delete "inherits" attributes))) | ||||||
|  |         (if inherit-entry | ||||||
|  |           (begin | ||||||
|  |             (for-each (lambda (attribute) (assoc-set! inherits-attributes (car attribute) (cdr attribute))) override-attributes) | ||||||
|  |             (cons key inherits-attributes) | ||||||
|  |           ) | ||||||
|  |           (ly:error "~a can not inherit from ~a" key inherits)) | ||||||
|  |       ) | ||||||
|  |       entry | ||||||
|  |     ))) | ||||||
|  |  | ||||||
|  | (define (resolve-inherits alist) | ||||||
|  |   (map (lambda (entry) (resolve-inherit-entry-in-list alist entry)) alist) | ||||||
|  | ) | ||||||
							
								
								
									
										154
									
								
								private_includes/base/scm/yaml_parser.scm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								private_includes/base/scm/yaml_parser.scm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,154 @@ | |||||||
|  | (use-modules (ice-9 rdelim) (ice-9 regex) (ice-9 pretty-print) (srfi srfi-1)) | ||||||
|  |  | ||||||
|  | ;; Hauptparsingfunktion | ||||||
|  | (define (yml-file->scm filename) | ||||||
|  |  | ||||||
|  |   ;; Utility: Zeile einlesen | ||||||
|  |   (define (read-lines filename) | ||||||
|  |     (call-with-input-file filename | ||||||
|  |       (lambda (port) | ||||||
|  |         (let loop ((lines '())) | ||||||
|  |           (let ((line (read-line port))) | ||||||
|  |             (if (eof-object? line) | ||||||
|  |                 (reverse lines) | ||||||
|  |                 (let ((clean (string-trim line))) | ||||||
|  |                   (if (or (string=? clean "---") (string-null? clean)) | ||||||
|  |                       (loop lines) ;; Ignoriere "---" oder leere Zeile | ||||||
|  |                       (loop (cons line lines)))))))))) | ||||||
|  |  | ||||||
|  |   ;; Einrückung bestimmen (Anzahl Leerzeichen am Anfang) | ||||||
|  |   (define (line-indent line) | ||||||
|  |     (let ((match (string-match "^ *" line))) | ||||||
|  |       (if match | ||||||
|  |           (match:end match)  ; Anzahl der Leerzeichen = Position nach Leerzeichen | ||||||
|  |           0)))               ; Falls kein Match → 0 | ||||||
|  |  | ||||||
|  |   ;; Kommentar entfernen | ||||||
|  |   (define (strip-comment line) | ||||||
|  |     (let ((m (string-match "#.*" line))) | ||||||
|  |       (if m | ||||||
|  |           (string-trim-right (string-take line (match:start m))) | ||||||
|  |           line))) | ||||||
|  |  | ||||||
|  |   ;; Hilfsfunktion: Whitespace entfernen | ||||||
|  |   (define (clean-line line) | ||||||
|  |     (string-trim (strip-comment line))) | ||||||
|  |  | ||||||
|  |   ;; Ist Zeile leer (nach Entfernen von Kommentar & Whitespace)? | ||||||
|  |   (define (blank-or-comment? line) | ||||||
|  |     (string-null? (clean-line line))) | ||||||
|  |  | ||||||
|  |   ;; Skalare Werte interpretieren | ||||||
|  |   (define (parse-scalar str) | ||||||
|  |     (define (strip-quotes s) | ||||||
|  |       (cond | ||||||
|  |        ((and (string-prefix? "\"" s) (string-suffix? "\"" s)) | ||||||
|  |         (string-drop-right (string-drop s 1) 1)) | ||||||
|  |        ((and (string-prefix? "'" s) (string-suffix? "'" s)) | ||||||
|  |         (string-drop-right (string-drop s 1) 1)) | ||||||
|  |        (else s))) | ||||||
|  |     (let ((s (strip-quotes (string-trim str)))) | ||||||
|  |       (cond | ||||||
|  |        ((string=? s "{}") '())  ;; leere Map | ||||||
|  |        ((string=? s "[]") '())  ;; leere Liste | ||||||
|  |        ((string-match "^[0-9]+$" s) (string->number s)) | ||||||
|  |        ((string=? s "true") #t) | ||||||
|  |        ((string=? s "false") #f) | ||||||
|  |        ((string=? s "null") '()) | ||||||
|  |        (else s)))) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   ;; Hilfsfunktion: Zeilen mit gleicher oder höherer Einrückung sammeln | ||||||
|  |   (define (take-indented lines min-indent) | ||||||
|  |     (let loop ((ls lines) (acc '())) | ||||||
|  |       (if (null? ls) | ||||||
|  |           (reverse acc) | ||||||
|  |           (let ((line (car ls))) | ||||||
|  |             (if (or (blank-or-comment? line) | ||||||
|  |                     (>= (line-indent line) min-indent)) | ||||||
|  |                 (loop (cdr ls) (cons line acc)) | ||||||
|  |                 (reverse acc)))))) | ||||||
|  |  | ||||||
|  |   ;; Hilfsfunktion: N Zeilen überspringen | ||||||
|  |   (define (drop lst n) | ||||||
|  |     (let loop ((l lst) (i n)) | ||||||
|  |       (if (or (zero? i) (null? l)) | ||||||
|  |           l | ||||||
|  |           (loop (cdr l) (- i 1))))) | ||||||
|  |  | ||||||
|  |   ;; Listenparsing: Liest Zeilen mit `-` als Listeneinträge | ||||||
|  |   (define (parse-list lines current-indent) | ||||||
|  |     (let loop ((ls lines) (result '())) | ||||||
|  |       (if (null? ls) | ||||||
|  |           (reverse result) | ||||||
|  |           (let* ((line (clean-line (car ls)))) | ||||||
|  |             (if (string-match "^-" line) | ||||||
|  |                 (let* ((indent (line-indent (car ls))) | ||||||
|  |                        (item-str (string-trim (string-drop line 1))) | ||||||
|  |                        (next-lines (cdr ls))) | ||||||
|  |                   (if (or (null? next-lines) | ||||||
|  |                           (> (line-indent (car next-lines)) indent)) | ||||||
|  |                       ;; Verschachtelter Inhalt | ||||||
|  |                       (let* ((sub (take-indented next-lines (+ indent 2))) | ||||||
|  |                              (parsed (if (null? sub) | ||||||
|  |                                          (parse-scalar item-str) | ||||||
|  |                                          (parse-lines sub (+ indent 2)))) | ||||||
|  |                              (remaining (drop next-lines (length sub)))) | ||||||
|  |                         (loop remaining (cons parsed result))) | ||||||
|  |                       ;; Einfacher Skalar | ||||||
|  |                       (loop next-lines (cons (parse-scalar item-str) result)))) | ||||||
|  |                 ;; Nicht mehr Teil der Liste | ||||||
|  |                 (reverse result)))))) | ||||||
|  |  | ||||||
|  |   ;; Hauptparser für Key-Value oder Listen | ||||||
|  |   (define (parse-lines lines current-indent) | ||||||
|  |     (let loop ((ls lines) (result '())) | ||||||
|  |       (if (null? ls) | ||||||
|  |           (reverse result) | ||||||
|  |           (let* ((raw-line (car ls)) | ||||||
|  |                  (line (clean-line raw-line))) | ||||||
|  |             (cond | ||||||
|  |              ;; Kommentar oder leere Zeile | ||||||
|  |              ((blank-or-comment? raw-line) | ||||||
|  |               (loop (cdr ls) result)) | ||||||
|  |  | ||||||
|  |              ;; Liste | ||||||
|  |              ((string-match "^- " line) | ||||||
|  |               (let ((list-lines (take-indented ls current-indent))) | ||||||
|  |                 (let ((parsed-list (parse-list list-lines current-indent))) | ||||||
|  |                   (loop (drop ls (length list-lines)) | ||||||
|  |                         (cons parsed-list result))))) | ||||||
|  |  | ||||||
|  |              ;; Key: Value | ||||||
|  |              ((string-match "^[^:]+:" line) | ||||||
|  |               (let* ((kv (string-split line #\:)) | ||||||
|  |                      (key (string-trim (car kv))) | ||||||
|  |                      (value-str (string-trim (string-join (cdr kv) ":"))) | ||||||
|  |                      (next-lines (cdr ls))) | ||||||
|  |                 (if (string-null? value-str) | ||||||
|  |                     ;; Wert auf nachfolgender Einrückungsebene | ||||||
|  |                     (let* ((sub (take-indented next-lines (+ current-indent 2))) | ||||||
|  |                            (parsed (parse-lines sub (+ current-indent 2))) | ||||||
|  |                            (remaining (drop next-lines (length sub)))) | ||||||
|  |                       (loop remaining | ||||||
|  |                             (cons (cons key parsed) result))) | ||||||
|  |                     ;; Einfacher Key:Value | ||||||
|  |                     (loop next-lines | ||||||
|  |                           (cons (cons key (parse-scalar value-str)) result))))) | ||||||
|  |  | ||||||
|  |              ;; Fehlerhafte Zeile | ||||||
|  |              (else | ||||||
|  |                ;; Vermeide Fehlermeldung für Leerzeilen oder leere Objekte | ||||||
|  |                (if (or (string-null? (string-trim line)) | ||||||
|  |                        (member line '("{}" "[]"))) | ||||||
|  |                    (loop (cdr ls) result) | ||||||
|  |                    (begin | ||||||
|  |                      (format (current-error-port) | ||||||
|  |                              "Syntaxfehler: Ungültige Zeile: ~a\n" raw-line) | ||||||
|  |                      (loop (cdr ls) result)))) | ||||||
|  |              ))))) | ||||||
|  |  | ||||||
|  |   (let ((lines (read-lines filename))) | ||||||
|  |     (parse-lines lines 0))) | ||||||
|  |  | ||||||
|  | (define (parse-yml-file filename) (resolve-inherits (yml-file->scm filename))) | ||||||
							
								
								
									
										121
									
								
								private_includes/base/swing_style.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								private_includes/base/swing_style.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | |||||||
|  | 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" | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | swingOff = \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 Beam.positions = #'(2 . 2) | ||||||
|  |         h'8 [h8] | ||||||
|  |       } | ||||||
|  |       \layout { | ||||||
|  |         ragged-right= ##t | ||||||
|  |         indent = 0 | ||||||
|  |         \context { | ||||||
|  |           \Staff | ||||||
|  |           \remove "Clef_engraver" | ||||||
|  |           \remove "Time_signature_engraver" | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | \include "swing.ly" | ||||||
|  |  | ||||||
|  | swingMusic = | ||||||
|  | #(define-music-function (parser location music) (ly:music?) | ||||||
|  |   (define (partial-duration-length m) | ||||||
|  |     (let ((name (ly:music-property m 'name)) | ||||||
|  |           (es (ly:music-property m 'elements)) | ||||||
|  |           (e (ly:music-property m 'element))) | ||||||
|  |       (if (pair? es) | ||||||
|  |         (partial-duration-length (car es)) | ||||||
|  |         (if (ly:music? e) | ||||||
|  |           (if (and (eq? name 'ContextSpeccedMusic) (eq? (ly:music-property e 'name) 'PartialSet)) | ||||||
|  |             (ly:duration->moment (ly:music-property e 'duration)) | ||||||
|  |             (if (eq? name 'NoteEvent) | ||||||
|  |               ZERO-MOMENT | ||||||
|  |               (partial-duration-length e) | ||||||
|  |             ) | ||||||
|  |           ) | ||||||
|  |           ZERO-MOMENT)))) | ||||||
|  | #{ | ||||||
|  |   \swing | ||||||
|  |   \applySwingWithOffset 8 #'(2 1) #(partial-duration-length music) #music | ||||||
|  | #}) | ||||||
| @@ -1,16 +1,6 @@ | |||||||
| #(define-markup-command (bookTitleMarkupCustom layout props)() | #(define-markup-command (bookTitleMarkupCustom layout props)() | ||||||
|    (interpret-markup layout |    (interpret-markup layout | ||||||
|      (prepend-alist-chain 'defaultmarkup #{ |      (prepend-alist-chain 'songfilename (chain-assoc-get 'header:songfilename props "") props) | ||||||
| \markup { |  | ||||||
|   \override #'(baseline-skip . 3.5) |  | ||||||
|   \center-column { |  | ||||||
|     \override #`(font-name . ,songTitleFont) { \fontsize #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 |      (make-column-markup | ||||||
|        (list |        (list | ||||||
|          (make-vspace-markup (chain-assoc-get 'header:titletopspace props 0)) |          (make-vspace-markup (chain-assoc-get 'header:titletopspace props 0)) | ||||||
| @@ -35,31 +25,28 @@ | |||||||
|            (string-tokenize (chain-assoc-get 'header:categories props "")))) |            (string-tokenize (chain-assoc-get 'header:categories props "")))) | ||||||
|        (make-null-markup)))) |        (make-null-markup)))) | ||||||
| 
 | 
 | ||||||
| #(define pdf-encode | #(define pdf-encode (@@ (lily framework-ps) pdf-encode)) | ||||||
|    (if (< (list-ref (ly:version) 1) 24) |  | ||||||
|        ly:encode-string-for-pdf |  | ||||||
|    (@@ (lily framework-ps) pdf-encode))) |  | ||||||
| % PDF tags | % PDF tags | ||||||
| #(define-markup-command (title-to-pdf-toc layout props title) (string?) | #(define-markup-command (title-to-pdf-toc layout props title) (string?) | ||||||
|  |   (if (string-null? title) | ||||||
|  |      empty-stencil | ||||||
|      (ly:make-stencil |      (ly:make-stencil | ||||||
|       (list 'embedded-ps |       (list 'embedded-ps | ||||||
|              (ly:format |              (ly:format | ||||||
|               "[/Action /GoTo /View [/Fit] /Title (~a) /OUT pdfmark" (pdf-encode title))) |               "[/Action /GoTo /View [/XYZ -4 currentpagedevice /PageSize get 1 get 4 add null] /Title (~a) /OUT pdfmark" (pdf-encode title))) | ||||||
|       empty-interval empty-interval |       empty-interval empty-interval | ||||||
|       ;'(0 . 0) '(0 . 0) |       ;'(0 . 0) '(0 . 0) | ||||||
|       )) |       ))) | ||||||
| 
 | 
 | ||||||
| #(define-markup-command (title-with-category-images layout props right)(boolean?) | #(define-markup-command (title-with-category-images layout props right)(boolean?) | ||||||
|    (interpret-markup layout props |    (interpret-markup layout props | ||||||
|      (let* ((title (chain-assoc-get 'header:title props #f)) |      (let* ((title (chain-assoc-get 'header:title props "")) | ||||||
|             (pdfbookmark (chain-assoc-get 'header:songfilename props title))) |             (starttext (chain-assoc-get 'header:starttext props #f)) | ||||||
|  |             (pdfbookmark (if starttext (string-append starttext " | " title) title))) | ||||||
|      (if title |      (if title | ||||||
|      ;(if (chain-assoc-get 'header:categories props #f) |  | ||||||
|        (if right |        (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 { \null \bookTitleMarkupCustom \category-images } } #} | ||||||
|          #{\markup { \title-to-pdf-toc #pdfbookmark \fill-line \general-align #Y #UP { \category-images \bookTitleMarkupCustom \null } } #}) |          #{\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 { " " } #}) |       #{ \markup { " " } #}) | ||||||
|      ))) |      ))) | ||||||
| 
 | 
 | ||||||
| @@ -68,4 +55,12 @@ | |||||||
|   scoreTitleMarkup = \markup \null |   scoreTitleMarkup = \markup \null | ||||||
|   oddHeaderMarkup = \markup { \if \on-first-page-of-part \title-with-category-images ##t } |   oddHeaderMarkup = \markup { \if \on-first-page-of-part \title-with-category-images ##t } | ||||||
|   evenHeaderMarkup = \markup { \if \on-first-page-of-part \title-with-category-images ##f } |   evenHeaderMarkup = \markup { \if \on-first-page-of-part \title-with-category-images ##f } | ||||||
|  |   defaultTitleMarkup = \markup { | ||||||
|  |     \override #'(baseline-skip . 3.5) | ||||||
|  |     \center-column { | ||||||
|  |       \override #`(font-name . ,songTitleFont) { \fontsize #songTitleSize \fromproperty #'header:title } | ||||||
|  |       \large \bold \fromproperty #'header:subtitle | ||||||
|  |       \smaller \bold \fromproperty #'header:subsubtitle | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
							
								
								
									
										22
									
								
								private_includes/base/transposition.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								private_includes/base/transposition.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | TRANSPOSITION = #(cons #f #f) | ||||||
|  |  | ||||||
|  | transposeGlobal = | ||||||
|  | #(define-void-function (from to) (ly:pitch? ly:pitch?) | ||||||
|  |    (set! TRANSPOSITION (cons from to))) | ||||||
|  |  | ||||||
|  | transposable = | ||||||
|  | #(define-music-function (fromto music) (pair? ly:music?) | ||||||
|  |   (if (car fromto) | ||||||
|  |     #{ | ||||||
|  |       \transpose #(car fromto) #(cdr fromto) #music | ||||||
|  |     #} | ||||||
|  |     music)) | ||||||
|  |  | ||||||
|  | % Akkorde in Strophen transponieren | ||||||
|  | #(define-markup-list-command (transpose layout props from to markuplist) | ||||||
|  |   (markup? markup? markup-list?) | ||||||
|  |  | ||||||
|  |   (define (markup->pitch m) | ||||||
|  |     (ly:assoc-get (string->symbol (markup->string m)) pitchnames)) | ||||||
|  |  | ||||||
|  |   (interpret-markup-list layout (prepend-alist-chain 'transposition (cons (markup->pitch from) (markup->pitch to)) props) markuplist)) | ||||||
							
								
								
									
										353
									
								
								private_includes/base/verses_with_chords.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										353
									
								
								private_includes/base/verses_with_chords.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,353 @@ | |||||||
|  | % 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 "\r?\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))))) | ||||||
|  |  | ||||||
|  | #(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." | ||||||
|  |    (let ((verselayout (chain-assoc-get 'verselayout props generalLayout))) | ||||||
|  |    (interpret-markup layout props | ||||||
|  |      #{\markup { | ||||||
|  |        \size-box-to-box-style-dependent ##t ##f | ||||||
|  |          \general-align #X #LEFT \override #`(direction . ,UP) \override #'(baseline-skip . 1.0) \dir-column \chord-alignment-style-dependent { | ||||||
|  |            \pad-to-box #'(0 . 0) #'(0 . 2.0) { #text } | ||||||
|  |            \size-box-to-box ##f ##t #uptext \score { \chords { g4:m a } \layout { \verselayout } } | ||||||
|  |          } | ||||||
|  |          #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) | ||||||
|  |    (string-or-music?) | ||||||
|  |    (let ((verselayout (chain-assoc-get 'verselayout props generalLayout))) | ||||||
|  |    (interpret-markup layout props | ||||||
|  |      (if (and (string? arg) (string-null? arg)) | ||||||
|  |          " " | ||||||
|  |          #{\markup | ||||||
|  |            \score { \new Lyrics { \lyricmode { #(if (ly:music? arg) arg #{ \set stanza = #arg #}) "" } } \layout { \verselayout } } | ||||||
|  |          #} | ||||||
|  |      )))) | ||||||
|  |  | ||||||
|  | #(define-markup-command (stanza layout props arg) | ||||||
|  |    (string-or-music?) | ||||||
|  |    (interpret-markup layout props | ||||||
|  |      (make-size-box-to-box-markup #f #t (make-stanza-raw-markup arg) (make-stanza-raw-markup "x")))) | ||||||
|  |  | ||||||
|  | #(define (handle-custom-newlines custom-verse-breaks text) | ||||||
|  |   (if (null? custom-verse-breaks) | ||||||
|  |     text | ||||||
|  |     (let make-custom-linebreaks | ||||||
|  |       ((break-words custom-verse-breaks) | ||||||
|  |        (newtext (ly:regex-replace (ly:make-regex "\r?\n") text " "))) | ||||||
|  |       (if (null? break-words) | ||||||
|  |           newtext | ||||||
|  |           (make-custom-linebreaks | ||||||
|  |             (cdr break-words) | ||||||
|  |             (ly:regex-replace | ||||||
|  |               (ly:make-regex | ||||||
|  |                 (string-append | ||||||
|  |                   "(" | ||||||
|  |                   (string-concatenate | ||||||
|  |                     (map | ||||||
|  |                       (lambda (character) | ||||||
|  |                         (let ((escaped_char (ly:regex-quote (string character)))) | ||||||
|  |                              (string-append "(?: *,[^,)]+\\)" escaped_char "|\\(?" escaped_char ")"))) | ||||||
|  |                       (string->list (car break-words)))) | ||||||
|  |                   "(?: *,[^,)]+\\))?)(.*)$")) | ||||||
|  |               newtext | ||||||
|  |               1 "\n" 2)))))) | ||||||
|  |  | ||||||
|  | #(use-modules (lily display-lily)) | ||||||
|  |  | ||||||
|  | % Kompletten Vers mit Akkorden | ||||||
|  | #(define-markup-command (chordverse layout props stanza verse) (string-or-music? string?) | ||||||
|  |    #:properties ( | ||||||
|  |     (intraverse-vspace 0) | ||||||
|  |     (custom-verse-breaks '()) | ||||||
|  |     (transposition (cons #f #f)) | ||||||
|  |     (verselayout generalLayout) | ||||||
|  |     ) | ||||||
|  |    "Vers mit Akkorden" | ||||||
|  |    (let ((transp (if (car transposition) | ||||||
|  |                     (string-append "\\transpose " (symbol->string (note-name->lily-string (car transposition))) " " (symbol->string (note-name->lily-string (cdr transposition)))) | ||||||
|  |                     ""))) | ||||||
|  |    (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(]*)+)") (handle-custom-newlines custom-verse-breaks verse) " \\concat { " 1 " } ") | ||||||
|  |                 "\\textup \\line { \"" 1 "\" " 2 " \"" 3 "\" } \\score { " transp " \\chords { s4 " 4 " } \\layout { \\verselayout } }") | ||||||
|  |                 ) | ||||||
|  |      )))) | ||||||
|  |  | ||||||
|  | % Kompletter Vers aus dem Akkorde entfernt werden | ||||||
|  | #(define-markup-command (nochordverse layout props stanza verse) (string-or-music? string?) | ||||||
|  |    #:properties ((intraverse-vspace 0)(custom-verse-breaks '())) | ||||||
|  |    "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 "\\(([^,]*),([^)]*)\\)") (handle-custom-newlines custom-verse-breaks verse) 1) | ||||||
|  |      ) | ||||||
|  |    ) | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | #(define-markup-command (verseformat layout props verse) (markup?) | ||||||
|  |    #:properties ((verselayout generalLayout)) | ||||||
|  |    "Textformatierung für Strophen" | ||||||
|  |    (interpret-markup layout props | ||||||
|  |      (let* ( | ||||||
|  |          (layout-scale (ly:output-def-lookup layout 'output-scale 1.0)) | ||||||
|  |          (verselayout-scale (ly:output-def-lookup verselayout 'output-scale layout-scale)) | ||||||
|  |          (mag-scale (/ verselayout-scale layout-scale)) | ||||||
|  |          (lyric-context-props (ly:context-def-lookup (ly:assoc-get 'Lyrics (ly:output-find-context-def verselayout 'Lyrics)) 'property-ops)) | ||||||
|  |          (lyric-size (caddr (find (lambda (prop) (and (equal? 'push (car prop)) (equal? 'LyricText (cadr prop)) (equal? 'font-size (cadddr prop)))) lyric-context-props))) | ||||||
|  |        ) | ||||||
|  |        (make-magnify-markup mag-scale (make-sans-markup (make-fontsize-markup 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" | ||||||
|  |    (define (add-markup-between-elements reverses markup-between elements) | ||||||
|  |      ((if reverses fold fold-right) (lambda (element filled-list) | ||||||
|  |               (cons element (if (null? filled-list) '() (cons markup-between filled-list)))) | ||||||
|  |         '() elements)) | ||||||
|  |    (let* ((column-item-count (ceiling (/ (length versegroup) verse-cols))) | ||||||
|  |           (column-data (make-list verse-cols))) | ||||||
|  |     (let columnize-list ((index 0) (items versegroup)) | ||||||
|  |       (if (not (null? items)) | ||||||
|  |         (let* ((column-index (if verse-ordering-horizontal | ||||||
|  |                                  (modulo index verse-cols) | ||||||
|  |                                  (floor (/ index column-item-count)))) | ||||||
|  |                (column-markups (list-ref column-data column-index))) | ||||||
|  |           (list-set! column-data column-index (cons (car items) column-markups)) | ||||||
|  |           (columnize-list (+ index 1) (cdr items))))) | ||||||
|  |     (interpret-markup layout props | ||||||
|  |       (make-fill-line-markup (list (make-verseformat-markup (make-line-markup | ||||||
|  |         (add-markup-between-elements #f | ||||||
|  |           (make-hspace-markup verse-hspace) | ||||||
|  |           (map (lambda (column-markups) | ||||||
|  |               (make-column-markup | ||||||
|  |                 (add-markup-between-elements #t (make-vspace-markup verse-vspace) column-markups))) | ||||||
|  |             column-data))))))))) | ||||||
|  |  | ||||||
|  | #(define-markup-command (pad-left layout props amount arg) | ||||||
|  |   (number? markup?) | ||||||
|  |   (let* ((m (interpret-markup layout props arg)) | ||||||
|  |          (x (ly:stencil-extent m X)) | ||||||
|  |          (y (ly:stencil-extent m Y))) | ||||||
|  |     (ly:stencil-translate | ||||||
|  |       (ly:make-stencil (ly:stencil-expr m) | ||||||
|  |                        (cons (- (car x) amount) (cdr x)) | ||||||
|  |                        y) | ||||||
|  |       `(,amount . 0)))) | ||||||
|  |  | ||||||
|  | #(define-markup-command (pad-right layout props amount arg) | ||||||
|  |   (number? markup?) | ||||||
|  |   (let* ((m (interpret-markup layout props arg)) | ||||||
|  |          (x (ly:stencil-extent m X)) | ||||||
|  |          (y (ly:stencil-extent m Y))) | ||||||
|  |       (ly:make-stencil (ly:stencil-expr m) | ||||||
|  |                        (cons (car x) (+ (cdr x) amount)) | ||||||
|  |                        y))) | ||||||
|  |  | ||||||
|  | #(define-markup-command (score-equal-height-with-indents layout props lines) | ||||||
|  |   (markup-list?) | ||||||
|  |   #:category music | ||||||
|  |   #:properties ((intraverse-vspace 0) | ||||||
|  |                 (verse-line-height songTextLineHeigth) | ||||||
|  |                 (line-indents '())) | ||||||
|  |     (let ((indents-max-index (- (length line-indents) 1))) | ||||||
|  |       (stack-stencils Y DOWN intraverse-vspace | ||||||
|  |         (index-map | ||||||
|  |           (lambda (index line) | ||||||
|  |             (let ((stil | ||||||
|  |                     (ly:make-stencil | ||||||
|  |                       (ly:stencil-expr line) | ||||||
|  |                       (ly:stencil-extent line X) | ||||||
|  |                       `(,(/ verse-line-height -2.0) . ,(/ verse-line-height 2.0))))) | ||||||
|  |               (if (<= index indents-max-index) | ||||||
|  |                 (ly:stencil-translate-axis | ||||||
|  |                   stil | ||||||
|  |                   (list-ref line-indents index) | ||||||
|  |                   X) | ||||||
|  |                 stil))) | ||||||
|  |           (interpret-markup-list layout props lines))))) | ||||||
|  |  | ||||||
|  | #(define-public (custom-lyric-text::print grob) | ||||||
|  |   "Allow interpretation of tildes as lyric tieing marks." | ||||||
|  |   ;; See also similar code in Lyric_performer. | ||||||
|  |   (let ((text (ly:grob-property grob 'text))) | ||||||
|  |  | ||||||
|  |     (grob-interpret-markup grob (if (string? text) | ||||||
|  |                                     (make-pad-right-markup -0.1 (make-tied-lyric-markup text)) | ||||||
|  |                                     text)))) | ||||||
|  |  | ||||||
|  | #(define-markup-command (chordlyrics layout props lyrics) (ly:music?) | ||||||
|  |    #:properties ((verse-chords #{#}) | ||||||
|  |                  (verse-reference-voice #{#}) | ||||||
|  |                  (verse-break-voice #{#}) | ||||||
|  |                  (verse-text-chord-distance songTextChordDistance) | ||||||
|  |                  (transposition (cons #f #f)) | ||||||
|  |                  (verselayout generalLayout)) | ||||||
|  |   "Vers mit Akkorden" | ||||||
|  |   (interpret-markup layout props | ||||||
|  |     #{ | ||||||
|  |       \markup { | ||||||
|  |         \score-equal-height-with-indents \score-lines { | ||||||
|  |           << | ||||||
|  |             \new Devnull { #(music-clone verse-break-voice) } | ||||||
|  |             \new NullVoice = "dummyvoice" { #(music-clone verse-reference-voice) } | ||||||
|  |             \transposable #transposition #(music-clone verse-chords) | ||||||
|  |             \new Lyrics \lyricsto "dummyvoice" { #lyrics } | ||||||
|  |           >> | ||||||
|  |           \layout { | ||||||
|  |             \verselayout | ||||||
|  |             #(let | ||||||
|  |               ((custom-size (ly:output-def-lookup verselayout 'size #f))) | ||||||
|  |               (if custom-size (layout-set-staff-size custom-size))) | ||||||
|  |             ragged-right = ##t | ||||||
|  |             \context { | ||||||
|  |               \Lyrics | ||||||
|  |               \override VerticalAxisGroup.nonstaff-relatedstaff-spacing.basic-distance = #verse-text-chord-distance | ||||||
|  |               \override VerticalAxisGroup.nonstaff-relatedstaff-spacing.padding = #(- verse-text-chord-distance songTextChordDistance) | ||||||
|  |               \override LyricText.parent-alignment-X = #LEFT | ||||||
|  |               \override LyricText.self-alignment-X = #LEFT | ||||||
|  |               \override LyricText.word-space = 0.8 | ||||||
|  |               \override LyricSpace.minimum-distance = 0.8 | ||||||
|  |               \override LyricText.stencil = #custom-lyric-text::print | ||||||
|  |             } | ||||||
|  |             \context { | ||||||
|  |               \ChordNames | ||||||
|  |               \override VerticalAxisGroup.staff-affinity = ##f | ||||||
|  |               \override ChordName.extra-spacing-width = #'(-0.1 . 0.1) | ||||||
|  |               \consists \Ensure_first_chord_after_line_break_printed_engraver | ||||||
|  |             } | ||||||
|  |             \context { | ||||||
|  |               \Score | ||||||
|  |               \override PaperColumn.keep-inside-line = ##f | ||||||
|  |              % \override SpacingSpanner.strict-note-spacing = ##t | ||||||
|  |               \override SpacingSpanner.uniform-stretching = ##t | ||||||
|  |               \override SpacingSpanner.spacing-increment = 0 | ||||||
|  |               \remove Bar_number_engraver | ||||||
|  |               \remove Mark_engraver | ||||||
|  |               \remove Jump_engraver | ||||||
|  |               \remove Volta_engraver | ||||||
|  |               \remove Parenthesis_engraver | ||||||
|  |               \remove Metronome_mark_engraver | ||||||
|  |             } | ||||||
|  |             \context { | ||||||
|  |               \Staff | ||||||
|  |               \remove Staff_symbol_engraver | ||||||
|  |               \remove Clef_engraver | ||||||
|  |               \remove Time_signature_engraver | ||||||
|  |               \remove Bar_engraver | ||||||
|  |               \remove Separating_line_group_engraver | ||||||
|  |               \omit KeySignature | ||||||
|  |               \omit KeyCancellation | ||||||
|  |             } | ||||||
|  |             \context { | ||||||
|  |               \Voice | ||||||
|  |               \remove Stem_engraver | ||||||
|  |               \remove Rest_engraver | ||||||
|  |               \remove Multi_measure_rest_engraver | ||||||
|  |               \remove Phrasing_slur_engraver | ||||||
|  |               \remove Slur_engraver | ||||||
|  |               \remove Tie_engraver | ||||||
|  |               \remove Dynamic_engraver | ||||||
|  |               \remove Note_heads_engraver | ||||||
|  |               \remove Script_engraver | ||||||
|  |             } | ||||||
|  |             \context { | ||||||
|  |               \NullVoice | ||||||
|  |               \consists Rest_engraver | ||||||
|  |               \omit Rest | ||||||
|  |               \undo \omit NoteHead | ||||||
|  |               \hide NoteHead | ||||||
|  |               \override NoteHead.X-extent = #'(0 . 0) | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     #} | ||||||
|  |   ) | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | #(define-markup-command (nochordlyrics layout props lyrics) (ly:music?) | ||||||
|  |     "Vers ohne Akkorde" | ||||||
|  |   (interpret-markup layout props | ||||||
|  |     (markup | ||||||
|  |       #:override `(verse-chords . ,#{#}) | ||||||
|  |       #:override `(verse-line-height . ,(- songTextLineHeigth 2)) | ||||||
|  |       #:chordlyrics lyrics)) | ||||||
|  | ) | ||||||
							
								
								
									
										44
									
								
								private_includes/book/appendix.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								private_includes/book/appendix.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | appendix = | ||||||
|  | #(define-void-function (parser location title) (markup?) | ||||||
|  |   (define (appendix-item->markup layout props appendix-item) | ||||||
|  |     (interpret-markup layout props | ||||||
|  |       (markup | ||||||
|  |           #:override (cons 'appendixItem:heading (assoc-ref appendix-item "heading")) | ||||||
|  |           #:override (cons 'appendixItem:text (assoc-ref appendix-item "text")) | ||||||
|  |           (ly:output-def-lookup layout 'appendixItemMarkup)))) | ||||||
|  |   (ly:book-add-bookpart! (ly:parser-lookup '$current-book) | ||||||
|  |   #{ | ||||||
|  |     \bookpart { | ||||||
|  |       \markup { #title } | ||||||
|  |       #(for-each | ||||||
|  |           (lambda (item) | ||||||
|  |             (add-score (ly:make-page-label-marker (string->symbol (car item)))) | ||||||
|  |             (add-text | ||||||
|  |               (make-on-the-fly-markup | ||||||
|  |                 (lambda (layout props arg) (appendix-item->markup layout props (cdr item))) | ||||||
|  |                 (make-null-markup))) | ||||||
|  |           ) | ||||||
|  |         (reverse APPENDIX_DATA)) | ||||||
|  |     } | ||||||
|  |   #})) | ||||||
|  |  | ||||||
|  | #(define-markup-command (appendix-ref layout props label) (symbol?) | ||||||
|  |   "call page-ref to appendix-item" | ||||||
|  |   (interpret-markup layout props | ||||||
|  |     (markup #:with-link label | ||||||
|  |       #:override (cons 'appendixPage (make-page-ref-markup label "888" "?")) | ||||||
|  |       (ly:output-def-lookup layout 'appendixReferenceMarkup)))) | ||||||
|  |  | ||||||
|  | \paper { | ||||||
|  |   appendixItemMarkup = \markup { | ||||||
|  |     \left-column { | ||||||
|  |       \line { \large \bold \fromproperty #'appendixItem:heading } | ||||||
|  |       \vspace #0.2 | ||||||
|  |       \sans \wordwrap-field #'appendixItem:text | ||||||
|  |       \vspace #0.7 | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   appendixReferenceMarkup = \markup { | ||||||
|  |     \fromproperty #'appendixPage | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -1,6 +1,5 @@ | |||||||
| \version "2.18" |  | ||||||
| 
 |  | ||||||
| #(define song-list '()) | #(define song-list '()) | ||||||
|  | #(define song-number 0) | ||||||
| 
 | 
 | ||||||
| #(define (files-in-directory dirname) | #(define (files-in-directory dirname) | ||||||
|       ;;; Generate list containing filenames |       ;;; Generate list containing filenames | ||||||
| @@ -11,7 +10,7 @@ | |||||||
|     	     (closedir dir) |     	     (closedir dir) | ||||||
|     	     files) |     	     files) | ||||||
|     	    (else |     	    (else | ||||||
|     	     (next (readdir dir) (if (string-match "^(0|\\.)" f) files (cons f files)))))))) |     	     (next (readdir dir) (if (ly:regex-match? (ly:regex-exec (ly:make-regex "^(0|\\.)") f)) files (cons f files)))))))) | ||||||
| 
 | 
 | ||||||
| #(define (file-to-stats filename) | #(define (file-to-stats filename) | ||||||
|    (set! song-list (cons filename song-list))) |    (set! song-list (cons filename song-list))) | ||||||
| @@ -66,7 +65,10 @@ additionalPageNumbers = | |||||||
|   display-pages-list |   display-pages-list | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| 
 | % TODO: | ||||||
|  | % Eigentlich können wir das direkt in oddFooderMarkup und evenFooterMarkup aufrufen | ||||||
|  | % vermutlich sogar ohne den delay kram. Wir sollten außerdem einfach nur die property | ||||||
|  | % page:page-number-string setzen dann klappts auch mit PDF Seiten | ||||||
| #(define-markup-command (custom-page-number layout props label real-current-page-number) | #(define-markup-command (custom-page-number layout props label real-current-page-number) | ||||||
|   (symbol? number?) |   (symbol? number?) | ||||||
|   #:category other |   #:category other | ||||||
| @@ -90,9 +92,10 @@ width may require additional tweaking.)" | |||||||
|         ,(delay (ly:stencil-expr |         ,(delay (ly:stencil-expr | ||||||
|                  (let* ((display-page (assq-ref (build-display-pages-list layout) label)) |                  (let* ((display-page (assq-ref (build-display-pages-list layout) label)) | ||||||
|                         (real-current-page (if (negative? real-current-page-number) (real-page-number layout label) real-current-page-number)) |                         (real-current-page (if (negative? real-current-page-number) (real-page-number layout label) real-current-page-number)) | ||||||
|  |                         (number-type (ly:output-def-lookup layout 'page-number-type)) | ||||||
|                         (page-markup |                         (page-markup | ||||||
|                           (if (assq-ref additional-page-switch-label-list label) |                           (if (assq-ref additional-page-switch-label-list label) | ||||||
|                               (make-concat-markup (list (number-format 'arabic display-page) |                               (make-concat-markup (list (number-format number-type display-page) | ||||||
|                                 (make-char-markup (+ 97 (- real-current-page (real-page-number layout |                                 (make-char-markup (+ 97 (- real-current-page (real-page-number layout | ||||||
|                                   (let find-earliest-additional-label |                                   (let find-earliest-additional-label | ||||||
|                                        ((rest-additional-page-switch-label-list (member (cons label #t) additional-page-switch-label-list))) |                                        ((rest-additional-page-switch-label-list (member (cons label #t) additional-page-switch-label-list))) | ||||||
| @@ -100,7 +103,7 @@ width may require additional tweaking.)" | |||||||
|                                            (find-earliest-additional-label (cdr rest-additional-page-switch-label-list)) |                                            (find-earliest-additional-label (cdr rest-additional-page-switch-label-list)) | ||||||
|                                            (caar rest-additional-page-switch-label-list))) |                                            (caar rest-additional-page-switch-label-list))) | ||||||
|                                 )))))) |                                 )))))) | ||||||
|                               (number-format 'arabic (+ display-page (- real-current-page (real-page-number layout label)))) |                               (number-format number-type (+ display-page (- real-current-page (real-page-number layout label)))) | ||||||
|                           )) |                           )) | ||||||
|                         (page-stencil (interpret-markup layout props page-markup)) |                         (page-stencil (interpret-markup layout props page-markup)) | ||||||
|                         (gap (- (interval-length x-ext) |                         (gap (- (interval-length x-ext) | ||||||
| @@ -116,18 +119,26 @@ width may require additional tweaking.)" | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| includeSong = | includeSong = | ||||||
| #(define-void-function (parser location textproc filename) ((procedure?) string?) | #(define-void-function (parser location filename) (string?) | ||||||
|      #{ |      #{ | ||||||
|      \bookOutputName #filename |      \bookOutputName #filename | ||||||
|      #} |      #} | ||||||
|     (ly:parser-parse-string (if (< (list-ref (ly:version) 1) 19) (ly:parser-clone parser) (ly:parser-clone)) |     (ly:parser-parse-string (ly:parser-clone) | ||||||
|       (ly:format "\\include \"~a/~a/~a.ly\"" songPath filename filename)) |       (ly:format "\\include \"~a/~a/~a.ly\"" songPath filename filename)) | ||||||
|     (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)) | ||||||
|       (set! song-list |       (set! song-list | ||||||
|         (acons (string->symbol filename) |         (acons (string->symbol filename) | ||||||
|           (acons 'label label (acons 'header HEADER (acons 'music MUSIC (acons 'layout LAYOUT (acons 'text #{ \markuplist \setsongfilename $filename $(if textproc (textproc TEXT) TEXT) #} '()))))) |           (acons 'label label | ||||||
|  |             (acons 'header HEADER | ||||||
|  |               (acons 'music MUSIC | ||||||
|  |                 (acons 'layout LAYOUT | ||||||
|  |                   (acons 'text-pages | ||||||
|  |                     (map (lambda (text) | ||||||
|  |                       #{ \markuplist \setsongfilename $filename $text #}) | ||||||
|  |                       TEXT_PAGES) | ||||||
|  |                     '()))))) | ||||||
|           song-list)) |           song-list)) | ||||||
|     )) |     )) | ||||||
| 
 | 
 | ||||||
| @@ -155,7 +166,7 @@ imagepage = | |||||||
| songs = | songs = | ||||||
| #(define-void-function (parser location) () | #(define-void-function (parser location) () | ||||||
|  (for-each (lambda (songitems) |  (for-each (lambda (songitems) | ||||||
|    (ly:book-add-bookpart! (if (< (list-ref (ly:version) 1) 19) (ly:parser-lookup parser '$current-book) (ly:parser-lookup '$current-book)) |    (ly:book-add-bookpart! (ly:parser-lookup '$current-book) | ||||||
|     (let ((filename (car songitems)) |     (let ((filename (car songitems)) | ||||||
|           (songvars (cdr songitems))) |           (songvars (cdr songitems))) | ||||||
|       (if (eq? filename 'emptyPage) |       (if (eq? filename 'emptyPage) | ||||||
| @@ -179,21 +190,23 @@ songs = | |||||||
|               \markup { \pagecenter { \epsfile #X #xsize #filename } } |               \markup { \pagecenter { \epsfile #X #xsize #filename } } | ||||||
|           } #} |           } #} | ||||||
|           ) |           ) | ||||||
|           (let ((header #{ \bookpart { $(assq-ref songvars 'header) \header { |           (let* ((newnumber (+ 1 song-number)) | ||||||
|                   songfilename = $(symbol->string filename) |                  (header #{ \bookpart { $(assq-ref songvars 'header) \header { | ||||||
|                   myindexlabel = #(assq-ref songvars 'label) |                    songfilename = $(symbol->string filename) | ||||||
|                 } } #}) |                    myindexlabel = #(assq-ref songvars 'label) | ||||||
|                 ;(header (assq-ref songvars 'header)) |                    songnumber = #(number->string newnumber) | ||||||
|                 (music (assq-ref songvars 'music)) |                  } } #}) | ||||||
|                 (layout (assq-ref songvars 'layout)) |                  (music (assq-ref songvars 'music)) | ||||||
|                 (text (assq-ref songvars 'text)) |                  (layout (assq-ref songvars 'layout)) | ||||||
|                 (label (assq-ref songvars 'label))) |                  (text-pages (assq-ref songvars 'text-pages)) | ||||||
|  |                  (label (assq-ref songvars 'label))) | ||||||
|  |             (set! song-number newnumber) | ||||||
|             #{ |             #{ | ||||||
|               \bookpart { |               \bookpart { | ||||||
|                 $header |                 $header | ||||||
|                 \headerToTOC #header #label |                 \headerToTOC #header #label | ||||||
|                 \score { $music \layout { $layout } } |                 \score { $music \layout { $layout } } | ||||||
|                 $text |                 $(add-text-pages text-pages) | ||||||
|               } |               } | ||||||
|             #})))))) |             #})))))) | ||||||
|    (reverse song-list) |    (reverse song-list) | ||||||
							
								
								
									
										448
									
								
								private_includes/book/toc_include.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										448
									
								
								private_includes/book/toc_include.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,448 @@ | |||||||
|  | % embed all category images in postscript once | ||||||
|  | #(define-markup-list-command (embed-category-images layout props)() | ||||||
|  |    (map (lambda (category) | ||||||
|  |      (interpret-markup layout props | ||||||
|  |        (markup #:epsfileembed (category-image-path (symbol->string (car category)))))) | ||||||
|  |        category-names)) | ||||||
|  |  | ||||||
|  | % print a markup-list in columns | ||||||
|  | #(define-markup-list-command (columnlayout layout props cols margin heightpair lines) (integer? number? pair? markup-list?) | ||||||
|  |    (let create-col-page ((line-width (- (/ (chain-assoc-get 'line-width props | ||||||
|  |                           (ly:output-def-lookup layout 'line-width)) | ||||||
|  |                            cols) margin )) | ||||||
|  |                          (cols cols) | ||||||
|  |                          (height (car heightpair)) | ||||||
|  |                          (restlines lines)) | ||||||
|  |      (cons | ||||||
|  |      (interpret-markup layout props | ||||||
|  |        (make-fill-line-markup | ||||||
|  |         (map (lambda (foo) | ||||||
|  |          (make-general-align-markup Y UP (make-override-markup '(baseline-skip . 1) (make-column-markup | ||||||
|  |           (let add-to-col ((lines restlines) (height-left height)) | ||||||
|  |             (set! restlines lines) | ||||||
|  |             (if (null? lines) | ||||||
|  |               '() | ||||||
|  |               (let* ((line-to-stencil (lambda (line) (interpret-markup layout (cons (list (cons 'line-width line-width) (cons 'baseline-skip 1)) props) (markup line)))) | ||||||
|  |                      (stencil-height (lambda (stencil) (interval-length (ly:stencil-extent stencil Y)))) | ||||||
|  |                      (linestencil (line-to-stencil (car lines))) | ||||||
|  |                      (current-line-height (stencil-height linestencil)) | ||||||
|  |                      (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)))) | ||||||
|  |      (if (null? restlines) | ||||||
|  |          (list) | ||||||
|  |        (create-col-page line-width cols (cdr heightpair) restlines))))) | ||||||
|  |  | ||||||
|  | %%%%%%%%%%%%%%%%%%%%%%% | ||||||
|  | %%%Funktionen für Inhaltsverzeichnis | ||||||
|  | % geklaut von da: | ||||||
|  | % http://lsr.dsi.unimi.it/LSR/Snippet?id=763 | ||||||
|  |  | ||||||
|  | % Usage: | ||||||
|  | % - define and index item with \indexItem $sortstring $markup | ||||||
|  | % - use \indexSection $sortstring $markup to divide the index into several sections | ||||||
|  | % - display the alphabetical index with \markuplines \index | ||||||
|  |  | ||||||
|  | % code ist mostly taken from ./ly/toc-init.ly and just renamed and slightly modfied | ||||||
|  |  | ||||||
|  | %% defined later, in a closure | ||||||
|  | #(define*-public (add-index-item! markup-symbol text sorttext #:optional label) #f) | ||||||
|  | #(define-public (index-items) #f) | ||||||
|  |  | ||||||
|  | #(let ((index-item-list (list))) | ||||||
|  |    (set! add-index-item! | ||||||
|  |    (lambda* (markup-symbol textoptions sorttext #:optional (label (gensym "index"))) | ||||||
|  |        (set! index-item-list | ||||||
|  |        ;; We insert index items sorted from the beginning on and do | ||||||
|  |        ;; not sort them later - this saves pretty much computing time | ||||||
|  |        (insert-alphabetical-sorted! (list label markup-symbol textoptions | ||||||
|  |         ;; this crazy hack is necessary because lilypond depends on guile 1.8 atm | ||||||
|  |         ;; and so the cool unicode conversion functions cannot be used | ||||||
|  |           (ly:string-substitute " " "" | ||||||
|  |           (ly:string-substitute "…" "" | ||||||
|  |           (ly:string-substitute "Č" "C" | ||||||
|  |           (ly:string-substitute "Đ" "D" | ||||||
|  |           (ly:string-substitute "Š" "S" | ||||||
|  |           (ly:string-substitute "Т" "T" | ||||||
|  |           (ly:string-substitute "Ä" "Ae" | ||||||
|  |           (ly:string-substitute "ä" "ae" | ||||||
|  |           (ly:string-substitute "Ö" "O" | ||||||
|  |           (ly:string-substitute "ö" "oe" | ||||||
|  |           (ly:string-substitute "Ü" "U" | ||||||
|  |           (ly:string-substitute "ü" "ue" sorttext))))))))))))) | ||||||
|  |         index-item-list)) | ||||||
|  |        (make-music 'EventChord | ||||||
|  |          'page-marker #t | ||||||
|  |          'page-label label | ||||||
|  |          'elements (list (make-music 'LabelEvent | ||||||
|  |          'page-label label))))) | ||||||
|  |    (set! index-items (lambda () | ||||||
|  |          index-item-list))) | ||||||
|  |  | ||||||
|  | #(define (insert-alphabetical-sorted! iitem ilist) | ||||||
|  |   (if (null? ilist) | ||||||
|  |       (list iitem) | ||||||
|  |       (if (string-ci<? (cadddr iitem) (cadddr (car ilist))) | ||||||
|  |           (cons iitem ilist) | ||||||
|  |           (cons (car ilist) (insert-alphabetical-sorted! iitem (cdr ilist)))))) | ||||||
|  |  | ||||||
|  | % code for category index | ||||||
|  | #(define*-public (add-category-index-item! categories markup-symbol textoptions #:optional label) #f) | ||||||
|  | #(define-public (category-index-items) #f) | ||||||
|  |  | ||||||
|  | #(let ((category-index-hash (make-hash-table))) | ||||||
|  |    (set! add-category-index-item! | ||||||
|  |    (lambda* (categories markup-symbol textoptions #:optional (label (gensym "index"))) | ||||||
|  |      (for-each (lambda (category) | ||||||
|  |             (let* ((catsym (string->symbol category)) | ||||||
|  |                    (catlist (hashq-ref category-index-hash catsym | ||||||
|  |                               (list (list label 'indexCategoryMarkup `(((rawtext . ,category)))))))) | ||||||
|  |               (if (assq catsym category-names) | ||||||
|  |                 (hashq-set! category-index-hash catsym | ||||||
|  |                   (cons (list label markup-symbol textoptions) catlist)) | ||||||
|  |                 (ly:error "song: <~a> category ~a is not defined!" (markup->string (chain-assoc-get 'rawtext textoptions)) category)))) | ||||||
|  |        categories) | ||||||
|  |        (make-music 'EventChord | ||||||
|  |          'page-marker #t | ||||||
|  |          'page-label label | ||||||
|  |          'elements (list (make-music 'LabelEvent | ||||||
|  |          'page-label label))))) | ||||||
|  |    (set! category-index-items (lambda () | ||||||
|  |           (append-map (lambda (kv) (reverse (hashq-ref category-index-hash (car kv) (list)))) category-names)))) | ||||||
|  |  | ||||||
|  | % code for author index | ||||||
|  | #(define*-public (add-author-index-item! authorIDs markup-symbol text #:optional label) #f) | ||||||
|  | #(define-public (author-index-items) #f) | ||||||
|  |  | ||||||
|  | #(let ((author-index-hash (make-hash-table))) | ||||||
|  |    (set! add-author-index-item! | ||||||
|  |    (lambda* (authorIDs markup-symbol textoptions #:optional (label (gensym "index"))) | ||||||
|  |      (for-each (lambda (authorID) | ||||||
|  |             (let* ((authorsym (string->symbol authorID)) | ||||||
|  |                    (authorlist (hashq-ref author-index-hash authorsym | ||||||
|  |                               (list (list label 'indexAuthorMarkup `(((rawtext . ,authorID)))))))) | ||||||
|  |                 (hashq-set! author-index-hash authorsym | ||||||
|  |                   (cons (list label markup-symbol textoptions) authorlist)) | ||||||
|  |                 )) | ||||||
|  |        authorIDs) | ||||||
|  |        (make-music 'EventChord | ||||||
|  |          'page-marker #t | ||||||
|  |          'page-label label | ||||||
|  |          'elements (list (make-music 'LabelEvent | ||||||
|  |          'page-label label))))) | ||||||
|  |    (set! author-index-items (lambda () | ||||||
|  |           (append-map cdr | ||||||
|  |             (sort-list | ||||||
|  |               (hash-map->list | ||||||
|  |                 (lambda (authorsym authorlist) (cons (string-downcase (symbol->string authorsym)) (reverse authorlist))) | ||||||
|  |                 author-index-hash) | ||||||
|  |               (lambda (a b) (string-ci<? (car a) (car b)))))))) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #(define-markup-command (with-link-symbol-ref layout props symbol arg) | ||||||
|  |    (symbol? markup?) | ||||||
|  |    "call with-link with the label referenced by symbol" | ||||||
|  |    (let ((label (chain-assoc-get symbol props))) | ||||||
|  |      (interpret-markup layout props | ||||||
|  |      (markup #:with-link label arg)))) | ||||||
|  |  | ||||||
|  | #(define-markup-command (category-image-symbol-ref layout props size symbol) | ||||||
|  |    (number? symbol?) | ||||||
|  |    "call category-image with the category referenced by symbol" | ||||||
|  |    (let ((category (chain-assoc-get symbol props))) | ||||||
|  |      (interpret-markup layout props | ||||||
|  |      (markup #:category-image size category)))) | ||||||
|  |  | ||||||
|  | #(define-markup-command (category-name-symbol-ref layout props symbol) | ||||||
|  |    (symbol?) | ||||||
|  |    "get the name of a category referenced by symbol" | ||||||
|  |    (let* ((category (chain-assoc-get symbol props)) | ||||||
|  |           (catname (assq (string->symbol category) category-names))) | ||||||
|  |      (interpret-markup layout props | ||||||
|  |      (markup #:override (cons 'baseline-skip 3.5) (if catname (make-left-column-markup (string-split (cadr catname) #\newline)) category))))) | ||||||
|  |  | ||||||
|  | #(define-markup-command (index-item-with-pattern layout props)() | ||||||
|  |     #:properties ((index:text "") | ||||||
|  |                   (index:alternative #f) | ||||||
|  |                   (index:page #f) | ||||||
|  |                   (line-width)) | ||||||
|  |     (let* ( | ||||||
|  |             (width (- | ||||||
|  |                      line-width | ||||||
|  |                      (interval-length (ly:stencil-extent (interpret-markup layout props "XXXX") X)))) | ||||||
|  |             (lines-reversed | ||||||
|  |               (reverse (map (lambda (stil) (markup #:stencil stil)) | ||||||
|  |                 (wordwrap-string-internal-markup-list layout | ||||||
|  |                   (prepend-alist-chain 'line-width width | ||||||
|  |                     (if index:alternative | ||||||
|  |                         (prepend-alist-chain 'font-shape 'italic props) | ||||||
|  |                         props)) | ||||||
|  |                   #f | ||||||
|  |                   index:text)))) | ||||||
|  |             (last-line-with-dots (make-fill-with-pattern-markup 1 RIGHT "." (car lines-reversed) index:page)) | ||||||
|  |             (lines-without-dots (cdr lines-reversed)) | ||||||
|  |             (target-line-size-markup | ||||||
|  |                  (make-column-markup | ||||||
|  |                    (list | ||||||
|  |                     (make-simple-markup "Agj") | ||||||
|  |                     (make-vspace-markup 0.2)))) | ||||||
|  |             ) | ||||||
|  |       (interpret-markup layout props | ||||||
|  |         (make-size-box-to-box-markup #f #t | ||||||
|  |           (make-with-link-symbol-ref-markup 'index:label | ||||||
|  |             (make-column-markup | ||||||
|  |               (reverse (cons | ||||||
|  |                           last-line-with-dots | ||||||
|  |                           (map (lambda (m) (make-size-box-to-box-markup #f #t m target-line-size-markup)) lines-without-dots))))) | ||||||
|  |           ; this column is just to have a reference height for resizing | ||||||
|  |           (make-column-markup | ||||||
|  |             (reverse (map (lambda (m) (make-size-box-to-box-markup #f #t m target-line-size-markup)) (cons last-line-with-dots lines-without-dots)))) | ||||||
|  |                           )))) | ||||||
|  |  | ||||||
|  | \paper { | ||||||
|  |   indexItemMarkup = \markup { | ||||||
|  |     \sans \index-item-with-pattern | ||||||
|  |   } | ||||||
|  |   indexSectionMarkup = \markup \override #'(baseline-skip . 1.5) \left-column { | ||||||
|  |     \sans \bold \fontsize #3 \fromproperty #'index:text | ||||||
|  |     \null | ||||||
|  |   } | ||||||
|  |   indexCategoryMarkup = \markup \override #'(baseline-skip . 1.5) \column { | ||||||
|  |     \fill-line { \line { \vcenter \category-image-symbol-ref #7 #'index:text \hspace #3 \vcenter \sans \bold \fontsize #3 \category-name-symbol-ref #'index:text } \null } | ||||||
|  |     \vspace #.4 | ||||||
|  |   } | ||||||
|  |   indexAuthorMarkup = \markup \override #'(baseline-skip . 1.5) \left-column { | ||||||
|  |     \vspace #1 | ||||||
|  |     \sans \bold \fontsize #3 | ||||||
|  |       #(make-on-the-fly-markup | ||||||
|  |         (lambda (layout props m) | ||||||
|  |           (interpret-markup layout props | ||||||
|  |             (make-justify-string-markup (format-author (ly:output-def-lookup layout 'authorFormat) (chain-assoc-get 'index:text props #f) #t)))) | ||||||
|  |         (make-null-markup)) | ||||||
|  |     \vspace #.4 | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #(define (prepare-item-markup items layout) | ||||||
|  |    (map (lambda (index-item) | ||||||
|  |          (let* ((label (car index-item)) | ||||||
|  |                 (index-markup (cadr index-item)) | ||||||
|  |                 (textoptions (caddr index-item)) | ||||||
|  |                 (text (chain-assoc-get 'rawtext textoptions)) | ||||||
|  |                 (alternative (chain-assoc-get 'alternative textoptions)) | ||||||
|  |                 (songnumber (chain-assoc-get 'songnumber textoptions))) | ||||||
|  |            (markup #:override (cons 'index:label label) | ||||||
|  |              #:override (cons 'index:page (markup #:custom-page-number label -1)) | ||||||
|  |              #:override (cons 'index:text text) | ||||||
|  |              #:override (cons 'index:alternative alternative) | ||||||
|  |              #:override (cons 'index:songnumber songnumber) | ||||||
|  |              (ly:output-def-lookup layout index-markup)))) | ||||||
|  |        (items))) | ||||||
|  |  | ||||||
|  | #(define-markup-list-command (index-in-columns-with-title layout props index-type title-markup) (symbol? markup?) | ||||||
|  |   ( _i "Outputs index alphabetical sorted or in categories" ) | ||||||
|  |     (let ((items (case index-type | ||||||
|  |             ((alphabetical) index-items) | ||||||
|  |             ((categories) category-index-items) | ||||||
|  |             ((authors) author-index-items))) | ||||||
|  |           (title (interpret-markup layout props title-markup))) | ||||||
|  |       (cons title | ||||||
|  |       (interpret-markup-list layout props | ||||||
|  |         (make-columnlayout-markup-list songTocColumns 2 | ||||||
|  |           (let ((h (- (ly:output-def-lookup layout 'paper-height) 12))) | ||||||
|  |             (cons (- h (interval-length (ly:stencil-extent title Y))) h)) | ||||||
|  |           (prepare-item-markup items layout)))))) | ||||||
|  |  | ||||||
|  | indexItem = | ||||||
|  | #(define-music-function (parser location sorttext text) (string? markup?) | ||||||
|  |    "Add a line to the alphabetical index, using the @code{indexItemMarkup} paper variable markup." | ||||||
|  |    (add-index-item! 'indexItemMarkup (prepend-alist-chain 'rawtext text '()) sorttext)) | ||||||
|  |  | ||||||
|  | indexSection = | ||||||
|  | #(define-music-function (parser location sorttext text) (string? markup?) | ||||||
|  |    "Add a section line to the alphabetical index, using @code{indexSectionMarkup} paper variable markup. This can be used to divide the alphabetical index into different sections, for example one section for each first letter." | ||||||
|  |    (add-index-item! 'indexSectionMarkup (prepend-alist-chain 'rawtext text '()) sorttext)) | ||||||
|  |  | ||||||
|  | #(define (extract-and-check-vars-from-header bookheader varlist) | ||||||
|  |   (let* ((headervars (hash-map->list cons (struct-ref (ly:book-header bookheader) 0))) | ||||||
|  |          (extract-var-and-check (lambda (headervar) | ||||||
|  |            (let* ((variableref (assoc-ref headervars headervar)) | ||||||
|  |                   (extracted (if variableref (variable-ref variableref) #f))) | ||||||
|  |               (if (and extracted (not (and (string? extracted) (string-null? extracted)))) extracted #f))))) | ||||||
|  |     (map (lambda (varsymbol) | ||||||
|  |       (cons varsymbol (extract-var-and-check varsymbol)) | ||||||
|  |     ) varlist))) | ||||||
|  |  | ||||||
|  | headerToTOC = #(define-music-function (parser location header label) (ly:book? symbol?) | ||||||
|  |     (define (all-author-ids authors) | ||||||
|  |       (let ((poetIds (find-author-ids-by 'text authors)) | ||||||
|  |             (translatorIds (find-author-ids-by 'translation authors)) | ||||||
|  |             (versePoetData (find-author-id-with-part-numbers 'verse authors)) | ||||||
|  |             (composerIds (find-author-ids-by 'melody authors)) | ||||||
|  |             (verseComposerData (find-author-id-with-part-numbers 'meloverse authors)) | ||||||
|  |             (voiceComposerData (find-author-id-with-part-numbers 'voice authors)) | ||||||
|  |             (compositionIds (find-author-ids-by 'composition authors)) | ||||||
|  |             (adaptionIds (find-author-ids-by 'adaption authors)) | ||||||
|  |             (bridgeIds (find-author-ids-by 'bridge authors)) | ||||||
|  |             (interludeIds (find-author-ids-by 'interlude authors))) | ||||||
|  |         (delete-duplicates | ||||||
|  |           (append poetIds translatorIds (map car versePoetData) composerIds (map car verseComposerData) (map car voiceComposerData) compositionIds adaptionIds bridgeIds interludeIds)) | ||||||
|  |     )) | ||||||
|  |     (let* | ||||||
|  |       ( | ||||||
|  |        (extractedheadervars (extract-and-check-vars-from-header header '(title starttext alttitle categorytitle categories authors songnumber))) | ||||||
|  |        (title (assq-ref extractedheadervars 'title)) | ||||||
|  |        (starttext (assq-ref extractedheadervars 'starttext)) | ||||||
|  |        (alttitle (assq-ref extractedheadervars 'alttitle)) | ||||||
|  |        (categorytitle (assq-ref extractedheadervars 'categorytitle)) | ||||||
|  |        (categories (assq-ref extractedheadervars 'categories)) | ||||||
|  |        (authors (assq-ref extractedheadervars 'authors)) | ||||||
|  |        (songnumber (assq-ref extractedheadervars 'songnumber)) | ||||||
|  |        (textoptions (lambda (text alternative) `(((rawtext . ,text) (alternative . ,alternative) (songnumber . ,songnumber))))) | ||||||
|  |        (add-to-toc! (lambda (toctitle alternative) | ||||||
|  |                       (add-index-item! 'indexItemMarkup (textoptions toctitle alternative) toctitle label))) | ||||||
|  |        ) | ||||||
|  |            (if categories (add-category-index-item! (string-tokenize categories) 'indexItemMarkup (textoptions (if categorytitle categorytitle title) #f) label)) | ||||||
|  |            (if authors (add-author-index-item! (all-author-ids authors) 'indexItemMarkup (textoptions (if categorytitle categorytitle title) #f) label)) | ||||||
|  |            (if starttext (add-to-toc! starttext #t)) | ||||||
|  |            (if alttitle | ||||||
|  |                (if (list? alttitle) | ||||||
|  |                    (for-each (lambda (alt) | ||||||
|  |                                 (add-to-toc! alt #t)) | ||||||
|  |                              alttitle) | ||||||
|  |                    (add-to-toc! alttitle #t))) | ||||||
|  |            (if title (add-to-toc! title #f) #{ #}) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | %% https://github.com/NalaGinrut/guile-csv/blob/master/csv/csv.scm | ||||||
|  |  | ||||||
|  | #(define* (sxml->csv sxml port #:key (delimiter #\,)) | ||||||
|  |   (let* ((d (string delimiter)) | ||||||
|  |          (csv (map (lambda (l) (string-join l d)) sxml))) | ||||||
|  |     (for-each (lambda (l) | ||||||
|  |                 (format port "~a~%" l)) | ||||||
|  |               csv))) | ||||||
|  |  | ||||||
|  | #(define csv-write sxml->csv) | ||||||
|  |  | ||||||
|  | #(define-markup-command (write-toc-csv layout props) () | ||||||
|  |   (define (csv-escape field) | ||||||
|  |     (if (string-null? field) | ||||||
|  |         field | ||||||
|  |         (string-append | ||||||
|  |           "\"" | ||||||
|  |           (ly:string-substitute "\n" "\\n" | ||||||
|  |             (ly:string-substitute "\"" "\\\"" field)) | ||||||
|  |           "\""))) | ||||||
|  |   (define (format-authors authorIds) | ||||||
|  |     (string-join (map (lambda (authorId) (format-author (ly:output-def-lookup layout 'authorFormat) authorId #f)) authorIds) ", ")) | ||||||
|  |   (define cr-regex (ly:make-regex "\r")) | ||||||
|  |   (define crlf-regex (ly:make-regex "\r\n")) | ||||||
|  |   (define para-sep-regex (ly:make-regex "\n[ \t\n]*\n[ \t\n]*")) | ||||||
|  |   (define whitespace-regex (ly:make-regex "[ \t\n]+")) | ||||||
|  |   (define leading-whitespace-regex (ly:make-regex "^[ \t\n]+")) | ||||||
|  |   (define trailing-whitespace-regex (ly:make-regex "[ \t\n]+$")) | ||||||
|  |   (define (cleanup-whitespaces str) | ||||||
|  |     (ly:regex-replace leading-whitespace-regex | ||||||
|  |       (ly:regex-replace trailing-whitespace-regex | ||||||
|  |         (ly:regex-replace whitespace-regex str " ") | ||||||
|  |         "") | ||||||
|  |       "")) | ||||||
|  |   (define (format-info-paragraphs text) | ||||||
|  |     (let* ((para-strings (ly:regex-split | ||||||
|  |                         para-sep-regex | ||||||
|  |                         (ly:regex-replace | ||||||
|  |                          cr-regex | ||||||
|  |                          (ly:regex-replace crlf-regex text "\n") | ||||||
|  |                          "\n"))) | ||||||
|  |          (para-lines (map cleanup-whitespaces para-strings))) | ||||||
|  |     (string-join para-lines "\n"))) | ||||||
|  |   (define (generate-toc-csv labelPageTable) | ||||||
|  |     (let ((song-lines (map (lambda (song) | ||||||
|  |             (let* ((filename (symbol->string (car song))) | ||||||
|  |                    (songvars (cdr song)) | ||||||
|  |                    (page-number (number->string (assoc-get (assq-ref songvars 'label) labelPageTable))) | ||||||
|  |                    (extractedheadervars (extract-and-check-vars-from-header (assq-ref songvars 'header) | ||||||
|  |                       '(title starttext alttitle categorytitle categories authors year_text year_melody year_translation year_composition year_adaption infotext translation pronunciation copyright source))) | ||||||
|  |                    (headervar-or-empty (lambda (varsym) | ||||||
|  |                      (let ((extracted (assq-ref extractedheadervars varsym))) | ||||||
|  |                        (if extracted extracted "")))) | ||||||
|  |                    (authors (assq-ref extractedheadervars 'authors)) | ||||||
|  |                    (poetIds (find-author-ids-by 'text authors)) | ||||||
|  |                    (translatorIds (find-author-ids-by 'translation authors)) | ||||||
|  |                    (versePoetData (find-author-id-with-part-numbers 'verse authors)) | ||||||
|  |                    (composerIds (find-author-ids-by 'melody authors)) | ||||||
|  |                    (verseComposerData (find-author-id-with-part-numbers 'meloverse authors)) | ||||||
|  |                    (voiceComposerData (find-author-id-with-part-numbers 'voice authors)) | ||||||
|  |                    (compositionIds (find-author-ids-by 'composition authors)) | ||||||
|  |                    (adaptionTextIds (find-author-ids-by 'adaption_text authors)) | ||||||
|  |                    (adaptionMusicIds (find-author-ids-by 'adaption_music authors)) | ||||||
|  |                    (bridgeIds (find-author-ids-by 'bridge authors)) | ||||||
|  |                    (interludeIds (find-author-ids-by 'interlude authors))) | ||||||
|  |               (map csv-escape | ||||||
|  |                 (list | ||||||
|  |                   filename | ||||||
|  |                   page-number | ||||||
|  |                   (headervar-or-empty 'title) | ||||||
|  |                   (headervar-or-empty 'starttext) | ||||||
|  |                   (let ((alttitle-value (headervar-or-empty 'alttitle))) | ||||||
|  |                     (if (list? alttitle-value) | ||||||
|  |                         (string-join alttitle-value ", ")  ; Wenn eine Liste, dann zusammenfügen | ||||||
|  |                         alttitle-value))  ; Wenn kein Liste, den originalen Wert verwenden | ||||||
|  |  | ||||||
|  |                   (headervar-or-empty 'categorytitle) | ||||||
|  |                   (headervar-or-empty 'categories) | ||||||
|  |                   (format-authors (append poetIds adaptionTextIds (map car versePoetData))) | ||||||
|  |                   (format-authors translatorIds) | ||||||
|  |                   (format-authors (append composerIds compositionIds adaptionMusicIds bridgeIds interludeIds (map car voiceComposerData) (map car verseComposerData))) | ||||||
|  |                   (headervar-or-empty 'year_text) | ||||||
|  |                   (headervar-or-empty 'year_melody) | ||||||
|  |                   (headervar-or-empty 'year_translation) | ||||||
|  |                   (headervar-or-empty 'year_composition) | ||||||
|  |                   (headervar-or-empty 'year_adaption_text) | ||||||
|  |                   (headervar-or-empty 'year_adaption_music) | ||||||
|  |                   (headervar-or-empty 'copyright) | ||||||
|  |                   (headervar-or-empty 'source) | ||||||
|  |                   (format-info-paragraphs (headervar-or-empty 'infotext)) | ||||||
|  |                   (format-info-paragraphs (headervar-or-empty 'translation)) | ||||||
|  |                   (format-info-paragraphs (headervar-or-empty 'pronunciation)) | ||||||
|  |               )))) | ||||||
|  |             (alist-delete 'imagePage (alist-delete 'emptyPage song-list))))) | ||||||
|  |     (call-with-output-file "toc.csv" | ||||||
|  |       (lambda (port) | ||||||
|  |        (csv-write (cons '( | ||||||
|  |         "filename" | ||||||
|  |         "page-number" | ||||||
|  |         "title" | ||||||
|  |         "starttext" | ||||||
|  |         "alttitle" | ||||||
|  |         "categorytitle" | ||||||
|  |         "categories" | ||||||
|  |         "poets" | ||||||
|  |         "translators" | ||||||
|  |         "composers" | ||||||
|  |         "year_text" | ||||||
|  |         "year_melody" | ||||||
|  |         "year_translation" | ||||||
|  |         "year_composition" | ||||||
|  |         "year_adaption_text" | ||||||
|  |         "year_adaption_music" | ||||||
|  |         "copyright" | ||||||
|  |         "source" | ||||||
|  |         "infotext" | ||||||
|  |         "translation" | ||||||
|  |         "pronunciation" | ||||||
|  |         ) song-lines) port)) | ||||||
|  |   ))) | ||||||
|  |   ; we use a delayed stencil to have all the page references available | ||||||
|  |   (ly:make-stencil | ||||||
|  |     `(delay-stencil-evaluation | ||||||
|  |       ,(delay (let* ((table (ly:output-def-lookup layout 'label-page-table))) | ||||||
|  |         (generate-toc-csv (if (list? table) table '())) | ||||||
|  |         empty-stencil))))) | ||||||
							
								
								
									
										3
									
								
								public_includes/book_top.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								public_includes/book_top.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | \include "../private_includes/book/book_include.ily" | ||||||
|  | \include "../private_includes/book/toc_include.ily" | ||||||
|  | \include "../private_includes/book/appendix.ily" | ||||||
							
								
								
									
										2
									
								
								public_includes/break_paged_output.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								public_includes/break_paged_output.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | \include "lilypond-book-preamble.ly" | ||||||
|  | #(ly:set-option 'separate-page-formats "pdf") | ||||||
							
								
								
									
										88
									
								
								public_includes/layout_bottom.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								public_includes/layout_bottom.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | |||||||
|  | % set the speed of the midi music | ||||||
|  | #(define midiQuarterNoteSpeed (if (defined? 'midiQuarterNoteSpeed) midiQuarterNoteSpeed 90)) | ||||||
|  |  | ||||||
|  | MUSIC = { \transposable #TRANSPOSITION \MUSIC } | ||||||
|  |  | ||||||
|  | verselayout = \layout { | ||||||
|  |   \LAYOUT | ||||||
|  |   \context { | ||||||
|  |     \ChordNames | ||||||
|  |     \override ChordName.font-size = \songTextChordFontSize | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | LAYOUT = \layout { | ||||||
|  |   \LAYOUT | ||||||
|  |   #(let | ||||||
|  |     ((custom-size (ly:output-def-lookup LAYOUT 'size #f))) | ||||||
|  |     (if custom-size (layout-set-staff-size custom-size))) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEXT = \markuplist { | ||||||
|  |   \override #`(transposition . ,TRANSPOSITION) | ||||||
|  |   \override #`(verselayout . ,verselayout) | ||||||
|  |   \override #`(verse-chords . ,#{ \chords { \verseChords } #}) | ||||||
|  |   \override #`(verse-reference-voice . ,#{ \global \firstVoice  #}) | ||||||
|  |   \TEXT | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #(define TEXT_PAGES | ||||||
|  |   (map | ||||||
|  |     (lambda (text) #{ | ||||||
|  |       \markuplist { | ||||||
|  |         \override #`(transposition . ,TRANSPOSITION) | ||||||
|  |         \override #`(verselayout . ,verselayout) | ||||||
|  |         \override #`(verse-chords . ,#{ \chords { \verseChords } #}) | ||||||
|  |         \override #`(verse-reference-voice . ,#{ \global \firstVoice  #}) | ||||||
|  |         #text | ||||||
|  |       } | ||||||
|  |     #}) | ||||||
|  |   (if | ||||||
|  |     (and | ||||||
|  |       (defined? 'TEXT_PAGES) | ||||||
|  |       (pair? TEXT_PAGES)) | ||||||
|  |     TEXT_PAGES | ||||||
|  |     (list TEXT)))) | ||||||
|  |  | ||||||
|  | #(define (add-text-pages text-pages) | ||||||
|  |   (if (pair? text-pages) | ||||||
|  |     (begin | ||||||
|  |       (add-score (car text-pages)) | ||||||
|  |       (for-each | ||||||
|  |         (lambda (text) | ||||||
|  |           (add-music (pageBreak)) | ||||||
|  |           (add-score text)) | ||||||
|  |         (cdr text-pages))))) | ||||||
|  |  | ||||||
|  | #(if (not noStandaloneOutput) | ||||||
|  | (begin | ||||||
|  |   (let ((header (ly:book-header HEADER)) (paper (ly:book-paper HEADER))) | ||||||
|  |     (if header (set! $defaultheader header)) | ||||||
|  |     (if paper (set! $defaultpaper paper)) | ||||||
|  |   ) | ||||||
|  |   (add-score #{ | ||||||
|  |     \score { | ||||||
|  |       \MUSIC | ||||||
|  |       \layout { \LAYOUT } | ||||||
|  |     }#}) | ||||||
|  |   (add-text-pages TEXT_PAGES) | ||||||
|  |   (add-score #{ | ||||||
|  |     \score { | ||||||
|  |       \unfoldRepeats { \MUSIC \INLINESCOREMUSIC } | ||||||
|  |       \midi { | ||||||
|  |         \context { | ||||||
|  |           \Score | ||||||
|  |           % Tempo des midi files | ||||||
|  |           tempoWholesPerMinute = #(/ midiQuarterNoteSpeed 4) | ||||||
|  |         } | ||||||
|  |         \context { | ||||||
|  |           \Staff | ||||||
|  |           \remove "Staff_performer" | ||||||
|  |         } | ||||||
|  |         \context { | ||||||
|  |           \Voice | ||||||
|  |           \consists "Staff_performer" | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }#}) | ||||||
|  | )) | ||||||
							
								
								
									
										5
									
								
								public_includes/layout_top.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								public_includes/layout_top.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | #(ly:set-option 'relative-includes #t) | ||||||
|  |  | ||||||
|  | #(define noDefaultOutput #t) | ||||||
|  |  | ||||||
|  | \include "../private_includes/base/all.ily" | ||||||
							
								
								
									
										7
									
								
								public_includes/pool_bottom.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								public_includes/pool_bottom.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | #(define noDefaultOutput (if (defined? 'noDefaultOutput) noDefaultOutput #f)) | ||||||
|  | HEADER = \bookpart { | ||||||
|  |   \header { | ||||||
|  |     \basicSongInfo | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | \include #(if noDefaultOutput "../private_includes/void.ily" "layout_bottom.ily") | ||||||
							
								
								
									
										5
									
								
								public_includes/pool_top.ily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								public_includes/pool_top.ily
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | #(ly:set-option 'relative-includes #t) | ||||||
|  |  | ||||||
|  | #(define noDefaultOutput (if (defined? 'noDefaultOutput) noDefaultOutput #f)) | ||||||
|  |  | ||||||
|  | \include #(if noDefaultOutput "../private_includes/void.ily" "../private_includes/base/all.ily") | ||||||
| @@ -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 } |  | ||||||
| } |  | ||||||
							
								
								
									
										16
									
								
								styles.ly
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								styles.ly
									
									
									
									
									
								
							| @@ -1,16 +0,0 @@ | |||||||
| #(define bookStyle |  | ||||||
|   (if (not (defined? 'bookStyle)) |  | ||||||
|       #f |  | ||||||
|       bookStyle)) |  | ||||||
|  |  | ||||||
| #(define songStyle |  | ||||||
|   (if (not (defined? 'songStyle)) |  | ||||||
|       (if (not (defined? 'defaultSongStyle)) 'börnel defaultSongStyle) |  | ||||||
|       songStyle)) |  | ||||||
|  |  | ||||||
| #(if (not (boolean? bookStyle)) |  | ||||||
|          (set! songStyle bookStyle)) |  | ||||||
|  |  | ||||||
| #(define (bock-style layout props) |  | ||||||
|   "Whether we have bockstyle or not" |  | ||||||
|   (eq? songStyle 'bock)) |  | ||||||
| @@ -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 |  | ||||||
| @@ -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 |  | ||||||
| @@ -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 |  | ||||||
| @@ -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" |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
							
								
								
									
										311
									
								
								toc_include.ly
									
									
									
									
									
								
							
							
						
						
									
										311
									
								
								toc_include.ly
									
									
									
									
									
								
							| @@ -1,311 +0,0 @@ | |||||||
| % embed all category images in postscript once |  | ||||||
| #(define-markup-list-command (embed-category-images layout props)() |  | ||||||
|    (map (lambda (category) |  | ||||||
|      (interpret-markup layout props |  | ||||||
|        (markup #:epsfileembed (category-image-path (symbol->string (car category)))))) |  | ||||||
|        category-names)) |  | ||||||
|  |  | ||||||
| % print a markup-list in columns |  | ||||||
| #(define-markup-list-command (columnlayout layout props cols margin heightpair lines) (integer? number? pair? markup-list?) |  | ||||||
|    (let create-col-page ((line-width (- (/ (chain-assoc-get 'line-width props |  | ||||||
|                           (ly:output-def-lookup layout 'line-width)) |  | ||||||
|                            cols) margin )) |  | ||||||
|                          (cols cols) |  | ||||||
|                          (height (car heightpair)) |  | ||||||
|                          (restlines lines)) |  | ||||||
|      (cons |  | ||||||
|      (interpret-markup layout props |  | ||||||
|        (make-fill-line-markup |  | ||||||
|         (map (lambda (foo) |  | ||||||
|          (make-general-align-markup Y UP (make-override-markup '(baseline-skip . 1) (make-column-markup |  | ||||||
|           (let add-to-col ((lines restlines) (height-left height)) |  | ||||||
|             (set! restlines lines) |  | ||||||
|             (if (null? lines) |  | ||||||
|               '() |  | ||||||
|               (let* ((line-to-stencil (lambda (line) (interpret-markup layout (cons (list (cons 'line-width line-width) (cons 'baseline-skip 1)) props) (markup line)))) |  | ||||||
|                      (stencil-height (lambda (stencil) (interval-length (ly:stencil-extent stencil Y)))) |  | ||||||
|                      (linestencil (line-to-stencil (car lines))) |  | ||||||
|                      (current-line-height (stencil-height linestencil)) |  | ||||||
|                      (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)))) |  | ||||||
|      (if (null? restlines) |  | ||||||
|          (list) |  | ||||||
|        (create-col-page line-width cols (cdr heightpair) restlines))))) |  | ||||||
|  |  | ||||||
| %%%%%%%%%%%%%%%%%%%%%%% |  | ||||||
| %%%Funktionen für Inhaltsverzeichnis |  | ||||||
| % geklaut von da: |  | ||||||
| % http://lsr.dsi.unimi.it/LSR/Snippet?id=763 |  | ||||||
|  |  | ||||||
| % Usage: |  | ||||||
| % - define and index item with \indexItem $sortstring $markup |  | ||||||
| % - use \indexSection $sortstring $markup to divide the index into several sections |  | ||||||
| % - display the alphabetical index with \markuplines \index |  | ||||||
|  |  | ||||||
| % code ist mostly taken from ./ly/toc-init.ly and just renamed and slightly modfied |  | ||||||
|  |  | ||||||
| %% defined later, in a closure |  | ||||||
| #(define*-public (add-index-item! markup-symbol text sorttext #:optional label) #f) |  | ||||||
| #(define-public (index-items) #f) |  | ||||||
|  |  | ||||||
| #(let ((index-item-list (list))) |  | ||||||
|    (set! add-index-item! |  | ||||||
|    (lambda* (markup-symbol text sorttext #:optional (label (gensym "index"))) |  | ||||||
|        (set! index-item-list |  | ||||||
|        ;; We insert index items sorted from the beginning on and do |  | ||||||
|        ;; not sort them later - this saves pretty much computing time |  | ||||||
|        (insert-alphabetical-sorted! (list label markup-symbol text |  | ||||||
|         ;; this crazy hack is necessary because lilypond depends on guile 1.8 atm |  | ||||||
|         ;; and so the cool unicode conversion functions cannot be used |  | ||||||
|           (ly:string-substitute " " "" |  | ||||||
|           (ly:string-substitute "…" "" |  | ||||||
|           (ly:string-substitute "Č" "C" |  | ||||||
|           (ly:string-substitute "Đ" "D" |  | ||||||
|           (ly:string-substitute "Т" "T" |  | ||||||
|           (ly:string-substitute "Ä" "Ae" |  | ||||||
|           (ly:string-substitute "ä" "ae" |  | ||||||
|           (ly:string-substitute "Ö" "O" |  | ||||||
|           (ly:string-substitute "ö" "oe" |  | ||||||
|           (ly:string-substitute "Ü" "U" |  | ||||||
|           (ly:string-substitute "ü" "ue" sorttext)))))))))))) |  | ||||||
|         index-item-list)) |  | ||||||
|        (make-music 'EventChord |  | ||||||
|          'page-marker #t |  | ||||||
|          'page-label label |  | ||||||
|          'elements (list (make-music 'LabelEvent |  | ||||||
|          'page-label label))))) |  | ||||||
|    (set! index-items (lambda () |  | ||||||
|          index-item-list))) |  | ||||||
|  |  | ||||||
| #(define (insert-alphabetical-sorted! iitem ilist) |  | ||||||
|   (if (null? ilist) |  | ||||||
|       (list iitem) |  | ||||||
|       (if (string-ci<? (cadddr iitem) (cadddr (car ilist))) |  | ||||||
|           (cons iitem ilist) |  | ||||||
|           (cons (car ilist) (insert-alphabetical-sorted! iitem (cdr ilist)))))) |  | ||||||
|  |  | ||||||
| % code for category index |  | ||||||
| #(define*-public (add-category-index-item! categories markup-symbol text #:optional label) #f) |  | ||||||
| #(define-public (category-index-items) #f) |  | ||||||
|  |  | ||||||
| #(let ((category-index-hash (make-hash-table))) |  | ||||||
|    (set! add-category-index-item! |  | ||||||
|    (lambda* (categories markup-symbol text #:optional (label (gensym "index"))) |  | ||||||
|      (for-each (lambda (category) |  | ||||||
|             (let* ((catsym (string->symbol category)) |  | ||||||
|                    (catlist (hashq-ref category-index-hash catsym |  | ||||||
|                               (list (list label 'indexCategoryMarkup category))))) |  | ||||||
|               (if (assq catsym category-names) |  | ||||||
|                 (hashq-set! category-index-hash catsym |  | ||||||
|                   (cons (list label markup-symbol text) catlist)) |  | ||||||
|                 (ly:error "song: <~a> category ~a is not defined!" (markup->string text) category)))) |  | ||||||
|        categories) |  | ||||||
|        (make-music 'EventChord |  | ||||||
|          'page-marker #t |  | ||||||
|          'page-label label |  | ||||||
|          'elements (list (make-music 'LabelEvent |  | ||||||
|          'page-label label))))) |  | ||||||
|    (set! category-index-items (lambda () |  | ||||||
|           (append-map (lambda (kv) (reverse (hashq-ref category-index-hash (car kv) (list)))) category-names)))) |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #(define-markup-command (with-link-symbol-ref layout props symbol arg) |  | ||||||
|    (symbol? markup?) |  | ||||||
|    "call with-link with the label referenced by symbol" |  | ||||||
|    (let ((label (chain-assoc-get symbol props))) |  | ||||||
|      (interpret-markup layout props |  | ||||||
|      (markup #:with-link label arg)))) |  | ||||||
|  |  | ||||||
| #(define-markup-command (category-image-symbol-ref layout props size symbol) |  | ||||||
|    (number? symbol?) |  | ||||||
|    "call category-image with the category referenced by symbol" |  | ||||||
|    (let ((category (chain-assoc-get symbol props))) |  | ||||||
|      (interpret-markup layout props |  | ||||||
|      (markup #:category-image size category)))) |  | ||||||
|  |  | ||||||
| #(define-markup-command (category-name-symbol-ref layout props symbol) |  | ||||||
|    (symbol?) |  | ||||||
|    "get the name of a category referenced by symbol" |  | ||||||
|    (let* ((category (chain-assoc-get symbol props)) |  | ||||||
|           (catname (assq (string->symbol category) category-names))) |  | ||||||
|      (interpret-markup layout props |  | ||||||
|      (markup #:override (cons 'baseline-skip 3.5) (if catname (make-left-column-markup (string-split (cadr catname) #\newline)) category))))) |  | ||||||
|  |  | ||||||
| #(define-markup-command (index-item-with-pattern layout props)() |  | ||||||
|      (let ( |  | ||||||
|             (text (chain-assoc-get 'index:text props)) |  | ||||||
|             (page (chain-assoc-get 'index:page props)) |  | ||||||
|             (width (- |  | ||||||
|                      (chain-assoc-get 'line-width props) |  | ||||||
|                      (interval-length (ly:stencil-extent (interpret-markup layout props "XXXX") X)))) |  | ||||||
|             ) |  | ||||||
|      (interpret-markup layout props |  | ||||||
|        (make-column-markup |  | ||||||
|          (let ((revlist |  | ||||||
|                 (if (markup? text) |  | ||||||
|                     (list text) |  | ||||||
|                     (reverse (map (lambda (stil) (markup #:stencil stil)) |  | ||||||
|                       (wordwrap-string-internal-markup-list layout |  | ||||||
|                         (cons (if (chain-assoc-get 'alternative text) |  | ||||||
|                                 (list (cons 'line-width width) (cons 'font-shape 'italic)) |  | ||||||
|                                 (list (cons 'line-width width))) props) #f |  | ||||||
|                         (chain-assoc-get 'rawtext text)))))) |  | ||||||
|                (target-size-markup |  | ||||||
|                  (make-column-markup |  | ||||||
|                    (list |  | ||||||
|                     (make-simple-markup "Agj") |  | ||||||
|                     (make-vspace-markup 0.2)))) |  | ||||||
|                ) |  | ||||||
|                (reverse (map (lambda (m) |  | ||||||
|                                (make-size-box-to-box-markup #f #t m target-size-markup)) |  | ||||||
|                           (cons |  | ||||||
|                            (make-fill-with-pattern-markup 1 RIGHT "." (car revlist) page) |  | ||||||
|                            (cdr revlist))))))))) |  | ||||||
|  |  | ||||||
| \paper { |  | ||||||
|   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 { |  | ||||||
|     \fontsize #5 \sans \bold \fill-line { \null \fromproperty #'index:text \null } |  | ||||||
|     \vspace #1 |  | ||||||
|   } |  | ||||||
|   indexItemMarkup = \markup \with-link-symbol-ref #'index:label { |  | ||||||
|     \index-item-with-pattern |  | ||||||
|   } |  | ||||||
|   indexSectionMarkup = \markup \override #'(baseline-skip . 1.5) \left-column { |  | ||||||
|     \sans \bold \fontsize #3 \fromproperty #'index:text |  | ||||||
|     \null |  | ||||||
|   } |  | ||||||
|   indexCategoryMarkup = \markup \override #'(baseline-skip . 1.5) \column { |  | ||||||
|     \fill-line { \line { \vcenter \category-image-symbol-ref #7 #'index:text \hspace #3 \vcenter \sans \bold \fontsize #3 \category-name-symbol-ref #'index:text } \null } |  | ||||||
|     \vspace #.4 |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| } |  | ||||||
| %{ |  | ||||||
| #(define-markup-list-command (index layout props) () |  | ||||||
|   ( _i "Outputs an alphabetical sorted index, using the paper |  | ||||||
|   variable @code{indexTitleMarkup} for its title, then the list of |  | ||||||
|   lines built using the @code{indexItem} music function |  | ||||||
|   Usage: @code{\\markuplines \\index}" ) |  | ||||||
|   (cons (interpret-markup layout (cons (list (cons 'index:text "Inhaltsverzeichnis")) props) |  | ||||||
|         (ly:output-def-lookup layout 'indexTitleMarkup)) |  | ||||||
|     (space-lines (chain-assoc-get 'baseline-skip props) |  | ||||||
|         (map (lambda (index-item) |  | ||||||
|          (let ((label (car index-item)) |  | ||||||
|          (index-markup (cadr index-item)) |  | ||||||
|          (text (caddr index-item))) |  | ||||||
|            (interpret-markup |  | ||||||
|              layout |  | ||||||
|              (cons (list (cons 'index:page |  | ||||||
|               (markup #:page-ref label "XXX" "?")) |  | ||||||
|              (cons 'index:text text) |  | ||||||
|              (cons 'index:label label)) |  | ||||||
|              props) |  | ||||||
|              (ly:output-def-lookup layout index-markup)))) |  | ||||||
|        (index-items))))) |  | ||||||
| %} |  | ||||||
| #(define (prepare-item-markup items layout) |  | ||||||
|    (map (lambda (index-item) |  | ||||||
|          (let ((label (car index-item)) |  | ||||||
|                (index-markup (cadr index-item)) |  | ||||||
|                (text (caddr index-item))) |  | ||||||
|            (markup #:override (cons 'index:label label) |  | ||||||
|              #:override (cons 'index:page (markup #:custom-page-number label -1)) |  | ||||||
|              #:override (cons 'index:text text) |  | ||||||
|              (ly:output-def-lookup layout index-markup)))) |  | ||||||
|        (items))) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #(define-markup-list-command (colindex layout props) () |  | ||||||
|   ( _i "Outputs an alphabetical sorted index, using the paper |  | ||||||
|   variable @code{indexTitleMarkup} for its title, then the list of |  | ||||||
|   lines built using the @code{indexItem} music function |  | ||||||
|   Usage: @code{\\markuplines \\index}" ) |  | ||||||
|       (let ((title (interpret-markup layout (cons (list (cons 'index:text "Inhaltsverzeichnis")) props) |  | ||||||
|         (ly:output-def-lookup layout 'indexTitleMarkup)))) |  | ||||||
|         (cons title |  | ||||||
|   (interpret-markup-list layout props |  | ||||||
|     (make-columnlayout-markup-list songTocColumns 2 |  | ||||||
|       (let ((h (- (ly:output-def-lookup layout 'paper-height) 12))) |  | ||||||
|         (cons (- h (interval-length (ly:stencil-extent title Y))) h)) |  | ||||||
|       (prepare-item-markup index-items layout)))))) |  | ||||||
|  |  | ||||||
| #(define-markup-list-command (categoryindex layout props) () |  | ||||||
|   ( _i "Outputs categorized song titles" ) |  | ||||||
|     (if (null-list? (category-index-items)) |  | ||||||
|         (list) |  | ||||||
|       (let ((title (interpret-markup layout (cons (list (cons 'index:text "Inhaltsverzeichnis nach Kategorien")) props) |  | ||||||
|         (ly:output-def-lookup layout 'categoryTitleMarkup)))) |  | ||||||
|         (cons title |  | ||||||
|   (interpret-markup-list layout props |  | ||||||
|     (make-columnlayout-markup-list songTocColumns 2 |  | ||||||
|       (let ((h (- (ly:output-def-lookup layout 'paper-height) 12))) |  | ||||||
|         (cons (- h (interval-length (ly:stencil-extent title Y))) h)) |  | ||||||
|       (prepare-item-markup category-index-items layout))))))) |  | ||||||
|  |  | ||||||
| indexItem = |  | ||||||
| #(define-music-function (parser location sorttext text) (string? markup?) |  | ||||||
|    "Add a line to the alphabetical index, using the @code{indexItemMarkup} paper variable markup." |  | ||||||
|    (add-index-item! 'indexItemMarkup text sorttext)) |  | ||||||
|  |  | ||||||
| indexSection = |  | ||||||
| #(define-music-function (parser location sorttext text) (string? markup?) |  | ||||||
|    "Add a section line to the alphabetical index, using @code{indexSectionMarkup} paper variable markup. This can be used to divide the alphabetical index into different sections, for example one section for each first letter." |  | ||||||
|    (add-index-item! 'indexSectionMarkup text sorttext)) |  | ||||||
|  |  | ||||||
| %{ |  | ||||||
| addTitleToTOC = #(define-music-function (parser location title) (string?) |  | ||||||
|   #{ |  | ||||||
|     \indexItem #title \markup { #title } |  | ||||||
|   #}) |  | ||||||
|  |  | ||||||
| addAltTitleToTOC = #(define-music-function (parser location title) (string?) |  | ||||||
|   #{ |  | ||||||
|     \indexItem #title \markup { \italic #title } |  | ||||||
|   #}) |  | ||||||
| %} |  | ||||||
|  |  | ||||||
| #(define (extract-var-from-module module sym) |  | ||||||
|   (let ((variableref (assoc-ref module sym))) |  | ||||||
|     (if variableref (variable-ref variableref) #f)) |  | ||||||
|   ) |  | ||||||
|  |  | ||||||
| headerToTOC = #(define-music-function (parser location header label) (ly:book? symbol?) |  | ||||||
|     (let* |  | ||||||
|       ( |  | ||||||
|        (headervars (hash-map->list cons (struct-ref (ly:book-header header) 0))) |  | ||||||
|        (extract-var-and-check (lambda (headervar) (let |  | ||||||
|                                                    ((extracted (extract-var-from-module headervars headervar))) |  | ||||||
|                                                    (if (and extracted (not (string-null? extracted))) extracted #f) |  | ||||||
|                                                     ))) |  | ||||||
|        (title (extract-var-and-check 'title)) |  | ||||||
|        (alttitle (extract-var-and-check 'alttitle)) |  | ||||||
|        (altalttitle (extract-var-and-check 'altalttitle)) |  | ||||||
|        (categorytitle (extract-var-and-check 'categorytitle)) |  | ||||||
|        (categories (extract-var-and-check 'categories)) |  | ||||||
|        (add-to-toc! (lambda (toctitle tocmarkup) |  | ||||||
|                       (add-index-item! 'indexItemMarkup tocmarkup toctitle label))) |  | ||||||
|        ) |  | ||||||
|            (if categories (add-category-index-item! (string-tokenize categories) 'indexItemMarkup (cons (list (cons 'rawtext (if categorytitle categorytitle title))) '()) label)) |  | ||||||
|            (if alttitle (add-to-toc! alttitle (cons (list (cons 'rawtext alttitle) (cons 'alternative #t)) '()))) |  | ||||||
|            (if altalttitle (add-to-toc! altalttitle (cons (list (cons 'rawtext altalttitle) (cons 'alternative #t)) '()))) |  | ||||||
|            (if title (add-to-toc! title (cons (list (cons 'rawtext title)) '())) #{ #}) |  | ||||||
|     )) |  | ||||||
| @@ -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)) |  | ||||||
| @@ -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)))))) |  | ||||||
		Reference in New Issue
	
	Block a user