From 4d8f773563ad6b84f08d1c30667f444178fb75d0 Mon Sep 17 00:00:00 2001 From: Nicolas Sceaux Date: Sun, 19 Oct 2008 16:19:44 +0200 Subject: [PATCH] Nested book parts: in header/footer texts, make the difference between part last page and book last page. --- input/new/book-parts.ly | 41 ++++++++++++++++++++++++++++++++++++-- lily/page-breaking.cc | 13 +++++++----- ly/titling-init.ly | 21 ++++++++++++++++++- scm/layout-page-layout.scm | 39 ++++++++++++++++++++---------------- scm/page.scm | 15 +++++++------- scm/titling.scm | 6 ++++-- 6 files changed, 100 insertions(+), 35 deletions(-) diff --git a/input/new/book-parts.ly b/input/new/book-parts.ly index ce0c11ce04..19617d026d 100644 --- a/input/new/book-parts.ly +++ b/input/new/book-parts.ly @@ -10,15 +10,52 @@ Each part last page can be affected by @code{ragged-bottom-last}. #(set-default-paper-size "a6") +\paper { + oddFooterMarkup = "toplevel paper footer" + id ="\ntoplevel paper\n" +} + \book { %% book-level paper, which is inherited by all bookparts - \paper { ragged-last-bottom = ##t } + \paper { + id = "\nbook level paper\n" + ragged-last-bottom = ##t + %% Page footer: add a different part-tagline at part last page + oddFooterMarkup = \markup { + \column { + \fill-line { + %% Copyright header field only on book first page. + \on-the-fly #first-page \fromproperty #'header:copyright + } + \fill-line { + %% Part tagline header field only on each part last page. + \on-the-fly #part-last-page \fromproperty #'header:parttagline + } + \fill-line { + %% Tagline header field only on book last page. + \on-the-fly #last-page \fromproperty #'header:tagline + } + toto + } + } + } %% book-level header, which is inherited by the first bookpart - \header { title = "Book title" } + \header { + title = "Book title" + copyright = "Copyright line on book first page" + parttagline = "Part tagline" + tagline = "Book tagline" + } + %% first book part \bookpart { + %% a different page breaking function may be used on each part + \paper { #(define page-breaking optimal-page-breaks) } \header { subtitle = "First part" } \markup { The first book part } + \markup { a page break } + \pageBreak + \markup { first part last page } \markup \wordwrap { with ragged-last-bottom (see the space below this text) } } %% an other book part diff --git a/lily/page-breaking.cc b/lily/page-breaking.cc index 10a428de5b..56746a6a2f 100644 --- a/lily/page-breaking.cc +++ b/lily/page-breaking.cc @@ -212,6 +212,7 @@ Page_breaking::systems () Real Page_breaking::page_height (int page_num, bool last) const { + bool last_part = ly_scm2bool (book_->paper_->c_variable ("part-is-last")); SCM mod = scm_c_resolve_module ("scm page"); SCM calc_height = scm_c_module_lookup (mod, "calc-printable-height"); SCM make_page = scm_c_module_lookup (mod, "make-page"); @@ -222,7 +223,8 @@ Page_breaking::page_height (int page_num, bool last) const SCM page = scm_apply_0 (make_page, scm_list_n ( book_->self_scm (), ly_symbol2scm ("page-number"), scm_from_int (page_num), - ly_symbol2scm ("is-last"), scm_from_bool (last), + ly_symbol2scm ("is-last"), scm_from_bool (last_part && last), + ly_symbol2scm ("is-part-last"), scm_from_bool (last), SCM_UNDEFINED)); SCM height = scm_apply_1 (calc_height, page, SCM_EOL); return scm_to_double (height) - page_top_space_; @@ -264,14 +266,15 @@ Page_breaking::make_pages (vector lines_per_page, SCM systems) { SCM page_num = scm_from_int (i + first_page_number); bool last_from_part = (i == lines_per_page.size () - 1); - SCM last_from_book = scm_from_bool (last_part && last_from_part); + bool last_from_book = (last_part && last_from_part); SCM rag = scm_from_bool (ragged () || (last_from_part && ragged_last ())); SCM line_count = scm_from_int (lines_per_page[i]); SCM lines = scm_list_head (systems, line_count); SCM page = scm_apply_0 (make_page, - scm_list_n (book, lines, page_num, - rag, last_from_book, SCM_UNDEFINED)); - + scm_list_n (book, lines, page_num, rag, + scm_from_bool (last_from_book), + scm_from_bool (last_from_part), + SCM_UNDEFINED)); /* collect labels */ for (SCM l = lines ; scm_is_pair (l) ; l = scm_cdr (l)) { diff --git a/ly/titling-init.ly b/ly/titling-init.ly index 9ef8cd48dd..ebec85b53e 100644 --- a/ly/titling-init.ly +++ b/ly/titling-init.ly @@ -69,9 +69,16 @@ scoreTitleMarkup = \markup { \column { } } +%% Book first page and last page predicates #(define (first-page layout props arg) + (define (ancestor layout) + "Return the topmost layout ancestor" + (let ((parent (ly:output-def-parent layout))) + (if (not (ly:output-def? parent)) + layout + (ancestor parent)))) (if (= (chain-assoc-get 'page:page-number props -1) - (ly:output-def-lookup layout 'first-page-number)) + (ly:output-def-lookup (ancestor layout) 'first-page-number)) (interpret-markup layout props arg) empty-stencil)) @@ -80,6 +87,18 @@ scoreTitleMarkup = \markup { \column { (interpret-markup layout props arg) empty-stencil)) +%% Part first page and last page predicates +#(define (part-first-page layout props arg) + (if (= (chain-assoc-get 'page:page-number props -1) + (ly:output-def-lookup layout 'first-page-number)) + (interpret-markup layout props arg) + empty-stencil)) + +#(define (part-last-page layout props arg) + (if (chain-assoc-get 'page:part-last? props #f) + (interpret-markup layout props arg) + empty-stencil)) + #(define (not-first-page layout props arg) (if (not (= (chain-assoc-get 'page:page-number props -1) (ly:output-def-lookup layout 'first-page-number))) diff --git a/scm/layout-page-layout.scm b/scm/layout-page-layout.scm index 1686d9613a..c5b8b65227 100644 --- a/scm/layout-page-layout.scm +++ b/scm/layout-page-layout.scm @@ -31,7 +31,7 @@ (= (interval-start system-extent) (interval-end system-extent)))))) -(define (stretch-and-draw-page paper-book systems page-number ragged last) +(define (stretch-and-draw-page paper-book systems page-number ragged book-last part-last) (define (max-stretch sys) (if (ly:grob? sys) (ly:grob-property sys 'max-stretch) @@ -78,7 +78,8 @@ (let* ((page (make-page paper-book 'page-number page-number - 'is-last last)) + 'is-last book-last + 'is-part-last part-last)) (paper (ly:paper-book-paper paper-book)) (height (page-printable-height page)) ; there is a certain amount of impreciseness going on here: @@ -351,8 +352,8 @@ is what have collected so far, and has ascending page numbers." inter-system-space)) user))) -(define (walk-paths done-lines best-paths current-lines last current-best - paper-book page-alist) +(define (walk-paths done-lines best-paths current-lines is-last-part + is-last-page current-best paper-book page-alist) "Return the best optimal-page-break-node that contains CURRENT-LINES. DONE-LINES.reversed ++ CURRENT-LINES is a consecutive ascending range of lines, and BEST-PATHS contains the optimal breaks @@ -362,18 +363,19 @@ CURRENT-BEST is the best result sofar, or #f." (let* ((paper (ly:paper-book-paper paper-book)) (this-page (make-page paper-book - 'is-last last + 'is-last (and is-last-part is-last-page) + 'is-part-last is-last-page 'page-number (if (null? best-paths) (ly:output-def-lookup paper 'first-page-number) (1+ (page-page-number (first best-paths)))))) (ragged-all (eq? #t (ly:output-def-lookup paper 'ragged-bottom))) (ragged-last (eq? #t (ly:output-def-lookup paper 'ragged-last-bottom))) - (ragged (or ragged-all (and ragged-last last))) + (ragged (or ragged-all (and ragged-last is-last-page))) (space-to-fill (page-maximum-space-to-fill this-page current-lines paper)) (vertical-spacing (space-systems space-to-fill current-lines ragged paper #f)) (satisfied-constraints (car vertical-spacing)) (force (if satisfied-constraints - (if (and last ragged-last) + (if (and is-last-page ragged-last) 0.0 satisfied-constraints) 10000)) @@ -411,7 +413,7 @@ CURRENT-BEST is the best result sofar, or #f." (list "\nuser pen " user-penalty "\nsatisfied-constraints" satisfied-constraints - "\nlast? " last "ragged?" ragged + "\nlast? " is-last-page "ragged?" ragged "\nis-better " is-better " total-penalty " total-penalty "\n" "\nconfig " positions "\nforce " force @@ -427,11 +429,11 @@ CURRENT-BEST is the best result sofar, or #f." satisfied-constraints) (walk-paths (cdr done-lines) (cdr best-paths) (cons (car done-lines) current-lines) - last new-best + is-last-part is-last-page new-best paper-book page-alist) new-best))) -(define (walk-lines done best-paths todo paper-book page-alist) +(define (walk-lines done best-paths todo paper-book page-alist is-last-part) "Return the best page breaking as a single page node for optimally breaking TODO ++ DONE.reversed. BEST-PATHS is a list of break nodes corresponding to @@ -439,14 +441,15 @@ DONE." (if (null? todo) (car best-paths) (let* ((this-line (car todo)) - (last (null? (cdr todo))) - (next (walk-paths done best-paths (list this-line) last #f - paper-book page-alist))) + (is-last-page (null? (cdr todo))) + (next (walk-paths done best-paths (list this-line) is-last-part + is-last-page #f paper-book page-alist))) (walk-lines (cons this-line done) (cons next best-paths) (cdr todo) paper-book - page-alist)))) + page-alist + is-last-part)))) (define-public (optimal-page-breaks paper-book) "Return pages as a list starting with 1st page. Each page is a 'page Prob." @@ -454,11 +457,13 @@ DONE." (lines (ly:paper-book-systems paper-book)) (page-alist (layout->page-init paper)) (force-equalization-factor (ly:output-def-lookup - paper 'verticalequalizationfactor 0.3))) + paper 'verticalequalizationfactor 0.3)) + (part-is-last (ly:output-def-lookup paper 'part-is-last))) (ly:message (_ "Calculating page breaks...")) - (let* ((best-break-node (walk-lines '() '() lines paper-book page-alist)) + (let* ((best-break-node (walk-lines '() '() lines paper-book page-alist part-is-last)) (break-nodes (get-path best-break-node '()))) - (page-set-property! (car (last-pair break-nodes)) 'is-last #t) + ;(page-set-property! (car (last-pair break-nodes)) 'is-last part-is-last) + ;(page-set-property! (car (last-pair break-nodes)) 'is-part-last #t) (if #f; (ly:get-option 'verbose) (begin (display (list diff --git a/scm/page.scm b/scm/page.scm index 3e25bdaaee..068572694b 100644 --- a/scm/page.scm +++ b/scm/page.scm @@ -136,8 +136,8 @@ -(define (page-headfoot layout scopes number - sym separation-symbol dir last?) +(define (page-headfoot layout scopes number sym separation-symbol dir + is-book-last-page is-part-last-page) "Create a stencil including separating space." @@ -146,9 +146,8 @@ (stencil (ly:make-stencil "" '(0 . 0) '(0 . 0))) (head-stencil (if (procedure? header-proc) - (header-proc layout scopes number last?) - #f)) - ) + (header-proc layout scopes number is-book-last-page is-part-last-page) + #f))) (if (and (number? sep) (ly:stencil? head-stencil) @@ -198,8 +197,8 @@ (layout (ly:paper-book-paper paper-book)) (scopes (ly:paper-book-scopes paper-book)) (number (page-page-number page)) - (last? (page-property page 'is-last)) - ) + (is-book-last-page (page-property page 'is-last)) + (is-part-last-page (page-property page 'is-part-last))) (page-headfoot layout scopes number (if (= dir UP) @@ -208,7 +207,7 @@ (if (= dir UP) 'head-separation 'foot-separation) - dir last?))) + dir is-book-last-page is-part-last-page))) (define (page-header page) (page-header-or-footer page UP)) diff --git a/scm/titling.scm b/scm/titling.scm index 23fdce8775..28e0e9c8c8 100644 --- a/scm/titling.scm +++ b/scm/titling.scm @@ -12,7 +12,8 @@ ;;;;;;;;;;;;;;;;;; -(define-public ((marked-up-headfoot what-odd what-even) layout scopes page-number last?) +(define-public ((marked-up-headfoot what-odd what-even) + layout scopes page-number is-book-last-page is-part-last-page) "Read variables WHAT-ODD, WHAT-EVEN from LAYOUT, and interpret them as markup. The PROPS argument will include variables set in SCOPES and @@ -41,7 +42,8 @@ page:last?, page:page-number-string and page:page-number (cons 'header:tagline (ly:modules-lookup scopes 'tagline (ly:output-def-lookup layout 'tagline))) - (cons 'page:last? last?) + (cons 'page:last? is-book-last-page) + (cons 'page:part-last? is-part-last-page) (cons 'page:page-number-string (number->string page-number)) (cons 'page:page-number page-number))) -- 2.39.2