bookpart als function

Begonnen von Köbi, Mittwoch, 2. August 2017, 00:33

« vorheriges - nächstes »

Köbi

Seit einiger Zeit arbeite mit einer "define-scheme-function", die mir ein score zurück gibt. Beim Aufruf kann ich verschiedene Parameter übergeben (z.Z. markup? string? ly:pitch? ly:music?). Funktioniert wunderbar.

Nun möchte ich das gleiche mit bookpart machen, das scheint aber viel schwieriger zu sein. Bei der bookpart-function würde ich gerne eine Liste mit scores übergeben plus einige weitere Parameter, die bookpart-weit gelten.

Unter http://lilypond.1069038.n5.nabble.com/Scheme-function-to-output-bookpart-td181590.html habe ich etwas gefunden. Aber ich schaffe es nicht, das Ding so umzubauen, dass für mich funktionieren würde.

Folgendes habe ich zum Laufen gebracht:


\version "2.19.64"

test = #(define-scheme-function (scoreA scoreB myTitle printAllHeaders) (ly:score? ly:score? string? boolean?)
  (
    ly:book-process
    (ly:make-book-part (list scoreA scoreB))
    $defaultpaper
    $defaultlayout
    (ly:parser-output-name)
  )
)

scoreA = \score { \header { piece = "p1" } { a' } }
scoreB = \score { \header { piece = "p2" } { b' } }
printAllHeaders = ##t

\test \scoreA \scoreB "MyTitle" \printAllHeaders


Aber
1. Wie bilde ich eine Liste mit den scores und übergebe und verarbeite dann diese?
2. Wie bringe ich myTitle in den header rein?
3. Wie bringe ich printAllHeaders in den paper-Block rein?

harm6

Hallo,


\version "2.19.64"

makeBookpartForCurrentBook =
#(define-void-function (scores my-title print-all-headers?)
  (list? string? boolean?)
  "Add a new bookpart with @var{scores} and settings for paper and header to
   current book."
  (let* (
         ;; get an empty paper
         (bkp-paper #{ \paper {} #})
         ;; fill this paper with content and return it
         ;; REMARK I don't know a method to do it _after_ the bookpart is
         ;; initialized.
         (new-bkp-paper
           (begin
             (ly:output-def-set-variable!
               bkp-paper
               'print-all-headers print-all-headers?)
             bkp-paper))
         ;; get an empty header, filled later
         (bkp-header #{ \header {} #})
         ;; get a bookpart with those paper and header
         (bkp #{ \bookpart { $new-bkp-paper $bkp-header } #}))

  ;; fill the header with content
  (module-define! bkp-header 'title my-title)
  ;; get the filled header into the bookpart
  (ly:book-set-header! bkp bkp-header)
 
  ;; get the scores into the bookpart
  (for-each (lambda (score) (ly:book-add-score! bkp score)) scores)

  ;; add the bookpart to current book, don't put out a separate book
  (collect-bookpart-for-book bkp)))
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% score-definitions
scoreA = \score { \header { title = "T1" piece = "p1" } { a' } }
scoreB = \score { \header { title = "T2" piece = "p2" } { b' } }

%% list of scores
scores = #(list scoreA scoreB)

%% function-call
%% returning a bookpart with the specified scores
%% title is set as specified in bookpart-header
%% print-all-headers is set as specified in bookpart-paper
\makeBookpartForCurrentBook \scores "MyTitle" ##t
\makeBookpartForCurrentBook \scores "MySecondTitle" ##t


Kommentare inline. Wenn etwas unklar ist, frag ;)

Allerdings finde ich es unbequem, daß ich das paper nicht verändern kann nachdem der bookpart erst mal da ist, im Gegensatz zum header.
Dazu habe ich selbst mal nachgefragt:
http://lilypond.1069038.n5.nabble.com/Setting-paper-for-bookpart-tt204803.html
Mal sehen was dabei rauskommt.

Zu Deiner Frage:
ZitatWie bilde ich eine Liste mit den scores und übergebe und verarbeite dann diese?
weiß ich nichts anderes als diese Liste manuell zu erstellen, siehe meinen code oben.
Möglicherweise kann man alle scores eines files finden, aber eigentlich denke ich der Sinn einer solchen Funktion besteht u.a. in der Auswahl dessen was wie gedruckt wird.

Gruß,
  Harm

Nachtrag:


#(pretty-print
   (filter
     (lambda (e) (ly:score? (cdr e)))
     (ly:module->alist (current-module))))

zeigt tatsächlich alle scores-definitionen eines files.
Aber natürlich nicht die toplevel-scores, das ginge mit:
#(pretty-print (ly:parser-lookup 'toplevel-scores))

Köbi

Hallo Harm, vielen Dank, perfekt! Ich hoffe, dass ich es schaffe, jetzt noch meine weiteren Parameter einzubauen. Und dann versuche ich dasselbe für book ;-)

Manuela

Zitat von: Köbi am Mittwoch,  2. August 2017, 00:33
Seit einiger Zeit arbeite mit einer "define-scheme-function", die mir ein score zurück gibt. Beim Aufruf kann ich verschiedene Parameter übergeben (z.Z. markup? string? ly:pitch? ly:music?). Funktioniert wunderbar.

Magst du den Code nicht hier posten? Ich könnte mir vorstellen, dass diese Funktion auch für andere nützlich sein könnte, mir fallen spontan einige Anwendungsmöglichkeiten ein.
Danke für eure Hilfe
viele Grüße
-- Manuela

Köbi

Ja, das mache ich gerne. Bin aber noch nicht soweit, das würde aktuell nur verwirren, sorry.

Köbi

Uups, jetzt bin ich schon gestrandet:


\book {
  \bookpart {
    \markup "Title"
  }
  \makeBookpartForCurrentBook \scores "MyTitle" ##t
}


Da werden zwei PDFs erzeugt, für jeden bookpart ein separates :-( Kann ich diese bookpart-function nicht wie in normales bookpart in einem book einsetzen?

harm6

#6
Hallo,

immer vorausgesetzt, daß ich mich nicht irre...

Falls Du
http://lilypond.1069038.n5.nabble.com/Setting-paper-for-bookpart-td204803.html
gelesen hast, so weißt Du, daß bei der ganzen Sache noch einiges im argen liegt.
Wenn selbst David Kastrup, unser ausgewiesener parser-Experte, keine fertige Antwort aus der Schublade ziehen kann ...
Darüber hinaus wird die von Dir gewünschte Funktionalität nicht häufig nachgefragt, so ist die Anzahl entsprechender tools auch nicht der Rede wert, bzw sind auch sehr unhandlich.

Z.B kann eine Musikfunktion kein book ausgeben.
foo = #(define-music-function ()() #{ \bookpart { { c'1 } } #})
\foo

->
Zitat von: terminal
error: music function cannot return ##<Book>

Eine scheme-Funktion klappt auch nicht:
buzz = #(define-scheme-function ()() #{ \bookpart { { c'1 } } #})
\buzz

->
Zitat von: terminal
error: bad expression type

Einzig eine void-Funktion kann verwendet werden. Aber eine void-Funktion kann zwar was tun, sie returniert aber nichts, bzw genauer: sie returniert #<unspecified>.

Meine makeBookpartForCurrentBook-Funktion ist so eine void-Funktion.
Die letzte Zeile lautet: (collect-bookpart-for-book bkp)
Sie bedeutet, daß der bookpart 'bkp' zu den toplevel-bookparts hinzugefügt wird.
Falls ein book explizit durch den Anwender initialisiert wird, so kommt toplevel-Stoff der außerhalb diese books erscheint nicht
in dieses book sondern in ein eigenes.
Im Nachhinein betrachtet wäre es wohl besser gewesen diese Funktion makeToplevelBookpart zu nennen.

In Deinem Versuch:
Zitat
\book {
  \bookpart {
    \markup "Title"
  }
  \makeBookpartForCurrentBook \scores "MyTitle" ##t
}
erzeugt die rot markierte Zeile also einen toplevel-bookpart, und damit einen bookpart, der nicht zum book gehört in dem dieser Code aufgerufen wird.
Der Rest des Code erzeugt ein weiteres, zweites book mit einem bookpart der momentan ein einzelnes markup enthält.
Im Endeffekt entstehen zwei books, deshalb auch zwei pdfs.

Was also tun?

In Worten ist es ganz einfach ;)
- kodiere eine void-Funktion, die die von ihr geschaffenen bookparts zu einem gegebenen book hinzufügt.
- gebe dieses Buch aus

Tatsächlich ist das soweit gar nicht mehr so viel:

(1) Definiere ein (leeres) book, für jetzt nenne ich es mal test-book
(2) Ersetze in makeBookpartForCurrentBook die letzte Zeile durch (ly:book-add-bookpart! test-book bkp)
(3) Rufe makeBookpartForCurrentBook mit geeigneten Parametern auf.
(4) Rufe test-book auf

Führt zu:

\version "2.19.64"

test-book = \book {}

makeBookpartForCurrentBook =
#(define-void-function (scores my-title print-all-headers?)
  (list? string? boolean?)
  "Add a new bookpart with @var{scores} and settings for paper and header to
   current book."
  (let* (
         ;; get an empty paper
         (bkp-paper #{ \paper {} #})
         ;; fill this paper with content and return it
         ;; REMARK I don't know a method to do it _after_ the bookpart is
         ;; initialized.
         (new-bkp-paper
           (begin
             (ly:output-def-set-variable!
               bkp-paper
               'print-all-headers print-all-headers?)
             bkp-paper))
         ;; get an empty header, filled later
         (bkp-header #{ \header {} #})
         ;; get a bookpart with those paper and header
         (bkp #{ \bookpart { $new-bkp-paper $bkp-header } #}))

  ;; fill the header with content
  (module-define! bkp-header 'title my-title)
  ;; get the filled header into the bookpart
  (ly:book-set-header! bkp bkp-header)
 
  ;; get the scores into the bookpart
  (for-each (lambda (score) (ly:book-add-score! bkp score)) scores)

  ;; add the bookpart to 'test-book'
  (ly:book-add-bookpart! test-book bkp)
  ))
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% score-definitions
scoreA = \score { \header { title = "T1" piece = "p1" } { a' } }
scoreB = \score { \header { title = "T2" piece = "p2" } { b' } }

%% list of scores
scores = #(list scoreA scoreB)

%% function-call
%% add a bookpart with the specified scores to 'test-book'
%% title is set as specified in bookpart-header
%% print-all-headers is set as specified in bookpart-paper

\makeBookpartForCurrentBook \scores "MyTitle" ##t
\makeBookpartForCurrentBook \scores "MySecondTitle" ##f 

%%call the ready test-book
\test-book


Ich hoffe meine Ausführungen helfen Dir ein wenig weiter. Das Thema ist komplex, wenig end-user-tauglich (wegen fehlender bequemer tools) und möglicherweise (bis sicherlich[1]) buggy.

HTH,
  Harm

[1] probier mal:

bk-c = \book { \bookpart { { r1 } } }
\bk-c

Köbi

Hallo Harm

Huch, das ist ja furchtbar kompliziert! Da brauche ich eine Weile, um das alles nachzuvollziehen. Als Software-Entwickler (C#) bin ich mir einfach gewohnt, alles nur einmal schreiben zu müssen und suche nun halt nach Möglichkeiten, das auch beim Notenschreiben mit Lilypond so zu machen.

Folgende Anforderungen habe ich aktuell:
- Ein dreistimmiges Werk in fünf Teilen mit je fünf Sätzen (Mozart-Divertimenti KV229)
- Einzelstimmen, normale Partitur, "Fagott-Partitur" (3. Stimme normal gross, die beiden anderen etwas kleiner, ev. zusammen auf einem System)
- Ausgaben für verschiedene Instrumente, z.B. 2 Oboen (in C) + Fagott, Streichtrio, 2 Klarinetten (in B) + Bassetthorn (in F)

Es soll alles mit allem kombinierbar sein natürlich so flexibel, so dass Änderungen/Erweiterungen leicht implementierbar sind ;-) Mit http://lilypondblog.org/2014/07/trees-music-and-lilypond/ habe ich eine gute Möglichkeit gefunden, die Parameter übersichtlich an die score- und bookpart-Funktion übergeben zu können. Pro "Dimension" habe ich ein eigenes root im Tree gebildet. Wie würdest du in einem solchen Fall vorgehen?

harm6

ZitatEin dreistimmiges Werk in fünf Teilen mit je fünf Sätzen (Mozart-Divertimenti KV229)

Handelt es sich um: http://dme.mozarteum.at/DME/nma/nma_cont.php?vsep=181&gen=edition&p1=67&l=1 ff ?
In den Quellen sehe ich verschiedene KV-Nummern...

Ich bin nicht sicher, ob ich der richtige bin, um nach der Methodik für ein großes Projekt zu fragen.
Noten eingeben nervt mich. So greife ich in meinen eigenen scores doch häufiger zu quick'n dirty tricks als wahrscheinlich gut wär...

Auch bin ich bald im Urlaub und völlig ohne Netz...

Aber ich denk mal drüber nach, falls mir was halbwegs gescheites vorm Urlaub einfällt werd ich's posten.

Soweit, Gruß,
  Harm

ingmar

Harms:
ZitatDarüber hinaus wird die von Dir gewünschte Funktionalität nicht häufig nachgefragt, so ist die Anzahl entsprechender tools auch nicht der Rede wert, bzw sind auch sehr unhandlich.

Ich muss gestehen, dass ich seit längerer Zeit genau an sowas arbeite! Leider stoße ich immer wieder auf unüberwindliche Schwierigkeiten, die zu ich vor allem deshalb nicht hier anspreche, weil es mir oft genug nicht gelingt, die Fragen auf kleine Beispiele einzudampfen. Bei mir sind immer mindestens drei, in manchen Fällen vier Files beteiligt.


Gruß,
--ingmar

harm6

Zitat von: ingmarIch muss gestehen, dass ich seit längerer Zeit genau an sowas arbeite! Leider stoße ich immer wieder auf unüberwindliche Schwierigkeiten, die zu ich vor allem deshalb nicht hier anspreche, weil es mir oft genug nicht gelingt, die Fragen auf kleine Beispiele einzudampfen. Bei mir sind immer mindestens drei, in manchen Fällen vier Files beteiligt.

Nun, ein minimal Example ist ein minimal working Example.
Wenns 3-4 files braucht, dann ist das eben so. Am besten als .zip o.ä. angehängt.

Ich würde aber einen neuen thread machen, das entfernt sich doch zu sehr vom Thema dieses threads.

Gruß,
  Harm

Köbi

#11
Hallo Harm

Zitat von: harm6 am Samstag,  5. August 2017, 18:01
Handelt es sich um: http://dme.mozarteum.at/DME/nma/nma_cont.php?vsep=181&gen=edition&p1=67&l=1 ff ?

Ja genau.

Ich habe versucht, deine makeBookpartForCurrentBook-function zu nutzen und manuell weitere bookparts dazu zu tun, aber es klappt leider nicht. Der folgende Code läuft nicht, aber er zeigt, was ich genau machen möchte. Wieso wird das manuell erzeugte bookpart nicht in das book gehängt?


%%%%%%%% Book A
test-book = \book {
  \bookOutputName "BookA"
}

bkA = \bookpart { \markup "TitleA" }
#(ly:book-add-bookpart! test-book bkA)

\makeBookpartForCurrentBook \scores "MyTitle" ##t

\test-book

harm6

Zitat von: KöbiWieso wird das manuell erzeugte bookpart nicht in das book gehängt?

Erinnere Dich an meinen post hier
https://lilypondforum.de/index.php/topic,105.msg712.html#msg712
ganz unten. Hast Du es ausprobiert? Klappt nicht.

Dazu aus dem bereits verlinkten thread
http://lists.gnu.org/archive/html/lilypond-user/2017-08/msg00107.html

Irgendetwas läuft nicht rund, mit Sicherheit ein bug, den Du völlig ohne meine Funktion schon mit folgendem auslösen kannst:

test-book = \book { \bookOutputName "BookA" }
bkA = \bookpart { \markup "TitleA" }
#(ly:book-add-bookpart! test-book bkA)
\test-book


Wenn bkA aber wie folgt definiert ist gehts:
bkA = \bookpart { \paper {} \markup "TitleA" }

Warum? Keine Ahnung.

Tut mir leid hier nicht mehr sagen zu können,
  Harm




Köbi

Zitat von: harm6 am Dienstag,  8. August 2017, 21:52
Wenn bkA aber wie folgt definiert ist gehts:
bkA = \bookpart { \paper {} \markup "TitleA" }

Ok, so weit klar. Damit kann ich umgehen. Nun wollte ich die function erweitern und scheitere (vermutlich) an der Syntax:


\version "2.19.64"

test-book = \book {}

makeBookpartForCurrentBook =
#(define-void-function (scores my-title showPoet?)
  (list? string? boolean?)
  "Add a new bookpart with @var{scores} and settings for paper and header to
   current book."
  (let* (
         ;; get an empty paper
         (bkp-paper #{ \paper {
            oddHeaderMarkup = \markup \fill-line {
            " "
            \on-the-fly #not-part-first-page \fromproperty #'header:instrumentHeader
            \on-the-fly #print-page-number-check-first \fromproperty #'page:page-number-string }
            evenHeaderMarkup = \markup \fill-line {
            \on-the-fly #print-page-number-check-first \fromproperty #'page:page-number-string
            \on-the-fly #not-part-first-page \fromproperty #'header:instrumentHeader
            " " }
         } #})
         ;; fill this paper with content and return it
         ;; REMARK I don't know a method to do it _after_ the bookpart is
         ;; initialized.
         (new-bkp-paper
           (begin
             bkp-paper))
         ;; get an empty header, filled later
         (bkp-header #{ \header {
           poet = showPoet?
         } #})
         ;; get a bookpart with those paper and header
         (bkp #{ \bookpart { $new-bkp-paper $bkp-header } #}))

  ;; fill the header with content
  (module-define! bkp-header 'title my-title)
  ;(module-define! bkp-header 'poet showPoet?)
  ;; get the filled header into the bookpart
  (ly:book-set-header! bkp bkp-header)
 
  ;; get the scores into the bookpart
  (for-each (lambda (score) (ly:book-add-score! bkp score)) scores)

  ;; add the bookpart to 'test-book'
  (ly:book-add-bookpart! test-book bkp)
  ))
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% score-definitions
scoreA = \score { \header { title = "T1" piece = "p1" } { a'1 \pageBreak a' } }
scoreB = \score { \header { title = "T2" piece = "p2" } { b'1 } }

%% list of scores
scores = #(list scoreA scoreB)

myInstrument = "Violino"
%% function-call
%% add a bookpart with the specified scores to 'test-book'
\header {
  poet = \markup \box { \pad-around #1 { \myInstrument } }
  instrumentHeader = \markup { \myInstrument }
}
\makeBookpartForCurrentBook \scores "MyTitle" ##t
\makeBookpartForCurrentBook \scores "MySecondTitle" ##f

%%call the ready test-book
\test-book


Zwei Probleme:

  • showPoet: Auf der ersten Seite sollte oben links in einer box "Violino" erscheinen, was es leider nicht tut :-(
  • paper: Das Ding, das ich eingefügt habe, führt zu einem Compile-Error. Warum? Ich ging davon aus, dass ich innerhalb von #{ ... #} normale Lilypond-Syntax verwenden kann.

Wenn's dann funktioniert, möchte ich steuern, dass im paper-Block das "\on-the-fly #not-part-first-page" nur drin ist, wenn showPoet=true ist. Auf der ersten Seite eines bookpart's soll also entweder das Instrument oben links boxed erschienen oder oben in der Mitte ohne box. Hintergrund: Ich habe mehrere Stücke mit je mehreren Sätzen in einem book. Bei einem neuen Stück (immer ein neues bookpart) soll das Instrument links auf der ersten Seite oben in der box erscheinen, wenn ein bookpart nur mit einem neuen Satz beginnt (weil ich z.B. davor aus wendetechnischen Gründen eine leere Seite eingefügt habe), dann soll das Instrument nur oben in der Mitte erscheinen.

harm6

#14
Hallo,

bin erst seit gestern abend wieder im Lande, ich hoffe Du brauchst es noch:

(1)
Wenn ich Deinen Code kompiliere kommt zunächst:
Zitat von: terminalerror: GUILE signaled an error for the expression beginning here
               \on-the-fly #
                                 not-part-first-page \fromproperty #'header:instrumentHeader
Unbound variable: not-part-first-page

`not-part-first-page' stammt aus titling-init.ly und ist nicht public. Um weiter zu kommen mach ich immer quick'n dirty:
\include "titling-init.ly"

(2)
Danach sieht man dann denn error den Du beschreibst (ist allerdings im header nicht im paper.)
Zitat von: köbi2. paper: Das Ding, das ich eingefügt habe, führt zu einem Compile-Error. Warum? Ich ging davon aus, dass ich innerhalb von #{ ... #} normale Lilypond-Syntax verwenden kann.
Zitat von: terminalerror: syntax error, unexpected '?'
           poet = showPoet
                          ?
bookpart-def-03.ly:168:1: error: error in #{ ... #}
Das Problem ist, daß Du versuchst in LilyPond eine scheme-Variable aufzurufen, showPoet?. Es handelt sich also eben nicht um LilyPond-syntax. Insoweit muß ein $- oder #-Zeichen davor (der Unterschied vernachlässige ich hier mal, bis auf: in Funktionen empfiehlt sich meistens das $-Zeichen)

(3)
Jetzt läuft es zwar ohne Fehler durch aber nicht mi dem gewünschten Ergebnis.
Erklärung:
Du hast einen toplevel header angegeben:
Zitat
\header {
  poet = \markup \box { \pad-around #1 { \myInstrument } }
  instrumentHeader = \markup { \myInstrument }
}
Dieser ist jetzt der header für alle books des files.
Einzelne Setzungen können durch zusätzliche header im bookpart oder score verändert oder auch hinzugefügt werden.
Und genau das machst Du, indem Du in der Funktion schreibst:
Zitat
         (bkp-header #{ \header {
           poet = $showPoet?
         } #})
showPoet? ist aber immer #t oder #f
Im toplevel-header wird die poet-Setzung also überschrieben durch ein boolean, welches zwar möglich ist, es gibt ja auch weder warning noch error, aber keine Ausgabe erzeugt.

(4)
Lösungsansatz:
Ich würde im toplevel-header wirklich nur die Setzungen reinschreiben die für das ganze Buch gelten sollen.
Setzungen für das Instrument gehören dann nicht dort hinein, da das book ja zahlreich Teile für verschiedene Instrumente beinhalten wird (wenn ich Dich richtig verstanden habe)
Vielmehr sollten die Instrument-Setzungen in den bookpart-header, der in der Funktion angelegt und dort bearbeitet wird.
Du mußt also der Funktion das Instrument übergeben und brauchst deshalb ein weiteres Argument. Dann kannst Du auch eine Abhängigkeit von showPoet? recht einfach etablieren.

Führt zu:

\version "2.19.56"

%% quick'n dirty to get access to 'not-part-first-page', etc
\include "titling-init.ly"

test-book = \book {}

makeBookpartForCurrentBook =
#(define-void-function (scores my-title instrument showPoet?)
  (list? string? markup? boolean?)
  "Add a new bookpart with @var{scores} and settings for paper and header to
   current book."
  (let* (
         ;; get a paper-module with some deafaults
         (bkp-paper
         #{
           \paper {
              oddHeaderMarkup =
                \markup \fill-line {
                  " "
                  \on-the-fly #not-part-first-page
                    $instrument
                  \on-the-fly #print-page-number-check-first
                    \fromproperty #'page:page-number-string
                }
              evenHeaderMarkup =
                \markup \fill-line {
                  \on-the-fly #print-page-number-check-first
                    \fromproperty #'page:page-number-string
                  \on-the-fly #not-part-first-page
                    $instrument
                  " "
                }
           }
         #})
         
         ;; Probably fill this paper with content and return it
         ;; REMARK I don't know a method to do it _after_ the bookpart is
         ;; initialized.
         (new-bkp-paper
           (begin ;;;;  (ly:output-def-set-variable! ... ... ...)
             bkp-paper))
             
         ;; get an empty header, filled later
         (bkp-header #{ \header { } #})
         
         ;; get a bookpart with those paper and header
         (bkp #{ \bookpart { $new-bkp-paper $bkp-header } #}))

    ;;;; fill the bookpart-header with content
    ;;;;
    ;; (1) put in 'my-title' as title
    (module-define! bkp-header 'title my-title)
    ;; (2) If 'showPoet?' s true put in formated 'instrument' as poet
    ;;     otherwise put in 'instrument' as instrument
    (if showPoet?
        (module-define! bkp-header
                        'poet
                        (if (string-null? (markup->string instrument))
                            ""
                            (markup #:box #:pad-around 1 instrument))
                        )
        (module-define! bkp-header
                        'instrument
                        instrument))
    ;; (3) more? ...
   
    ;; get the filled header into the bookpart
    (ly:book-set-header! bkp bkp-header)
   
    ;; get the scores into the bookpart
    (for-each (lambda (score) (ly:book-add-score! bkp score)) scores)
   
    ;; add the bookpart to 'test-book'
    (ly:book-add-bookpart! test-book bkp)
    ))

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% score-definitions
scoreA = \score { \header { title = "T1" piece = "p1" } { a'1 \pageBreak a' } }
scoreB = \score { \header { title = "T2" piece = "p2" } { b'1 } }

%% list of scores
scores = #(list scoreA scoreB)

myInstrument = "Violino"

%% function-call
%% add a bookpart with the specified scores to 'test-book'

\makeBookpartForCurrentBook \scores "MyTitle" \myInstrument ##t
\makeBookpartForCurrentBook \scores "MySecondTitle" "foo" ##f

%%call the ready test-book
\test-book


(5)
Kritik:
Falls Du weitere Setzungen im den bookpart header vornehmen willst brauchst Du mehr Argumente. Das wird schnell unbequem. Deshalb könnte man überlegen ob man nicht eine alist als Argument übergibt über die man dann module-define! iterieren kann.

(6)
Anderer Ansatz (hier nur als Skizze)
Schreib doch alles in einen toplevel-header und wähle innerhalb der Funktion aus was Du haben willst, führt zu:

\version "2.19.64"

\include "titling-init.ly"

\header {
first-mov =
#'(
   (title . "1. Satz")
   (instrument . "Violino")
   )
second-mov =
#'(
   (title . "2. Satz")
   (instrument . "Viola")
   )
}

test-book = \book {}

makeBookpartForCurrentBook =
#(define-void-function (scores header-setting showPoet?)
  (list? symbol? boolean?)
  "Add a new bookpart with @var{scores} and settings for paper and header to
   current book."
  (let* (
         (instr
           (assoc-get 'instrument (module-ref $defaultheader header-setting)))
         ;; get an empty paper
         (bkp-paper
         #{
           \paper {
              oddHeaderMarkup =
                \markup \fill-line {
                  " "
                  \on-the-fly #not-part-first-page
                    $instr
                  \on-the-fly #print-page-number-check-first
                    \fromproperty #'page:page-number-string
                }
              evenHeaderMarkup =
                \markup \fill-line {
                  \on-the-fly #print-page-number-check-first
                    \fromproperty #'page:page-number-string
                  \on-the-fly #not-part-first-page
                    $instr
                  " "
                }
           }
         #})
         ;; fill this paper with content and return it
         ;; REMARK I don't know a method to do it _after_ the bookpart is
         ;; initialized.
         (new-bkp-paper
           (begin
             bkp-paper))
         ;; get an empty header, filled later
         (bkp-header #{ \header { } #})
         ;; get a bookpart with those paper and header
         (bkp #{ \bookpart { $new-bkp-paper $bkp-header } #}))
  ;; fill the header with content
  (for-each
    (lambda (e)
      (if (and showPoet? (eq? (car e) 'instrument))
          (module-define! bkp-header
                          'poet
                          (if (string-null? (markup->string (cdr e)))
                              ""
                              (markup #:box #:pad-around 1 (cdr e))))
          (module-define! bkp-header (car e) (cdr e))))
    (module-ref $defaultheader header-setting))

  ;; get the filled header into the bookpart
  (ly:book-set-header! bkp bkp-header)

  ;; get the scores into the bookpart
  (for-each (lambda (score) (ly:book-add-score! bkp score)) scores)

  ;; add the bookpart to 'test-book'
  (ly:book-add-bookpart! test-book bkp)
  ))

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% score-definitions
scoreA = \score { \header { title = "T1" piece = "p1" } { a'1 \pageBreak a' } }
scoreB = \score { \header { title = "T2" piece = "p2" } { b'1 } }

%% list of scores
scores = #(list scoreA scoreB)

%% function-call
%% add a bookpart with the specified scores to 'test-book'
\makeBookpartForCurrentBook \scores #'first-mov ##t
\makeBookpartForCurrentBook \scores #'second-mov ##t

%%call the ready test-book
\test-book

Ist jetzt doch mehr als nur eine Skizze geworden.
Und wenn ichs mir recht überlege, so würde ich diesem Ansatz den Vorzug geben, denn dadurch wird auch das in (5) geschilderte Problem gelöst.


HTH,
  Harm