Use chapters for digital toc

* introduce \songsChapter and \markuppage
* have nested chapters in PDF toc
This commit is contained in:
tux
2026-07-05 14:09:44 +02:00
parent 50e08220c4
commit 7076b16b63
3 changed files with 145 additions and 56 deletions
@@ -26,25 +26,49 @@
#(define pdf-encode (@@ (lily framework-ps) pdf-encode))
% PDF tags
#(define-markup-command (title-to-pdf-toc layout props title) (string?)
% Erzeugt ein PDF-Lesezeichen (Outline-Eintrag) auf der aktuellen Seite.
% count = Anzahl der direkten Unterpunkte, die (in Seitenreihenfolge) direkt
% nachfolgen. 0 = Blatt-Eintrag (kein /Count), >0 = aufgeklappt,
% <0 = zugeklappt (Betrag = Anzahl direkter Kinder).
#(define (make-pdf-toc-stencil title count)
(if (string-null? title)
empty-stencil
(ly:make-stencil
(list 'embedded-ps
(ly:format
"[/Action /GoTo /View [/XYZ -4 currentpagedevice /PageSize get 1 get 4 add null] /Title (~a) /OUT pdfmark" (pdf-encode title)))
"[~a/Action /GoTo /View [/XYZ -4 currentpagedevice /PageSize get 1 get 4 add null] /Title (~a) /OUT pdfmark"
(if (= count 0) "" (ly:format "/Count ~a " count))
(pdf-encode title)))
empty-interval empty-interval
;'(0 . 0) '(0 . 0)
)))
% Einzelner (Blatt-)Eintrag im PDF-Inhaltsverzeichnis.
#(define-markup-command (title-to-pdf-toc layout props title) (string?)
(make-pdf-toc-stencil title 0))
% Kapitel-Eintrag mit verschachtelten Unterpunkten.
% count = Anzahl der direkt nachfolgenden Einträge, die diesem Kapitel
% untergeordnet werden sollen (positiv = aufgeklappt, negativ = zugeklappt).
#(define-markup-command (chapter-to-pdf-toc layout props count title) (integer? string?)
(make-pdf-toc-stencil title count))
#(define-markup-command (build-full-title layout props right)(boolean?)
(interpret-markup layout (prepend-alist-chain 'songfilename (chain-assoc-get 'header:songfilename props "") props)
(let* ((title (chain-assoc-get 'header:title props ""))
(starttext (chain-assoc-get 'header:starttext props #f))
(pdfbookmark (if starttext (string-append starttext " | " title) title))
(chaptertitle (chain-assoc-get 'header:chaptertitle props #f))
(chaptercount (chain-assoc-get 'header:chaptercount props 0))
(title-markup (ly:output-def-lookup layout (if right 'oddTitleLineMarkup 'evenTitleLineMarkup))))
(if title
(markup #:title-to-pdf-toc pdfbookmark title-markup)
;; Ist dieses Lied das erste eines Kapitels, wird der Kapitel-Eintrag
;; unmittelbar vor dem Lied-Eintrag ausgegeben, damit die pdfmark-/OUT-
;; Reihenfolge (Elternteil vor Kindern) im PDF-Stream garantiert stimmt.
(if (and (string? chaptertitle) (not (string-null? chaptertitle)))
(markup #:chapter-to-pdf-toc chaptercount chaptertitle
#:title-to-pdf-toc pdfbookmark title-markup)
(markup #:title-to-pdf-toc pdfbookmark title-markup))
make-null-markup)
)))