diff --git a/private_includes/base/all.ily b/private_includes/base/all.ily index 49cdc4e..daad8f6 100644 --- a/private_includes/base/all.ily +++ b/private_includes/base/all.ily @@ -39,6 +39,7 @@ \include "title_with_category_images.ily" \include "chord_settings.ily" \include "chordpro.ily" +\include "data_extractor.ily" \include "transposition.ily" \include "markup_tag_groups_hack.ily" \include "verses_with_chords.ily" diff --git a/private_includes/base/data_extractor.ily b/private_includes/base/data_extractor.ily new file mode 100644 index 0000000..e7537ed --- /dev/null +++ b/private_includes/base/data_extractor.ily @@ -0,0 +1,82 @@ +%%% Extrahiert Informationen aus einem ly:music-Objekt und liefert eine alist +%%% mit String-Werten zurueck (z.B. ((time . "4/4") (key . "d minor"))). +%%% Benoetigt LilyPond >= 2.26. + +%% note-name->lily-string liegt im Modul (lily display-lily). +#(use-modules (lily display-lily)) + +#(begin + + ;; --- Taktangabe -------------------------------------------------------- + + ;; Numerator einer Taktangabe kann eine Zahl oder eine Liste sein. + (define (numerator->string num) + (if (list? num) + (string-join (map number->string num) "+") + (number->string num))) + + ;; Liefert die Taktangabe als String (z.B. "4/4" oder "7/8") oder #f. + ;; time-signature ist ein Paar (numerator . denominator). + (define (time-music->string m) + (let ((ts (ly:music-property m 'time-signature))) + (and (pair? ts) + (string-append (numerator->string (car ts)) "/" + (number->string (cdr ts)))))) + + ;; --- Tonart ------------------------------------------------------------ + + ;; Liefert die Tonart als String (z.B. "d minor" oder "c major") oder #f. + ;; Vorgehen wie in LilyPonds eigenem \displayMusic (define-music-display- + ;; methods.scm): pitch-alist nach c zuruecktransponieren und mit den + ;; bekannten Modus-Definitionen vergleichen. note-name->lily-string liefert + ;; den Grundton in der aktuell eingestellten Notensprache. + (define (key-music->string m) + (let ((tonic (ly:music-property m 'tonic)) + (alist (ly:music-property m 'pitch-alist))) + (and (ly:pitch? tonic) (pair? alist) + (let* ((c-alist (ly:transpose-key-alist alist (- tonic))) + (mode (any (lambda (mode) + (and (equal? (ly:parser-lookup mode) c-alist) + (symbol->string mode))) + '(major minor)))) + (and mode + (string-append (symbol->string (note-name->lily-string tonic)) + " " mode)))))) + + ;; --- Header-Metadaten ---------------------------------------------------- + + ;; Nimmt einen Bookpart entgegen (wie HEADER aus pool_bottom.ily) und + ;; liefert dessen Header-Felder als alist, z.B. + ;; ((title . "Ako umram") (authors . (("..." text melody))) ...). + ;; Die Werte bleiben unveraendert, wie sie im \header definiert wurden + ;; (Strings, Listen, Markups ...). + (define (bookpart->header-alist bookpart) + (let ((header (ly:book-header bookpart))) + (if (module? header) + (sort + (filter-map (lambda (entry) + (and (variable-bound? (cdr entry)) + (cons (car entry) (variable-ref (cdr entry))))) + (module-map cons header)) + (lambda (a b) + (stringstring (car a)) + (symbol->string (car b))))) + '()))) + + ;; --- Hauptfunktion ----------------------------------------------------- + + ;; Liefert das erste Music-Objekt mit gegebenem Namen (oder #f). + (define (first-named-music music music-name) + (let ((matches (extract-named-music music music-name))) + (and (pair? matches) (car matches)))) + + ;; Nimmt ly:music entgegen und liefert eine alist mit String-Werten. + (define (music->data-alist music) + (let* ((time-m (first-named-music + music '(TimeSignatureMusic ReferenceTimeSignatureMusic))) + (key-m (first-named-music music 'KeyChangeEvent)) + (time-s (and time-m (time-music->string time-m))) + (key-s (and key-m (key-music->string key-m)))) + (append + (if time-s (list (cons 'time time-s)) '()) + (if key-s (list (cons 'key key-s)) '()))))) diff --git a/public_includes/layout_bottom.ily b/public_includes/layout_bottom.ily index 3a4f03a..d53edc1 100644 --- a/public_includes/layout_bottom.ily +++ b/public_includes/layout_bottom.ily @@ -72,6 +72,8 @@ TEXT = \markuplist { (if paper (set! $defaultpaper paper)) ) + ;(ly:warning (format #f "~a" (bookpart->header-alist HEADER))) + ;; ChordPro export: Store filename and extract metadata from basicSongInfo FIRST (when (and (defined? 'chordpro-export-enabled) chordpro-export-enabled) ;; Use ly:parser-output-name which returns the output basename