Manipulation d'une chaîne de caractères en scheme

Bonjour à tous,

Je cherche à faire une petite fonction scheme pour supprimer une partie d'un sous-titre et l'utiliser dans une entête. Voilà le code que j'ai imaginé pour l'instant mais qui ne fonctionne pas car la sortie n'est pas un markup :

\version "2.25.9"

\header {
  title    = "TITRE"
  subtitle = "Soustitre (année)"
}

#(define (remove-year str)
  (substring str 0 (- (string-length str) 7)))

\paper {
  oddHeaderMarkup = \markup {
    \fromproperty #'header:title 
    "-" 
    #(remove-year #{ \fromproperty #'header:subtitle #})
    "- p."
  }
}

\relative c' { a }

Est-ce que quelqu'un peut me donner un coup de main ? (D'ailleurs j'aimerais autant utiliser une regex plutôt que supprimer bêtement les 7 derniers caractères... Mais c'est l'étape suivante !)

Merci !

Simon

D'abord, #{ \fromproperty ... #} donne une erreur parce que le #{ #} sort du mode markup, donc il faut y revenir : #{ \markup \fromproperty ... #}.

Mais surtout, \markup \fromproperty #'header:subtitle n'est pas une chaîne de caractères, c'est un markup (pour être plus précis, un markup est soit une chaîne de caractères soit le résultat d'une commande markup, et on est dans le deuxième cas). Donc on ne peut pas s'en servir comme chaîne de caractères directement. C'est assez normal : le code Scheme est exécuté au moment de lire le fichier, alors que ce n'est que bien plus tard (au moment d'écrire la sortie, pour faire simple) que toute l'infrastructure est en place pour pouvoir lire des propriétés. Par contre, on peut appliquer une commande markup au \fromproperty, or il en existe une justement pour ce genre de cas, c'est \with-string-transformer. Avec en plus une regex, ça donne

\version "2.25.9"

\header {
  title    = "TITRE"
  subtitle = "Soustitre (année)"
}

#(define (remove-year str)
   (let ((pat (ly:make-regex " \\(année\\)")))
     (ly:regex-replace pat str)))

\paper {
  oddHeaderMarkup = \markup {
    \fromproperty #'header:title 
    "-" 
    \with-string-transformer
      #(lambda (layout props str)
         (remove-year str))
      \fromproperty #'header:subtitle
    "- p."
  }
}

\relative c' { a }

Merci beaucoup ! J'ai juste remplacé la regex \\(année\\) par \\(\\d{4}\\) et c'est exactement ce que je cherchais.

Est-ce qu'il y a une documentation pour ly:make-regex et ly:regex-replace et pour trouver d'autres fonctions de ce type ? Sans ton aide Jean j'aurais plutôt cherché une solution en pure scheme...

OK désolé j'ai répondu un peu rapidement, je viens de voir cette page : A.2 Function index (LilyPond Internals Reference)

C'est une affaire un peu triste : Guile dispose bel et bien d'une interface de regex (Regexp Functions (Guile Reference Manual)), sauf qu'elle ne prend pas en charge l'Unicode. C'est pour cette raison que LilyPond a la sienne propre.

Un peu triste en effet :slight_smile:

Merci beaucoup pour ces infos !