Re: Detecting first and last pages of a score

2019-09-06 Thread Leah Velleman
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

2019-09-06 Thread Thomas Morley
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

2019-09-06 Thread 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.

\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

2019-09-06 Thread David Kastrup
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

2019-09-06 Thread Wols Lists
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

2019-09-06 Thread David Kastrup
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

2019-09-06 Thread Leah Velleman
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

2019-09-06 Thread David Kastrup
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

2019-09-06 Thread Andrew Bernard

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

2019-09-03 Thread David Bowen
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

2019-09-03 Thread Andrew Bernard
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

2019-09-03 Thread Leah Velleman
> 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

2019-09-02 Thread Andrew Bernard

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

2019-09-02 Thread Leah Velleman
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