Subject: Plusieurs \score dans une fonction print-book-with-defaults

From: Simon Martineau <[email-masked]>
Date: Thu, 1 Dec 2022 11:38:50 +0100

Bonjour à tous,

Il y a quelques semaines Jean m’a aidé sur le forum pour une fonction scheme (https://lists.gnu.org/archive/html/lilypond-user-fr/2022-11/msg00093.html).

J’ai passé pas mal de temps à chercher une solution, mais je bloque pour une dernière chose : Je souhaiterai pouvoir inclure plusieurs blocks \score dans mon \book, mais je ne sais pas comment m’y prendre. Ci dessous un exemple minimal de code.

J’en profite pour vous demander si il existe des formations ou si quelqu’un donne des cours pour apprendre à utiliser le Scheme pour Lilypond : il y a pas mal de points que j’aimerais maitriser mieux sans spammer la liste de diffusion !

Merci beaucoup !

Simon

\version "2.22.2"

xBook =
#(define-void-function (key score)
(string? ly:score?)
(print-book-with-defaults
#{
\book {
\bookOutputSuffix $key
\paper {
oddHeaderMarkup = \markup {
\on-the-fly \first-page {
\circle \pad-around #2 $key
}
\on-the-fly \not-part-first-page {
\fromproperty #'header:title
\concat { "[" $key "]" }
"- p." \fromproperty #'page:page-number-string
}
}
evenHeaderMarkup = \markup {
\fromproperty #'header:title
\concat { "[" $key "]" }
"- p." \fromproperty #'page:page-number-string
}
}
$score
}
#}))

\header {
title = "TEST"
}

% FONCTIONNE PARFAITEMENT :

\xBook "Ut" \score {
\relative c' {
a b c d
\pageBreak
a b c d
}
}

% CE QUE JE SOUHAITERAIS
% NE FONCTIONNE PAS :

\xBook "Ut" {
\score {
\relative c' {
a b c d
\pageBreak
a b c d
}
}
\score {
\relative c' {
d c b a
}
}
}

---

From: Gilles Thibault <[email-masked]>
Date: Thu, 01 Dec 2022 15:31:56 +0100

Bonjour.
Je n'ai pas testé, mais je suppose qu'il faut commencer par rajouter un 
argument à la fonction si on veut 2 scores

xBook =
  #(define-void-function (key scoreI scoreII) (string? ly:score? 
ly:score?)

À la fin de xBooK
   $scoreI
   $scoreII ....
mais pas sûr que ça marche comme ça.

-- 
Gilles

---

From: Simon Martineau <[email-masked]>
Date: Thu, 1 Dec 2022 15:38:28 +0100

Bonjour,

Merci pour la réponse, oui cela fonctionne bien, mais comment faire pour avoir un nombre d'arguments non défini à l'avance ?

---

From: Gilles Thibault <[email-masked]>
Date: Thu, 01 Dec 2022 15:39:40 +0100

Le 2022-12-01 15:31, Gilles Thibault a écrit :
> Bonjour.
> Je n'ai pas testé, mais je suppose qu'il faut commencer par rajouter
> un argument à la fonction si on veut 2 scores

... ou peut-etre tout simplement changer ly:score? par ly:book?
Si j'ai bien compris, la musique ci dessous est un book et non un score 
même si on omet le \book au début :
{
    \score {
      \relative c' {
        a b c d
        \pageBreak
        a b c d
      }
    }
    \score {
      \relative c' {
        d c b a
      }
}

-- 
Gilles

---

From: Eulogia <[email-masked]>
Date: Thu, 1 Dec 2022 15:40:59 +0100

Bonjour,

En principe, c'est l'instruction \bookpart, qui permet d'avoir plusieurs score dans un book, pourquoi ne pas l'utiliser?

Cordialement, 

ben

