1 @c -*- coding: utf-8; mode: texinfo; documentlanguage: fr -*-
3 Translation of GIT committish: 952705bbbb000581a13836e6a733df04511e93c5
5 When revising a translation, copy the HEAD committish of the
6 version that you are working on. For details, see the Contributors'
7 Guide, node Updating translation committishes..
12 @c Translators: Jean-Charles Malahieude
15 @chapter Tutoriel Scheme
19 @cindex Scheme, inclusion de code
20 @cindex accéder à Scheme
21 @cindex évaluation Scheme
24 LilyPond recourt abondamment au langage de programmation Scheme, tant au
25 niveau de la syntaxe de saisie que des mécanismes internes chargés de
26 combiner les différents modules du logiciel. Les lignes qui suivent
27 constituent un bref aperçu de la manière de saisir des données en
28 Scheme. Si vous désirez en apprendre plus sur Scheme, n'hésitez pas à
29 vous rendre sur @uref{http://@/www@/.schemers@/.org}.
31 Le Scheme utilisé par LilyPond repose sur l'implémentation GNU
32 Guile ; celle-ci se base sur le standard Scheme @qq{R5RS}. Si
33 votre but est d'apprendre Scheme au travers de LilyPond, sachez que
34 l'utilisation d'une autre implémentation ou d'un autre standard pourrait
35 être source de désagrément. Vous trouverez plus d'information sur
36 GUILE à la page @uref{http://www.gnu.org/software/guile/} ; le
37 standard Scheme @qq{R5RS} est quant à lui disponible à la page
38 @uref{http://www.schemers.org/Documents/Standards/R5RS/}.
41 * Introduction à Scheme::
42 * Scheme et LilyPond::
43 * Construction de fonctions complexes::
47 @node Introduction à Scheme
48 @section Introduction à Scheme
49 @translationof Introduction to Scheme
51 Nous commencerons par nous intéresser à Scheme et à son fonctionnement,
52 grâce à l'interpréteur GUILE. Une fois plus à l'aise avec Scheme, nous
53 verrons comment ce langage peut s'intégrer à un fichier LilyPond.
56 * Le bac à sable de Scheme::
57 * Scheme et les variables::
58 * Types de données Scheme simples::
59 * Types de données Scheme composites::
60 * Scheme et les calculs::
61 * Scheme et les procédures::
62 * Scheme et les conditions::
66 @node Le bac à sable de Scheme
67 @subsection Le bac à sable de Scheme
68 @translationof Scheme sandbox
70 L'installation de LilyPond comprend l'implémentation GUILE de Scheme.
71 La plupart des systèmes disposent d'un @qq{bac à sable} Scheme pour
72 effectuer des tests ; vous y accéderez en tapant @qq{guile} dans
73 un terminal. Certains systèmes, notamment Windows, nécessitent d'avoir
74 auparavant créé la variable d'environnement @code{GUILE_LOAD_PATH} qui
75 devra pointer vers le répertoire @code{../usr/share/guile/1.8} de
76 l'installation de LilyPond -- pour connaître le chemin complet d'accès à
77 ce répertoire, consultez @rlearning{Autres sources de documentation}.
78 Les utilisateurs de Windows peuvent aussi prendre l'option @qq{Exécuter}
79 à partir du menu @qq{Démarrer} puis taper @qq{guile}.
81 Néanmoins, tous les paquetages de LilyPond disposent d'un bac à sable
82 Scheme, accessible par la commande :
84 lilypond scheme-sandbox
88 Une fois le bac à sable actif, vous obtiendrez l'invite :
93 Vous pouvez dès à présent saisir des expressions Scheme pour vous
94 exercer. Si vous souhaitez pouvoir utiliser la bibliothèque GNU
95 @code{readline}, qui offre une ligne de commande plus élaborée,
96 consultez les informations contenues dans le fichier
97 @file{ly/scheme-sandbox.ly}. La bibliothèque @var{readline}, dans la
98 mesure où elle est habituellement activée dans vos sessions Guile,
99 devrait être effective y compris dans le bac à sable.
102 @node Scheme et les variables
103 @subsection Scheme et les variables
104 @translationof Scheme variables
106 Une variable Scheme peut contenir n'importe quelle valeur valide en
107 Scheme, y compris une procédure Scheme.
109 Une variable Scheme se crée avec la fonction @code{define} :
116 L'évaluation d'une variable Scheme se réalise en saisissant le nom de
117 cette variable à l'invite de Guile :
125 Une variable Scheme s'affiche à l'écran à l'aide de la fonction
134 Vous aurez remarqué que la valeur @code{2} et l'invite @code{guile}
135 apparaissent sur une même ligne. On peut améliorer la présentation à
136 l'aide de la procédure @code{newline} ou bien en affichant un caractère
140 guile> (display a)(newline)
142 guile> (display a)(display "\n")
147 Après avoir créé une variable, vous pouvez en modifier la valeur grâce à
151 guile> (set! a 12345)
157 Vous quitterez proprement le bac à sable à l'aide de l'instruction
165 @node Types de données Scheme simples
166 @subsection Types de données Scheme simples
167 @translationof Scheme simple data types
169 L'un des concepts de base de tout langage est la saisie de données,
170 qu'il s'agisse de nombres, de chaînes de caractères, de listes etc.
171 Voici les différents types de données Scheme simples utilisées
172 couramment dans LilyPond.
176 Les valeurs booléennes sont vrai ou faux. En Scheme, ce sera @code{#t}
177 pour vrai, et @code{#f} pour faux.
182 Les nombres se saisissent le plus communément : @code{1} est le
183 nombre (entier) un, alors que @w{@code{-1.5}} est un nombre à virgule
184 flottante (un nombre non entier).
187 Les chaînes de caractères sont bornées par des guillemets
191 "ceci est une chaîne"
194 Une chaîne peut s'étendre sur plusieurs lignes :
203 auquel cas les retours à la ligne seront inclus dans la chaîne.
205 Un caractère de retour à la ligne peut s'ajouter dans la chaîne, sous la
206 forme d'un @code{\n}.
209 "ceci\nest une\nchaîne multiligne"
212 Guillemets et obliques inverses dans une chaîne doivent être précédés
213 d'une oblique inverse. La chaîne @code{\a dit "b"} se saisit donc
221 Il existe bien d'autres types de données Scheme, dont nous ne parlerons
222 pas ici. Vous en trouverez une liste exhaustive dans le guide de
223 référence de Guile, à la page
224 @uref{http://www.gnu.org/software/guile/manual/html_node/Simple-Data-Types.html}.
227 @node Types de données Scheme composites
228 @subsection Types de données Scheme composites
229 @translationof Scheme compound data types
231 Scheme prend aussi en charge des types de données composites. LilyPond
232 utilise beaucoup les paires, listes, listes associatives et tables de
237 Le type de donnée composite fondamental est la paire (@code{pair}).
238 Comme son nom l'indique, il s'agit de lier deux valeurs, à l'aide de
239 l'opérateur @code{cons}.
247 Vous aurez noté que la paire s'affiche sous la forme de deux éléments
248 bornés par des parenthèses et séparés par une espace, un point
249 (@code{.}) et une autre espace. Le point n'est en aucune manière un
250 séparateur décimal ; il s'agit de l'indicateur d'une paire.
252 Vous pouvez aussi saisir littéralement les valeurs d'une paire, en la
253 faisant précéder d'une apostrophe.
261 Les deux éléments d'une paire peuvent être constitués de n'importe
262 quelle valeur Scheme valide :
267 guile> '("blah-blah" . 3.1415926535)
268 ("blah-blah" . 3.1415926535)
272 Les premier et second éléments de la paire sont accessibles à l'aide des
273 procédures Scheme @code{car} et @code{cdr}.
276 guile> (define mypair (cons 123 "hello there")
287 Note : @code{cdr} se prononce @qq{couldeur}, comme l'indiquent Sussman et
289 @uref{http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-14.html#footnote_Temp_133}.
294 Autre structure de donnée commune en Scheme : la liste (@emph{list}).
295 Une liste se définit comme étant vide (représentée par @code{'()}) ou
296 une paire dont le @code{cdr} est une liste.
298 Il existe plusieurs méthodes pour créer une liste, la plus courante
299 étant l'utilisation de la procédure @code{list} :
302 guile> (list 1 2 3 "abc" 17.5)
306 Comme vous le remarquez, une liste s'affiche sous la forme d'une suite
307 d'éléments séparés par une espace, bornée par des parenthèses.
308 Contrairement à une paire, il n'y a pas de point entre les éléments.
310 Vous pouvez aussi saisir directement une liste en entourant ses éléments
311 par des parenthèses à la suite d'une apostrophe :
314 guile> '(17 23 "foo" "bar" "bazzle")
315 (17 23 "foo" "bar" "bazzle")
318 Les listes ont une importance considérable en Scheme. Certains vont
319 d'ailleurs jusqu'à considérer Scheme comme un dialecte du lisp, où
320 @qq{lisp} serait une abréviation de @qq{List Processing}. Il est vrai
321 que toute expression Scheme est une liste.
324 @subheading Listes associatives (alists)
326 Il existe un type particulier de liste : la @emph{liste associative} --
327 ou @emph{alist}. Une @emph{alist} permet de stocker des données dans le
328 but de les réutiliser.
330 Une liste associative est une liste dont les éléments sont des paires.
331 Le @code{car} de chacun des éléments constitue une clé (@emph{key}) et
332 chaque @code{cdr} une valeur (@emph{value}). La procédure Scheme
333 @code{assoc} permet de retrouver une entrée de la liste
334 associative ; son @code{cdr} en fournira la valeur :
337 guile> (define mon-alist '((1 . "A") (2 . "B") (3 . "C")))
339 ((1 . "A") (2 . "B") (3 . "C"))
340 guile> (assoc 2 mon-alist)
342 guile> (cdr (assoc 2 mon-alist))
347 LilyPond recourt abondamment aux @emph{alists} pour stocker des
348 propriétés ou autres données.
351 @subheading Tables de hachage
353 Il s'agit d'une structure de données à laquelle LilyPond fait parfois
354 appel. Une table de hachage (@emph{hash table}) peut se comparer à une
355 matrice ou un tableau dont l'index peut être n'importe quel type de
356 valeur Scheme et ne se limitant pas à des nombres entiers.
358 Les tables de hachage sont un moyen plus efficace que les listes
359 associatives lorsqu'il s'agit d'enregistrer de nombreuses données qui ne
360 changeront que peu fréquemment.
362 La syntaxe permettant de créer une table de hachage peut paraître
363 complexe, mais vous en trouverez de nombreux exemples dans les sources
367 guile> (define h (make-hash-table 10))
370 guile> (hashq-set! h 'cle1 "valeur1")
372 guile> (hashq-set! h 'key2 "valeur2")
374 guile> (hashq-set! h 3 "valeur3")
378 La procédure @code{hashq-ref} permet de récupérer une valeur dans la
382 guile> (hashq-ref h 3)
384 guile> (hashq-ref h 'cle2)
389 La procédure @code{hashq-get-handle} permet de retrouver à la fois une
390 clé et sa valeur. Cette procédure a l'avantage de renvoyer @code{#f}
391 lorsque la clé n'existe pas.
394 guile> (hashq-get-handle h 'cle1)
396 guile> (hashq-get-handle h 'zut)
401 @node Scheme et les calculs
402 @subsection Scheme et les calculs
403 @translationof Calculations in Scheme
406 We have been using lists all along. A calculation, like @code{(+ 1 2)}
407 is also a list (containing the symbol @code{+} and the numbers 1
408 and@tie{}2). Normally lists are interpreted as calculations, and the
409 Scheme interpreter substitutes the outcome of the calculation. To enter a
410 list, we stop the evaluation. This is done by quoting the list with a
411 quote @code{'} symbol. So, for calculations do not use a quote.
413 Inside a quoted list or pair, there is no need to quote anymore. The
414 following is a pair of symbols, a list of symbols and a list of lists
419 #'(staff clef key-signature)
424 Scheme permet aussi d'effectuer des calculs. Il utilise alors un
425 @emph{préfixe}. Additionner 1 et 2 s'écrira @code{(+ 1 2)} et
426 non @math{1+2} comme on aurait pu s'y attendre.
433 Les calculs peuvent s'imbriquer ; le résultat d'une fonction peut
434 servir pour un autre calcul.
441 Ces calculs sont un exemple d'évaluation : une expression telle que
442 @code{(* 3 4)} est remplacée par sa valeur, soit @code{12}.
444 En matière de calcul, Scheme fait la différence entre des nombres entiers
445 ou non. Les calculs sur des nombres entiers seront exacts, alors que
446 s'il s'agit de nombres non entiers, les calculs tiendront compte de la
447 précision mentionnée :
456 Lorsque l'interpréteur Scheme rencontre une expression sous forme de
457 liste, le premier élément de cette liste est considéré en tant que
458 procédure qui prendra en argument le restant de la liste. C'est la
459 raison pour laquelle, en Scheme, tous les opérateurs sont en préfixe.
461 Le fait que le premier élément d'une expression Scheme sous forme de
462 liste ne soit pas un opérateur ou une procédure déclenchera une
463 erreur de la part de l'interpréteur :
472 <unnamed port>:52:1: In expression (1 2 3):
473 <unnamed port>:52:1: Wrong type to apply: 1
478 Vous pouvez constater que l'interpréteur a tenté de considérer @code{1}
479 comme étant un opérateur ou une procédure, ce qu'il n'a pu réaliser. Il
480 a donc renvoyé l'erreur @qq{Wrong type to apply: 1} (@emph{Application
481 d'un type erroné : 1}).
483 C'est pourquoi il est impératif, pour créer une liste, soit d'utiliser
484 l'opérateur consacré (@code{list}), soit de faire précéder la liste
485 d'une apostrophe, de telle sorte que l'interpréteur ne tente pas de
496 Vous pourrez être confronté à cette erreur lorsque vous intégrerez
500 The same assignment can be done in completely in Scheme as well,
503 #(define twentyFour (* 2 twelve))
506 @c this next section is confusing -- need to rewrite
508 The @emph{name} of a variable is also an expression, similar to a
509 number or a string. It is entered as
516 @cindex quoting in Scheme
518 The quote mark @code{'} prevents the Scheme interpreter from substituting
519 @code{24} for the @code{twentyFour}. Instead, we get the name
524 @node Scheme et les procédures
525 @subsection Scheme et les procédures
526 @translationof Scheme procedures
528 Une procédure Scheme est une expression Scheme qui renverra une valeur
529 issue de son exécution. Les procédures Scheme sont capables de
530 manipuler des variables qui ne sont pas définies en leur sein.
533 @subheading Définition de procédures
535 En Scheme, on définit une procédure à l'aide de l'instruction
539 (define (nom-fonction argument1 argument2 ... argumentn)
540 expression-scheme-qui-donnera-une-valeur-en-retour)
543 Nous pourrions, par exemple, définir une procédure calculant la moyenne
547 guile> (define (moyenne x y) (/ (+ x y) 2))
549 #<procedure moyenne (x y)>
552 Une fois la procédure définie, on l'appelle en la faisant suivre, dans
553 une liste, des arguments qui doivent l'accompagner. Calculons
554 maintenant la moyenne de 3 et 12 :
557 guile> (moyenne 3 12)
562 @subheading Prédicats
564 Une procédure Scheme chargée de retourner une valeur booléenne s'appelle
565 un @qq{prédicat} (@emph{predicate}). Par convention, plutôt que par
566 nécessité, le nom d'un prédicat se termine par un point
570 guile> (define (moins-de-dix? x) (< x 10))
571 guile> (moins-de-dix? 9)
573 guile> (moins-de-dix? 15)
578 @subheading Valeurs de retour
580 Une procédure Scheme doit toujours renvoyer une valeur de retour, en
581 l'occurrence la valeur de la dernière expression exécutée par cette
582 procédure. La valeur de retour sera une valeur Scheme valide, y compris
583 une structure de donnée complexe ou une procédure.
585 On peut avoir besoin de regrouper plusieurs expressions Scheme dans une
586 même procédure. Deux méthodes permettent de combiner des expressions
587 multiples. La première consiste à utiliser la procédure @code{begin},
588 qui permet l'évaluation de plusieurs expressions et renvoie la valeur de
589 la dernière expression.
592 guile> (begin (+ 1 2) (- 5 8) (* 2 2))
596 Une deuxième méthode consiste à combiner les expressions dans un bloc
597 @code{let}. Ceci aura pour effet de créer une série de liens, puis
598 d'évaluer en séquence les expressions susceptibles d'inclure ces
599 liens. La valeur renvoyée par un bloc @emph{let} est la valeur de
600 retour de la dernière clause de ce bloc :
603 guile> (let ((x 2) (y 3) (z 4)) (display (+ x y)) (display (- z 4))
604 ... (+ (* x y) (/ z x)))
609 @node Scheme et les conditions
610 @subsection Scheme et les conditions
611 @translationof Scheme conditionals
615 Scheme dispose d'une procédure @code{if} :
618 (if expression-test expression-affirmative expression-négative)
621 @var{expression-test} est une expression qui renverra une valeur
622 booléenne. Dans le cas où @var{expression-test} retourne @code{#t}, la
623 procédure @code{if} renvoie la valeur de @var{expression-affirmative},
624 et celle de @var{expression-négative} dans le cas contraire.
629 guile> (if (> a b) "a est plus grand que b" "a n'est pas plus grand que b")
630 "a n'est pas plus grand que b"
636 Une autre manière d'introduire une condition en Scheme est d'utiliser
637 l'instruction @code{cond} :
640 (cond (expression-test-1 expression-résultat-séquence-1)
641 (expression-test-2 expression-résultat-séquence-2)
643 (expression-test-n expression-résultat-séquence-n))
646 Comme par exemple ici :
651 guile> (cond ((< a b) "a est plus petit que b")
652 ... ((= a b) "a égale b")
653 ... ((> a b) "a est plus grand que b"))
654 "a est plus petit que b"
658 @node Scheme et LilyPond
659 @section Scheme et LilyPond
660 @translationof Scheme in LilyPond
663 * Syntaxe Scheme dans LilyPond::
664 * Variables LilyPond::
665 * Saisie de variables et Scheme::
666 * Import de code Scheme dans LilyPond::
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 @code{$} au lieu
714 d'un @code{#}. En pareil cas, LilyPond évalue le code dès sa lecture
715 par l'analyseur lexical, vérifie le type d'expression Scheme qui en
716 résulte et détermine un type de jeton (l'un des @code{xxx_IDENTIFIER} de
717 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*} (pour
720 @emph{non spécifiée}), aucune information n'est transmise à l'analyseur
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 ; 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} ; aussi est-il préférable
733 d'utiliser un @code{#} dès que l'analyseur grammatical le supporte.
734 Dans le cadre d'une expression musicale, une expression qui aura été
735 créée à l'aide d'un @code{#} sera interprétée comme étant de la musique.
736 Elle ne sera cependant pas recopiée avant utilisation. Si la structure
737 qui l'abrite devait être réutilisée, un appel expicite à
738 @code{ly:music-deep-copy} pourrait être requis.
743 Les opérateurs @code{$@@} et @code{#@@} agissent comme des « colleurs de
744 liste » : leur fonction consiste à insérer tous les éléments d'un liste
745 dans le contexte environnant.
747 Examinons à présent du vrai code Scheme. Nous pouvons définir des
748 procédures Scheme au milieu d'un fichier source LilyPond :
751 #(define (moyenne a b c) (/ (+ a b c) 3))
754 Pour mémoire, vous noterez que les commentaires LilyPond (@code{%} ou
755 @code{%@{ %@}}) ne peuvent s'utiliser dans du code Scheme, même si
756 celui-ci se trouve au sein d'un fichier LilyPond. Ceci tient au fait
757 que l'expression Scheme est lue par l'interpréteur Guile, et en aucune
758 façon par l'analyseur lexical de LilyPond. Voici comment introduire des
759 commentaires dans votre code Scheme :
762 ; ceci n'est qu'une simple ligne de commentaire
765 Ceci constitue un bloc de commentaire (non imbricable)
767 En fait, les Schemeurs les utilisent très rarement,
768 et vous n'en trouverez jamais dans le code source
773 Dans la suite de notre propos, nous partons du principe que les données
774 sont incluses dans un fichier musical, aussi toutes les expressions
775 Scheme seront introduites par un @code{#}.
777 Toutes les expressions Scheme de haut niveau incluses dans un fichier
778 LilyPond peuvent se combiner en une expression Scheme unique à l'aide de
779 la clause @code{begin} :
788 @node Variables LilyPond
789 @subsection Variables LilyPond
790 @translationof LilyPond variables
792 Les variables LilyPond sont enregistrées en interne sous la forme de
793 variables Scheme. Ainsi,
806 Ceci a pour conséquence que toute variable LilyPond peut être utilisée
807 dans une expression Scheme. Par exemple, nous pourrions dire
810 vingtQuatre = #(* 2 douze)
814 ce qui aurait pour conséquence que le nombre 24 sera stocké dans la
815 variable LilyPond (et Scheme) @code{vingtQuatre}.
817 La façon habituelle de faire référence à une variable LilyPond consiste
818 à la rappeler à l'aide d'une oblique inverse -- autrement dit saisir
819 @code{\vingtQuatre}. Dans la mesure où ceci, pour la plupart des types
820 internes de LilyPond y compris les expressions musicales, aura pour
821 effet d'en recopier la valeur, les fonctions musicales n'ont pas pour
822 habitude de créer une copie du matériau qu'elles vont modifier. De
823 fait, une expression musicale introduite par @code{#} ne devrait pas
824 contenir de matériau inexistant auparavant ou bien littéralement
825 recopié, mais plutôt une référence explicite.
828 @node Saisie de variables et Scheme
829 @subsection Saisie de variables et Scheme
830 @translationof Input variables and Scheme
832 Le format de saisie prend en charge la notion de variable -- ou
833 identificateur. Dans l'exemple suivant, une expression musicale se voit
834 attribuer un identificateur qui portera le nom de @code{traLaLa}.
837 traLaLa = @{ c'4 d'4 @}
842 Une variable a aussi une portée. Dans l'exemple suivant, le bloc
843 @code{\layout} contient une variable @code{traLaLa} tout à fait
844 indépendante de l'autre @code{\traLaLa}.
847 traLaLa = @{ c'4 d'4 @}
848 \layout @{ traLaLa = 1.0 @}
851 Dans les faits, chaque fichier a un domaine de compétence, et les
852 différents blocs @code{\header}, @code{\midi} et @code{\layout} ont leur
853 propre champ de compétence, imbriqué dans ce domaine principal.
855 Variables et champs de compétence sont implémentés par le système de
856 modules de Guile. Un module anonyme Scheme est attaché à chacun de ces
857 domaines. Une assertion telle que
860 traLaLa = @{ c'4 d'4 @}
864 est convertie, en interne, en une définition Scheme :
867 (define traLaLa @var{valeur Scheme de `@code{... }'})
870 Cela signifie que variables LilyPond et variables Scheme peuvent tout à
871 fait se mélanger. Dans l'exemple suivant, un fragment musical est
872 stocké dans la variable @code{traLaLa} puis dupliqué à l'aide de Scheme.
873 Le résultat est alors importé dans un bloc @code{\score} au moyen d'une
874 seconde variable @code{twice}.
877 traLaLa = { c'4 d'4 }
879 #(define newLa (map ly:music-deep-copy
880 (list traLaLa traLaLa)))
882 (make-sequential-music newLa))
887 @c Due to parser lookahead
889 Cet exemple est particulièrement intéressant. L'assignation
890 n'interviendra qu'une fois que l'analyseur grammatical aura l'assurance
891 que rien du type de @code{\addlyrics} ne suit ; il doit donc
892 vérifier ce qui vient après. Le @emph{parser} lit le @code{#} et
893 l'expression Scheme qui le suit @strong{sans} l'évaluer, de telle sorte
894 qu'il peut procéder à l'assignation, et @strong{ensuite} exécuter le
895 code Scheme sans problème.
898 @node Import de code Scheme dans LilyPond
899 @subsection Import de code Scheme dans LilyPond
900 @translationof Importing Scheme in LilyPond
905 L'exemple précédent illustre la manière @qq{d'exporter} une expression
906 musicale à partir des saisies et à destination de l'interpréteur Scheme.
907 L'inverse est aussi réalisable : en la plaçant derrière un @code{$}, une
908 valeur Scheme sera interprétée comme si elle avait été saisie en
909 syntaxe LilyPond. Au lieu de définir @code{\twice}, nous aurions tout
914 $(make-sequential-music (list newLa))
917 Vous pouvez utiliser @code{$} suivi d'une expression Scheme partout où
918 vous auriez utilisé @code{\@var{nom}}, dès lors que vous aurez assigné à
919 cette expression Scheme le nom de variable @var{nom}. La substitution
920 intervenant au niveau de l'analyseur lexical (le @emph{lexer}), LilyPond
921 ne saurait faire la différence.
923 Cette manière de procéder comporte cependant un inconvénient au niveau
924 de la temporisation. Si nous avions défini @code{newLa} avec un
925 @code{$} plutôt qu'un @code{#}, la définition Scheme suivante aurait
926 échoué du fait que @code{traLaLa} n'était pas encore défini. Pour plus
927 d'information quant au problème de synchronisation, voir la rubrique
928 @ref{Syntaxe Scheme dans LilyPond}.
933 Une autre façon de procéder serait de recourir aux « colleurs de liste »
934 @code{$@@} et @code{#@@} dont la fonction est d'insérer les éléments
935 d'une liste dans le contexte environnant. Grâce à ces opérateurs, la
936 dernière partie de notre fonction pourrait s'écrire ainsi :
943 Ici, chaque élément de la liste stockée dans @code{newLa} est pris à
944 son tour et inséré dans la liste, tout comme si nous avions écrit
947 @{ #(premier newLa) #(deuxième newLa) @}
950 Dans ces deux dernières formes, le code Scheme est évalué alors même que
951 le code initial est en cours de traitement, que ce soit par le
952 @emph{lexer} ou par le @emph{parser}. Si le code Scheme ne doit être
953 exécuté que plus tard, consultez la rubrique
954 @ref{Fonctions Scheme fantômes}, ou stockez le dans une procédure comme
959 (ly:set-option 'point-and-click #f))
967 L'imbrication de variables Scheme et LilyPond n'est pas possible
968 avec l'option @option{--safe}.
971 @node Propriétés des objets
972 @subsection Propriétés des objets
973 @translationof Object properties
975 Les propriétés des objets sont stockées dans LilyPond sous la forme
976 d'enchaînements de listes associatives, autrement dit des listes de
977 listes associatives. Une propriété se détermine par l'ajout de valeurs
978 en début de liste de cette propriété. Les caractéristiques d'une
979 propriété s'ajustent donc à la lecture des différentes valeurs des
982 La modification d'une valeur pour une propriété donnée requiert
983 l'assignation d'une valeur de la liste associative, tant pour la clé que
984 la valeur associée. Voici comment procéder selon la syntaxe de
988 \override Stem #'thickness = #2.6
991 Cette instruction ajuste l'apparence des hampes. Une entrée
992 @w{@code{'(thickness . 2.6)}} de la @emph{alist} est ajoutée à la liste
993 de la propriété de l'objet @code{Stem}. @code{thickness} devant
994 s'exprimer en unité d'épaisseur de ligne, les hampes auront donc une
995 épaisseur de 2,6 ligne de portée, et à peu près le double de leur
996 épaisseur normale. Afin de faire la distinction entre les variables que
997 vous définissez au fil de vos fichiers -- tel le @code{vingtQuatre} que
998 nous avons vu plus haut -- et les variables internes des objets, nous
999 parlerons de @qq{propriétés} pour ces dernières, et de @qq{variables}
1000 pour les autres. Ainsi, l'objet hampe possède une propriété
1001 @code{thickness}, alors que @code{vingtQuatre} est une variable.
1003 @cindex propriétés ou variables
1004 @cindex variables ou propriétés
1006 @c todo -- here we're getting interesting. We're now introducing
1007 @c LilyPond variable types. I think this deserves a section all
1011 @node Variables LilyPond composites
1012 @subsection Variables LilyPond composites
1013 @translationof LilyPond compound variables
1015 @subheading Décalages (@emph{offsets})
1017 Les décalages (@emph{offset}) sur deux axes (coordonnées X et Y) sont
1018 stockés sous forme de @emph{paires}. Le @code{car} de l'offset
1019 correspond à l'abscisse (coordonnée X) et le @code{cdr} à l'ordonnée
1023 \override TextScript #'extra-offset = #'(1 . 2)
1026 Cette clause affecte la paire @code{(1 . 2)} à la propriété
1027 @code{extra-offset} de l'objet @code{TextScript}. Ces nombres sont
1028 exprimés en espace de portée. La commande aura donc pour effet de
1029 déplacer l'objet d'un espace de portée vers la droite, et de deux
1030 espaces vers le haut.
1032 Les procédures permettant de manipuler les offsets sont regroupées dans
1033 le fichier @file{scm/lily-library.scm}.
1036 @subheading Fractions
1038 Les fractions, tel que LilyPond les utilise, sont aussi stockées sous
1039 forme de @emph{paire}. Alors que Scheme est tout à fait capable de
1040 représenter des nombres rationnels, vous conviendrez que, musicalement
1041 parlant, @samp{2/4} et @samp{1/2} ne se valent pas ; nous devrons
1042 donc pouvoir les distinguer. Dans le même ordre d'idée, LilyPond ne
1043 connaît pas les @qq{fractions} négatives. Pour ces raisons, @code{2/4}
1044 en LilyPond correspond à @code{(2 . 4)} en Scheme, et @code{#2/4} en
1045 LilyPond correspond à @code{1/2} en Scheme.
1048 @subheading Étendues (@emph{extents})
1050 Les paires permettent aussi de stocker des intervalles qui représentent
1051 un ensemble de nombres compris entre un minimum (le @code{car}) et un
1052 maximum (le @code{cdr}). Ces intervalles stockent l'étendue, tant au
1053 niveau horizontal (X) que vertical (Y) des objets imprimables. En
1054 matière d'étendue sur les X, le @code{car} correspond à la coordonnée de
1055 l'extrémité gauche, et le @code{cdr} à la coordonnée de l'extrémité
1056 droite. En matière d'étendue sur les Y, le @code{car} correspond à la
1057 coordonnée de l'extrémité basse, et le @code{cdr} à la coordonnée de
1060 Les procédures permettant de manipuler les offsets sont regroupées dans
1061 le fichier @file{scm/lily-library.scm}. Nous vous recommandons
1062 l'utilisation de ces procédures dans toute la mesure du possible afin
1063 d'assurer la cohérence du code.
1066 @subheading Propriété en @emph{alists}
1068 Les propriétés en @emph{alists} sont des structures de données
1069 particulières à LilyPond. Il s'agit de listes associatives dont les
1070 clés sont des propriétés et les valeurs des expressions Scheme
1071 fournissant la valeur requise pour cette propriété.
1073 Les propriétés LilyPond sont des symboles Scheme, à l'instar de
1077 @subheading Chaînes d'@emph{alist}
1079 Une chaîne d'@emph{alist} est une liste contenant les listes
1080 associatives d'une propriété.
1082 L'intégralité du jeu de propriétés qui doivent s'appliquer à un objet
1083 graphique est en fait stocké en tant que chaîne d'@emph{alist}. Afin
1084 d'obtenir la valeur d'une propriété particulière qu'un objet graphique
1085 devrait avoir, on examinera chacune des listes associatives de la
1086 chaîne, à la recherche d'une entrée contenant la clé de cette propriété.
1087 Est renvoyée la première entrée d'@emph{alist} trouvée, sa valeur étant
1088 la valeur de la propriété.
1090 L'obtention des valeurs de propriété des objets graphiques se réalise en
1091 principe à l'aide de la procédure Scheme @code{chain-assoc-get}.
1094 @node Représentation interne de la musique
1095 @subsection Représentation interne de la musique
1096 @translationof Internal music representation
1098 Dans les entrailles du programme, la musique se présente comme une liste
1099 Scheme. Cette liste comporte les différents éléments qui affecteront la
1100 sortie imprimable. L'analyse grammaticale (l'opération @emph{parsing})
1101 est le processus chargé de convertir la musique représentée par le code
1102 LilyPond en présentation interne Scheme.
1104 L'analyse d'une expression musicale se traduit par un jeu d'objets
1105 musicaux en Scheme. Une objet musical est déterminé par le temps qu'il
1106 occupe, que l'on appelle @emph{durée}. Les durées s'expriment par des
1107 nombres rationnels représentant la longueur d'un objet musical par
1110 Un objet musical dispose de trois types :
1113 un nom de musique : Toute expression musicale a un nom. Par exemple,
1114 une note amène à un @rinternals{NoteEvent}, un @code{\simultaneous} à un
1115 @rinternals{SimultaneousMusic}. Une liste exhaustive des différentes
1116 expressions est disponible dans la référence des propriétés internes, à
1117 la rubrique @rinternals{Music expressions}.
1120 un @qq{type} ou interface : Tout nom de musique dispose de
1121 plusieurs types ou interfaces. Ainsi, une note est tout à la fois un
1122 @code{event}, un @code{note-event}, un @code{rhythmic-event} et un
1123 @code{melodic-event}. Les différentes classes musicales sont
1124 répertoriées à la rubrique @rinternals{Music classes} de la référence
1125 des propriétés internes.
1128 un objet C++ : Tout objet musical est représenté par un objet de la
1129 classe C++ @code{Music}.
1132 L'information réelle d'une expression musicale est enregistrée sous
1133 forme de propriétés. Par exemple, un @rinternals{NoteEvent} dispose des
1134 propriétés @code{pitch} et @code{duration}, respectivement chargées de
1135 stocker la hauteur et la durée de cette note. Les différentes
1136 propriétés sont répertoriées à la rubrique @rinternals{Music properties}
1137 de la référence des propriétés internes.
1139 Une expression composite est un objet musical dont les propriétés
1140 contiennent d'autres objets musicaux. S'il s'agit d'une liste d'objets,
1141 elle sera stockée dans la propriété @code{elements} d'un objet
1142 musical ; s'il n'y a qu'un seul objet @qq{enfant}, il sera stocké
1143 dans la propriété @code{element}. Ainsi, par exemple, les enfants de
1144 @rinternals{SequentialMusic} iront dans @code{elements}, alors que
1145 l'argument unique de @rinternals{GraceMusic} ira dans @code{element}.
1146 De même, le corps d'une répétition ira dans la propriété @code{element}
1147 d'un @rinternals{RepeatedMusic}, les alternatives quant à elles dans la
1148 propriété @code{elements}.
1151 @node Construction de fonctions complexes
1152 @section Construction de fonctions complexes
1153 @translationof Building complicated functions
1155 Nous allons voir dans cette partie les moyens dont vous disposez pour
1156 obtenir les informations qui vous permettront de créer vos propres
1157 fonctions musicales complexes.
1160 * Affichage d'expressions musicales::
1161 * Propriétés musicales::
1162 * Doublement d'une note avec liaison (exemple)::
1163 * Ajout d'articulation à des notes (exemple)::
1167 @node Affichage d'expressions musicales
1168 @subsection Affichage d'expressions musicales
1169 @translationof Displaying music expressions
1171 @cindex stockage interne
1172 @cindex expression musicale, affichage
1173 @cindex représentation interne, affichage
1174 @cindex displayMusic
1175 @funindex \displayMusic
1177 Lorsque l'on veut écrire une fonction musicale, il est intéressant
1178 d'examiner comment une expression musicale est représentée en interne.
1179 Vous disposez à cet effet de la fonction musicale @code{\displayMusic}.
1183 \displayMusic @{ c'4\f @}
1198 'AbsoluteDynamicEvent
1202 (ly:make-duration 2 0 1 1)
1204 (ly:make-pitch 0 0 0))))
1207 Par défaut, LilyPond affichera ces messages sur la console, parmi toutes
1208 les autres informations. Vous pouvez, afin de les isoler et de garder
1209 le résultat des commandes @code{\display@{TRUC@}}, rediriger la sortie
1213 lilypond file.ly >display.txt
1216 Un peu de Scheme combiné à notre code LilyPond, et les seules
1217 informations qui nous intéressent se retrouveront directement dans un
1218 fichier indépendant :
1222 #(with-output-to-file "display.txt"
1223 (lambda () #@{ \displayMusic @{ c'4\f @} #@}))
1227 L'information sera encore plus lisible après un peu de mise en forme :
1230 (make-music 'SequentialMusic
1232 (make-music 'NoteEvent
1233 'articulations (list
1234 (make-music 'AbsoluteDynamicEvent
1237 'duration (ly:make-duration 2 0 1 1)
1238 'pitch (ly:make-pitch 0 0 0))))
1241 Une séquence musicale @code{@{ ... @}} se voit attribuer le nom de
1242 @code{SequentialMusic}, et les expressions qu'elle contient sont
1243 enregistrées en tant que liste dans sa propriété @code{'elements}. Une
1244 note est représentée par un objet @code{NoteEvent} -- contenant les
1245 propriétés de durée et hauteur -- ainsi que l'information qui lui est
1246 attachée -- en l'occurrence un @code{AbsoluteDynamicEvent} ayant une
1247 propriété @code{text} de valeur @code{"f"} -- et stockée dans sa
1248 propriété @code{articulations}.
1251 La fonction @code{\displayMusic} renvoie la musique qu'elle
1252 affiche ; celle-ci sera donc aussi interprétée. L'insertion d'une
1253 commande @code{\void} avant le @code{\displayMusic} permet de
1254 s'affranchir de la phase d'interprétation.
1257 @node Propriétés musicales
1258 @subsection Propriétés musicales
1259 @translationof Music properties
1261 Nous abordons ici les propriétés @emph{music}, et non pas les propriétés
1262 @emph{context} ou @emph{layout}.
1264 Partons de cet exemple simple@tie{}:
1268 \displayMusic \someNote
1273 (ly:make-duration 2 0 1 1)
1275 (ly:make-pitch 0 0 0))
1278 L'objet @code{NoteEvent} est la représentation brute de @code{someNote}.
1279 Voyons ce qui se passe lorsque nous plaçons ce @notation{c'} dans une
1280 construction d'accord :
1284 \displayMusic \someNote
1292 (ly:make-duration 2 0 1 1)
1294 (ly:make-pitch 0 0 0))))
1297 L'objet @code{NoteEvent} est maintenant le premier objet de la propriété
1298 @code{'elements} de @code{someNote}.
1300 @code{\displayMusic} utilise la fonction @code{display-scheme-music}
1301 pour afficher la représentation en Scheme d'une expression musicale :
1304 #(display-scheme-music (first (ly:music-property someNote 'elements)))
1309 (ly:make-duration 2 0 1 1)
1311 (ly:make-pitch 0 0 0))
1314 La hauteur de la note est accessible au travers de la propriété
1315 @code{'pitch} de l'objet @code{NoteEvent} :
1318 #(display-scheme-music
1319 (ly:music-property (first (ly:music-property someNote 'elements))
1322 (ly:make-pitch 0 0 0)
1325 La hauteur de la note se modifie en définissant sa propriété
1326 @code{'pitch}@tie{}:
1328 @funindex \displayLilyMusic
1331 #(set! (ly:music-property (first (ly:music-property someNote 'elements))
1333 (ly:make-pitch 0 1 0)) ;; set the pitch to d'.
1334 \displayLilyMusic \someNote
1340 @node Doublement d'une note avec liaison (exemple)
1341 @subsection Doublement d'une note avec liaison (exemple)
1342 @translationof Doubling a note with slurs (example)
1344 Supposons que nous ayons besoin de créer une fonction transformant une
1345 saisie @code{a} en @w{@code{@{ a( a) @}}}. Commençons par examiner
1346 comment le résultat est représenté en interne.
1349 \displayMusic@{ a'( a') @}
1362 (ly:make-duration 2 0 1 1)
1364 (ly:make-pitch 0 5 0))
1373 (ly:make-duration 2 0 1 1)
1375 (ly:make-pitch 0 5 0))))
1378 Mauvaise nouvelle ! Les expressions @code{SlurEvent} doivent
1379 s'ajouter @qq{à l'intérieur} de la note -- dans sa propriété
1380 @code{articulations}.
1382 Examinons à présent la saisie :
1390 (ly:make-duration 2 0 1 1)
1392 (ly:make-pitch 0 5 0))))
1395 Nous aurons donc besoin, dans notre fonction, de cloner cette expression
1396 -- de telle sorte que les deux notes constituent la séquence -- puis
1397 d'ajouter un @code{SlurEvent} à la propriété @code{'articulations} de
1398 chacune d'elles, et enfin réaliser un @code{SequentialMusic} de ces deux
1399 @code{EventChords}. En tenant compte du fait que, dans le cadre d'un
1400 ajout, une propriété non définie est lue @code{'()} (une liste vide),
1401 aucune vérification n'est requise avant d'introduire un nouvel élément
1402 en tête de la propriété @code{articulations}.
1405 doubleSlur = #(define-music-function (parser location note) (ly:music?)
1406 "Renvoie : @{ note ( note ) @}.
1407 `note' est censé être une note unique."
1408 (let ((note2 (ly:music-deep-copy note)))
1409 (set! (ly:music-property note 'articulations)
1410 (cons (make-music 'SlurEvent 'span-direction -1)
1411 (ly:music-property note 'articulations)))
1412 (set! (ly:music-property note2 'articulations)
1413 (cons (make-music 'SlurEvent 'span-direction 1)
1414 (ly:music-property note2 'articulations)))
1415 (make-music 'SequentialMusic 'elements (list note note2))))
1419 @node Ajout d'articulation à des notes (exemple)
1420 @subsection Ajout d'articulation à des notes (exemple)
1421 @translationof Adding articulation to notes (example)
1423 Le moyen d'ajouter une articulation à des notes consiste à fusionner
1424 deux expressions musicales en un même contexte, comme nous l'avons vu à
1425 la rubrique @ruser{Création d'un contexte}. L'option de réaliser
1426 nous-mêmes une fonction musicale à cette fin nous offre l'avantage de
1427 pouvoir alors ajouter une articulation, telle qu'une instruction de
1428 doigté, individuellement à l'une des notes d'un accord, ce qui est
1429 impossible dans le cadre d'une simple fusion de musique indépendante.
1431 Un @code{$variable} au milieu de la notation @code{#@{...#@}} se
1432 comporte exactement comme un banal @code{\variable} en notation LilyPond
1433 traditionnelle. Nous savons déjà que
1436 @{ \musique -. -> @}
1440 n'est pas admis par LilyPond. Nous pourrions tout à fait contourner ce
1441 problème en attachant l'articulation à un accord vide,
1444 @{ << \musique <> -. -> >> @}
1448 mais, pour les besoins de la démonstration, nous allons voir comment
1449 réaliser ceci en Scheme. Commençons par examiner une saisie simple et
1450 le résultat auquel nous désirons aboutir :
1459 (ly:make-duration 2 0 1 1)
1461 (ly:make-pitch -1 0 0))))
1474 (ly:make-duration 2 0 1 1)
1476 (ly:make-pitch -1 0 0))
1479 Nous voyons qu'une note (@code{c4}) est représentée par une expression
1480 @code{NoteEvent}. Si nous souhaitons ajouter une articulation
1481 @notation{accent}, nous devrons ajouter une expression
1482 @code{ArticulationEvent} à la propriété @code{articulations} de
1483 l'expression @code{NoteEvent}.
1485 Construisons notre fonction en commençant par
1488 (define (ajoute-accent note-event)
1489 "Ajoute un accent (ArticulationEvent) aux articulations de `note-event',
1490 qui est censé être une expression NoteEvent."
1491 (set! (ly:music-property note-event 'articulations)
1492 (cons (make-music 'ArticulationEvent
1493 'articulation-type "accent")
1494 (ly:music-property note-event 'articulations)))
1498 La première ligne est la manière de définir une fonction en Scheme : la
1499 fonction Scheme a pour nom @code{ajoute-accent} et elle comporte une
1500 variable appelée @code{note-event}. En Scheme, le type d'une variable
1501 se déduit la plupart de temps de par son nom -- c'est d'ailleurs une
1502 excellente pratique que l'on retrouve dans de nombreux autres langages.
1505 "Ajoute un accent..."
1509 décrit ce que fait la fonction. Bien que ceci ne soit pas primordial,
1510 tout comme des noms de variable évidents, tâchons néanmoins de prendre
1511 de bonnes habitudes dès nos premiers pas.
1513 Vous pouvez vous demander pourquoi nous modifions directement
1514 l'événement note plutôt que d'en manipuler une copie -- on pourrait
1515 utiliser @code{ly:music-deep-copy} à cette fin. La raison en est qu'il
1516 existe un contrat tacite : les fonctions musicales sont autorisées
1517 à modifier leurs arguments -- ils sont générés en partant de zéro (comme
1518 les notes que vous saisissez) ou déjà recopiés (faire référence à une
1519 variable musicale avec @samp{\name} ou à de la musique issue
1520 d'expressions Scheme @samp{$(@dots{})} aboutit à une copie). Dans la
1521 mesure où surmultiplier les copies serait contre productif, la valeur de
1522 retour d'une fonction musicale n'est @strong{pas} recopiée. Afin de
1523 respecter ce contrat, n'utilisez pas un même argument à plusieurs
1524 reprises, et n'oubliez pas que le retourner compte pour une utilisation.
1526 Dans un exemple précédent, nous avons construit de la musique en
1527 répétant un certain argument musical. Dans ce cas là, l'une des
1528 répétitions se devait d'être une copie. Dans le cas contraire,
1529 certaines bizarreries auraient pu survenir. Par exemple, la présence
1530 d'un @code{\relative} ou d'un @code{\transpose}, après plusieurs
1531 répétitions du même élément, entraînerait des @qq{relativisations} ou
1532 transpositions en cascade. Si nous les assignons à une variable
1533 musicale, l'enchaînement est rompu puisque la référence à @samp{\nom}
1534 créera une nouvelle copie sans toutefois prendre en considération
1535 l'identité des éléments répétés.
1537 Cette fonction n'étant pas une fonction musicale à part entière, elle
1538 peut s'utiliser dans d'autres fonctions musicales. Il est donc sensé de
1539 respecter le même contrat que pour les fonctions musicales :
1540 l'entrée peut être modifiée pour arriver à une sortie, et il est de la
1541 responsabilité de l'appelant d'effectuer des copies s'il a réellement
1542 besoin de l'argument dans son état originel. Vous constaterez, à la
1543 lecture des fonctions propres à LilyPond, comme @code{music-map}, que ce
1544 principe est toujours respecté.
1546 Revenons à nos moutons@dots{} Nous disposons maintenant d'un
1547 @code{note-event} que nous pouvons modifier, non pas grâce à un
1548 @code{ly:music-deep-copy}, mais plutôt en raison de notre précédente
1549 réflexion. Nous ajoutons @notation{l'accent} à la liste de ses
1550 propriétés @code{'articulations}.
1553 (set! emplacement nouvelle-valeur)
1556 L'emplacement est ce que nous voulons ici définir. Il s'agit de la
1557 propriété @code{'articulations} de l'expression @code{note-event}.
1560 (ly:music-property note-event 'articulations)
1563 La fonction @code{ly:music-property} permet d'accéder aux propriétés
1564 musicales -- les @code{'articulations}, @code{'duration}, @code{'pitch}
1565 etc. que @code{\displayMusic} nous a indiquées. La nouvelle valeur sera
1566 l'ancienne propriété @code{'articulations}, augmentée d'un
1567 élément : l'expression @code{ArticulationEvent}, que nous
1568 recopions à partir des informations de @code{\displayMusic}.
1571 (cons (make-music 'ArticulationEvent
1572 'articulation-type "accent")
1573 (ly:music-property result-event-chord 'articulations))
1576 @code{cons} permet d'ajouter un élément en tête de liste sans pour
1577 autant modifier la liste originale. C'est exactement ce que nous
1578 recherchons : la même liste qu'auparavant, plus la nouvelle
1579 expression @code{ArticulationEvent}. L'ordre au sein de la propriété
1580 @code{'articulations} n'a ici aucune importance.
1582 Enfin, après avoir ajouté l'articulation @notation{accent} à sa
1583 propriété @code{articulations}, nous pouvons renvoyer le
1584 @code{note-event}, ce que réalise la dernière ligne de notre fonction.
1586 Nous pouvons à présent transformer la fonction @code{ajoute-accent} en
1587 fonction musicale, à l'aide d'un peu d'enrobage syntaxique et mention du
1588 type de son unique argument @qq{réel}.
1591 ajouteAccent = #(define-music-function (parser location note-event)
1593 "Ajoute un accent (ArticulationEvent) aux articulations de `note-event',
1594 qui est censé être une expression NoteEvent."
1595 (set! (ly:music-property note-event 'articulations)
1596 (cons (make-music 'ArticulationEvent
1597 'articulation-type "accent")
1598 (ly:music-property note-event 'articulations)))
1602 Par acquis de conscience, vérifions que tout ceci fonctione :
1605 \displayMusic \ajouteAccent c4
1612 * Tweaking with Scheme::
1615 @c @nod e Tweaking with Scheme
1616 @c @sectio n Tweaking with Scheme
1618 We have seen how LilyPond output can be heavily modified using
1620 @code{\override TextScript #'extra-offset = ( 1 . -1)}. But
1621 we have even more power if we use Scheme. For a full explanation
1622 of this, see the @ref{Scheme tutorial}, and
1623 @ref{Interfaces for programmers}.
1625 We can use Scheme to simply @code{\override} commands,
1627 TODO Find a simple example
1628 @c This isn't a valid example with skylining
1629 @c It works fine without padText -td
1633 @lilypond[quote,verbatim,ragged-right]
1634 padText = #(define-music-function (parser location padding) (number?)
1636 \once \override TextScript #'padding = #padding
1640 c4^"piu mosso" b a b
1642 c4^"piu mosso" d e f
1644 c4^"piu mosso" fis a g
1650 We can use it to create new commands:
1652 @c Check this is a valid example with skylining
1653 @c It is - 'padding still works
1656 @lilypond[quote,verbatim,ragged-right]
1657 tempoPadded = #(define-music-function (parser location padding tempotext)
1660 \once \override Score.MetronomeMark #'padding = #padding
1661 \tempo \markup { \bold #tempotext }
1665 \tempo \markup { "Low tempo" }
1667 \tempoPadded #4.0 "High tempo"
1673 Even music expressions can be passed in:
1675 @lilypond[quote,verbatim,ragged-right]
1676 pattern = #(define-music-function (parser location x y) (ly:music? ly:music?)
1683 \pattern {d16 dis} { ais16-> b\p }