1 ;;;; layout-page-tweaks.scm -- page breaking and page layout
3 ;;;; source file of the GNU LilyPond music typesetter
5 ;;;; (c) 2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
6 ;;;; 2006 Nicolas Sceaux <nicolas.sceaux@free.fr>
8 (define-module (scm layout-page-dump)
9 #:use-module (srfi srfi-1)
10 #:use-module (ice-9 pretty-print)
11 #:use-module (scm paper-system)
12 #:use-module (scm page)
13 #:use-module (scm layout-page-layout)
15 #:export (write-page-breaks
16 ;; utilisties for writing other page dump functions
17 record-tweaks dump-all-tweaks))
19 (define (record-tweaks what property-pairs tweaks)
20 (let ((key (ly:output-def-lookup (ly:grob-layout what)
23 (when (ly:grob-property what 'when)))
24 (if (not (hash-ref tweaks key))
25 (hash-set! tweaks key '()))
27 (acons when property-pairs
28 (hash-ref tweaks key)))))
30 (define (graceless-moment mom)
31 (ly:make-moment (ly:moment-main-numerator mom)
32 (ly:moment-main-denominator mom)
35 (define (moment->skip mom)
36 (let ((main (if (> (ly:moment-main-numerator mom) 0)
37 (format "\\skip 1*~a/~a"
38 (ly:moment-main-numerator mom)
39 (ly:moment-main-denominator mom))
41 (grace (if (< (ly:moment-grace-numerator mom) 0)
42 (format "\\grace { \\skip 1*~a/~a }"
43 (- (ly:moment-grace-numerator mom))
44 (ly:moment-grace-denominator mom))
46 (format "~a~a" main grace)))
48 (define (dump-tweaks out-port tweak-list last-moment)
49 (if (not (null? tweak-list))
50 (let* ((now (caar tweak-list))
51 (diff (ly:moment-sub now last-moment))
52 (these-tweaks (cdar tweak-list))
53 (skip (moment->skip diff))
54 (line-break-str (if (assoc-get 'line-break these-tweaks #f)
57 (page-break-str (if (assoc-get 'page-break these-tweaks #f)
60 (space-tweaks (format "\\spacingTweaks #'~a\n"
61 (with-output-to-string
64 (assoc-get 'spacing-parameters
65 these-tweaks '()))))))
66 (base (format "~a~a~a"
70 (format out-port "~a\n~a\n" skip base)
71 (dump-tweaks out-port (cdr tweak-list) (graceless-moment now)))))
73 (define (dump-all-tweaks pages tweaks output-name)
74 (let* ((paper (ly:paper-book-paper (page-property (car pages) 'paper-book)))
75 (name (format "~a-page-layout.ly" output-name))
76 (out-port (open-output-file name)))
78 (ly:message "Writing page layout to ~a" name)
81 (format out-port "~a = {" key)
82 (dump-tweaks out-port (reverse val) (ly:make-moment 0 1))
83 (display "}" out-port))
85 (close-port out-port)))
87 (define (write-page-breaks pages output-name)
88 "Dump page breaks and tweaks"
89 (let ((tweaks (make-hash-table 60)))
90 (define (handle-page page)
91 "Computes vertical stretch for each music line of `page' (starting by
92 the smallest lines), then record the tweak parameters of each line to
93 the `tweaks' hash-table."
94 (let* ((lines (page-property page 'lines))
95 (line-count (length lines))
96 (compute-max-stretch (ly:output-def-lookup
97 (ly:paper-book-paper (page-property page
99 'system-maximum-stretch-procedure))
100 (page-number (page-property page 'page-number)))
101 (let set-line-stretch! ((sorted-lines (sort lines
105 (rest-height ;; sum of stretchable line heights
108 (filter stretchable-line? lines))))
109 (space-left (page-maximum-space-left page)))
110 (if (not (null? sorted-lines))
111 (let* ((line (first sorted-lines))
112 (height (line-height line))
113 (stretch (min (compute-max-stretch line)
114 (if (and (stretchable-line? line)
115 (positive? rest-height))
116 (/ (* height space-left) rest-height)
118 (set! (ly:prob-property line 'stretch) stretch)
119 (set-line-stretch! (cdr sorted-lines)
120 (if (stretchable-line? line)
121 (- rest-height height)
123 (- space-left stretch)))))
124 (let record-line-tweak ((lines lines)
127 (if (not (null? lines))
128 (let ((line (first lines)))
129 (if (not (ly:prob-property? line 'is-title))
131 (ly:spanner-bound (ly:prob-property line 'system-grob) LEFT)
133 (page-break . ,is-first-line)
135 . ((page-number . ,page-number)
136 (system-index . ,index)
137 (system-stretch . ,(ly:prob-property line 'stretch))
138 (system-Y-extent . ,(paper-system-extent line Y))
139 (system-refpoint-Y-extent . ,(paper-system-staff-extents line))
140 (page-system-count . ,line-count)
141 (page-printable-height . ,(page-printable-height page))
142 (page-space-left . ,(page-property page 'space-left)))))
144 (record-line-tweak (cdr lines) #f (1+ index)))))))
145 ;; Compute tweaks for each page, then dump them to the page-layout file
146 (for-each handle-page pages)
147 (dump-all-tweaks pages tweaks output-name)))