> Le 1 déc. 2022 à 11:38, Simon Martineau <[email-masked]> a écrit :
> 
> Bonjour à tous,
> 
> Il y a quelques semaines Jean m’a aidé sur le forum pour une fonction scheme (https://lists.gnu.org/archive/html/lilypond-user-fr/2022-11/msg00093.html <https://lists.gnu.org/archive/html/lilypond-user-fr/2022-11/msg00093.html>).
> 
>  <x-msg://6/#cb1-1>\version "2.22.2"
>  <x-msg://6/#cb1-2>
>  <x-msg://6/#cb1-3>xBook =
>  <x-msg://6/#cb1-4>#(define-void-function (key score)
>  <x-msg://6/#cb1-5>   (string? ly:score?)
>  <x-msg://6/#cb1-6>   (print-book-with-defaults
>  <x-msg://6/#cb1-7>     #{
>  <x-msg://6/#cb1-8>     \book {
>  <x-msg://6/#cb1-9>       \bookOutputSuffix $key
>  <x-msg://6/#cb1-10>       \paper {
>  <x-msg://6/#cb1-11>         oddHeaderMarkup = \markup {
>  <x-msg://6/#cb1-12>           \on-the-fly \first-page {
>  <x-msg://6/#cb1-13>             \circle \pad-around #2 $key
>  <x-msg://6/#cb1-14>           }
>  <x-msg://6/#cb1-15>           \on-the-fly \not-part-first-page {
>  <x-msg://6/#cb1-16>             \fromproperty #'header:title
>  <x-msg://6/#cb1-17>             \concat { "[" $key "]"  }
>  <x-msg://6/#cb1-18>             "- p." \fromproperty #'page:page-number-string
>  <x-msg://6/#cb1-19>           }
>  <x-msg://6/#cb1-20>         }
>  <x-msg://6/#cb1-21>         evenHeaderMarkup = \markup {
>  <x-msg://6/#cb1-22>           \fromproperty #'header:title
>  <x-msg://6/#cb1-23>           \concat { "[" $key "]"  }
>  <x-msg://6/#cb1-24>           "- p." \fromproperty #'page:page-number-string
>  <x-msg://6/#cb1-25>         }
>  <x-msg://6/#cb1-26>       }
>  <x-msg://6/#cb1-27>       $score
>  <x-msg://6/#cb1-28>     }
>  <x-msg://6/#cb1-29>     #}))
>  <x-msg://6/#cb1-30>
>  <x-msg://6/#cb1-31>\header {
>  <x-msg://6/#cb1-32>  title = "TEST"
>  <x-msg://6/#cb1-33>}
>  <x-msg://6/#cb1-34>
>  <x-msg://6/#cb1-35>% FONCTIONNE PARFAITEMENT :
>  <x-msg://6/#cb1-36>
>  <x-msg://6/#cb1-37>\xBook "Ut" \score {
>  <x-msg://6/#cb1-38>  \relative c' {
>  <x-msg://6/#cb1-39>    a b c d
>  <x-msg://6/#cb1-40>    \pageBreak
>  <x-msg://6/#cb1-41>    a b c d
>  <x-msg://6/#cb1-42>  }
>  <x-msg://6/#cb1-43>}
>  <x-msg://6/#cb1-44>
>  <x-msg://6/#cb1-45>% CE QUE JE SOUHAITERAIS
>  <x-msg://6/#cb1-46>% NE FONCTIONNE PAS :
>  <x-msg://6/#cb1-47>
>  <x-msg://6/#cb1-48>\xBook "Ut" {
>  <x-msg://6/#cb1-49>  \score {
>  <x-msg://6/#cb1-50>    \relative c' {
>  <x-msg://6/#cb1-51>      a b c d
>  <x-msg://6/#cb1-52>      \pageBreak
>  <x-msg://6/#cb1-53>      a b c d
>  <x-msg://6/#cb1-54>    }
>  <x-msg://6/#cb1-55>  }
>  <x-msg://6/#cb1-56>  \score {
>  <x-msg://6/#cb1-57>    \relative c' {
>  <x-msg://6/#cb1-58>      d c b a
>  <x-msg://6/#cb1-59>    }
>  <x-msg://6/#cb1-60>  }
>  <x-msg://6/#cb1-61>}

---

From: Simon Martineau <[email-masked]>
Date: Thu, 1 Dec 2022 16:15:18 +0100

Merci pour la réponse !

Ce que je voudrais c’est vraiment \score et non \bookpart pour éviter les sauts de page, comme par exemple sur ce code :

\version "2.22.2"

\header {
title = "TITRE"
}

introUt = { a'' }

partieUt = { b'' }

codaUt = { c'' }

\book {
\score { \introUt }
\score { \partieUt }
\score { \codaUt }
}

Ma difficulté c’est de garder le block \paper et \bookOutputSuffix dans ma fonction \xBook. Pour cette raison je pense que l’argument de type ly:book? ne fonctionnera pas…

Merci beaucoup pour votre aide, je galère un peu !!

Simon

---

From: Eulogia <[email-masked]>
Date: Thu, 1 Dec 2022 17:03:25 +0100

Bonjour Simon, 

Je comprends mieux merci!

Pour ma part, j'essayerais de mettre le code lilypond du formatage du book dans un fichier ily et j'appellerais le fichier dans la fonction scheme avec une instruction de ce genre:

(ly:parser-include-string (format #f "\\include \"~A\"\n" "Modeles/Formatage.ily" ))

Ce qui est équivalent à faire ce code, qui devrait fonctionner:

\book
{
	\include "Modeles/Formatage.ily"
	\score {}
	\score {}
}

Cordialement, 

ben

>  <x-msg://8/#cb1-1>\version "2.22.2"
>  <x-msg://8/#cb1-2>
>  <x-msg://8/#cb1-3>xBook =
>  <x-msg://8/#cb1-4>#(define-void-function (key score)
>  <x-msg://8/#cb1-5>   (string? ly:score?)
>  <x-msg://8/#cb1-6>   (print-book-with-defaults
>  <x-msg://8/#cb1-7>     #{
>  <x-msg://8/#cb1-8>     \book {
>  <x-msg://8/#cb1-9>       \bookOutputSuffix $key
>  <x-msg://8/#cb1-10>       \paper {
>  <x-msg://8/#cb1-11>         oddHeaderMarkup = \markup {
>  <x-msg://8/#cb1-12>           \on-the-fly \first-page {
>  <x-msg://8/#cb1-13>             \circle \pad-around #2 $key
>  <x-msg://8/#cb1-14>           }
>  <x-msg://8/#cb1-15>           \on-the-fly \not-part-first-page {
>  <x-msg://8/#cb1-16>             \fromproperty #'header:title
>  <x-msg://8/#cb1-17>             \concat { "[" $key "]"  }
>  <x-msg://8/#cb1-18>             "- p." \fromproperty #'page:page-number-string
>  <x-msg://8/#cb1-19>           }
>  <x-msg://8/#cb1-20>         }
>  <x-msg://8/#cb1-21>         evenHeaderMarkup = \markup {
>  <x-msg://8/#cb1-22>           \fromproperty #'header:title
>  <x-msg://8/#cb1-23>           \concat { "[" $key "]"  }
>  <x-msg://8/#cb1-24>           "- p." \fromproperty #'page:page-number-string
>  <x-msg://8/#cb1-25>         }
>  <x-msg://8/#cb1-26>       }
>  <x-msg://8/#cb1-27>       $score
>  <x-msg://8/#cb1-28>     }
>  <x-msg://8/#cb1-29>     #}))
>  <x-msg://8/#cb1-30>
>  <x-msg://8/#cb1-31>\header {
>  <x-msg://8/#cb1-32>  title = "TEST"
>  <x-msg://8/#cb1-33>}
>  <x-msg://8/#cb1-34>
>  <x-msg://8/#cb1-35>% FONCTIONNE PARFAITEMENT :
>  <x-msg://8/#cb1-36>
>  <x-msg://8/#cb1-37>\xBook "Ut" \score {
>  <x-msg://8/#cb1-38>  \relative c' {
>  <x-msg://8/#cb1-39>    a b c d
>  <x-msg://8/#cb1-40>    \pageBreak
>  <x-msg://8/#cb1-41>    a b c d
>  <x-msg://8/#cb1-42>  }
>  <x-msg://8/#cb1-43>}
>  <x-msg://8/#cb1-44>
>  <x-msg://8/#cb1-45>% CE QUE JE SOUHAITERAIS
>  <x-msg://8/#cb1-46>% NE FONCTIONNE PAS :
>  <x-msg://8/#cb1-47>
>  <x-msg://8/#cb1-48>\xBook "Ut" {
>  <x-msg://8/#cb1-49>  \score {
>  <x-msg://8/#cb1-50>    \relative c' {
>  <x-msg://8/#cb1-51>      a b c d
>  <x-msg://8/#cb1-52>      \pageBreak
>  <x-msg://8/#cb1-53>      a b c d
>  <x-msg://8/#cb1-54>    }
>  <x-msg://8/#cb1-55>  }
>  <x-msg://8/#cb1-56>  \score {
>  <x-msg://8/#cb1-57>    \relative c' {
>  <x-msg://8/#cb1-58>      d c b a
>  <x-msg://8/#cb1-59>    }
>  <x-msg://8/#cb1-60>  }
>  <x-msg://8/#cb1-61>}

---

From: Simon Martineau <[email-masked]>
Date: Fri, 2 Dec 2022 00:31:11 +0100

Merci beaucoup Ben, je ne connaissais pas ly:parser-include-string. C’est une bonne idée je pense, mais ma fonction inclue une variable pour le formatage du book, et j’ai l’impression qu’avec cette méthode cela ne peut pas fonctionner.

Pour l’instant le code le plus efficace que j’ai trouvé est le suivant :

\version "2.22.2"

xBook =
#(define-scheme-function
(key)
(string?)
#{
\paper {
\on-the-fly \first-page { \circle \pad-around #2 $key }
#})

\book {
\bookOutputSuffix "Ut"
\xBook "Ut"
\score {
\relative c' {
\mark "Theme"
\repeat unfold 15 { a1 b c d \break }
}
}
\score {
\relative c' {
\mark "Coda"
a b c d
}
}
}

J’aurais bien aimé avoir une seule commande pour \bookOutputSuffix et \xBook, d’où l’idée du code dans mon premier mail, mais pour l’instant je n’ai pas assez de connaissances…

Merci à tous pour votre aide !

Simon

---

From: Eulogia <[email-masked]>
Date: Fri, 2 Dec 2022 01:06:12 +0100

Dès lors que l'on fait un \include en instruction directe ou appelée par la commande parser-include-string, les variables lilypond déclarées avant l'appel de l'include seront reconnues sans problème et peuvent être exploitées dans le fichier inclus, ainsi que les instructions bookname, etc. 

L'avantage de cette méthode est que la fonction scheme se contente de choisir les bons fichiers ily en fonction des paramètres donnés, et que les fichiers ily restent du pur lilypond, qui est plus lisible et pas exposés aux problèmes de mélange avec le scheme. 

Bonne nuit, 

ben

> Le 2 déc. 2022 à 00:31, Simon Martineau <[email-masked] <mailto:[email-masked]>> a écrit :
> 
>  <x-msg://9/#cb1-1>\version "2.22.2"
>  <x-msg://9/#cb1-2>
>  <x-msg://9/#cb1-3>xBook = 
>  <x-msg://9/#cb1-4>#(define-scheme-function 
>  <x-msg://9/#cb1-5>   (key)
>  <x-msg://9/#cb1-6>   (string?)
>  <x-msg://9/#cb1-7>#{
>  <x-msg://9/#cb1-8>  \paper {
>  <x-msg://9/#cb1-9>    oddHeaderMarkup = \markup {
>  <x-msg://9/#cb1-10>      \on-the-fly \first-page { \circle \pad-around #2 $key } 
>  <x-msg://9/#cb1-11>      \on-the-fly \not-part-first-page {
>  <x-msg://9/#cb1-12>        \fromproperty #'header:title
>  <x-msg://9/#cb1-13>        \concat { "[" $key "]"  }
>  <x-msg://9/#cb1-14>        "- p." \fromproperty #'page:page-number-string
>  <x-msg://9/#cb1-15>      }
>  <x-msg://9/#cb1-16>    }
>  <x-msg://9/#cb1-17>    evenHeaderMarkup = \markup {
>  <x-msg://9/#cb1-18>      \fromproperty #'header:title
>  <x-msg://9/#cb1-19>      \concat { "[" $key "]"  }
>  <x-msg://9/#cb1-20>      "- p." \fromproperty #'page:page-number-string
>  <x-msg://9/#cb1-21>    }
>  <x-msg://9/#cb1-22>  }
>  <x-msg://9/#cb1-23>#})
>  <x-msg://9/#cb1-24>
>  <x-msg://9/#cb1-25>\book {
>  <x-msg://9/#cb1-26>  \bookOutputSuffix "Ut"
>  <x-msg://9/#cb1-27>  \xBook "Ut"
>  <x-msg://9/#cb1-28>  \score {
>  <x-msg://9/#cb1-29>    \relative c' {
>  <x-msg://9/#cb1-30>      \mark "Theme"
>  <x-msg://9/#cb1-31>      \repeat unfold 15 { a1 b c d \break }
>  <x-msg://9/#cb1-32>    }
>  <x-msg://9/#cb1-33>  }
>  <x-msg://9/#cb1-34>  \score {
>  <x-msg://9/#cb1-35>    \relative c' {
>  <x-msg://9/#cb1-36>      \mark "Coda"
>  <x-msg://9/#cb1-37>      a b c d 
>  <x-msg://9/#cb1-38>    }
>  <x-msg://9/#cb1-39>  }
>  <x-msg://9/#cb1-40>}

---

From: Jean Abou Samra <[email-masked]>
Date: Fri, 2 Dec 2022 11:39:14 +0100

Le 01/12/2022 à 11:38, Simon Martineau a écrit :
>
>
> Bonjour à tous,
>
> Il y a quelques semaines Jean m’a aidé sur le forum pour une fonction 
> scheme 
> (https://lists.gnu.org/archive/html/lilypond-user-fr/2022-11/msg00093.html).
>
> J’ai passé pas mal de temps à chercher une solution, mais je bloque 
> pour une dernière chose : Je souhaiterai pouvoir inclure plusieurs 
> blocks |\score| dans mon |\book|, mais je ne sais pas comment m’y 
> prendre. Ci dessous un exemple minimal de code.
>

Bonjour,

Désolé, j'étais en train d'oublier cette question.

Je ne vous cache pas que c'est un point sur lequel LilyPond
est légèrement étrange.

Voici au moins une solution qui marche :

\version "2.22.2"

xBook =
#(define-void-function (key book)
    (string? ly:book?)
        $@(ly:book-scores book)
      }
      #}))

\header {
   title = "TEST"
}

\xBook "Ut" \book {
   \relative c' {
     a b c d
     \pageBreak
     a b c d
   }
}

\xBook "Ut" \book {
   \score {
     \relative c' {
       a b c d
       \pageBreak
       a b c d
     }
   }
   \score {
     \relative c' {
       d c b a
     }
   }
}

