Re: Please tear apart this example lead sheet template for traditional Western folk tunes

2022-02-23 Thread Valentin Petzel
Hello Tom,

you accidently forwarded me the digest. Unless there is a reason not to when 
replying to a message please change the Subject to match the discussion, make 
sure to include the list to the recipients and optimally adjust the quoted 
body to not include the whole digest.

If you’ve got any questions about what is happening here feel free to ask. We 
are using here that we can "register" scores to the current book(part) from 
scheme using the function (add-score score) (similarly we can use (add-text 
markup) to add a stand-alone markup to the book). This allows us to construct 
scores using scheme, which makes automated handling of thing much easier.

So what we want to have is a function that creates a score using standard 
elements, that is, chords, a voice, and lyrics. At the same time we want to be 
flexible enough to leave out some of these elements.

So we define a void-function (that is a scheme function that returns nothing) 
that takes:
→ The title of the score
→ Optionally the composer of the score
→ A piece of music for the voice or #f
→ A piece of music for the chords or #f
→ A piece of lyrics (which is also music) or a list of such (to allow stanzas)
 or #f

The syntax here is
myfunction =
#(define-void-function (arg1 arg2 ...)
(type-check-arg1 type-check-arg1 ...)
function-body)

where the type-checks are predicates (functions returning truth values) or 
(predicate default) for optional arguments with default value.

We then use let* which allows us to locally bind some variables (similar to 
let, but let* lets each binding access the previous bindings). The syntax here 
is

(let* ((var1 value1) (var2 value2) ...) body)

So we define CN, FB, VC, LY as shorthands for the ChordNames, FretBoards, Voice 
and Lyrics. If one of these is set to #f we use empty-music, which is music 
containing nothing, else we create the contexts with the specified music.

As lyrics might be a list of lyrics we have to handle both of these things, 
which is done by either doing something to the lyrics or by doing to the whole 
list (which is the (map function list) expression). We also need to handle the 
presence of the Voice here. If for some reason voice is set to #f we should 
not align the lyrics to anything and rely on the lyrics themselves being 
rhythmicised. To make further handling easier we make sure that LY is list 
even when lyrics isn’t. [WHICH BY THE WAY I FORGOT IF lyrics IS #f, THIS IS 
FIXED IN THE APPENDED FILE!]

So we get a big expression basically just checking:
→ Is lyrics #f? If so use (in the fixed version a list of) empty music.
→ Is voice #f? If so do not use \lyricsto "auto"
→ Is lyrics music or a list? If so we use map to create Lyrics for each member 
of the list. If not we create a list containing a single Lyrics context.

Next we basically want to put all of these contexts in a << ... >> construct. 
This is known as "simultaneous music" and is internally stored as
(make-music 'SimulataneousMusic 'elements A-LIST-OF-MUSIC)
where the list of music contains the content of ... . This means we simply 
have to construct this list and then do the above call with this list.

