1.2.1 Syntaxe Scheme dans LilyPond (GNU LilyPond – Extension des fonctionnalités)

#### 1.2.1 Syntaxe Scheme dans LilyPond

L’installation de LilyPond comprenant l’interpréteur Guile, les fichiers source LilyPond peuvent contenir du Scheme. Vous disposez de plusieurs méthodes pour inclure du Scheme dans vos fichiers LilyPond.

La méthode la plus simple consiste à insérer un hash (le caractère `#`, improprement appelé dièse) avant l’expression Scheme.

Rappelons-nous qu’un fichier source LilyPond est structuré en jetons et expressions, tout comme le langage humain est structuré en mots et phrases. LilyPond dispose d’un analyseur lexical (appelé lexer) qui sait identifier les jetons – nombres, chaînes, éléments Scheme, hauteurs, etc. – ainsi que d’un analyseur syntaxique (appelé parser). Dès lors que le programme sait quelle règle grammaticale particulière doit s’appliquer, il exécute les consignes qui lui sont associées.

Le recours à un hash pour mettre en exergue du Scheme est tout à fait approprié. Dès qu’il rencontre un `#`, l’analyseur lexical passe le relais au lecteur Scheme qui va alors déchiffrer l’intégralité de l’expression Scheme – ce peut être un identifiant, une expression bornée par des parenthèses ou bien d’autres choses encore. Une fois cette expression lue, elle est enregistrée en tant que valeur d’un élément grammatical `SCM_TOKEN`. Puisque l’analyseur syntaxique sait comment traiter ce jeton, il charge Guile d’évaluer l’expression Scheme. Dans la mesure où le parser requiert une lecture en avance de la part du lexer pour prendre une décision, cette distinction entre lecture et évaluation – lexer et parser – révèle toute sa pertinence lorsqu’il s’agit d’exécuter conjointement des expressions LilyPond et des expressions Scheme. C’est la raison pour laquelle nous vous recommandons, dans toute la mesure du possible, d’utiliser un signe hash lorsque vous faites appel à Scheme.

Une autre manière de faire appel à l’interpréteur Scheme à partir de LilyPond consiste à introduire une expression Scheme par un caractère dollar au lieu d’un caractère dièse – un `$` au lieu d’un `#`. En pareil cas, LilyPond évalue le code dès sa lecture par l’analyseur lexical, vérifie le type d’expression Scheme qui en résulte et détermine un type de jeton (l’un des `xxx_IDENTIFIER` de la grammaire) qui lui correspond, puis en fait une copie qui servira à traiter la valeur de ce jeton. Lorsque la valeur de l’expression est void, autrement dit une valeur Guile `*unspecified*` (pour non spécifiée), aucune information n’est transmise à l’analyseur grammatical.

C’est, en réalité, la manière dont LilyPond opère lorsque vous rappelez une variable ou une fonction par son nom – au travers d’un `\nom` –, à la seule différence que sa finalité est déterminée par l’analyseur lexical de LilyPond sans consultation du lecteur Scheme ; le nom de la variable rappelée doit donc être en corrélation avec le mode LilyPond actif à ce moment là.

L’immédiateté de l’opérateur `$` peut entraîner des effets indésirables dont nous reparlerons à la rubrique Saisie de variables et Scheme ; aussi est-il préférable d’utiliser un `#` dès que l’analyseur grammatical le supporte. Dans le cadre d’une expression musicale, une expression qui aura été créée à l’aide d’un `#` sera interprétée comme étant de la musique. Elle ne sera cependant pas recopiée avant utilisation. Si la structure qui l’abrite devait être réutilisée, un appel explicite à `ly:music-deep-copy` pourrait être requis.

Les opérateurs `$@` et `#@` agissent comme des « colleurs de liste » : leur fonction consiste à insérer tous les éléments d’une liste dans le contexte environnant.

Examinons à présent du vrai code Scheme. Nous pouvons définir des procédures Scheme au milieu d’un fichier source LilyPond :

    #(define (moyenne a b c) (/ (+ a b c) 3))

