Re: Detecting first and last pages of a score
This is a very interesting approach! It wouldn't have occurred to me to handle it like this — thank you for taking the time to spell it out and code it up. I'll give it a try! Thanks, LV On Fri, Sep 6, 2019 at 8:01 PM Thomas Morley wrote: > Am Sa., 7. Sept. 2019 um 01:42 Uhr schrieb Thomas Morley > : > > > > Am Fr., 6. Sept. 2019 um 23:55 Uhr schrieb David Kastrup : > > > > > > On 06/09/19 17:00, David Kastrup wrote: > > > (short of some > > > multi-pass algorithm writing out table-of-content like information on > > > each run) > > > > David, > > > > we have a prob-property 'last-in-score, iiuc it's set far too late to > > be of any use here. > > But maybe a point to start? > > > > Leah, > > > > below a multi-pass-function as David mentioned, not exactly what you > > requested, though maybe a hint for someone to drop in... > > Likely better to go for the table-of-content, for now you need to > > mantain the first argument for `writeBookTwice´ yourself. > > Found a way to avoid manually mantaing: > > writeBookTwice = > #(define-void-function (book) (ly:book?) > >;; Get all titles from score-headers >(define headers > (reverse >(map > (lambda (l) (assoc-get 'title l "")) > (map >(lambda (mod) > (if (module? mod) > (ly:module->alist mod) > '())) >(map ly:score-header (filter ly:score? (ly:book-scores > book))) >;; Set the variable `page-post-process´ in the book-paper to the > procedure >;; `scores-and-pages´ >(module-define! > (ly:output-def-scope (ly:book-paper book)) > 'page-post-process > (lambda (layout pages) >(scores-and-pages layout pages))) > >;; First run of the book, in order to find the pages where new scores > start >(ly:book-process > book > $defaultpaper > $defaultlayout > (ly:parser-output-name)) > >;; clear book-paper's `page-post-process´ >(module-set! > (ly:output-def-scope (ly:book-paper book)) > 'page-post-process > '()) > >;; Insert page-headers refering to the found pages/scores >(ly:output-def-set-variable! > (ly:book-paper book) > 'oddHeaderMarkup > (myOddHeaderMarkup >(assign-pages-header > (ly:output-def-lookup $defaultpaper 'pages-and-scores '()) > headers))) > >(ly:output-def-set-variable! > (ly:book-paper book) > 'evenHeaderMarkup > (myEvenHeaderMarkup >(assign-pages-header > (ly:output-def-lookup $defaultpaper 'pages-and-scores '()) > headers))) > >;; Rerun the book with the found values >(ly:book-process > book > $defaultpaper > $defaultlayout > (ly:parser-output-name)) > >;; Clear `pages-and-scores´ in $defaultpaper >(ly:output-def-set-variable! > $defaultpaper > 'pages-and-scores > '())) > > \writeBookTwice > \book { > ... > } > > Cheers, > Harm > ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Detecting first and last pages of a score
Am Sa., 7. Sept. 2019 um 01:42 Uhr schrieb Thomas Morley : > > Am Fr., 6. Sept. 2019 um 23:55 Uhr schrieb David Kastrup : > > > > On 06/09/19 17:00, David Kastrup wrote: > > (short of some > > multi-pass algorithm writing out table-of-content like information on > > each run) > > David, > > we have a prob-property 'last-in-score, iiuc it's set far too late to > be of any use here. > But maybe a point to start? > > Leah, > > below a multi-pass-function as David mentioned, not exactly what you > requested, though maybe a hint for someone to drop in... > Likely better to go for the table-of-content, for now you need to > mantain the first argument for `writeBookTwice´ yourself. Found a way to avoid manually mantaing: writeBookTwice = #(define-void-function (book) (ly:book?) ;; Get all titles from score-headers (define headers (reverse (map (lambda (l) (assoc-get 'title l "")) (map (lambda (mod) (if (module? mod) (ly:module->alist mod) '())) (map ly:score-header (filter ly:score? (ly:book-scores book))) ;; Set the variable `page-post-process´ in the book-paper to the procedure ;; `scores-and-pages´ (module-define! (ly:output-def-scope (ly:book-paper book)) 'page-post-process (lambda (layout pages) (scores-and-pages layout pages))) ;; First run of the book, in order to find the pages where new scores start (ly:book-process book $defaultpaper $defaultlayout (ly:parser-output-name)) ;; clear book-paper's `page-post-process´ (module-set! (ly:output-def-scope (ly:book-paper book)) 'page-post-process '()) ;; Insert page-headers refering to the found pages/scores (ly:output-def-set-variable! (ly:book-paper book) 'oddHeaderMarkup (myOddHeaderMarkup (assign-pages-header (ly:output-def-lookup $defaultpaper 'pages-and-scores '()) headers))) (ly:output-def-set-variable! (ly:book-paper book) 'evenHeaderMarkup (myEvenHeaderMarkup (assign-pages-header (ly:output-def-lookup $defaultpaper 'pages-and-scores '()) headers))) ;; Rerun the book with the found values (ly:book-process book $defaultpaper $defaultlayout (ly:parser-output-name)) ;; Clear `pages-and-scores´ in $defaultpaper (ly:output-def-set-variable! $defaultpaper 'pages-and-scores '())) \writeBookTwice \book { ... } Cheers, Harm ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Detecting first and last pages of a score
Am Fr., 6. Sept. 2019 um 23:55 Uhr schrieb David Kastrup : > > On 06/09/19 17:00, David Kastrup wrote: > (short of some > multi-pass algorithm writing out table-of-content like information on > each run) David, we have a prob-property 'last-in-score, iiuc it's set far too late to be of any use here. But maybe a point to start? Leah, below a multi-pass-function as David mentioned, not exactly what you requested, though maybe a hint for someone to drop in... Likely better to go for the table-of-content, for now you need to mantain the first argument for `writeBookTwice´ yourself. \version "2.19.83" %% Needed to get the all definitions from /ly/titling-init.ly to predefine %% different footers/headers. \include "titling-init.ly" #(define (scores-and-pages layout pages) ;; Sets the variable `pages-and-scores´ in $defaultpaper to a list like: ;; ((1 new-score) ;;(2 new-score new-score) ;;(3) ;;(4 new-score) ;;(5)) ;; The symbol 'new-score indicates a new score started. The number is ofcourse ;; the page-number. ;; Ofcourse one could go for #t, we keep the symbol for now, because it's ;; more haptic ... (let* ((page-score (map (lambda (page) (let* (;; Get each line of the page (lines-of-page (ly:prob-property page 'lines)) ;; Find every system, collect only those which have a ;; system-grob (systems (append-map (lambda (l) (let ((system-grob (ly:prob-property l 'system-grob))) (if (not (null? system-grob)) (list system-grob) '( lines-of-page)) ;; Find the rhythmic-location for each system (locations (map (lambda (sys) (car (grob::rhythmic-location sys))) systems)) ;; Insert 'new-score, if we find bar-number 1, i.e. a new ;; score. (is-new-score (filter-map (lambda (loc) (if (eqv? 1 loc) 'new-score #f)) locations))) (cons (ly:prob-property page 'page-number) is-new-score))) pages))) (ly:output-def-set-variable! $defaultpaper 'pages-and-scores page-score))) #(define (assign-pages-header page-scores-list header-list) ;; replace the 'new-score entries form `page-scores-list´ with appropriate ;; entries from `header-list´ (define (helper l1 l2 rl) (if (null? l1) (reverse rl) (let* ((scores-amount (1- (length (car l1 (score-headers (take l2 scores-amount))) (helper (cdr l1) (drop l2 scores-amount) (cons score-headers rl) (helper page-scores-list header-list '())) #(define-markup-command (print-on-certain-pages layout props arg-ls)(list?) ;; Return a center-columned markup-stencil for cerstain pages. ;; `arg-ls´ is supposed to be a list like ;; (("foo") ("bar" "buzz") () ("") ()) ;; Each entry contains the args to be printes of the list-index' page (interpret-markup layout props (make-column-markup (map (lambda (i vals) #{ \markup \on-the-fly #(on-page i) \center-column #vals #}) (iota (length arg-ls) 1 1) arg-ls myOddHeaderMarkup = #(define-scheme-function (lst)(list?) ;; Used to define `oddHeaderMarkup´ later #{ \markup \fill-line { "" \print-on-certain-pages #lst \on-the-fly #print-page-number-check-first \fromproperty #'page:page-number-string } #}) myEvenHeaderMarkup = #(define-scheme-function (lst)(list?) ;; Used to define `evenHeaderMarkup´ later #{ \markup \fill-line { \on-the-fly #print-page-number-check-first \fromproperty #'page:page-number-string \print-on-certain-pages #lst "" } #}) writeBookTwice = #(define-void-function (headers book) (list? ly:book?) ;; Set the variable `page-post-process´ in the book-paper to the procedure ;; `scores-and-pages´ (module-define! (ly:output-def-scope (ly:book-paper book)) 'page-post-process (lambda (layout pages) (scores-and-pages layout pages))) ;; First run of the book, in order to find the pages where new scores start (ly:book-process book $defaultpaper $defaultlayout (ly:parser-output-name)) ;; clear book-paper's `page-post-process´ (module-set! (ly:output-def-scope (ly:book-paper book)) 'page-post-process '())
Re: Detecting first and last pages of a score
Wols Lists writes: > On 06/09/19 17:00, David Kastrup wrote: >> I am not saying "it never will be able to do" things like that but the >> mechanisms are not there even in rudimentary form, so the manner in >> which it may be done at some prospective future time is not clear. > > Is this the sort of thing the editions engraver could handle? (I've > never used it - I don't know what it can do ...) I am pretty sure that it cannot do what isn't possible (short of some multi-pass algorithm writing out table-of-content like information on each run) either. -- David Kastrup ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Detecting first and last pages of a score
On 06/09/19 17:00, David Kastrup wrote: > I am not saying "it never will be able to do" things like that but the > mechanisms are not there even in rudimentary form, so the manner in > which it may be done at some prospective future time is not clear. Is this the sort of thing the editions engraver could handle? (I've never used it - I don't know what it can do ...) Okay, it would be a bit of work for every new document, but it would avoid having to go in and edit the score every time. Cheers, Wol ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Detecting first and last pages of a score
Leah Velleman writes: > Well, although my knowledge of the internals is quite limited, it looks to > me like there is precedent for this, involving page headers. As you say, a > score can be placed multiple times. And each time it is placed, it can be > interrupted at different points by page headers. I could see this being > quite tricky -- but there is apparently a mechanism that lets it happen. > > At the moment when Lilypond stops placing systems on the page in order to > insert one of those page headers, could it not be given access to the > information "this is partway through a score, and here is the title from > the header block of that score"? LilyPond does not have something akin to TeX's "output routine", user-accessible code that gets called at the time an output page wants to get assembled. Instead it calls hardcoded C++ code that does stuff like resolving page references and adding head- and footlines and footnotes and so on. So what it does at the time of page building is closed in its functionality and most certainly not accessible to decision-making. > (If the answer is "no, it can't do that and it never will be able to," > then that's the answer. I'm not trying to argue with you, just > clarifying what I was imagining.) I am not saying "it never will be able to do" things like that but the mechanisms are not there even in rudimentary form, so the manner in which it may be done at some prospective future time is not clear. -- David Kastrup ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Detecting first and last pages of a score
Well, although my knowledge of the internals is quite limited, it looks to me like there is precedent for this, involving page headers. As you say, a score can be placed multiple times. And each time it is placed, it can be interrupted at different points by page headers. I could see this being quite tricky -- but there is apparently a mechanism that lets it happen. At the moment when Lilypond stops placing systems on the page in order to insert one of those page headers, could it not be given access to the information "this is partway through a score, and here is the title from the header block of that score"? (If the answer is "no, it can't do that and it never will be able to," then that's the answer. I'm not trying to argue with you, just clarifying what I was imagining.) On Fri, Sep 6, 2019 at 10:48 AM David Kastrup wrote: > Andrew Bernard writes: > > >> On 3/9/19 7:48 am, Leah Velleman wrote: > >>> In > >>> https://github.com/lilypond/lilypond/blob/master/ly/titling-init.ly > there > >>> are predicates that detect if the current page is the first or last > >>> one of a /book/, or of a /bookpart/. But it's not clear to me how to > >>> generalize from there. How would I detect if the current page was > >>> the first or last page of a /score/? > > > > Hello Leah, > > > > I have been looking into this. Searching the archives I see you have > > been asking about this since at least 2015. > > > > I don't think it is possible. The control stops art bookparts where > > you can use the on the fly functions. Next level down at \score - > > either impossible or not documented. > > > > Lilypond internals gurus, can we do this? [Pretty please?] > > Do _what_? You can place a score multiple times with its distribution > across pages being different every time. When do you plan to take > action for "detecting if the current page was the first or last page of > a score" when each copy of the score will have a different page > distribution? This action can then not be part of the score proper > because it has to be different each time. > > -- > David Kastrup > > ___ > lilypond-user mailing list > lilypond-user@gnu.org > https://lists.gnu.org/mailman/listinfo/lilypond-user > ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Detecting first and last pages of a score
Andrew Bernard writes: >> On 3/9/19 7:48 am, Leah Velleman wrote: >>> In >>> https://github.com/lilypond/lilypond/blob/master/ly/titling-init.ly there >>> are predicates that detect if the current page is the first or last >>> one of a /book/, or of a /bookpart/. But it's not clear to me how to >>> generalize from there. How would I detect if the current page was >>> the first or last page of a /score/? > > Hello Leah, > > I have been looking into this. Searching the archives I see you have > been asking about this since at least 2015. > > I don't think it is possible. The control stops art bookparts where > you can use the on the fly functions. Next level down at \score - > either impossible or not documented. > > Lilypond internals gurus, can we do this? [Pretty please?] Do _what_? You can place a score multiple times with its distribution across pages being different every time. When do you plan to take action for "detecting if the current page was the first or last page of a score" when each copy of the score will have a different page distribution? This action can then not be part of the score proper because it has to be different each time. -- David Kastrup ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Detecting first and last pages of a score
Hello Leah, I have been looking into this. Searching the archives I see you have been asking about this since at least 2015. I don't think it is possible. The control stops art bookparts where you can use the on the fly functions. Next level down at \score - either impossible or not documented. Lilypond internals gurus, can we do this? [Pretty please?] Andrew On 3/9/19 7:48 am, Leah Velleman wrote: In https://github.com/lilypond/lilypond/blob/master/ly/titling-init.ly there are predicates that detect if the current page is the first or last one of a /book/, or of a /bookpart/. But it's not clear to me how to generalize from there. How would I detect if the current page was the first or last page of a /score/? ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Detecting first and last pages of a score
The Sacred Harp hymnbooks I'm familiar with are set in landscape mode with two systems per page, so you won't have three songs on a page. Dave Bowen On Tue, Sep 3, 2019 at 7:19 AM Andrew Bernard wrote: > Lovely! Do you use the shape heads? > > Are you trying to make a book like the 19c originals? Is there an example > we can take a look at? > > I'm confused about what the page title should be if you have say three > songs on one page, or does that not happen? > > Andrew > > > On Tue, 3 Sep 2019 at 21:51, Leah Velleman > wrote: > >> > To do what? >> >> So here's the situation. >> >> I'm writing a template for collections of Sacred Harp–style songs. >> (Templates for individual songs already exist, but not openly available >> ones that handle an entire collection.) >> > ___ > lilypond-user mailing list > lilypond-user@gnu.org > https://lists.gnu.org/mailman/listinfo/lilypond-user > ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Detecting first and last pages of a score
Lovely! Do you use the shape heads? Are you trying to make a book like the 19c originals? Is there an example we can take a look at? I'm confused about what the page title should be if you have say three songs on one page, or does that not happen? Andrew On Tue, 3 Sep 2019 at 21:51, Leah Velleman wrote: > > To do what? > > So here's the situation. > > I'm writing a template for collections of Sacred Harp–style songs. > (Templates for individual songs already exist, but not openly available > ones that handle an entire collection.) > ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Detecting first and last pages of a score
> To do what? So here's the situation. I'm writing a template for collections of Sacred Harp–style songs. (Templates for individual songs already exist, but not openly available ones that handle an entire collection.) In this tradition, when a song runs over a page break, "SONGTITLE Continued" or "SONGTITLE Concluded" is written at the top of the page. I want to automate this. But I can't make each song its own bookpart. This is because, unlike bookparts, songs in this tradition don't always start with new pages, but can begin and end in mid-page. I believe this means each song needs to be its own score. And as far as I can tell, that means that in order to automatically generate those "Continued" and "Concluded" headers, we need to know when we're on the non-first page of a score, and when we're on the last page. (I could, of course, hard-code all the line breaks, all the page breaks, and all the headers. But I prefer not to do this: I want collaborators to be able to typeset individual songs without knowing in advance where on the page those songs will start in the finished book.) On Mon, Sep 2, 2019 at 8:30 PM Andrew Bernard wrote: > To do what? > > Andrew > On 3/9/19 7:48 am, Leah Velleman wrote: > > In https://github.com/lilypond/lilypond/blob/master/ly/titling-init.ly there > are predicates that detect if the current page is the first or last one of > a *book*, or of a *bookpart*. But it's not clear to me how to generalize > from there. How would I detect if the current page was the first or last > page of a *score*? > > ___ > lilypond-user mailing list > lilypond-user@gnu.org > https://lists.gnu.org/mailman/listinfo/lilypond-user > ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Detecting first and last pages of a score
To do what? Andrew On 3/9/19 7:48 am, Leah Velleman wrote: In https://github.com/lilypond/lilypond/blob/master/ly/titling-init.ly there are predicates that detect if the current page is the first or last one of a /book/, or of a /bookpart/. But it's not clear to me how to generalize from there. How would I detect if the current page was the first or last page of a /score/? ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Detecting first and last pages of a score
In https://github.com/lilypond/lilypond/blob/master/ly/titling-init.ly there are predicates that detect if the current page is the first or last one of a *book*, or of a *bookpart*. But it's not clear to me how to generalize from there. How would I detect if the current page was the first or last page of a *score*? Thanks, LV ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user