I won’t go into detail what a LISP list is, if you are interested please ask 
or checkout what I wrote to Simon earlier this thread. But basically if L is a 
list then `(,a ,b ,c . ,L) will be L with a, b and c prepended. As Jean 
pointed out this can be done by (cons* a b c L).

So we do a
(cons* CN FB VC LY)
to create a list of all the contexts we created so far (and maybe some empty 
music, but we do not really have to care about these).

Next we create a score with the specified header informations and the 
previously created simultaneous music. Using #{ ... #} allows us to parse the 
content between as Lilypond syntax instead of scheme syntax. So we do
#{ \score { ... } #}
and create the score just like we would in Lilypond syntax.

Then the last thing we do is use add-score to add this newly created score to 
the current book.

Cheers,
Valentin

Am Donnerstag, 24. Februar 2022, 00:05:42 CET schrieben Sie:
> Thank you for completely upgrading my lead sheet template. WOW! I haven't
> acknowledged because it's so advanced. You've added a bunch of advanced
> features I'm trying to understand thoroughly.% Lead sheet with:
% - Guitar fretboard diagrams
% - Override a predefined fretboard diagram
% - Pickup note with text above it suppressed
% - Chord and other text suppressed above the pickup note
 Please send critiques to tomcampb...@gmail.com
\version "2.22"

 STARTING INCLUDABLE TEMPLATE
#(define (music-or-false? m) (or (ly:music? m) (not m)))
#(define (music-or-list-or-false? m) (or (music-or-false? m) (list? m)))

leadsheetScore =
#(define-void-function (title composer voice chords lyrics)
   (markup? (markup? "Trad.") music-or-false? music-or-false? music-or-list-or-false?)
   (let* ((CN (if chords #{ \new ChordNames $chords #} (empty-music)))
  (FB (if chords
 

Re: Page turning in song book: Only \scores with more than 1 page should be forced to start on even page number

2022-02-23 Thread Valentin Petzel
Hello Johannes,

using page-turn-breaking only acts like this if ragged-bottom is set to #t 
(which should be considered as weird behaviour). I suppose what’s happening 
there is that with ragged-bottom set to #t there is no demerit for short 
pages, as the pages are not stretched out (which is the thing that would get 
demerits). This means that there is no demerit to breaking in every possible 
place, which I think is one of the first solutions tried by the breaking 
algorithm. Thus even if we find a shorter solution of equal demerit we won’t 
use it.

I’d suggest we should add a very small demerit for solutions with lots of 
pages so that with configurations with the same overall demerit the one with 
less pages is preferred.

E.g. changing line 124 in page-turn-page-breaking.cc to
ret.demerits_ = result.demerits_ + static_cast(ret.page_count_)/1000;
we do already get better behaviour (although probably not the best, for some 
weird reason it allows compression of pages when it is not nescessary, like 
here

\paper {
  page-breaking = #ly:page-turn-breaking
  ragged-bottom = ##t
}

{\repeat unfold 20 c1 }
{\repeat unfold 20 c1 }
{\repeat unfold 20 c1 }
{\repeat unfold 40 c1 }
{\repeat unfold 20 c1 }
{\repeat unfold 100 c1 }
{\repeat unfold 20 c1 }
{\repeat unfold 20 c1 }
{\repeat unfold 20 c1 }
{\repeat unfold 20 c1 }
{\repeat unfold 200 c1 }

on page 2). It might also be sensible to add a small demerit depending on the 
free whitespace to enforce a more even distribution of whitespace.

Cheers,
Valentin

Am Mittwoch, 23. Februar 2022, 18:13:15 CET schrieb Johannes Maibaum:
> Hello,
> 
> I am working on a lead-sheet song book (i.e. one \book with many short
> \scores inside), and I was looking for a way to optimize page turning
> for musicians playing tunes from the book. Most songs fit on a single
> page, but there are a few songs which span 2 or more pages.
> 
> I want to make sure that all songs which more than 1 page start on an
> even page, but all 1-page songs should be allowed to start on an even or
> an odd page.
> 
> Looking through the documentation, and testing the built-in page-
> breaking algorithms, there doesn't seem to be a turn-key solution for my
> use-case. The default optimal-breaking algorithm starts every \score on
> the next page (even or odd), and page-turn-breaking forces every \score
> to start on an even page, which causes (almost) blank pages (the last
> line is put on the odd page) after all tunes which would happily fit on
> 1 page.
> 
> I tried fiddling with the different blank-page-*-penalties, but so far I
> wasn't able to achieve my goal. Is it possible after all?
> 
> 
> Best,
> Johannes



signature.asc
Description: This is a digitally signed message part.


Page turning in song book: Only \scores with more than 1 page should be forced to start on even page number

2022-02-23 Thread Johannes Maibaum
Hello,

I am working on a lead-sheet song book (i.e. one \book with many short
\scores inside), and I was looking for a way to optimize page turning
for musicians playing tunes from the book. Most songs fit on a single
page, but there are a few songs which span 2 or more pages.

I want to make sure that all songs which more than 1 page start on an
even page, but all 1-page songs should be allowed to start on an even or
an odd page.

Looking through the documentation, and testing the built-in page-
breaking algorithms, there doesn't seem to be a turn-key solution for my
use-case. The default optimal-breaking algorithm starts every \score on
the next page (even or odd), and page-turn-breaking forces every \score
to start on an even page, which causes (almost) blank pages (the last
line is put on the odd page) after all tunes which would happily fit on
1 page.

I tried fiddling with the different blank-page-*-penalties, but so far I
wasn't able to achieve my goal. Is it possible after all?


Best,
Johannes