2 Commits
Author SHA1 Message Date
tux 7de31cf0dd chapter toc 2026-07-07 12:16:13 +02:00
tux ae72640b1a chapters for every pagetype 2026-07-07 11:05:47 +02:00
2 changed files with 83 additions and 8 deletions
+42 -6
View File
@@ -216,6 +216,32 @@ songs =
(end (if (null? (cdr chs)) total (cdadr chs))) (end (if (null? (cdr chs)) total (cdadr chs)))
(cnt (count-bookmark-songs start end))) (cnt (count-bookmark-songs start end)))
(loop (cdr chs) (cons (list start title cnt) acc)))))) (loop (cdr chs) (cons (list start title cnt) acc))))))
;; Aktuell aktives Kapitel (Titel-String) waehrend des Durchlaufs. Wird
;; gesetzt, sobald ein Kapitel aktiviert (aus `pending` entfernt) wird --
;; egal ob auf einer Seite (chapter-prefixed-markup) oder auf dem ersten
;; Song. Jeder danach folgende Song erhaelt dieses Kapitel als
;; chapterref-Header-Feld, woraus toc_include.ily den Kapitel-Index baut.
(current-chapter #f)
;; Stellt einer beliebigen Seite (markup-/image-/emptyPage) den Kapitel-
;; Eintrag (chapter-to-pdf-toc) bei, falls an Position `this-index` ein
;; Kapitel faellig ist, und entfernt es aus `pending`. So fuehrt die
;; Kapitel-Referenz zur ersten Seite nach dem \songsChapter -- egal
;; welcher Seitentyp das ist. Der Eintrag wird als unsichtbares Overlay
;; (\combine) beigelegt, damit er das Seitenlayout nicht veraendert;
;; \with-dimensions gibt dem sonst extent-losen pdfmark einen minimalen
;; Extent, damit er auch auf leeren Seiten nicht verworfen wird.
(chapter-prefixed-markup
(lambda (this-index base-markup)
(if (and (pair? pending) (<= (car (car pending)) this-index))
(let ((cnt (caddr (car pending)))
(title (cadr (car pending))))
(set! pending (cdr pending))
(set! current-chapter title)
(make-combine-markup
base-markup
(make-with-dimensions-markup '(0 . 0) '(0 . 0.1)
(make-chapter-to-pdf-toc-markup cnt title))))
base-markup)))
(index 0)) (index 0))
(for-each (lambda (songitems) (for-each (lambda (songitems)
(let ((this-index index)) (let ((this-index index))
@@ -224,12 +250,15 @@ songs =
(let ((filename (car songitems)) (let ((filename (car songitems))
(songvars (cdr songitems))) (songvars (cdr songitems)))
(if (eq? filename 'emptyPage) (if (eq? filename 'emptyPage)
#{ \bookpart { \markup { \null } } #} #{ \bookpart { \markup { $(chapter-prefixed-markup this-index (make-null-markup)) } } #}
(if (eq? filename 'markupPage) (if (eq? filename 'markupPage)
#{ \bookpart { \markup { $(assq-ref songvars 'markup) } } #} ;; Kapitelanfang auf einer markuppage: Kapitel-Eintrag wird dieser
;; Seite beigelegt (siehe chapter-prefixed-markup).
#{ \bookpart { \markup { $(chapter-prefixed-markup this-index (assq-ref songvars 'markup)) } } #}
(if (eq? filename 'imagePage) (if (eq? filename 'imagePage)
(let ((xsize (assq-ref songvars 'xsize)) (let* ((xsize (assq-ref songvars 'xsize))
(filename (ly:format "~a/~a" imagePagePath (assq-ref songvars 'filename)))) (filename (ly:format "~a/~a" imagePagePath (assq-ref songvars 'filename)))
(img-markup #{ \markup { \pagecenter { \epsfile #X #xsize #filename } } #}))
#{ \bookpart { #{ \bookpart {
\paper { \paper {
%{ %{
@@ -243,7 +272,7 @@ songs =
last-bottom-spacing = #'((basic-distance . 0) (minimum-distance . 0) (padding . 0)) last-bottom-spacing = #'((basic-distance . 0) (minimum-distance . 0) (padding . 0))
page-count = 1 page-count = 1
} }
\markup { \pagecenter { \epsfile #X #xsize #filename } } \markup { $(chapter-prefixed-markup this-index img-markup) }
} #} } #}
) )
;; Ist ein Kapitel faellig (Start <= aktuelle Position) und dies ein ;; Ist ein Kapitel faellig (Start <= aktuelle Position) und dies ein
@@ -253,18 +282,25 @@ songs =
(chaptertitle (if (and (pair? pending) (<= (car (car pending)) this-index)) (chaptertitle (if (and (pair? pending) (<= (car (car pending)) this-index))
(cadr (car pending)) #f)) (cadr (car pending)) #f))
(chaptercount (if chaptertitle (caddr (car pending)) 0)) (chaptercount (if chaptertitle (caddr (car pending)) 0))
;; Startet das Kapitel erst auf diesem Song (nicht schon auf
;; einer vorangehenden Seite), wird current-chapter jetzt
;; gesetzt und pending entfernt -- vor dem Bau des Headers,
;; damit chapterref bereits das neue Kapitel enthaelt.
(_ (if chaptertitle
(begin (set! current-chapter chaptertitle)
(set! pending (cdr pending)))))
(header #{ \bookpart { $(assq-ref songvars 'header) \header { (header #{ \bookpart { $(assq-ref songvars 'header) \header {
songfilename = $(symbol->string filename) songfilename = $(symbol->string filename)
myindexlabel = #(assq-ref songvars 'label) myindexlabel = #(assq-ref songvars 'label)
songnumber = #(number->string newnumber) songnumber = #(number->string newnumber)
chaptertitle = #chaptertitle chaptertitle = #chaptertitle
chaptercount = #chaptercount chaptercount = #chaptercount
chapterref = #current-chapter
} } #}) } } #})
(music (assq-ref songvars 'music)) (music (assq-ref songvars 'music))
(layout (assq-ref songvars 'layout)) (layout (assq-ref songvars 'layout))
(text-pages (assq-ref songvars 'text-pages)) (text-pages (assq-ref songvars 'text-pages))
(label (assq-ref songvars 'label))) (label (assq-ref songvars 'label)))
(if chaptertitle (set! pending (cdr pending)))
(set! song-number newnumber) (set! song-number newnumber)
#{ #{
\bookpart { \bookpart {
+41 -2
View File
@@ -132,6 +132,37 @@
author-index-hash) author-index-hash)
(lambda (a b) (string-ci<? (car a) (car b)))))))) (lambda (a b) (string-ci<? (car a) (car b))))))))
% code for chapter index
% Anders als bei Kategorien/Autoren ergibt sich die Kapitelzugehoerigkeit nicht
% aus dem Song-Header, sondern aus dem \songsChapter, das dem Song vorangeht
% (in book_include.ily als Header-Feld chapterref an jeden Song gehaengt).
% Die Kapitel behalten hier ihre Auftritts-Reihenfolge (nicht alphabetisch),
% ebenso die Songs innerhalb eines Kapitels ihre Song-Reihenfolge.
#(define*-public (add-chapter-index-item! chapter markup-symbol textoptions #:optional label) #f)
#(define-public (chapter-index-items) #f)
#(let ((chapter-index-hash (make-hash-table))
(chapter-order '()))
(set! add-chapter-index-item!
(lambda* (chapter markup-symbol textoptions #:optional (label (gensym "index")))
(let* ((chaptersym (string->symbol chapter))
(existing (hashq-ref chapter-index-hash chaptersym #f))
(chapterlist (or existing
(begin
(set! chapter-order (cons chaptersym chapter-order))
(list (list label 'indexChapterMarkup `(((combine-with-next . #t) (rawtext . ,chapter))))))))
)
(hashq-set! chapter-index-hash chaptersym
(cons (list label markup-symbol textoptions) chapterlist)))
(make-music 'EventChord
'page-marker #t
'page-label label
'elements (list (make-music 'LabelEvent
'page-label label)))))
(set! chapter-index-items (lambda ()
(append-map (lambda (chaptersym) (reverse (hashq-ref chapter-index-hash chaptersym (list))))
(reverse chapter-order)))))
#(define-markup-command (with-link-symbol-ref layout props symbol arg) #(define-markup-command (with-link-symbol-ref layout props symbol arg)
(symbol? markup?) (symbol? markup?)
@@ -215,6 +246,11 @@
(make-null-markup)) (make-null-markup))
\vspace #.4 \vspace #.4
} }
indexChapterMarkup = \markup \override #'(baseline-skip . 1.5) \left-column {
\vspace #1
\sans \bold \fontsize #3 \fromproperty #'index:text
\vspace #.4
}
} }
#(define (prepare-item-markup items layout) #(define (prepare-item-markup items layout)
@@ -247,7 +283,8 @@
(let ((items (case index-type (let ((items (case index-type
((alphabetical) index-items) ((alphabetical) index-items)
((categories) category-index-items) ((categories) category-index-items)
((authors) author-index-items))) ((authors) author-index-items)
((chapters) chapter-index-items)))
(title (interpret-markup layout props title-markup))) (title (interpret-markup layout props title-markup)))
(cons title (cons title
(interpret-markup-list layout props (interpret-markup-list layout props
@@ -294,7 +331,7 @@ headerToTOC = #(define-music-function (parser location header label) (ly:book? s
)) ))
(let* (let*
( (
(extractedheadervars (extract-and-check-vars-from-header header '(title starttext alttitle categorytitle categories authors songnumber))) (extractedheadervars (extract-and-check-vars-from-header header '(title starttext alttitle categorytitle categories authors songnumber chapterref)))
(title (assq-ref extractedheadervars 'title)) (title (assq-ref extractedheadervars 'title))
(starttext (assq-ref extractedheadervars 'starttext)) (starttext (assq-ref extractedheadervars 'starttext))
(alttitle (assq-ref extractedheadervars 'alttitle)) (alttitle (assq-ref extractedheadervars 'alttitle))
@@ -302,12 +339,14 @@ headerToTOC = #(define-music-function (parser location header label) (ly:book? s
(categories (assq-ref extractedheadervars 'categories)) (categories (assq-ref extractedheadervars 'categories))
(authors (assq-ref extractedheadervars 'authors)) (authors (assq-ref extractedheadervars 'authors))
(songnumber (assq-ref extractedheadervars 'songnumber)) (songnumber (assq-ref extractedheadervars 'songnumber))
(chapterref (assq-ref extractedheadervars 'chapterref))
(textoptions (lambda (text alternative) `(((rawtext . ,text) (alternative . ,alternative) (songnumber . ,songnumber))))) (textoptions (lambda (text alternative) `(((rawtext . ,text) (alternative . ,alternative) (songnumber . ,songnumber)))))
(add-to-toc! (lambda (toctitle alternative) (add-to-toc! (lambda (toctitle alternative)
(add-index-item! 'indexItemMarkup (textoptions toctitle alternative) toctitle label))) (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 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 authors (add-author-index-item! (all-author-ids authors) 'indexItemMarkup (textoptions (if categorytitle categorytitle title) #f) label))
(if chapterref (add-chapter-index-item! chapterref 'indexItemMarkup (textoptions (if categorytitle categorytitle title) #f) label))
(if starttext (add-to-toc! starttext #t)) (if starttext (add-to-toc! starttext #t))
(if alttitle (if alttitle
(if (list? alttitle) (if (list? alttitle)