Ce code se sert du \book comme d'un « conteneur » qui permet de
regrouper les blocs \score.

Il y a aussi la solution avec une liste Scheme de \score, qui est
sans doute plus propre bien que légèrement plus verbeuse :

\version "2.22.2"

xBook =
#(define-void-function (key scores)
    (string? list?)
        $@scores
      }
      #}))

\header {
   title = "TEST"
}

\xBook "Ut"
#(list
   #{
     \score {
       \relative c' {
         a b c d
         \pageBreak
         a b c d
       }
     }
   #})

\xBook "Ut"
#(list
   #{
      \score {
        \relative c' {
          a b c d
          \pageBreak
          a b c d
        }
      }
   #}
   #{
      \score {
        \relative c' {
          d c b a
        }
      }
   #})

Dans les deux cas, j'ai utilisé le « $@ », une fonctionnalité
qui mériterait d'être plus connue, qui insère tous les
éléments d'une liste dans le contexte environnant. $(list a b c)
est comme $a $b $c, sauf que la liste peut avoir un nombre
quelconque d'éléments.

(Gilles : non, un \score n'est pas une expression musicale,
donc on ne peut pas le mettre dans une expression musicale
{ ... }.)

> J’en profite pour vous demander si il existe des formations ou si 
> quelqu’un donne des cours pour apprendre à utiliser le Scheme pour 
> Lilypond : il y a pas mal de points que j’aimerais maitriser mieux 
> sans spammer la liste de diffusion !
>

Question intéressante. Pour ma part, j'ai mis en ligne des ressources
d'apprentissage, à savoir un tutoriel Scheme :

https://tutoriel-scheme.readthedocs.io

et un guide d'extension de LilyPond (en anglais) :

https://extending-lilypond.readthedocs.io

Est-ce que c'est le genre de réponse que vous attendiez ?

Cordialement,
Jean

---

From: Simon Martineau <[email-masked]>
Date: Fri, 2 Dec 2022 21:00:16 +0100

Merci beaucoup Jean, c'est exactement ce que je cherchais !

Je vais voir dans la pratique quel code adopter entre les deux.

Merci également pour les liens, je connais le tutoriel-scheme mais pas encore "extending-lilypond". Je vais regarder ça ! En ce qui me concerne j'ai beaucoup appris dans les échanges pour cette fonction, mais j'ai l'impression qu'il me reste une montagne !

Je me disais qu'une petite séance de cours en direct pourrait également être efficace pour progresser. Peut-être que cela peut intéresser d'autres personnes sur le groupe ? C'était juste une idée comme ça...

Bonne soirée,

Simon