Fonction conditionnelle pour insérer une page blanche

Bonjour,

J'aimerais réaliser une fonction lilypond qui me paraitrait à priori relativement simple:

Lorsque la fonction est appelée dans un \book, elle regarde quel est le numéro de page courant, si ce numéro est pair (ou impair selon un paramètre), elle insère une page blanche, sinon elle ne fait rien.

J'arrive déjà à faire la page blanche avec ces instructions:

\bookpart
{
\paper
{
oddFooterMarkup = ""
evenFooterMarkup = ""
}
\markup { "" }
}

Et je peux récupérer le numéro de page courant avec ces instructions:

\label #'firstScore
numerodepage = \markup { \page-ref #'firstScore "0" "?" }

Mais, même après avoir relu la doc extending.fr.pdf, je ne comprends pas comment je peux intégrer cela proprement dans une fonction scheme.

Pour l'instant, je n'arrive à appeler ma page blanche conditionnelle qu'en enregistrant le code précédent dans un fichier ily et en utilisant une instruction trouvée assez laborieusement sur Internet:

CreerPageVide =
#(define-void-function (parser location)()
(
if (string=? RecueilType "") (ly:parser-include-string (format #f "\include "~A"\n" "PageVide.ily" ))
)
)

Ce qui implique, qu'en faisant un code de ce genre, il ne me resterait plus qu'à trouver comment faire une conversion en number et un test modulo 2 sur numerodepage:

\label #'firstScore
numerodepage = \markup { \page-ref #'firstScore "0" "?" }

\CreerPageVide

Mais ce n'est pas franchement très élégant, et j'aimerais savoir s'il serait possible de compléter la doc avec:

  1. Le traditionnel "Hello World" qui montre comment fonctionne l'intégration entre lilypond et scheme

  2. Où peut-on trouver la définition de fonctions comme ly:parser-include-string?

  3. Est-ce qu'il existe en scheme le moyen de récupérer directement le numéro de page courant, sans passer par un label et si oui, où peut-on trouver les spécificités de lilypond accessible via le scheme?

Au plaisir,

ben

Bonjour,

[...]

Mais ce n'est pas franchement très élégant, et j'aimerais savoir s'il serait possible de compléter la doc avec:

1. Le traditionnel "Hello World" qui montre comment fonctionne l'intégration entre lilypond et scheme

C'est vrai que la documentation officielle n'est pas absolument
brillante sur ce sujet, mais il y a quand même des exemples
simples sur

https://lilypond.org/doc/v2.23/Documentation/extending/lilypond-variables

et

https://lilypond.org/doc/v2.23/Documentation/extending/lilypond-code-blocks

Il y a aussi ce tutoriel Scheme (écrit par moi) :

https://tutoriel-scheme.readthedocs.io/

avec une introduction normalement progressive.

2. Où peut-on trouver la définition de fonctions comme ly:parser-include-string?

ly:parser-include-string est une fonction définie en C++ et exportée en
Scheme, comme la plupart des fonctions dont le nom commence par « ly: ».
Vous la trouverez dans le fichier lily/lily-parser-scheme.cc :

https://gitlab.com/lilypond/lilypond/-/blob/master/lily/lily-parser-scheme.cc#L276

Bien sûr, cela ne vous sera utile que si vous comprenez le C++ et la façon
dont Scheme est intégré au C++ de LilyPond.

Maintenant, si tout ce que vous cherchez est sa documentation, elle peut
se trouver dans la référence des propriétés internes, comme pour toutes
les fonctions Scheme :

https://lilypond.org/doc/v2.23/Documentation/internals/scheme-functions

3. Est-ce qu'il existe en scheme le moyen de récupérer directement le numéro de page courant, sans passer par un label et si oui, où peut-on trouver les spécificités de lilypond accessible via le scheme?

En fait, le \page-ref est une fausse piste, car cette commande
n'accède pas directement au numéro de page lorsqu'elle est
exécutée. Elle ne fait que créer une référence au numéro de
page, qui est remplacée par le numéro bien plus tard, à un
moment où il est trop tard pour rajouter une page.

Voilà une fonction qui fonctionne :

\version "2.23.82"

emptyPage =
\bookpart {
\paper {
oddHeaderMarkup = ""
oddFooterMarkup = ""
#(use-modules (ice-9 match))
page-breaking =
#(lambda (paper-book)
(match-let* (((page) (ly:optimal-breaking paper-book))
(num (ly:prob-property page 'page-number)))
(if (even? num)
(list page)
'())))
}
\markup ""
}

\book {
{ c' }
\bookpart { \emptyPage }
{ c' }
\pageBreak
{ c' }
\bookpart { \emptyPage }
{ d' }
}

L'idée est de modifier l'algorithme de calcul des sauts
de page pour ce \bookpart afin qu'il supprime l'unique
page générée si elle est paire. Vous pouvez remplacer even?
par odd?.

Pour en apprendre plus sur les interfaces Scheme de LilyPond,
il y a essentiellement deux ressources : le manuel d'extension,
que vous avez déjà trouvé, et puis un document que j'ai écrit,

https://extending-lilypond.readthedocs.io

qui se veut plus complet.

Il est vrai que ni l'un ni l'autre ne mentionnent les modifications
de page-breaking, qui est plutôt documenté ici du point de vue
des valeurs prédéfinies par LilyPond :

https://lilypond.org/doc/v2.23/Documentation/notation/page-breaking

En fait, je n'y ai pas pensé du tout en écrivant « Extending LilyPond ».
C'est un coin de LilyPond dans lequel on a très rarement besoin d'aller
mettre son nez, ça m'était peut-être arrivé deux fois mais pas bien
plus ...

Cordialement,
Jean

···

Le 08/12/2022 à 12:18, Eulogia a écrit :

Oups, pour correspondre à votre code, la première ligne devrait être « evenFooterMarkup = "" » et pas « oddHeaderMarkup = "" ».

···

Le 08/12/2022 à 14:00, Jean Abou Samra a écrit :

oddHeaderMarkup = ""
oddFooterMarkup = ""

Bonjour,

Merci beaucoup pour tous ces liens, j'étudierai tout cela en détail calmement.

Merci aussi pour la routine, le code donné tel quel fonctionne bien, mais pas du tout si je l'intègre dans ma solution:

Avec l'option odd, il ne m'affiche qu'une seule page blanche, peu importe où je place \emptypage

Avec l'option even, il m'affiche la partition normalement, mais sans page blanche, peu importe où je place \emptypage

A moins que cela ne vous inspire droit une idée, je vais essayer de voir si j'arrive à reproduire le problème sur un exemple simplifié.

Au plaisir,

ben

···

Le 8 déc. 2022 à 14:00, Jean Abou Samra <****@****> a écrit :

Bonjour,

Le 08/12/2022 à 12:18, Eulogia a écrit :

[...]

Mais ce n'est pas franchement très élégant, et j'aimerais savoir s'il serait possible de compléter la doc avec:

1. Le traditionnel "Hello World" qui montre comment fonctionne l'intégration entre lilypond et scheme

C'est vrai que la documentation officielle n'est pas absolument
brillante sur ce sujet, mais il y a quand même des exemples
simples sur

https://lilypond.org/doc/v2.23/Documentation/extending/lilypond-variables

et

https://lilypond.org/doc/v2.23/Documentation/extending/lilypond-code-blocks

Il y a aussi ce tutoriel Scheme (écrit par moi) :

https://tutoriel-scheme.readthedocs.io/

avec une introduction normalement progressive.

2. Où peut-on trouver la définition de fonctions comme ly:parser-include-string?

ly:parser-include-string est une fonction définie en C++ et exportée en
Scheme, comme la plupart des fonctions dont le nom commence par « ly: ».
Vous la trouverez dans le fichier lily/lily-parser-scheme.cc :

https://gitlab.com/lilypond/lilypond/-/blob/master/lily/lily-parser-scheme.cc#L276

Bien sûr, cela ne vous sera utile que si vous comprenez le C++ et la façon
dont Scheme est intégré au C++ de LilyPond.

Maintenant, si tout ce que vous cherchez est sa documentation, elle peut
se trouver dans la référence des propriétés internes, comme pour toutes
les fonctions Scheme :

https://lilypond.org/doc/v2.23/Documentation/internals/scheme-functions

3. Est-ce qu'il existe en scheme le moyen de récupérer directement le numéro de page courant, sans passer par un label et si oui, où peut-on trouver les spécificités de lilypond accessible via le scheme?

En fait, le \page-ref est une fausse piste, car cette commande
n'accède pas directement au numéro de page lorsqu'elle est
exécutée. Elle ne fait que créer une référence au numéro de
page, qui est remplacée par le numéro bien plus tard, à un
moment où il est trop tard pour rajouter une page.

Voilà une fonction qui fonctionne :

\version "2.23.82"

emptyPage =
\bookpart {
  \paper {
    oddHeaderMarkup = ""
    oddFooterMarkup = ""
    #(use-modules (ice-9 match))
    page-breaking =
      #(lambda (paper-book)
         (match-let* (((page) (ly:optimal-breaking paper-book))
                      (num (ly:prob-property page 'page-number)))
           (if (even? num)
               (list page)
               '())))
  }
  \markup ""
}

\book {
  { c' }
  \bookpart { \emptyPage }
  { c' }
  \pageBreak
  { c' }
  \bookpart { \emptyPage }
  { d' }
}

L'idée est de modifier l'algorithme de calcul des sauts
de page pour ce \bookpart afin qu'il supprime l'unique
page générée si elle est paire. Vous pouvez remplacer even?
par odd?.

Pour en apprendre plus sur les interfaces Scheme de LilyPond,
il y a essentiellement deux ressources : le manuel d'extension,
que vous avez déjà trouvé, et puis un document que j'ai écrit,

https://extending-lilypond.readthedocs.io

qui se veut plus complet.

Il est vrai que ni l'un ni l'autre ne mentionnent les modifications
de page-breaking, qui est plutôt documenté ici du point de vue
des valeurs prédéfinies par LilyPond :

https://lilypond.org/doc/v2.23/Documentation/notation/page-breaking

En fait, je n'y ai pas pensé du tout en écrivant « Extending LilyPond ».
C'est un coin de LilyPond dans lequel on a très rarement besoin d'aller
mettre son nez, ça m'était peut-être arrivé deux fois mais pas bien
plus ...

Cordialement,
Jean

Argh, j'ai oublié de remettre le \bookpart lors du lancement de la variable, d'où mon problème…

Cette fois cela fonctionne, et il suffit d'une seule evenHeaderMarkup = "" pour cacher les numéro de page.

Merci!

CreerPageVideConditionnelle =
\bookpart {
  \paper {
    evenHeaderMarkup = ""
    #(use-modules (ice-9 match))
    page-breaking =
    #(lambda (paper-book)
       (match-let* (((page) (ly:optimal-breaking paper-book))
                    (num (ly:prob-property page 'page-number)))
                   (if (even? num)
                       (list page)
                       '())))
  }
  \markup ""
}

\bookpart { \CreerPageVideConditionnelle }

Au plaisir,

ben

···

Le 8 déc. 2022 à 14:03, Jean Abou Samra <****@****> a écrit :

Le 08/12/2022 à 14:00, Jean Abou Samra a écrit :

oddHeaderMarkup = ""
    oddFooterMarkup = ""

Oups, pour correspondre à votre code, la première ligne devrait être « evenFooterMarkup = "" » et pas « oddHeaderMarkup = "" ».

Bonjour.

Et pour éviter le \bookpart et avoir une structure conditionnelle, j'en suis une fois de plus revenu au parser-include-string, j'ai enregistré les deux variantes de \bookpart dans deux fichiers ily, et je les appelle avec

\CreerPageVide "Gauche"
\CreerPageVide "Droite"

CreerPageVide =
#(define-void-function (parser location Type)(string?)
   (
     cond
     ((string=? Type "Gauche") (ly:parser-include-string (format #f "\\include \"~A\"\n" "Modeles/Recueil/PageVideGauche.ily" )))
     ((string=? Type "Droite") (ly:parser-include-string (format #f "\\include \"~A\"\n" "Modeles/Recueil/PageVideDroite.ily" )))
     )
   )

En tout cas grand merci, cette fonction me simplifie beaucoup la gestion de mes recueils.

Au plaisir,

ben

···

Le 8 déc. 2022 à 18:16, Eulogia <****@****> a écrit :

Argh, j'ai oublié de remettre le \bookpart lors du lancement de la variable, d'où mon problème…

Cette fois cela fonctionne, et il suffit d'une seule evenHeaderMarkup = "" pour cacher les numéro de page.

Merci!

CreerPageVideConditionnelle =
\bookpart {
\paper {
   evenHeaderMarkup = ""
   #(use-modules (ice-9 match))
   page-breaking =
   #(lambda (paper-book)
      (match-let* (((page) (ly:optimal-breaking paper-book))
                   (num (ly:prob-property page 'page-number)))
                  (if (even? num)
                      (list page)
                      '())))
}
\markup ""
}

\bookpart { \CreerPageVideConditionnelle }

Au plaisir,

ben

Le 8 déc. 2022 à 14:03, Jean Abou Samra <****@****> a écrit :

Le 08/12/2022 à 14:00, Jean Abou Samra a écrit :

oddHeaderMarkup = ""
   oddFooterMarkup = ""

Oups, pour correspondre à votre code, la première ligne devrait être « evenFooterMarkup = "" » et pas « oddHeaderMarkup = "" ».