1 @c -*- coding: utf-8; mode: texinfo; documentlanguage: fr -*-
4 Translation of GIT committish: 8c7bd1b47a9a147c8ce1329e7f80e7ca282e5d15
6 When revising a translation, copy the HEAD committish of the
7 version that you are working on. For details, see the Contributors'
8 Guide, node Updating translation committishes..
13 @c Translators: Jean-Charles Malahieude
16 @chapter Tutoriel Scheme
20 @cindex Scheme, inclusion de code
21 @cindex accéder à Scheme
22 @cindex évaluation Scheme
25 LilyPond recourt abondamment au langage de programmation Scheme, tant au
26 niveau de la syntaxe de saisie que des mécanismes internes chargés de
27 combiner les différents modules du logiciel. Les lignes qui suivent
28 constituent un bref aperçu de la manière de saisir des données en
29 Scheme. Si vous désirez en apprendre plus sur Scheme, n'hésitez pas à
30 vous rendre sur @uref{http://@/www@/.schemers@/.org}.
32 Le Scheme utilisé par LilyPond repose sur l'implémentation GNU
33 Guile@tie{}; celle-ci se base sur le standard Scheme @qq{R5RS}. Si
34 votre but est d'apprendre Scheme au travers de LilyPond, sachez que
35 l'utilisation d'une autre implémentation ou d'un autre standard pourrait
36 être source de désagrément. Vous trouverez plus d'information sur
37 GUILE à la page @uref{http://www.gnu.org/software/guile/}@tie{}; le
38 standard Scheme @qq{R5RS} est quant à lui disponible à la page
39 @uref{http://www.schemers.org/Documents/Standards/R5RS/}.
42 * Introduction à Scheme::
43 * Scheme et LilyPond::
44 * Construction de fonctions complexes::
48 @node Introduction à Scheme
49 @section Introduction à Scheme
50 @translationof Introduction to Scheme
52 Nous commencerons par nous intéresser à Scheme et à son fonctionnement,
53 grâce à l'interpréteur GUILE. Une fois plus à l'aise avec Scheme, nous
54 verrons comment ce langage peut s'intégrer à un fichier LilyPond.
57 * Le bac à sable de Scheme::
58 * Scheme et les variables::
59 * Types de données Scheme simples::
60 * Types de données Scheme composites::
61 * Scheme et les calculs::
62 * Scheme et les procédures::
63 * Scheme et les conditions::
67 @node Le bac à sable de Scheme
68 @subsection Le bac à sable de Scheme
69 @translationof Scheme sandbox
71 L'installation de LilyPond comprend l'implémentation GUILE de Scheme.
72 La plupart des systèmes disposent d'un @qq{bac à sable} Scheme pour
73 effectuer des tests@tie{}; vous y accéderez en tapant @qq{guile} dans
74 un terminal. Certains systèmes, notamment Windows, nécessitent d'avoir
75 auparavant créé la variable d'environnement @code{GUILE_LOAD_PATH} qui
76 devra pointer vers le répertoire @code{../usr/share/guile/1.8} de
77 l'installation de LilyPond -- pour connaître le chemin complet d'accès à
78 ce répertoire, consultez @rlearning{Autres sources de documentation}.
79 Les utilisateurs de Windows peuvent aussi prendre l'option @qq{Exécuter}
80 à partir du menu @qq{Démarrer} puis taper @qq{guile}.
82 Néanmoins, tous les paquetages de LilyPond disposent d'un bac à sable
83 Scheme, accessible par la commande@tie{}:
85 lilypond scheme-sandbox
89 Une fois le bac à sable actif, vous obtiendrez l'invite@tie{}:
94 Vous pouvez dès à présent saisir des expressions Scheme pour vous
95 exercer. Si vous souhaitez pouvoir utiliser la bibliothèque GNU
96 @code{readline}, qui offre une ligne de commande plus élaborée,
97 consultez les informations contenues dans le fichier
98 @file{ly/scheme-sandbox.ly}. La bibliothèque @var{readline}, dans la
99 mesure où elle est habituellement activée dans vos sessions Guile,
100 devrait être effective y compris dans le bac à sable.
103 @node Scheme et les variables
104 @subsection Scheme et les variables
105 @translationof Scheme variables
107 Une variable Scheme peut contenir n'importe quelle valeur valide en
108 Scheme, y compris une procédure Scheme.
110 Une variable Scheme se crée avec la fonction @code{define}@tie{}:
117 L'évaluation d'une variable Scheme se réalise en saisissant le nom de
118 cette variable à l'invite de Guile@tie{}:
126 Une variable Scheme s'affiche à l'écran à l'aide de la fonction
127 @code{display}@tie{}:
135 Vous aurez remarqué que la valeur @code{2} et l'invite @code{guile}
136 apparaissent sur une même ligne. On peut améliorer la présentation à
137 l'aide de la procédure @code{newline} ou bien en affichant un caractère
141 guile> (display a)(newline)
143 guile> (display a)(display "\n")
148 Après avoir créé une variable, vous pouvez en modifier la valeur grâce à
149 un @code{set!}@tie{}:
152 guile> (set! a 12345)
158 Vous quitterez proprement le bac à sable à l'aide de l'instruction
166 @node Types de données Scheme simples
167 @subsection Types de données Scheme simples
168 @translationof Scheme simple data types
170 L'un des concepts de base de tout langage est la saisie de données,
171 qu'il s'agisse de nombres, de chaînes de caractères, de listes etc.
172 Voici les différents types de données Scheme simples utilisées
173 couramment dans LilyPond.
177 Les valeurs booléennes sont vrai ou faux. En Scheme, ce sera @code{#t}
178 pour vrai, et @code{#f} pour faux.
183 Les nombres se saisissent le plus communément@tie{}: @code{1} est le
184 nombre (entier) un, alors que @w{@code{-1.5}} est un nombre à virgule
185 flottante (un nombre non entier).
188 Les chaînes de caractères sont bornées par des guillemets
192 "ceci est une chaîne"
195 Une chaîne peut s'étendre sur plusieurs lignes@tie{}:
204 auquel cas les retours à la ligne seront inclus dans la chaîne.
206 Un caractère de retour à la ligne peut s'ajouter dans la chaîne, sous la
207 forme d'un @code{\n}.
210 "ceci\nest une\nchaîne multiligne"
213 Guillemets et obliques inverses dans une chaîne doivent être précédés
214 d'une oblique inverse. La chaîne @code{\a dit "b"} se saisit donc
222 Il existe bien d'autres types de données Scheme, dont nous ne parlerons
223 pas ici. Vous en trouverez une liste exhaustive dans le guide de
224 référence de Guile, à la page
225 @uref{http://www.gnu.org/software/guile/manual/html_node/Simple-Data-Types.html}.
228 @node Types de données Scheme composites
229 @subsection Types de données Scheme composites
230 @translationof Scheme compound data types
232 Scheme prend aussi en charge des types de données composites. LilyPond
233 utilise beaucoup les paires, listes, listes associatives et tables de
238 Le type de donnée composite fondamental est la paire (@code{pair}).
239 Comme son nom l'indique, il s'agit de lier deux valeurs, à l'aide de
240 l'opérateur @code{cons}.
248 Vous aurez noté que la paire s'affiche sous la forme de deux éléments
249 bornés par des parenthèses et séparés par une espace, un point
250 (@code{.}) et une autre espace. Le point n'est en aucune manière un
251 séparateur décimal@tie{}; il s'agit de l'indicateur d'une paire.
253 Vous pouvez aussi saisir littéralement les valeurs d'une paire, en la
254 faisant précéder d'une apostrophe.
262 Les deux éléments d'une paire peuvent être constitués de n'importe
263 quelle valeur Scheme valide@tie{}:
268 guile> '("blah-blah" . 3.1415926535)
269 ("blah-blah" . 3.1415926535)
273 Les premier et second éléments de la paire sont accessibles à l'aide des
274 procédures Scheme @code{car} et @code{cdr}.
277 guile> (define mypair (cons 123 "hello there")
288 Note : @code{cdr} se prononce @qq{couldeur}, comme l'indiquent Sussman et
290 @uref{http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-14.html#footnote_Temp_133}.
295 Autre structure de donnée commune en Scheme@tie{}: la liste
296 (@emph{list}). Une liste se définit comme étant vide (représentée par
297 @code{'()}) ou une paire dont le @code{cdr} est une liste.
299 Il existe plusieurs méthodes pour créer une liste, la plus courante
300 étant l'utilisation de la procédure @code{list}@tie{}:
303 guile> (list 1 2 3 "abc" 17.5)
307 Comme vous le remarquez, une liste s'affiche sous la forme d'une suite
308 d'éléments séparés par une espace, bornée par des parenthèses.
309 Contrairement à une paire, il n'y a pas de point entre les éléments.
311 Vous pouvez aussi saisir directement une liste en entourant ses éléments
312 par des parenthèses à la suite d'une apostrophe@tie{}:
315 guile> '(17 23 "foo" "bar" "bazzle")
316 (17 23 "foo" "bar" "bazzle")
319 Les listes ont une importance considérable en Scheme. Certains vont
320 d'ailleurs jusqu'à considérer Scheme comme un dialecte du lisp, où
321 @qq{lisp} serait une abréviation de @qq{List Processing}. Il est vrai
322 que toute expression Scheme est une liste.
325 @subheading Listes associatives (alists)
327 Il existe un type particulier de liste@tie{}: la @emph{liste
328 associative} -- ou @emph{alist}. Une @emph{alist} permet de stocker des
329 données dans le but de les réutiliser.
331 Une liste associative est une liste dont les éléments sont des paires.
332 Le @code{car} de chacun des éléments constitue une clé (@emph{key}) et
333 chaque @code{cdr} une valeur (@emph{value}). La procédure Scheme
334 @code{assoc} permet de retrouver une entrée de la liste
335 associative@tie{}; son @code{cdr} en fournira la valeur@tie{}:
338 guile> (define mon-alist '((1 . "A") (2 . "B") (3 . "C")))
340 ((1 . "A") (2 . "B") (3 . "C"))
341 guile> (assoc 2 mon-alist)
343 guile> (cdr (assoc 2 mon-alist))
348 LilyPond recourt abondamment aux @emph{alists} pour stocker des
349 propriétés ou autres données.
352 @subheading Tables de hachage
354 Il s'agit d'une structure de données à laquelle LilyPond fait parfois
355 appel. Une table de hachage (@emph{hash table}) peut se comparer à une
356 matrice ou un tableau dont l'index peut être n'importe quel type de
357 valeur Scheme et ne se limitant pas à des nombres entiers.
359 Les tables de hachage sont un moyen plus efficace que les listes
360 associatives lorsqu'il s'agit d'enregistrer de nombreuses données qui ne
361 changeront que peu fréquemment.
363 La syntaxe permettant de créer une table de hachage peut paraître
364 complexe, mais vous en trouverez de nombreux exemples dans les sources
368 guile> (define h (make-hash-table 10))
371 guile> (hashq-set! h 'cle1 "valeur1")
373 guile> (hashq-set! h 'key2 "valeur2")
375 guile> (hashq-set! h 3 "valeur3")
379 La procédure @code{hashq-ref} permet de récupérer une valeur dans la
383 guile> (hashq-ref h 3)
385 guile> (hashq-ref h 'cle2)
390 La procédure @code{hashq-get-handle} permet de retrouver à la fois une
391 clé et sa valeur. Cette procédure a l'avantage de renvoyer @code{#f}
392 lorsque la clé n'existe pas.
395 guile> (hashq-get-handle h 'cle1)
397 guile> (hashq-get-handle h 'zut)
402 @node Scheme et les calculs
403 @subsection Scheme et les calculs
404 @translationof Calculations in Scheme
407 We have been using lists all along. A calculation, like @code{(+ 1 2)}
408 is also a list (containing the symbol @code{+} and the numbers 1
409 and@tie{}2). Normally lists are interpreted as calculations, and the
410 Scheme interpreter substitutes the outcome of the calculation. To enter a
411 list, we stop the evaluation. This is done by quoting the list with a
412 quote @code{'} symbol. So, for calculations do not use a quote.
414 Inside a quoted list or pair, there is no need to quote anymore. The
415 following is a pair of symbols, a list of symbols and a list of lists
420 #'(staff clef key-signature)
425 Scheme permet aussi d'effectuer des calculs. Il utilise alors un
426 @emph{préfixe}. Additionner 1 et@tie{}2 s'écrira @w{@code{(+ 1 2)}} et
427 non @math{1+2} comme on aurait pu s'y attendre.
434 Les calculs peuvent s'imbriquer@tie{}; le résultat d'une fonction peut
435 servir pour un autre calcul.
442 Ces calculs sont un exemple d'évaluation@tie{}: une expression telle que
443 @w{@code{(* 3 4)}} est remplacée par sa valeur, soit @code{12}.
445 En matière de calcul, Scheme fait la différence entre des nombres entiers
446 ou non. Les calculs sur des nombres entiers seront exacts, alors que
447 s'il s'agit de nombres non entiers, les calculs tiendront compte de la
448 précision mentionnée@tie{}:
457 Lorsque l'interpréteur Scheme rencontre une expression sous forme de
458 liste, le premier élément de cette liste est considéré en tant que
459 procédure qui prendra en argument le restant de la liste. C'est la
460 raison pour laquelle, en Scheme, tous les opérateurs sont en préfixe.
462 Le fait que le premier élément d'une expression Scheme sous forme de
463 liste ne soit pas un opérateur ou une procédure déclenchera une
464 erreur de la part de l'interpréteur@tie{}:
473 <unnamed port>:52:1: In expression (1 2 3):
474 <unnamed port>:52:1: Wrong type to apply: 1
479 Vous pouvez constater que l'interpréteur a tenté de considérer @code{1}
480 comme étant un opérateur ou une procédure, ce qu'il n'a pu réaliser. Il
481 a donc renvoyé l'erreur @qq{Wrong type to apply: 1} (@emph{Application
482 d'un type erroné@tie{}: 1}).
484 C'est pourquoi il est impératif, pour créer une liste, soit d'utiliser
485 l'opérateur consacré (@code{list}), soit de faire précéder la liste
486 d'une apostrophe, de telle sorte que l'interpréteur ne tente pas de
497 Vous pourrez être confronté à cette erreur lorsque vous intégrerez
501 The same assignment can be done in completely in Scheme as well,
504 #(define twentyFour (* 2 twelve))
507 @c this next section is confusing -- need to rewrite
509 The @emph{name} of a variable is also an expression, similar to a
510 number or a string. It is entered as
517 @cindex quoting in Scheme
519 The quote mark @code{'} prevents the Scheme interpreter from substituting
520 @code{24} for the @code{twentyFour}. Instead, we get the name
525 @node Scheme et les procédures
526 @subsection Scheme et les procédures
527 @translationof Scheme procedures
529 Une procédure Scheme est une expression Scheme qui renverra une valeur
530 issue de son exécution. Les procédures Scheme sont capables de
531 manipuler des variables qui ne sont pas définies en leur sein.
534 @subheading Définition de procédures
536 En Scheme, on définit une procédure à l'aide de l'instruction
540 (define (nom-fonction argument1 argument2 ... argumentn)
541 expression-scheme-qui-donnera-une-valeur-en-retour)
544 Nous pourrions, par exemple, définir une procédure calculant la moyenne
545 de deux nombres@tie{}:
548 guile> (define (moyenne x y) (/ (+ x y) 2))
550 #<procedure moyenne (x y)>
553 Une fois la procédure définie, on l'appelle en la faisant suivre, dans
554 une liste, des arguments qui doivent l'accompagner. Calculons
555 maintenant la moyenne de 3 et 12@tie{}:
558 guile> (moyenne 3 12)
563 @subheading Prédicats
565 Une procédure Scheme chargée de retourner une valeur booléenne s'appelle
566 un @qq{prédicat} (@emph{predicate}). Par convention, plutôt que par
567 nécessité, le nom d'un prédicat se termine par un point
568 d'interrogation@tie{}:
571 guile> (define (moins-de-dix? x) (< x 10))
572 guile> (moins-de-dix? 9)
574 guile> (moins-de-dix? 15)
579 @subheading Valeurs de retour
581 Une procédure Scheme doit toujours renvoyer une valeur de retour, en
582 l'occurrence la valeur de la dernière expression exécutée par cette
583 procédure. La valeur de retour sera une valeur Scheme valide, y compris
584 une structure de donnée complexe ou une procédure.
586 On peut avoir besoin de regrouper plusieurs expressions Scheme dans une
587 même procédure. Deux méthodes permettent de combiner des expressions
588 multiples. La première consiste à utiliser la procédure @code{begin},
589 qui permet l'évaluation de plusieurs expressions et renvoie la valeur de
590 la dernière expression.
593 guile> (begin (+ 1 2) (- 5 8) (* 2 2))
597 Une deuxième méthode consiste à combiner les expressions dans un bloc
598 @code{let}. Ceci aura pour effet de créer une série de liens, puis
599 d'évaluer en séquence les expressions susceptibles d'inclure ces
600 liens. La valeur renvoyée par un bloc @emph{let} est la valeur de
601 retour de la dernière clause de ce bloc@tie{}:
604 guile> (let ((x 2) (y 3) (z 4)) (display (+ x y)) (display (- z 4))
605 ... (+ (* x y) (/ z x)))
610 @node Scheme et les conditions
611 @subsection Scheme et les conditions
612 @translationof Scheme conditionals
616 Scheme dispose d'une procédure @code{if}@tie{}:
619 (if expression-test expression-affirmative expression-négative)
622 @var{expression-test} est une expression qui renverra une valeur
623 booléenne. Dans le cas où @var{expression-test} retourne @code{#t}, la
624 procédure @code{if} renvoie la valeur de @var{expression-affirmative},
625 et celle de @var{expression-négative} dans le cas contraire.
630 guile> (if (> a b) "a est plus grand que b" "a n'est pas plus grand que b")
631 "a n'est pas plus grand que b"
637 Une autre manière d'introduire une condition en Scheme est d'utiliser
638 l'instruction @code{cond}@tie{}:
641 (cond (expression-test-1 expression-résultat-séquence-1)
642 (expression-test-2 expression-résultat-séquence-2)
644 (expression-test-n expression-résultat-séquence-n))
647 Comme par exemple ici@tie{}:
652 guile> (cond ((< a b) "a est plus petit que b")
653 ... ((= a b) "a égale b")
654 ... ((> a b) "a est plus grand que b"))
655 "a est plus petit que b"
659 @node Scheme et LilyPond
660 @section Scheme et LilyPond
661 @translationof Scheme in LilyPond
664 * Syntaxe Scheme dans LilyPond::
665 * Variables LilyPond::
666 * Saisie de variables et Scheme::
667 * Propriétés des objets::
668 * Variables LilyPond composites::
669 * Représentation interne de la musique::
672 @node Syntaxe Scheme dans LilyPond
673 @subsection Syntaxe Scheme dans LilyPond
674 @translationof LilyPond Scheme syntax
679 L'installation de LilyPond comprenant l'interpréteur Guile, les fichiers
680 source LilyPond peuvent contenir du Scheme. Vous disposez de plusieurs
681 méthodes pour inclure du Scheme dans vos fichiers LilyPond.
683 La méthode la plus simple consiste à insérer un @emph{hash} (le caractère
684 @code{#}, improprement appelé dièse) avant l'expression Scheme.
686 Rappelons-nous qu'un fichier source LilyPond est structuré en jetons et
687 expressions, tout comme le langage humain est structuré en mots et
688 phrases. LilyPond dispose d'un analyseur lexical (appelé @emph{lexer})
689 qui sait identifier les jetons -- nombres, chaînes, éléments Scheme,
690 hauteurs etc. -- ainsi que d'un analyseur syntaxique (appelé
691 @emph{parser}) -- voir l'annexe @ruser{Grammaire de LilyPond}. Dès lors
692 que le programme sait quelle règle grammaticale particulière doit
693 s'appliquer, il exécute les consignes qui lui sont associées.
695 Le recours à un @emph{hash} pour mettre en exergue du Scheme est tout à
696 fait approprié. Dès qu'il rencontre un @code{#}, l'analyseur lexical
697 passe le relais au lecteur Scheme qui va alors déchiffrer l'intégralité
698 de l'expression Scheme -- ce peut être un identificateur, une expression
699 bornée par des parenthèses ou bien d'autres choses encore. Une fois
700 cette expression lue, elle est enregistrée en tant que valeur d'un
701 élément grammatical @code{SCM_TOKEN}. Puisque l'analyseur syntaxique
702 sait comment traiter ce jeton, il charge Guile d'évaluer l'expression
703 Scheme. Dans la mesure où le @emph{parser} requiert une lecture en
704 avance de la part du @emph{lexer} pour prendre une décision, cette
705 distinction entre lecture et évaluation -- @emph{lexer} et @emph{parser}
706 -- révèle toute sa pertinence lorsqu'il s'agit d'exécuter conjointement
707 des expressions LilyPond et des expressions Scheme. C'est la raison
708 pour laquelle nous vous recommandons, dans toute la mesure du possible,
709 d'utiliser un signe @emph{hash} lorsque vous faites appel à Scheme.
711 Une autre manière de faire appel à l'interpréteur Scheme à partir de
712 LilyPond consiste à introduire une expression Scheme par un caractère
713 dollar au lieu d'un caractère dièse -- un@tie{}@code{$} au lieu
714 d'un@tie{}@code{#}. En pareil cas, LilyPond évalue le code dès sa
715 lecture par l'analyseur lexical, vérifie le type d'expression Scheme qui
716 en résulte et détermine un type de jeton (l'un des @code{xxx_IDENTIFIER}
717 de la grammaire) qui lui corresponde, puis en fait une copie qui servira
718 à traiter la valeur de ce jeton. Lorsque la valeur de l'expression est
719 @emph{void}, autrement dit une valeur Guile @code{*unspecified*}
720 (pour @emph{non spécifiée}), aucune information n'est transmise à
721 l'analyseur grammatical.
723 C'est, en réalité, la manière dont LilyPond opère lorsque vous rappelez
724 une variable ou une fonction par son nom -- au travers d'un @code{\nom}
725 --, à la seule différence que sa finalité est déterminée par l'analyseur
726 lexical de LilyPond sans consultation du lecteur Scheme@tie{}; le nom de
727 la variable rappelée doit donc être en corrélation avec le mode LilyPond
728 actif à ce moment là.
730 L'immédiateté de l'opérateur @code{$} peut entraîner des effets
731 indésirables dont nous reparlerons à la rubrique
732 @ref{Saisie de variables et Scheme}@tie{}; aussi est-il préférable
733 d'utiliser un @code{#} dès que l'analyseur grammatical le supporte.
735 Examinons à présent du vrai code Scheme. Nous pouvons définir des
736 procédures Scheme au milieu d'un fichier source LilyPond@tie{}:
739 #(define (moyenne a b c) (/ (+ a b c) 3))
742 Pour mémoire, vous noterez que les commentaires LilyPond (@code{%} ou
743 @code{%@{ %@}}) ne peuvent s'utiliser dans du code Scheme, même si
744 celui-ci se trouve au sein d'un fichier LilyPond. Ceci tient au fait
745 que l'expression Scheme est lue par l'interpréteur Guile, et en aucune
746 façon par l'analyseur lexical de LilyPond. Voici comment introduire des
747 commentaires dans votre code Scheme@tie{}:
750 ; ceci n'est qu'une simple ligne de commentaire
753 Ceci constitue un bloc de commentaire (non imbricable)
755 En fait, les Schemeurs les utilisent très rarement,
756 et vous n'en trouverez jamais dans le code source
761 Dans la suite de notre propos, nous partons du principe que les données
762 sont incluses dans un fichier musical, aussi toutes les expressions
763 Scheme seront introduites par un@code{#}.
765 Toutes les expressions Scheme de haut niveau incluses dans un fichier
766 LilyPond peuvent se combiner en une expression Scheme unique à l'aide de
767 la clause @code{begin}@tie{}:
776 @node Variables LilyPond
777 @subsection Variables LilyPond
778 @translationof LilyPond variables
780 Les variables LilyPond sont enregistrées en interne sous la forme de
781 variables Scheme. Ainsi,
794 Ceci a pour conséquence que toute variable LilyPond peut être utilisée
795 dans une expression Scheme. Par exemple, nous pourrions dire
798 vingtQuatre = #(* 2 douze)
802 ce qui aurait pour conséquence que le nombre 24 sera stocké dans la
803 variable LilyPond (et Scheme) @code{vingtQuatre}.
805 La façon habituelle de faire référence à une variable LilyPond consiste
806 à la rappeler à l'aide d'une oblique inverse -- autrement dit saisir
807 @code{\vingtQuatre}. Dans la mesure où ceci, pour la plupart des types
808 internes de LilyPond y compris les expressions musicales, aura pour
809 effet d'en recopier la valeur, les fonctions musicales n'ont pas pour
810 habitude de créer une copie du matériau qu'elles vont modifier. De
811 fait, une expression musicale introduite par @code{#} ne devrait pas
812 contenir de matériau inexistant auparavant ou bien littéralement
813 recopié, mais plutôt une référence explicite.
816 @node Saisie de variables et Scheme
817 @subsection Saisie de variables et Scheme
818 @translationof Input variables and Scheme
820 Le format de saisie prend en charge la notion de variable -- ou
821 identificateur. Dans l'exemple suivant, une expression musicale se voit
822 attribuer un identificateur qui portera le nom de @code{traLaLa}.
825 traLaLa = @{ c'4 d'4 @}
830 Une variable a aussi une portée. Dans l'exemple suivant, le bloc
831 @code{\layout} contient une variable @code{traLaLa} tout à fait
832 indépendante de l'autre @code{\traLaLa}.
835 traLaLa = @{ c'4 d'4 @}
836 \layout @{ traLaLa = 1.0 @}
839 Dans les faits, chaque fichier a un domaine de compétence, et les
840 différents blocs @code{\header}, @code{\midi} et @code{\layout} ont leur
841 propre champ de compétence, imbriqué dans ce domaine principal.
843 Variables et champs de compétence sont implémentés par le système de
844 modules de Guile. Un module anonyme Scheme est attaché à chacun de ces
845 domaines. Une assertion telle que
848 traLaLa = @{ c'4 d'4 @}
852 est convertie, en interne, en une définition Scheme@tie{}:
855 (define traLaLa @var{valeur Scheme de `@code{... }'})
858 Cela signifie que variables LilyPond et variables Scheme peuvent tout à
859 fait se mélanger. Dans l'exemple suivant, un fragment musical est
860 stocké dans la variable @code{traLaLa} puis dupliqué à l'aide de Scheme.
861 Le résultat est alors importé dans un bloc @code{\score} au moyen d'une
862 seconde variable @code{twice}.
865 traLaLa = { c'4 d'4 }
867 #(define newLa (map ly:music-deep-copy
868 (list traLaLa traLaLa)))
870 (make-sequential-music newLa))
875 @c Due to parser lookahead
877 Cet exemple est particulièrement intéressant. L'assignation
878 n'interviendra qu'une fois que l'analyseur grammatical aura l'assurance
879 que rien du type de @code{\addlyrics} ne suit@tie{}; il doit donc
880 vérifier ce qui vient après. Le @emph{parser} lit le @code{#} et
881 l'expression Scheme qui le suit @strong{sans} l'évaluer, de telle sorte
882 qu'il peut procéder à l'assignation, et @strong{ensuite} exécuter le
883 code Scheme sans problème.
885 Cet exemple illustre la manière @qq{d'exporter} une expression musicale
886 à partir des saisies et à destination de l'interpréteur Scheme.
887 L'inverse est aussi réalisable@tie{}: en la plaçant derrière
888 un@tie{}@code{$}, une valeur Scheme sera interprétée comme si elle avait
889 été saisie en syntaxe LilyPond. Au lieu de définir @code{\twice}, nous
890 aurions tout aussi bien pu écrire
894 @{ $(make-sequential-music (list newLa)) @}
897 Vous pouvez utiliser @code{$} suivi d'une expression Scheme partout où
898 vous auriez utilisé @code{\@var{nom}}, dès lors que vous aurez assigné à
899 cette expression Scheme le nom de variable @var{nom}. La substitution
900 intervenant au niveau de l'analyseur lexical (le @emph{lexer}), LilyPond
901 ne saurait faire la différence.
903 Cette manière de procéder comporte cependant un inconvénient au niveau
904 de la temporisation. Si nous avions défini @code{newLa} avec un
905 @code{$} plutôt qu'un@tie{#}, la définition Scheme suivante aurait
906 échoué du fait que @code{traLaLa} n'était pas encore définie. Pour plus
907 d'information quant au problème de synchronisation, voir la rubrique
908 @ref{Syntaxe Scheme dans LilyPond}.
910 En tout état de cause, le @emph{parser} évalue le code Scheme en
911 dernier. S'il ne doit être exécuté que plus tard, consultez la rubrique
912 @ref{Fonctions Scheme fantômes}, ou stockez le dans une macro comme
917 (ly:set-option 'point-and-click #f))
925 L'imbrication de variables Scheme et LilyPond n'est pas possible
926 avec l'option @option{--safe}.
929 @node Propriétés des objets
930 @subsection Propriétés des objets
931 @translationof Object properties
933 Les propriétés des objets sont stockées dans LilyPond sous la forme
934 d'enchaînements de listes associatives, autrement dit des listes de
935 listes associatives. Une propriété se détermine par l'ajout de valeurs
936 en début de liste de cette propriété. Les caractéristiques d'une
937 propriété s'ajustent donc à la lecture des différentes valeurs des
940 La modification d'une valeur pour une propriété donnée requiert
941 l'assignation d'une valeur de la liste associative, tant pour la clé que
942 la valeur associée. Voici comment procéder selon la syntaxe de
946 \override Stem #'thickness = #2.6
949 Cette instruction ajuste l'apparence des hampes. Une entrée
950 @w{@code{'(thickness . 2.6)}} de la @emph{alist} est ajoutée à la liste
951 de la propriété de l'objet @code{Stem}. @code{thickness} devant
952 s'exprimer en unité d'épaisseur de ligne, les hampes auront donc une
953 épaisseur de 2,6@tie{}ligne de portée, et à peu près le double de leur
954 épaisseur normale. Afin de faire la distinction entre les variables que
955 vous définissez au fil de vos fichiers -- tel le @code{vingtQuatre} que
956 nous avons vu plus haut -- et les variables internes des objets, nous
957 parlerons de @qq{propriétés} pour ces dernières, et de @qq{variables}
958 pour les autres. Ainsi, l'objet hampe possède une propriété
959 @code{thickness}, alors que @code{vingtQuatre} est une variable.
961 @cindex propriétés ou variables
962 @cindex variables ou propriétés
964 @c todo -- here we're getting interesting. We're now introducing
965 @c LilyPond variable types. I think this deserves a section all
969 @node Variables LilyPond composites
970 @subsection Variables LilyPond composites
971 @translationof LilyPond compound variables
973 @subheading Décalages (@emph{offsets})
975 Les décalages (@emph{offset}) sur deux axes (coordonnées X et Y) sont
976 stockés sous forme de @emph{paires}. Le @code{car} de l'offset
977 correspond à l'abscisse (coordonnée X) et le @code{cdr} à l'ordonnée
981 \override TextScript #'extra-offset = #'(1 . 2)
984 Cette clause affecte la paire @code{(1 . 2)} à la propriété
985 @code{extra-offset} de l'objet @code{TextScript}. Ces nombres sont
986 exprimés en espace de portée. La commande aura donc pour effet de
987 déplacer l'objet d'un espace de portée vers la droite, et de deux
988 espaces vers le haut.
990 Les procédures permettant de manipuler les offsets sont regroupées dans
991 le fichier @file{scm/lily-library.scm}.
994 @subheading Fractions
996 Les fractions, tel que LilyPond les utilise, sont aussi stockées sous
997 forme de @emph{paire}. Alors que Scheme est tout à fait capable de
998 représenter des nombres rationnels, vous conviendrez que, musicalement
999 parlant, @samp{2/4} et @samp{1/2} ne se valent pas@tie{}; nous devrons
1000 donc pouvoir les distinguer. Dans le même ordre d'idée, LilyPond ne
1001 connaît pas les @qq{fractions} négatives. Pour ces raisons, @code{2/4}
1002 en LilyPond correspond à @code{(2 . 4)} en Scheme, et @code{#2/4} en
1003 LilyPond correspond à @code{1/2} en Scheme.
1006 @subheading Étendues (@emph{extents})
1008 Les paires permettent aussi de stocker des intervalles qui représentent
1009 un ensemble de nombres compris entre un minimum (le @code{car}) et un
1010 maximum (le @code{cdr}). Ces intervalles stockent l'étendue, tant au
1011 niveau horizontal (X) que vertical (Y) des objets imprimables. En
1012 matière d'étendue sur les X, le @code{car} correspond à la coordonnée de
1013 l'extrémité gauche, et le @code{cdr} à la coordonnée de l'extrémité
1014 droite. En matière d'étendue sur les Y, le @code{car} correspond à la
1015 coordonnée de l'extrémité basse, et le @code{cdr} à la coordonnée de
1018 Les procédures permettant de manipuler les offsets sont regroupées dans
1019 le fichier @file{scm/lily-library.scm}. Nous vous recommandons
1020 l'utilisation de ces procédures dans toute la mesure du possible afin
1021 d'assurer la cohérence du code.
1024 @subheading Propriété en @emph{alists}
1026 Les propriétés en @emph{alists} sont des structures de données
1027 particulières à LilyPond. Il s'agit de listes associatives dont les
1028 clés sont des propriétés et les valeurs des expressions Scheme
1029 fournissant la valeur requise pour cette propriété.
1031 Les propriétés LilyPond sont des symboles Scheme, à l'instar de
1035 @subheading Chaînes d'@emph{alist}
1037 Une chaîne d'@emph{alist} est une liste contenant les listes
1038 associatives d'une propriété.
1040 L'intégralité du jeu de propriétés qui doivent s'appliquer à un objet
1041 graphique est en fait stocké en tant que chaîne d'@emph{alist}. Afin
1042 d'obtenir la valeur d'une propriété particulière qu'un objet graphique
1043 devrait avoir, on examinera chacune des listes associatives de la
1044 chaîne, à la recherche d'une entrée contenant la clé de cette propriété.
1045 Est renvoyée la première entrée d'@emph{alist} trouvée, sa valeur étant
1046 la valeur de la propriété.
1048 L'obtention des valeurs de propriété des objets graphiques se réalise en
1049 principe à l'aide de la procédure Scheme @code{chain-assoc-get}.
1052 @node Représentation interne de la musique
1053 @subsection Représentation interne de la musique
1054 @translationof Internal music representation
1056 Dans les entrailles du programme, la musique se présente comme une liste
1057 Scheme. Cette liste comporte les différents éléments qui affecteront la
1058 sortie imprimable. L'analyse grammaticale (l'opération @emph{parsing})
1059 est le processus chargé de convertir la musique représentée par le code
1060 LilyPond en présentation interne Scheme.
1062 L'analyse d'une expression musicale se traduit par un jeu d'objets
1063 musicaux en Scheme. Une objet musical est déterminé par le temps qu'il
1064 occupe, que l'on appelle @emph{durée}. Les durées s'expriment par des
1065 nombres rationnels représentant la longueur d'un objet musical par
1068 Un objet musical dispose de trois types@tie{}:
1071 un nom de musique@tie{}: Toute expression musicale a un nom. Par
1072 exemple, une note amène à un @rinternals{NoteEvent}, un
1073 @code{\simultaneous} à un @rinternals{SimultaneousMusic}. Une liste
1074 exhaustive des différentes expressions est disponible dans la référence
1075 des propriétés internes, à la rubrique @rinternals{Music expressions}.
1078 un @qq{type} ou interface@tie{}: Tout nom de musique dispose de
1079 plusieurs types ou interfaces. Ainsi, une note est tout à la fois un
1080 @code{event}, un @code{note-event}, un @code{rhythmic-event} et un
1081 @code{melodic-event}. Les différentes classes musicales sont
1082 répertoriées à la rubrique @rinternals{Music classes} de la référence
1083 des propriétés internes.
1086 un objet C++@tie{}: Tout objet musical est représenté par un objet de la
1087 classe C++ @code{Music}.
1090 L'information réelle d'une expression musicale est enregistrée sous
1091 forme de propriétés. Par exemple, un @rinternals{NoteEvent} dispose des
1092 propriétés @code{pitch} et @code{duration}, respectivement chargées de
1093 stocker la hauteur et la durée de cette note. Les différentes
1094 propriétés sont répertoriées à la rubrique @rinternals{Music properties}
1095 de la référence des propriétés internes.
1097 Une expression composite est un objet musical dont les propriétés
1098 contiennent d'autres objets musicaux. S'il s'agit d'une liste d'objets,
1099 elle sera stockée dans la propriété @code{elements} d'un objet
1100 musical@tie{}; s'il n'y a qu'un seul objet @qq{enfant}, il sera stocké
1101 dans la propriété @code{element}. Ainsi, par exemple, les enfants de
1102 @rinternals{SequentialMusic} iront dans @code{elements}, alors que
1103 l'argument unique de @rinternals{GraceMusic} ira dans @code{element}.
1104 De même, le corps d'une répétition ira dans la propriété @code{element}
1105 d'un @rinternals{RepeatedMusic}, les alternatives quant à elles dans la
1106 propriété @code{elements}.
1109 @node Construction de fonctions complexes
1110 @section Construction de fonctions complexes
1111 @translationof Building complicated functions
1113 Nous allons voir dans cette partie les moyens dont vous disposez pour
1114 obtenir les informations qui vous permettront de créer vos propres
1115 fonctions musicales complexes.
1118 * Affichage d'expressions musicales::
1119 * Propriétés musicales::
1120 * Doublement d'une note avec liaison (exemple)::
1121 * Ajout d'articulation à des notes (exemple)::
1125 @node Affichage d'expressions musicales
1126 @subsection Affichage d'expressions musicales
1127 @translationof Displaying music expressions
1129 @cindex stockage interne
1130 @cindex expression musicale, affichage
1131 @cindex représentation interne, affichage
1132 @cindex displayMusic
1133 @funindex \displayMusic
1135 Lorsque l'on veut écrire une fonction musicale, il est intéressant
1136 d'examiner comment une expression musicale est représentée en interne.
1137 Vous disposez à cet effet de la fonction musicale @code{\displayMusic}.
1141 \displayMusic @{ c'4\f @}
1156 'AbsoluteDynamicEvent
1160 (ly:make-duration 2 0 1 1)
1162 (ly:make-pitch 0 0 0))))
1165 Par défaut, LilyPond affichera ces messages sur la console, parmi toutes
1166 les autres informations. Vous pouvez, afin de les isoler et de garder
1167 le résultat des commandes @code{\display@{TRUC@}}, rediriger la sortie
1168 vers un fichier@tie{}:
1171 lilypond file.ly >display.txt
1174 Un peu de Scheme combiné à notre code LilyPond, et les seules
1175 informations qui nous intéressent se retrouveront directement dans un
1176 fichier indépendant@tie{}:
1180 $(with-output-to-file "display.txt"
1181 (lambda () #@{ \displayMusic @{ c'4\f @} #@}))
1185 L'information sera encore plus lisible après un peu de mise en
1189 (make-music 'SequentialMusic
1191 (make-music 'NoteEvent
1192 'articulations (list
1193 (make-music 'AbsoluteDynamicEvent
1196 'duration (ly:make-duration 2 0 1 1)
1197 'pitch (ly:make-pitch 0 0 0))))
1200 Une séquence musicale @code{@{ ... @}} se voit attribuer le nom de
1201 @code{SequentialMusic}, et les expressions qu'elle contient sont
1202 enregistrées en tant que liste dans sa propriété @code{'elements}. Une
1203 note est représentée par un objet @code{NoteEvent} -- contenant les
1204 propriétés de durée et hauteur -- ainsi que l'information qui lui est
1205 attachée -- en l'occurrence un @code{AbsoluteDynamicEvent} ayant une
1206 propriété @code{text} de valeur @code{"f"} -- et stockée dans sa
1207 propriété @code{articulations}.
1210 La fonction @code{\displayMusic} renvoie la musique qu'elle
1211 affiche@tie{}; celle-ci sera donc aussi interprétée. L'insertion d'une
1212 commande @code{\void} avant le @code{\displayMusic} permet de
1213 s'affranchir de la phase d'interprétation.
1216 @node Propriétés musicales
1217 @subsection Propriétés musicales
1218 @translationof Music properties
1220 Nous abordons ici les propriétés @emph{music}, et non pas les propriétés
1221 @emph{context} ou @emph{layout}.
1223 Partons de cet exemple simple@tie{}:
1227 \displayMusic \someNote
1232 (ly:make-duration 2 0 1 1)
1234 (ly:make-pitch 0 0 0))
1237 L'objet @code{NoteEvent} est la représentation brute de @code{someNote}.
1238 Voyons ce qui se passe lorsque nous plaçons ce @notation{c'} dans une
1239 construction d'accord@tie{}:
1243 \displayMusic \someNote
1251 (ly:make-duration 2 0 1 1)
1253 (ly:make-pitch 0 0 0))))
1256 L'objet @code{NoteEvent} est maintenant le premier objet de la propriété
1257 @code{'elements} de @code{someNote}.
1259 @code{\displayMusic} utilise la fonction @code{display-scheme-music}
1260 pour afficher la représentation en Scheme d'une expression musicale@tie{}:
1263 #(display-scheme-music (first (ly:music-property someNote 'elements)))
1268 (ly:make-duration 2 0 1 1)
1270 (ly:make-pitch 0 0 0))
1273 La hauteur de la note est accessible au travers de la propriété
1274 @code{'pitch} de l'objet @code{NoteEvent}@tie{}:
1277 #(display-scheme-music
1278 (ly:music-property (first (ly:music-property someNote 'elements))
1281 (ly:make-pitch 0 0 0)
1284 La hauteur de la note se modifie en définissant sa propriété
1285 @code{'pitch}@tie{}:
1287 @funindex \displayLilyMusic
1290 #(set! (ly:music-property (first (ly:music-property someNote 'elements))
1292 (ly:make-pitch 0 1 0)) ;; set the pitch to d'.
1293 \displayLilyMusic \someNote
1299 @node Doublement d'une note avec liaison (exemple)
1300 @subsection Doublement d'une note avec liaison (exemple)
1301 @translationof Doubling a note with slurs (example)
1303 Supposons que nous ayons besoin de créer une fonction transformant une
1304 saisie @code{a} en @w{@code{@{ a( a) @}}}. Commençons par examiner
1305 comment le résultat est représenté en interne.
1308 \displayMusic@{ a'( a') @}
1321 (ly:make-duration 2 0 1 1)
1323 (ly:make-pitch 0 5 0))
1332 (ly:make-duration 2 0 1 1)
1334 (ly:make-pitch 0 5 0))))
1337 Mauvaise nouvelle@tie{}! Les expressions @code{SlurEvent} doivent
1338 s'ajouter @qq{à l'intérieur} de la note -- dans sa propriété
1339 @code{articulations}.
1341 Examinons à présent la saisie@tie{}:
1349 (ly:make-duration 2 0 1 1)
1351 (ly:make-pitch 0 5 0))))
1354 Nous aurons donc besoin, dans notre fonction, de cloner cette expression
1355 -- de telle sorte que les deux notes constituent la séquence -- puis
1356 d'ajouter un @code{SlurEvent} à la propriété @code{'articulations} de
1357 chacune d'elles, et enfin réaliser un @code{SequentialMusic} de ces deux
1358 @code{EventChords}. En tenant compte du fait que, dans le cadre d'un
1359 ajout, une propriété non définie est lue @code{'()} (une liste vide),
1360 aucune vérification n'est requise avant d'introduire un nouvel élément
1361 en tête de la propriété @code{articulations}.
1364 doubleSlur = #(define-music-function (parser location note) (ly:music?)
1365 "Renvoie : @{ note ( note ) @}.
1366 `note' est censé être une note unique."
1367 (let ((note2 (ly:music-deep-copy note)))
1368 (set! (ly:music-property note 'articulations)
1369 (cons (make-music 'SlurEvent 'span-direction -1)
1370 (ly:music-property note 'articulations)))
1371 (set! (ly:music-property note2 'articulations)
1372 (cons (make-music 'SlurEvent 'span-direction 1)
1373 (ly:music-property note2 'articulations)))
1374 (make-music 'SequentialMusic 'elements (list note note2))))
1378 @node Ajout d'articulation à des notes (exemple)
1379 @subsection Ajout d'articulation à des notes (exemple)
1380 @translationof Adding articulation to notes (example)
1382 Le moyen d'ajouter une articulation à des notes consiste à fusionner
1383 deux expressions musicales en un même contexte, comme nous l'avons vu à
1384 la rubrique @ruser{Création d'un contexte}. L'option de réaliser
1385 nous-mêmes une fonction musicale à cette fin nous offre l'avantage de
1386 pouvoir alors ajouter une articulation, telle qu'une instruction de
1387 doigté, individuellement à l'une des notes d'un accord, ce qui est
1388 impossible dans le cadre d'une simple fusion de musique indépendante.
1390 Un @code{$variable} au milieu de la notation @code{#@{...#@}} se
1391 comporte exactement comme un banal @code{\variable} en notation LilyPond
1392 traditionnelle. Nous savons déjà que
1395 @{ \musique -. -> @}
1399 n'est pas admis par LilyPond. Nous pourrions tout à fait contourner ce
1400 problème en attachant l'articulation à une @qq{fausse} note,
1403 @{ << \musique s1*0-.-> @}
1407 mais, pour les besoins de la démonstration, nous allons voir comment
1408 réaliser ceci en Scheme. Commençons par examiner une saisie simple et
1409 le résultat auquel nous désirons aboutir@tie{}:
1418 (ly:make-duration 2 0 1 1)
1420 (ly:make-pitch -1 0 0))))
1433 (ly:make-duration 2 0 1 1)
1435 (ly:make-pitch -1 0 0))
1438 Nous voyons qu'une note (@code{c4}) est représentée par une expression
1439 @code{NoteEvent}. Si nous souhaitons ajouter une articulation
1440 @notation{accent}, nous devrons ajouter une expression
1441 @code{ArticulationEvent} à la propriété @code{articulations} de
1442 l'expression @code{NoteEvent}.
1444 Construisons notre fonction en commençant par
1447 (define (ajoute-accent note-event)
1448 "Ajoute un accent (ArticulationEvent) aux articulations de `note-event',
1449 qui est censé être une expression NoteEvent."
1450 (set! (ly:music-property note-event 'articulations)
1451 (cons (make-music 'ArticulationEvent
1452 'articulation-type "accent")
1453 (ly:music-property note-event 'articulations)))
1457 La première ligne est la manière de définir une fonction en
1458 Scheme@tie{}: la fonction Scheme a pour nom @code{ajoute-accent} et elle
1459 comporte une variable appelée @code{note-event}. En Scheme, le type
1460 d'une variable se déduit la plupart de temps de par son nom -- c'est
1461 d'ailleurs une excellente pratique que l'on retrouve dans de nombreux
1465 "Ajoute un accent..."
1469 décrit ce que fait la fonction. Bien que ceci ne soit pas primordial,
1470 tout comme des noms de variable évidents, tâchons néanmoins de prendre
1471 de bonnes habitudes dès nos premiers pas.
1473 Vous pouvez vous demander pourquoi nous modifions directement
1474 l'événement note plutôt que d'en manipuler une copie -- on pourrait
1475 utiliser @code{ly:music-deep-copy} à cette fin. La raison en est qu'il
1476 existe un contrat tacite@tie{}: les fonctions musicales sont autorisées
1477 à modifier leurs arguments -- ils sont générés en partant de zéro (comme
1478 les notes que vous saisissez) ou déjà recopiés (faire référence à une
1479 variable musicale avec @samp{\name} ou à de la musique issue
1480 d'expressions Scheme @samp{$(@dots{})} aboutit à une copie). Dans la
1481 mesure où surmultiplier les copies serait contre productif, la valeur de
1482 retour d'une fonction musicale n'est @strong{pas} recopiée. Afin de
1483 respecter ce contrat, n'utilisez pas un même argument à plusieurs
1484 reprises, et n'oubliez pas que le retourner compte pour une utilisation.
1486 Dans un exemple précédent, nous avons construit de la musique en
1487 répétant un certain argument musical. Dans ce cas là, l'une des
1488 répétitions se devait d'être une copie. Dans le cas contraire,
1489 certaines bizarreries auraient pu survenir. Par exemple, la présence
1490 d'un @code{\relative} ou d'un @code{\transpose}, après plusieurs
1491 répétitions du même élément, entraînerait des @qq{relativisations} ou
1492 transpositions en cascade. Si nous les assignons à une variable
1493 musicale, l'enchaînement est rompu puisque la référence à @samp{\nom}
1494 créera une nouvelle copie sans toutefois prendre en considération
1495 l'identité des éléments répétés.
1497 Cette fonction n'étant pas une fonction musicale à part entière, elle
1498 peut s'utiliser dans d'autres fonctions musicales. Il est donc sensé de
1499 respecter le même contrat que pour les fonctions musicales@tie{}:
1500 l'entrée peut être modifiée pour arriver à une sortie, et il est de la
1501 responsabilité de l'appelant d'effectuer des copies s'il a réellement
1502 besoin de l'argument dans son état originel. Vous constaterez, à la
1503 lecture des fonctions propres à LilyPond, comme @code{music-map}, que ce
1504 principe est toujours respecté.
1506 Revenons à nos moutons@dots{} Nous disposons maintenant d'un
1507 @code{note-event} que nous pouvons modifier, non pas grâce à un
1508 @code{ly:music-deep-copy}, mais plutôt en raison de notre précédente
1509 réflexion. Nous ajoutons @notation{l'accent} à la liste de ses
1510 propriétés @code{'articulations}.
1513 (set! emplacement nouvelle-valeur)
1516 L'emplacement est ce que nous voulons ici définir. Il s'agit de la
1517 propriété @code{'articulations} de l'expression @code{note-event}.
1520 (ly:music-property note-event 'articulations)
1523 La fonction @code{ly:music-property} permet d'accéder aux propriétés
1524 musicales -- les @code{'articulations}, @code{'duration}, @code{'pitch}
1525 etc. que @code{\displayMusic} nous a indiquées. La nouvelle valeur sera
1526 l'ancienne propriété @code{'articulations}, augmentée d'un
1527 élément@tie{}: l'expression @code{ArticulationEvent}, que nous
1528 recopions à partir des informations de @code{\displayMusic}.
1531 (cons (make-music 'ArticulationEvent
1532 'articulation-type "accent")
1533 (ly:music-property result-event-chord 'articulations))
1536 @code{cons} permet d'ajouter un élément en tête de liste sans pour
1537 autant modifier la liste originale. C'est exactement ce que nous
1538 recherchons@tie{}: la même liste qu'auparavant, plus la nouvelle
1539 expression @code{ArticulationEvent}. L'ordre au sein de la propriété
1540 @code{'articulations} n'a ici aucune importance.
1542 Enfin, après avoir ajouté l'articulation @notation{accent} à sa
1543 propriété @code{articulations}, nous pouvons renvoyer le
1544 @code{note-event}, ce que réalise la dernière ligne de notre fonction.
1546 Nous pouvons à présent transformer la fonction @code{ajoute-accent} en
1547 fonction musicale, à l'aide d'un peu d'enrobage syntaxique et mention du
1548 type de son unique argument @qq{réel}.
1551 ajouteAccent = #(define-music-function (parser location note-event)
1553 "Ajoute un accent (ArticulationEvent) aux articulations de `note-event',
1554 qui est censé être une expression NoteEvent."
1555 (set! (ly:music-property note-event 'articulations)
1556 (cons (make-music 'ArticulationEvent
1557 'articulation-type "accent")
1558 (ly:music-property note-event 'articulations)))
1562 Par acquis de conscience, vérifions que tout ceci fonctione@tie{}:
1565 \displayMusic \ajouteAccent c4
1574 * Tweaking with Scheme::
1577 @c @nod e Tweaking with Scheme
1578 @c @sectio n Tweaking with Scheme
1580 We have seen how LilyPond output can be heavily modified using
1582 @code{\override TextScript #'extra-offset = ( 1 . -1)}. But
1583 we have even more power if we use Scheme. For a full explanation
1584 of this, see the @ref{Scheme tutorial}, and
1585 @ref{Interfaces for programmers}.
1587 We can use Scheme to simply @code{\override} commands,
1589 TODO Find a simple example
1590 @c This isn't a valid example with skylining
1591 @c It works fine without padText -td
1595 @lilypond[quote,verbatim,ragged-right]
1596 padText = #(define-music-function (parser location padding) (number?)
1598 \once \override TextScript #'padding = #padding
1602 c4^"piu mosso" b a b
1604 c4^"piu mosso" d e f
1606 c4^"piu mosso" fis a g
1612 We can use it to create new commands:
1614 @c Check this is a valid example with skylining
1615 @c It is - 'padding still works
1618 @lilypond[quote,verbatim,ragged-right]
1619 tempoPadded = #(define-music-function (parser location padding tempotext)
1622 \once \override Score.MetronomeMark #'padding = $padding
1623 \tempo \markup { \bold #tempotext }
1627 \tempo \markup { "Low tempo" }
1629 \tempoPadded #4.0 #"High tempo"
1635 Even music expressions can be passed in:
1637 @lilypond[quote,verbatim,ragged-right]
1638 pattern = #(define-music-function (parser location x y) (ly:music? ly:music?)
1645 \pattern {d16 dis} { ais16-> b\p }