Pour mémoire, vous noterez que les commentaires LilyPond (`%` ou `%{…%}`) ne peuvent s’utiliser dans du code Scheme, même si celui-ci se trouve au sein d’un fichier LilyPond. Ceci tient au fait que l’expression Scheme est lue par l’interpréteur Guile, et en aucune façon par l’analyseur lexical de LilyPond. Voici comment introduire des commentaires dans votre code Scheme :

    ; ceci n'est qu'une simple ligne de commentaire

    #!
      Ceci constitue un bloc de commentaire (non imbricable)
      dans le style Guile.
      En fait, les Schemeurs les utilisent très rarement,
      et vous n'en trouverez jamais dans le code source
      de LilyPond.
    !#

Dans la suite de notre propos, nous partons du principe que les données sont incluses dans un fichier musical, aussi toutes les expressions Scheme seront introduites par un `#`.

Toutes les expressions Scheme de haut niveau incluses dans un fichier LilyPond peuvent se combiner en une expression Scheme unique à l’aide de la clause `begin` :

    #(begin
      (define foo 0)
      (define bar 1))

#### GNU LilyPond – Extension des fonctionnalités v2.26.0 (stable-branch).

- 1 Tutoriel Scheme
  - 1.1 Introduction à Scheme
    - 1.1.1 Le bac à sable de Scheme
    - 1.1.2 Scheme et les variables
    - 1.1.3 Types de données Scheme simples
    - 1.1.4 Types de données Scheme composites
      - Paires
      - Listes
      - Listes associatives (alists)
      - Tables de hachage
    - 1.1.5 Scheme et les calculs
    - 1.1.6 Scheme et les procédures
      - Définition de procédures
      - Prédicats
      - Valeurs de retour
    - 1.1.7 Scheme et les conditions
      - if
      - cond
  - 1.2 Scheme et LilyPond
    - 1.2.1 Syntaxe Scheme dans LilyPond
    - 1.2.2 Variables LilyPond
    - 1.2.3 Débogage de code Scheme
    - 1.2.4 Saisie de variables et Scheme
    - 1.2.5 Import de code Scheme dans LilyPond
    - 1.2.6 Propriétés des objets
    - 1.2.7 Variables LilyPond composites
      - Décalages (offsets)
      - Fractions
      - Étendues (extents)
      - Propriété en alist
      - Chaînes d’alist
    - 1.2.8 Le modèle de boîte de LilyPond
    - 1.2.9 Représentation interne de la musique
  - 1.3 Construction de fonctions complexes
    - 1.3.1 Première approche (exemple)
    - 1.3.2 Affichage d’expressions musicales
    - 1.3.3 Propriétés musicales
    - 1.3.4 Doublement d’une note avec liaison (exemple)
    - 1.3.5 Ajout d’articulation à des notes (exemple)
- 2 Interfaces pour programmeurs
  - 2.1 Blocs de code LilyPond
  - 2.2 Fonctions Scheme
    - 2.2.1 Définition de fonctions Scheme
    - 2.2.2 Utilisation de fonctions Scheme
    - 2.2.3 Fonctions Scheme fantômes
  - 2.3 Fonctions musicales
    - 2.3.1 Définition de fonctions musicales
    - 2.3.2 Utilisation de fonctions musicales
    - 2.3.3 Fonctions de substitution simple
    - 2.3.4 Fonctions de substitution intermédiaires
    - 2.3.5 De l’usage des mathématiques dans les fonctions
    - 2.3.6 Fonctions dépourvues d’argument
    - 2.3.7 Fonctions musicales fantômes
  - 2.4 Fonctions événementielles
  - 2.5 Fonctions pour markups
    - 2.5.1 Construction d’un markup en Scheme
    - 2.5.2 Fonctionnement interne des markups
    - 2.5.3 Définition d’une nouvelle commande de markup
      - Syntaxe d’une commande markup
      - Attribution de propriétés
      - Exemple commenté
      - Adaptation d’une commande incorporée
      - Conversion de markups en chaînes
    - 2.5.4 Définition d’une nouvelle commande de liste de markups
  - 2.6 Contextes pour programmeurs
    - 2.6.1 Évaluation d’un contexte
    - 2.6.2 Application d’une fonction à tous les objets de mise en forme
  - 2.7 Fonctions de rappel
  - 2.8 Conteneurs requalifiants
  - 2.9 Retouches complexes
- 3 Interfaces LilyPond Scheme
- Appendix A GNU Free Documentation License
- Appendix B Index