Ajout de propriétés et types#

Cette annexe montre comment définir de nouvelles propriétés de contexte ou de grob ainsi que de nouveaux types d’expressions musicales et de grobs.

Attention : ces fonctions ne constituent pas une vraie interface à l’heure actuelle. Elle pourraient ne plus fonctionner dans une version ultérieure lorsqu’une meilleure interface sera ajoutée.

Ces fonctions sont adaptée du fameux test de régression scheme-text-spanner.ly écrit par David Nalesnik.

Pour les nouveaux types de contexte, une vraie interface existe, comme détaillé dans Définition d’un type de contextes.

Ajout de propriétés#

Définir une propriété, c’est essentiellement définir un prédicat utilisé pour vérifier les valeurs données à cette propriété par l’utilisateur. On le fait en réglant une propriétés d’objet sur le symbole du nom de la propriété (propriété d’objet = object property, mécanisme de Guile, à ne pas confondre avec les propriétés des probs de LilyPond). La propriété d’objet sera translation-type? pour les propriétés de contexte et backend-type? pour les propriétés de grob.

#(set-object-property! 'maPropriétéDeContexte 'translation-type? number?)
#(set-object-property! 'ma-propriété-de-grob 'translation-type? boolean?)

Les propriétés des expressions musicales n’ont pas de prédicat, donc aucune définition n’est nécessaire.

Ajout d’une classe d’événements#

La fonction define-event-class prend le nom d’une classe à créer et le nom d’une classe existante dont la nouvelle classe héritera. S’il n’y a pas de classe évidente dont faire descendre votre nouvelle classe, music-event est souvent un bon choix.

#(define-event-class 'highlight-event 'span-event)

Ajout d’un type d’expressions musicales#

Utilisez la fonction suivante :

#(define (define-event! type properties)
   (set-object-property! type
                         'music-description
                         (cdr (assq 'description properties)))
   (set! properties (assoc-set! properties 'name type))
   (set! properties (assq-remove! properties 'description))
   (hashq-set! music-name-to-property-table type properties)
   (set! music-descriptions
         (sort (cons (cons type properties)
                     music-descriptions)
               alist<?)))

L’argument type est le nom du nouveau type. properties est une liste associative de propriétés avec leurs valeurs par défaut. Les propriétés les plus importantes sont description et types. La description est obligatoire. types` est une liste de classes musicales auxquelles appartient le nouveau type.

Voici comment on pourrait définir un type d’expressions musicales qui dessinent des surlignages :

#(define-event!
   'HighlightEvent
   '((description . "Used to signal where colored highlights start and stop.")
     (types . (post-event highlight-event event))))

Ajout d’un type de grob#

Utilisez cette fonction :

#(define (define-grob! grob-name grob-entry)
   (set! all-grob-descriptions
         (cons ((@@ (lily) completize-grob-entry)
                (cons grob-name grob-entry))
               all-grob-descriptions)))

La définition du grob se fait en deux étapes. D’abord, appelez define-grob! avec le nom du nouveau type de grobs et une liste associative de propriétés avec leurs valeurs par défaut. Il doit y avoir une propriété meta avec une classe (Item, Spanner ou Paper_column, voir Grob flavors and line breaks) et une liste d’interfaces. Les interfaces correspondant à la classe (item-interface dans cet exemple) sont ajoutées automatiquement.

#(define-grob!
   'JustText
   `((stencil . ,ly:text-interface::print)
     (X-extent . ,empty-interval)
     (Y-extent . ,empty-interval)
     (meta . ((class . Item)
              (interfaces . (text-interface))))))

Ensuite, il est impératif de réinitialiser les descriptions de grobs :

\layout {
  \context {
    \Global
    \grobdescriptions #all-grob-descriptions
  }
}

Il n’y a pas besoin de définition particulière pour une interface de grobs.