1 @c -*- coding: utf-8; mode: texinfo; documentlanguage: fr -*-
4 Translation of GIT committish: 39912f861693f1c24b8833e6e9e6ba82eb3e6746
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 ; celle-ci se base sur le standard Scheme « 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/} ; le
38 standard Scheme « 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 « bac à sable » Scheme pour
73 effectuer des tests ; vous y accéderez en tapant @code{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 « Exécuter »
80 à partir du menu « Démarrer » puis taper @code{guile}.
82 Néanmoins, tous les paquetages de LilyPond disposent d'un bac à sable
83 Scheme, accessible par la commande :
85 lilypond scheme-sandbox
89 Une fois le bac à sable actif, vous obtiendrez l'invite :
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} :
117 L'évaluation d'une variable Scheme se réalise en saisissant le nom de
118 cette variable à l'invite de Guile :
126 Une variable Scheme s'affiche à l'écran à l'aide de la fonction
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 à
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 : @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 :
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
239 * Listes associatives (alists)::
240 * Tables de hachage::
245 @unnumberedsubsubsec Paires
248 Le type de donnée composite fondamental est la paire (@code{pair}).
249 Comme son nom l'indique, il s'agit de lier deux valeurs, à l'aide de
250 l'opérateur @code{cons}.
258 Vous aurez noté que la paire s'affiche sous la forme de deux éléments
259 bornés par des parenthèses et séparés par une espace, un point
260 (@code{.}) et une autre espace. Le point n'est en aucune manière un
261 séparateur décimal ; il s'agit de l'indicateur d'une paire.
263 Vous pouvez aussi saisir littéralement les valeurs d'une paire, en la
264 faisant précéder d'une apostrophe.
272 Les deux éléments d'une paire peuvent être constitués de n'importe
273 quelle valeur Scheme valide :
278 guile> '("blah-blah" . 3.1415926535)
279 ("blah-blah" . 3.1415926535)
283 Les premier et second éléments de la paire sont accessibles à l'aide des
284 procédures Scheme @code{car} et @code{cdr}.
287 guile> (define mypair (cons 123 "hello there")
298 Note : @code{cdr} se prononce « couldeur », comme l'indiquent Sussman et
300 @uref{http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-14.html#footnote_Temp_133}.
304 @unnumberedsubsubsec Listes
307 Autre structure de donnée commune en Scheme : la liste (@emph{list}).
308 Une liste « correcte » se définit comme étant vide (représentée par
309 @code{'()} et de longueur 0) ou une paire dont le @code{cdr} est une
312 Il existe plusieurs méthodes pour créer une liste, la plus courante
313 étant l'utilisation de la procédure @code{list} :
316 guile> (list 1 2 3 "abc" 17.5)
320 La représentation d'une liste par la succession de ses éléments, séparés
321 par des espaces, bornée par des parenthèses, n'est en fait qu'une vue
322 compacte des paires qui la constituent. Les paires sont ainsi
323 dépourvues du point de séparation et de la parenthèse ouvrante qui le
324 suit et des parenthèses fermantes. Sans ce « compactage », cette liste
325 serait ainsi présentée :
328 (1 . (2 . (3 . ("abc" . (17.5 . ())))))
331 Vous pouvez donc saisir une liste comme elle serrait présentée, en
332 entourant ses éléments par des parenthèses à la suite d'une apostrophe
333 (afin que ce qui suit ne soit pas interprété comme un appel à une
337 guile> '(17 23 "foo" "bar" "bazzle")
338 (17 23 "foo" "bar" "bazzle")
341 Les listes ont une importance considérable en Scheme. Certains vont
342 d'ailleurs jusqu'à considérer Scheme comme un dialecte du lisp, où
343 « lisp » serait une abréviation de « List Processing ». Il est vrai
344 que toute expression Scheme est une liste.
347 @node Listes associatives (alists)
348 @unnumberedsubsubsec Listes associatives (alists)
349 @translationof Association lists (alists)
351 Il existe un type particulier de liste : la @emph{liste associative} --
352 ou @emph{alist}. Une @emph{alist} permet de stocker des données dans le
353 but de les réutiliser.
355 Une liste associative est une liste dont les éléments sont des paires.
356 Le @code{car} de chacun des éléments constitue une clé (@emph{key}) et
357 chaque @code{cdr} une valeur (@emph{value}). La procédure Scheme
358 @code{assoc} permet de retrouver une entrée de la liste
359 associative ; son @code{cdr} en fournira la valeur :
362 guile> (define mon-alist '((1 . "A") (2 . "B") (3 . "C")))
364 ((1 . "A") (2 . "B") (3 . "C"))
365 guile> (assoc 2 mon-alist)
367 guile> (cdr (assoc 2 mon-alist))
372 LilyPond recourt abondamment aux @emph{alists} pour stocker des
373 propriétés ou autres données.
376 @node Tables de hachage
377 @unnumberedsubsubsec Tables de hachage
378 @translationof Hash tables
380 Il s'agit d'une structure de données à laquelle LilyPond fait parfois
381 appel. Une table de hachage (@emph{hash table}) peut se comparer à une
382 matrice ou un tableau dont l'index peut être n'importe quel type de
383 valeur Scheme et ne se limitant pas à des nombres entiers.
385 Les tables de hachage sont un moyen plus efficace que les listes
386 associatives lorsqu'il s'agit d'enregistrer de nombreuses données qui ne
387 changeront que peu fréquemment.
389 La syntaxe permettant de créer une table de hachage peut paraître
390 complexe, mais vous en trouverez de nombreux exemples dans les sources
394 guile> (define h (make-hash-table 10))
397 guile> (hashq-set! h 'cle1 "valeur1")
399 guile> (hashq-set! h 'key2 "valeur2")
401 guile> (hashq-set! h 3 "valeur3")
405 La procédure @code{hashq-ref} permet de récupérer une valeur dans la
409 guile> (hashq-ref h 3)
411 guile> (hashq-ref h 'cle2)
416 La procédure @code{hashq-get-handle} permet de retrouver à la fois une
417 clé et sa valeur. Cette procédure a l'avantage de renvoyer @code{#f}
418 lorsque la clé n'existe pas.
421 guile> (hashq-get-handle h 'cle1)
423 guile> (hashq-get-handle h 'zut)
429 @node Scheme et les calculs
430 @subsection Scheme et les calculs
431 @translationof Calculations in Scheme
434 We have been using lists all along. A calculation, like @code{(+ 1 2)}
435 is also a list (containing the symbol @code{+} and the numbers 1
436 and@tie{}2). Normally lists are interpreted as calculations, and the
437 Scheme interpreter substitutes the outcome of the calculation. To enter a
438 list, we stop the evaluation. This is done by quoting the list with a
439 quote @code{'} symbol. So, for calculations do not use a quote.
441 Inside a quoted list or pair, there is no need to quote anymore. The
442 following is a pair of symbols, a list of symbols and a list of lists
447 #'(staff clef key-signature)
452 Scheme permet aussi d'effectuer des calculs. Il utilise alors un
453 @emph{préfixe}. Additionner 1 et 2 s'écrira @code{(+ 1 2)} et
454 non @math{1+2} comme on aurait pu s'y attendre.
461 Les calculs peuvent s'imbriquer ; le résultat d'une fonction peut
462 servir pour un autre calcul.
469 Ces calculs sont un exemple d'évaluation : une expression telle que
470 @code{(* 3 4)} est remplacée par sa valeur, soit @code{12}.
472 En matière de calcul, Scheme fait la différence entre des nombres entiers
473 ou non. Les calculs sur des nombres entiers seront exacts, alors que
474 s'il s'agit de nombres non entiers, les calculs tiendront compte de la
475 précision mentionnée :
484 Lorsque l'interpréteur Scheme rencontre une expression sous forme de
485 liste, le premier élément de cette liste est considéré en tant que
486 procédure qui prendra en argument le restant de la liste. C'est la
487 raison pour laquelle, en Scheme, tous les opérateurs sont en préfixe.
489 Le fait que le premier élément d'une expression Scheme sous forme de
490 liste ne soit pas un opérateur ou une procédure déclenchera une
491 erreur de la part de l'interpréteur :
500 <unnamed port>:52:1: In expression (1 2 3):
501 <unnamed port>:52:1: Wrong type to apply: 1
506 Vous pouvez constater que l'interpréteur a tenté de considérer @code{1}
507 comme étant un opérateur ou une procédure, ce qu'il n'a pu réaliser. Il
508 a donc renvoyé l'erreur « Wrong type to apply: 1 » (@emph{Application
509 d'un type erroné : 1}).
511 C'est pourquoi il est impératif, pour créer une liste, soit d'utiliser
512 l'opérateur consacré (@code{list}), soit de faire précéder la liste
513 d'une apostrophe, de telle sorte que l'interpréteur ne tente pas de
524 Vous pourrez être confronté à cette erreur lorsque vous intégrerez
528 The same assignment can be done in completely in Scheme as well,
531 #(define twentyFour (* 2 twelve))
534 @c this next section is confusing -- need to rewrite
536 The @emph{name} of a variable is also an expression, similar to a
537 number or a string. It is entered as
544 @cindex quoting in Scheme
546 The quote mark @code{'} prevents the Scheme interpreter from substituting
547 @code{24} for the @code{twentyFour}. Instead, we get the name
552 @node Scheme et les procédures
553 @subsection Scheme et les procédures
554 @translationof Scheme procedures
556 Une procédure Scheme est une expression Scheme qui renverra une valeur
557 issue de son exécution. Les procédures Scheme sont capables de
558 manipuler des variables qui ne sont pas définies en leur sein.
561 * Définition de procédures::
563 * Valeurs de retour::
567 @node Définition de procédures
568 @unnumberedsubsubsec Définition de procédures
569 @translationof Defining procedures
571 En Scheme, on définit une procédure à l'aide de l'instruction
575 (define (nom-fonction argument1 argument2@dots{} argumentn)
576 expression-scheme-qui-donnera-une-valeur-en-retour)
579 Nous pourrions, par exemple, définir une procédure calculant la moyenne
583 guile> (define (moyenne x y) (/ (+ x y) 2))
585 #<procedure moyenne (x y)>
588 Une fois la procédure définie, on l'appelle en la faisant suivre, dans
589 une liste, des arguments qui doivent l'accompagner. Calculons
590 maintenant la moyenne de 3 et 12 :
593 guile> (moyenne 3 12)
599 @unnumberedsubsubsec Prédicats
600 @translationof Predicates
602 Une procédure Scheme chargée de retourner une valeur booléenne s'appelle
603 un « prédicat » (@emph{predicate}). Par convention, plutôt que par
604 nécessité, le nom d'un prédicat se termine par un point
608 guile> (define (moins-de-dix? x) (< x 10))
609 guile> (moins-de-dix? 9)
611 guile> (moins-de-dix? 15)
616 @node Valeurs de retour
617 @unnumberedsubsubsec Valeurs de retour
618 @translationof Return values
620 Une procédure Scheme doit toujours renvoyer une valeur de retour, en
621 l'occurrence la valeur de la dernière expression exécutée par cette
622 procédure. La valeur de retour sera une valeur Scheme valide, y compris
623 une structure de donnée complexe ou une procédure.
625 On peut avoir besoin de regrouper plusieurs expressions Scheme dans une
626 même procédure. Deux méthodes permettent de combiner des expressions
627 multiples. La première consiste à utiliser la procédure @code{begin},
628 qui permet l'évaluation de plusieurs expressions et renvoie la valeur de
629 la dernière expression.
632 guile> (begin (+ 1 2) (- 5 8) (* 2 2))
636 Une deuxième méthode consiste à combiner les expressions dans un bloc
637 @code{let}. Ceci aura pour effet de créer une série de liens, puis
638 d'évaluer en séquence les expressions susceptibles d'inclure ces
639 liens. La valeur renvoyée par un bloc @emph{let} est la valeur de
640 retour de la dernière clause de ce bloc :
643 guile> (let ((x 2) (y 3) (z 4)) (display (+ x y)) (display (- z 4))
644 @dots{} (+ (* x y) (/ z x)))
649 @node Scheme et les conditions
650 @subsection Scheme et les conditions
651 @translationof Scheme conditionals
660 @unnumberedsubsubsec if
663 Scheme dispose d'une procédure @code{if} :
666 (if expression-test expression-affirmative expression-négative)
669 @var{expression-test} est une expression qui renverra une valeur
670 booléenne. Dans le cas où @var{expression-test} retourne @code{#t}, la
671 procédure @code{if} renvoie la valeur de @var{expression-affirmative},
672 et celle de @var{expression-négative} dans le cas contraire.
677 guile> (if (> a b) "a est plus grand que b" "a n'est pas plus grand que b")
678 "a n'est pas plus grand que b"
683 @unnumberedsubsubsec cond
686 Une autre manière d'introduire une condition en Scheme est d'utiliser
687 l'instruction @code{cond} :
690 (cond (expression-test-1 expression-résultat-séquence-1)
691 (expression-test-2 expression-résultat-séquence-2)
693 (expression-test-n expression-résultat-séquence-n))
696 Comme par exemple ici :
701 guile> (cond ((< a b) "a est plus petit que b")
702 @dots{} ((= a b) "a égale b")
703 @dots{} ((> a b) "a est plus grand que b"))
704 "a est plus petit que b"
708 @node Scheme et LilyPond
709 @section Scheme et LilyPond
710 @translationof Scheme in LilyPond
713 * Syntaxe Scheme dans LilyPond::
714 * Variables LilyPond::
715 * Saisie de variables et Scheme::
716 * Import de code Scheme dans LilyPond::
717 * Propriétés des objets::
718 * Variables LilyPond composites::
719 * Représentation interne de la musique::
722 @node Syntaxe Scheme dans LilyPond
723 @subsection Syntaxe Scheme dans LilyPond
724 @translationof LilyPond Scheme syntax
729 L'installation de LilyPond comprenant l'interpréteur Guile, les fichiers
730 source LilyPond peuvent contenir du Scheme. Vous disposez de plusieurs
731 méthodes pour inclure du Scheme dans vos fichiers LilyPond.
733 La méthode la plus simple consiste à insérer un @emph{hash} (le caractère
734 @code{#}, improprement appelé dièse) avant l'expression Scheme.
736 Rappelons-nous qu'un fichier source LilyPond est structuré en jetons et
737 expressions, tout comme le langage humain est structuré en mots et
738 phrases. LilyPond dispose d'un analyseur lexical (appelé @emph{lexer})
739 qui sait identifier les jetons -- nombres, chaînes, éléments Scheme,
740 hauteurs, etc. -- ainsi que d'un analyseur syntaxique (appelé
741 @emph{parser}) -- voir
742 @rcontribnamed{LilyPond grammar, Grammaire de LilyPond}. Dès lors
743 que le programme sait quelle règle grammaticale particulière doit
744 s'appliquer, il exécute les consignes qui lui sont associées.
746 Le recours à un @emph{hash} pour mettre en exergue du Scheme est tout à
747 fait approprié. Dès qu'il rencontre un @code{#}, l'analyseur lexical
748 passe le relais au lecteur Scheme qui va alors déchiffrer l'intégralité
749 de l'expression Scheme -- ce peut être un identificateur, une expression
750 bornée par des parenthèses ou bien d'autres choses encore. Une fois
751 cette expression lue, elle est enregistrée en tant que valeur d'un
752 élément grammatical @code{SCM_TOKEN}. Puisque l'analyseur syntaxique
753 sait comment traiter ce jeton, il charge Guile d'évaluer l'expression
754 Scheme. Dans la mesure où le @emph{parser} requiert une lecture en
755 avance de la part du @emph{lexer} pour prendre une décision, cette
756 distinction entre lecture et évaluation -- @emph{lexer} et @emph{parser}
757 -- révèle toute sa pertinence lorsqu'il s'agit d'exécuter conjointement
758 des expressions LilyPond et des expressions Scheme. C'est la raison
759 pour laquelle nous vous recommandons, dans toute la mesure du possible,
760 d'utiliser un signe @emph{hash} lorsque vous faites appel à Scheme.
762 Une autre manière de faire appel à l'interpréteur Scheme à partir de
763 LilyPond consiste à introduire une expression Scheme par un caractère
764 dollar au lieu d'un caractère dièse -- un @code{$} au lieu
765 d'un @code{#}. En pareil cas, LilyPond évalue le code dès sa lecture
766 par l'analyseur lexical, vérifie le type d'expression Scheme qui en
767 résulte et détermine un type de jeton (l'un des @code{xxx_IDENTIFIER} de
768 la grammaire) qui lui corresponde, puis en fait une copie qui servira à
769 traiter la valeur de ce jeton. Lorsque la valeur de l'expression est
770 @emph{void}, autrement dit une valeur Guile @code{*unspecified*} (pour
771 @emph{non spécifiée}), aucune information n'est transmise à l'analyseur
774 C'est, en réalité, la manière dont LilyPond opère lorsque vous rappelez
775 une variable ou une fonction par son nom -- au travers d'un @code{\nom}
776 --, à la seule différence que sa finalité est déterminée par l'analyseur
777 lexical de LilyPond sans consultation du lecteur Scheme ; le nom de
778 la variable rappelée doit donc être en corrélation avec le mode LilyPond
779 actif à ce moment là.
781 L'immédiateté de l'opérateur @code{$} peut entraîner des effets
782 indésirables dont nous reparlerons à la rubrique
783 @ref{Saisie de variables et Scheme} ; aussi est-il préférable
784 d'utiliser un @code{#} dès que l'analyseur grammatical le supporte.
785 Dans le cadre d'une expression musicale, une expression qui aura été
786 créée à l'aide d'un @code{#} sera interprétée comme étant de la musique.
787 Elle ne sera cependant pas recopiée avant utilisation. Si la structure
788 qui l'abrite devait être réutilisée, un appel expicite à
789 @code{ly:music-deep-copy} pourrait être requis.
794 Les opérateurs @code{$@@} et @code{#@@} agissent comme des « colleurs de
795 liste » : leur fonction consiste à insérer tous les éléments d'une liste
796 dans le contexte environnant.
798 Examinons à présent du vrai code Scheme. Nous pouvons définir des
799 procédures Scheme au milieu d'un fichier source LilyPond :
802 #(define (moyenne a b c) (/ (+ a b c) 3))
805 Pour mémoire, vous noterez que les commentaires LilyPond (@code{%} ou
806 @code{%@{…%@}}) ne peuvent s'utiliser dans du code Scheme, même si
807 celui-ci se trouve au sein d'un fichier LilyPond. Ceci tient au fait
808 que l'expression Scheme est lue par l'interpréteur Guile, et en aucune
809 façon par l'analyseur lexical de LilyPond. Voici comment introduire des
810 commentaires dans votre code Scheme :
813 ; ceci n'est qu'une simple ligne de commentaire
816 Ceci constitue un bloc de commentaire (non imbricable)
818 En fait, les Schemeurs les utilisent très rarement,
819 et vous n'en trouverez jamais dans le code source
824 Dans la suite de notre propos, nous partons du principe que les données
825 sont incluses dans un fichier musical, aussi toutes les expressions
826 Scheme seront introduites par un @code{#}.
828 Toutes les expressions Scheme de haut niveau incluses dans un fichier
829 LilyPond peuvent se combiner en une expression Scheme unique à l'aide de
830 la clause @code{begin} :
839 @node Variables LilyPond
840 @subsection Variables LilyPond
841 @translationof LilyPond variables
843 Les variables LilyPond sont enregistrées en interne sous la forme de
844 variables Scheme. Ainsi,
857 Ceci a pour conséquence que toute variable LilyPond peut être utilisée
858 dans une expression Scheme. Par exemple, nous pourrions dire
861 vingtQuatre = #(* 2 douze)
865 ce qui aurait pour conséquence que le nombre @emph{24} sera stocké dans
866 la variable LilyPond (et Scheme) @code{vingtQuatre}.
868 Scheme autorise la modification d'expressions complexes au fil de l'eau,
869 ce que réalise LilyPond dans le cadre des fonctions musicales.
870 Toutefois, lorsqu'une expression musicale est stockée dans une variable,
871 plutôt que saisie au fur et à mesure, on s'attend, alors qu'elle est
872 passée à une fonction musicale, à ce que sa valeur originale ne soit en
873 rien modifiée. C'est la raison pour laquelle faire référence à une
874 variable à l'aide d'une oblique inverse -- autrement dit saisir
875 @code{\vingtQuatre} -- aura pour effet que LilyPond créera une copie de
876 la valeur musicale de cette variable aux fins de l'utiliser au sein de
877 l'expression musicale au lieu d'utiliser directement la valeur de cette
880 Par voie de conséquence, une expression musicale introduite par @code{#}
881 ne devrait pas contenir de matériau inexistant auparavant ou bien
882 littéralement recopié, mais plutôt une référence explicite.
886 @ref{Syntaxe Scheme dans LilyPond}.
889 @node Saisie de variables et Scheme
890 @subsection Saisie de variables et Scheme
891 @translationof Input variables and Scheme
893 Le format de saisie prend en charge la notion de variable -- ou
894 identificateur. Dans l'exemple suivant, une expression musicale se voit
895 attribuer un identificateur qui portera le nom de @code{traLaLa}.
898 traLaLa = @{ c'4 d'4 @}
903 Une variable a aussi une portée. Dans l'exemple suivant, le bloc
904 @code{\layout} contient une variable @code{traLaLa} tout à fait
905 indépendante de l'autre @code{\traLaLa}.
908 traLaLa = @{ c'4 d'4 @}
909 \layout @{ traLaLa = 1.0 @}
912 Dans les faits, chaque fichier a un domaine de compétence, et les
913 différents blocs @code{\header}, @code{\midi} et @code{\layout} ont leur
914 propre champ de compétence, imbriqué dans ce domaine principal.
916 Variables et champs de compétence sont implémentés par le système de
917 modules de Guile. Un module anonyme Scheme est attaché à chacun de ces
918 domaines. Une assertion telle que
921 traLaLa = @{ c'4 d'4 @}
925 est convertie, en interne, en une définition Scheme :
928 (define traLaLa @var{valeur Scheme de `@code{@dots{}}'})
931 Cela signifie que variables LilyPond et variables Scheme peuvent tout à
932 fait se mélanger. Dans l'exemple suivant, un fragment musical est
933 stocké dans la variable @code{traLaLa} puis dupliqué à l'aide de Scheme.
934 Le résultat est alors importé dans un bloc @code{\score} au moyen d'une
935 seconde variable @code{twice}.
938 traLaLa = { c'4 d'4 }
940 #(define newLa (map ly:music-deep-copy
941 (list traLaLa traLaLa)))
943 (make-sequential-music newLa))
948 @c Due to parser lookahead
950 Cet exemple est particulièrement intéressant. L'assignation
951 n'interviendra qu'une fois que l'analyseur grammatical aura l'assurance
952 que rien du type de @code{\addlyrics} ne suit ; il doit donc
953 vérifier ce qui vient après. Le @emph{parser} lit le @code{#} et
954 l'expression Scheme qui le suit @strong{sans} l'évaluer, de telle sorte
955 qu'il peut procéder à l'assignation, et @strong{ensuite} exécuter le
956 code Scheme sans problème.
959 @node Import de code Scheme dans LilyPond
960 @subsection Import de code Scheme dans LilyPond
961 @translationof Importing Scheme in LilyPond
966 L'exemple précédent illustre la manière « d'exporter » une expression
967 musicale à partir des saisies et à destination de l'interpréteur Scheme.
968 L'inverse est aussi réalisable : en la plaçant derrière un @code{$}, une
969 valeur Scheme sera interprétée comme si elle avait été saisie en
970 syntaxe LilyPond. Au lieu de définir @code{\twice}, nous aurions tout
975 $(make-sequential-music (list newLa))
978 Vous pouvez utiliser @code{$} suivi d'une expression Scheme partout où
979 vous auriez utilisé @code{\@var{nom}}, dès lors que vous aurez assigné à
980 cette expression Scheme le nom de variable @var{nom}. La substitution
981 intervenant au niveau de l'analyseur lexical (le @emph{lexer}), LilyPond
982 ne saurait faire la différence.
984 Cette manière de procéder comporte cependant un inconvénient au niveau
985 de la temporisation. Si nous avions défini @code{newLa} avec un
986 @code{$} plutôt qu'un @code{#}, la définition Scheme suivante aurait
987 échoué du fait que @code{traLaLa} n'était pas encore défini. Pour plus
988 d'information quant au problème de synchronisation, voir la rubrique
989 @ref{Syntaxe Scheme dans LilyPond}.
994 Une autre façon de procéder serait de recourir aux « colleurs de liste »
995 @code{$@@} et @code{#@@} dont la fonction est d'insérer les éléments
996 d'une liste dans le contexte environnant. Grâce à ces opérateurs, la
997 dernière partie de notre fonction pourrait s'écrire ainsi :
1004 Ici, chaque élément de la liste stockée dans @code{newLa} est pris à
1005 son tour et inséré dans la liste, tout comme si nous avions écrit
1008 @{ #(premier newLa) #(deuxième newLa) @}
1011 Dans ces deux dernières formes, le code Scheme est évalué alors même que
1012 le code initial est en cours de traitement, que ce soit par le
1013 @emph{lexer} ou par le @emph{parser}. Si le code Scheme ne doit être
1014 exécuté que plus tard, consultez la rubrique
1015 @ref{Fonctions Scheme fantômes}, ou stockez le dans une procédure comme
1020 (ly:set-option 'point-and-click #f))
1028 L'imbrication de variables Scheme et LilyPond n'est pas possible
1029 avec l'option @option{--safe}.
1032 @node Propriétés des objets
1033 @subsection Propriétés des objets
1034 @translationof Object properties
1036 Les propriétés des objets sont stockées dans LilyPond sous la forme
1037 d'enchaînements de listes associatives, autrement dit des listes de
1038 listes associatives. Une propriété se détermine par l'ajout de valeurs
1039 en début de liste de cette propriété. Les caractéristiques d'une
1040 propriété s'ajustent donc à la lecture des différentes valeurs des
1041 listes associatives.
1043 La modification d'une valeur pour une propriété donnée requiert
1044 l'assignation d'une valeur de la liste associative, tant pour la clé que
1045 pour la valeur associée. Voici comment procéder selon la syntaxe de
1049 \override Stem.thickness = #2.6
1052 Cette instruction ajuste l'apparence des hampes. Une entrée
1053 @w{@code{'(thickness . 2.6)}} de la @emph{alist} est ajoutée à la liste
1054 de la propriété de l'objet @code{Stem}. @code{thickness} devant
1055 s'exprimer en unité d'épaisseur de ligne, les hampes auront donc une
1056 épaisseur de 2,6 ligne de portée, et à peu près le double de leur
1057 épaisseur normale. Afin de faire la distinction entre les variables que
1058 vous définissez au fil de vos fichiers -- tel le @code{vingtQuatre} que
1059 nous avons vu plus haut -- et les variables internes des objets, nous
1060 parlerons de « propriétés » pour ces dernières, et de « variables »
1061 pour les autres. Ainsi, l'objet hampe possède une propriété
1062 @code{thickness}, alors que @code{vingtQuatre} est une variable.
1064 @cindex propriétés ou variables
1065 @cindex variables ou propriétés
1067 @c todo -- here we're getting interesting. We're now introducing
1068 @c LilyPond variable types. I think this deserves a section all
1072 @node Variables LilyPond composites
1073 @subsection Variables LilyPond composites
1074 @translationof LilyPond compound variables
1077 * Décalages (offsets)::
1079 * Étendues (extents)::
1080 * Propriété en alists::
1085 @node Décalages (offsets)
1086 @unnumberedsubsubsec Décalages (@emph{offsets})
1087 @translationof Offsets
1089 Les décalages (@emph{offset}) sur deux axes (coordonnées X et Y) sont
1090 stockés sous forme de @emph{paires}. Le @code{car} de l'offset
1091 correspond à l'abscisse (coordonnée X) et le @code{cdr} à l'ordonnée
1095 \override TextScript.extra-offset = #'(1 . 2)
1098 Cette clause affecte la paire @code{(1 . 2)} à la propriété
1099 @code{extra-offset} de l'objet @code{TextScript}. Ces nombres sont
1100 exprimés en espace de portée. La commande aura donc pour effet de
1101 déplacer l'objet d'un espace de portée vers la droite, et de deux
1102 espaces vers le haut.
1104 Les procédures permettant de manipuler les offsets sont regroupées dans
1105 le fichier @file{scm/lily-library.scm}.
1109 @unnumberedsubsubsec Fractions
1110 @translationof Fractions
1112 Les fractions, telles que LilyPond les utilise, sont aussi stockées sous
1113 forme de @emph{paire}. Alors que Scheme est tout à fait capable de
1114 représenter des nombres rationnels, vous conviendrez que, musicalement
1115 parlant, @samp{2/4} et @samp{1/2} ne se valent pas ; nous devrons
1116 donc pouvoir les distinguer. Dans le même ordre d'idée, LilyPond ne
1117 connaît pas les « fractions » négatives. Pour ces raisons, @code{2/4}
1118 en LilyPond correspond à @code{(2 . 4)} en Scheme, et @code{#2/4} en
1119 LilyPond correspond à @code{1/2} en Scheme.
1122 @node Étendues (extents)
1123 @unnumberedsubsubsec Étendues (@emph{extents})
1124 @translationof Extents
1126 Les paires permettent aussi de stocker des intervalles qui représentent
1127 un ensemble de nombres compris entre un minimum (le @code{car}) et un
1128 maximum (le @code{cdr}). Ces intervalles stockent l'étendue, tant au
1129 niveau horizontal (X) que vertical (Y) des objets imprimables. En
1130 matière d'étendue sur les X, le @code{car} correspond à la coordonnée de
1131 l'extrémité gauche, et le @code{cdr} à la coordonnée de l'extrémité
1132 droite. En matière d'étendue sur les Y, le @code{car} correspond à la
1133 coordonnée de l'extrémité basse, et le @code{cdr} à la coordonnée de
1136 Les procédures permettant de manipuler les offsets sont regroupées dans
1137 le fichier @file{scm/lily-library.scm}. Nous vous recommandons
1138 l'utilisation de ces procédures dans toute la mesure du possible afin
1139 d'assurer la cohérence du code.
1142 @node Propriété en alists
1143 @unnumberedsubsubsec Propriété en @emph{alists}
1144 @translationof Property alists
1146 Les propriétés en @emph{alists} sont des structures de données
1147 particulières à LilyPond. Il s'agit de listes associatives dont les
1148 clés sont des propriétés et les valeurs des expressions Scheme
1149 fournissant la valeur requise pour cette propriété.
1151 Les propriétés LilyPond sont des symboles Scheme, à l'instar de
1155 @node Chaînes d'alist
1156 @unnumberedsubsubsec Chaînes d'@emph{alist}
1157 @translationof Alist chains
1159 Une chaîne d'@emph{alist} est une liste contenant les listes
1160 associatives d'une propriété.
1162 L'intégralité du jeu de propriétés qui doivent s'appliquer à un objet
1163 graphique est en fait stocké en tant que chaîne d'@emph{alist}. Afin
1164 d'obtenir la valeur d'une propriété particulière qu'un objet graphique
1165 devrait avoir, on examinera chacune des listes associatives de la
1166 chaîne, à la recherche d'une entrée contenant la clé de cette propriété.
1167 Est renvoyée la première entrée d'@emph{alist} trouvée, sa valeur étant
1168 la valeur de la propriété.
1170 L'obtention des valeurs de propriété des objets graphiques se réalise en
1171 principe à l'aide de la procédure Scheme @code{chain-assoc-get}.
1174 @node Représentation interne de la musique
1175 @subsection Représentation interne de la musique
1176 @translationof Internal music representation
1178 Dans les entrailles du programme, la musique se présente comme une liste
1179 Scheme. Cette liste comporte les différents éléments qui affecteront la
1180 sortie imprimable. L'analyse grammaticale (l'opération @emph{parsing})
1181 est le processus chargé de convertir la musique représentée par le code
1182 LilyPond en présentation interne Scheme.
1184 L'analyse d'une expression musicale se traduit par un jeu d'objets
1185 musicaux en Scheme. Une objet musical est déterminé par le temps qu'il
1186 occupe, que l'on appelle @emph{durée}. Les durées s'expriment par des
1187 nombres rationnels représentant la longueur d'un objet musical par
1190 Un objet musical dispose de trois types :
1193 un nom de musique : toute expression musicale a un nom. Par exemple,
1194 une note amène à un @rinternals{NoteEvent}, un @code{\simultaneous} à un
1195 @rinternals{SimultaneousMusic}. Une liste exhaustive des différentes
1196 expressions est disponible dans la référence des propriétés internes, à
1197 la rubrique @rinternals{Music expressions}.
1200 un « type » ou interface : tout nom de musique dispose de
1201 plusieurs types ou interfaces. Ainsi, une note est tout à la fois un
1202 @code{event}, un @code{note-event}, un @code{rhythmic-event} et un
1203 @code{melodic-event}. Les différentes classes musicales sont
1204 répertoriées à la rubrique @rinternals{Music classes} de la référence
1205 des propriétés internes.
1208 un objet C++ : tout objet musical est représenté par un objet de la
1209 classe C++ @code{Music}.
1212 L'information réelle d'une expression musicale est enregistrée sous
1213 forme de propriétés. Par exemple, un @rinternals{NoteEvent} dispose des
1214 propriétés @code{pitch} et @code{duration}, respectivement chargées de
1215 stocker la hauteur et la durée de cette note. Les différentes
1216 propriétés sont répertoriées à la rubrique @rinternals{Music properties}
1217 de la référence des propriétés internes.
1219 Une expression composite est un objet musical dont les propriétés
1220 contiennent d'autres objets musicaux. S'il s'agit d'une liste d'objets,
1221 elle sera stockée dans la propriété @code{elements} d'un objet
1222 musical ; s'il n'y a qu'un seul objet « enfant », il sera stocké
1223 dans la propriété @code{element}. Ainsi, par exemple, les enfants de
1224 @rinternals{SequentialMusic} iront dans @code{elements}, alors que
1225 l'argument unique de @rinternals{GraceMusic} ira dans @code{element}.
1226 De même, le corps d'une répétition ira dans la propriété @code{element}
1227 d'un @rinternals{RepeatedMusic}, les alternatives quant à elles dans la
1228 propriété @code{elements}.
1231 @node Construction de fonctions complexes
1232 @section Construction de fonctions complexes
1233 @translationof Building complicated functions
1235 Nous allons voir dans cette partie les moyens dont vous disposez pour
1236 obtenir les informations qui vous permettront de créer vos propres
1237 fonctions musicales complexes.
1240 * Affichage d'expressions musicales::
1241 * Propriétés musicales::
1242 * Doublement d'une note avec liaison (exemple)::
1243 * Ajout d'articulation à des notes (exemple)::
1247 @node Affichage d'expressions musicales
1248 @subsection Affichage d'expressions musicales
1249 @translationof Displaying music expressions
1251 @cindex stockage interne
1252 @cindex expression musicale, affichage
1253 @cindex représentation interne, affichage
1254 @cindex displayMusic
1255 @funindex \displayMusic
1257 Lorsque l'on veut écrire une fonction musicale, il est intéressant
1258 d'examiner comment une expression musicale est représentée en interne.
1259 Vous disposez à cet effet de la fonction musicale @code{\displayMusic}.
1263 \displayMusic @{ c'4\f @}
1278 'AbsoluteDynamicEvent
1282 (ly:make-duration 2 0 1/1)
1284 (ly:make-pitch 0 0 0))))
1287 Par défaut, LilyPond affichera ces messages sur la console, parmi toutes
1288 les autres informations. Vous pouvez, afin de les isoler et de garder
1289 le résultat des commandes @code{\display@{TRUC@}}, spécifier un
1290 port optionnel à utiliser pour la sortie :
1294 \displayMusic #(open-output-file "display.txt") @{ c'4\f @}
1298 Ceci aura pour effet d'écraser tout fichier précédemment généré.
1299 Lorsque plusieurs expressions doivent être retranscrites, il suffit de
1300 faire appel à une variable pour le port puis de la réutiliser :
1304 port = #(open-output-file "display.txt")
1305 \displayMusic \port @{ c'4\f @}
1306 \displayMusic \port @{ d'4 @}
1307 #(close-output-port port)
1311 La documentation de Guile fournit une description détaillée des ports.
1312 Clôturer un port n'est requis que si vous désirez consulter le fichier
1313 avant que LilyPond n'ait fini, ce dont nous ne nous sommes pas préoccupé
1314 dans le premier exemple.
1316 L'information sera encore plus lisible après un peu de mise en forme :
1319 (make-music 'SequentialMusic
1321 (make-music 'NoteEvent
1322 'articulations (list
1323 (make-music 'AbsoluteDynamicEvent
1326 'duration (ly:make-duration 2 0 1/1)
1327 'pitch (ly:make-pitch 0 0 0))))
1330 Une séquence musicale @code{@{ @dots{} @}} se voit attribuer le nom de
1331 @code{SequentialMusic}, et les expressions qu'elle contient sont
1332 enregistrées en tant que liste dans sa propriété @code{'elements}. Une
1333 note est représentée par un objet @code{NoteEvent} -- contenant les
1334 propriétés de durée et hauteur -- ainsi que l'information qui lui est
1335 attachée -- en l'occurrence un @code{AbsoluteDynamicEvent} ayant une
1336 propriété @code{text} de valeur @code{"f"} -- et stockée dans sa
1337 propriété @code{articulations}.
1340 La fonction @code{\displayMusic} renvoie la musique qu'elle
1341 affiche ; celle-ci sera donc aussi interprétée. L'insertion d'une
1342 commande @code{\void} avant le @code{\displayMusic} permet de
1343 s'affranchir de la phase d'interprétation.
1346 @node Propriétés musicales
1347 @subsection Propriétés musicales
1348 @translationof Music properties
1350 Nous abordons ici les propriétés @emph{music}, et non pas les propriétés
1351 @emph{context} ou @emph{layout}.
1353 Partons de cet exemple simple :
1357 \displayMusic \someNote
1362 (ly:make-duration 2 0 1/1)
1364 (ly:make-pitch 0 0 0))
1367 L'objet @code{NoteEvent} est la représentation brute de @code{someNote}.
1368 Voyons ce qui se passe lorsque nous plaçons ce @notation{c'} dans une
1369 construction d'accord :
1373 \displayMusic \someNote
1381 (ly:make-duration 2 0 1/1)
1383 (ly:make-pitch 0 0 0))))
1386 L'objet @code{NoteEvent} est maintenant le premier objet de la propriété
1387 @code{'elements} de @code{someNote}.
1389 @code{\displayMusic} utilise la fonction @code{display-scheme-music}
1390 pour afficher la représentation en Scheme d'une expression musicale :
1393 #(display-scheme-music (first (ly:music-property someNote 'elements)))
1398 (ly:make-duration 2 0 1/1)
1400 (ly:make-pitch 0 0 0))
1403 La hauteur de la note est accessible au travers de la propriété
1404 @code{'pitch} de l'objet @code{NoteEvent} :
1407 #(display-scheme-music
1408 (ly:music-property (first (ly:music-property someNote 'elements))
1411 (ly:make-pitch 0 0 0)
1414 La hauteur de la note se modifie en définissant sa propriété
1417 @funindex \displayLilyMusic
1420 #(set! (ly:music-property (first (ly:music-property someNote 'elements))
1422 (ly:make-pitch 0 1 0)) ;; set the pitch to d'.
1423 \displayLilyMusic \someNote
1429 @node Doublement d'une note avec liaison (exemple)
1430 @subsection Doublement d'une note avec liaison (exemple)
1431 @translationof Doubling a note with slurs (example)
1433 Supposons que nous ayons besoin de créer une fonction transformant une
1434 saisie @code{a} en @w{@code{@{ a( a) @}}}. Commençons par examiner
1435 comment le résultat est représenté en interne.
1438 \displayMusic@{ a'( a') @}
1451 (ly:make-duration 2 0 1/1)
1453 (ly:make-pitch 0 5 0))
1462 (ly:make-duration 2 0 1/1)
1464 (ly:make-pitch 0 5 0))))
1467 Mauvaise nouvelle ! Les expressions @code{SlurEvent} doivent
1468 s'ajouter « à l'intérieur » de la note -- dans sa propriété
1469 @code{articulations}.
1471 Examinons à présent la saisie :
1479 (ly:make-duration 2 0 1/1)
1481 (ly:make-pitch 0 5 0))))
1484 Nous aurons donc besoin, dans notre fonction, de cloner cette expression
1485 -- de telle sorte que les deux notes constituent la séquence -- puis
1486 d'ajouter un @code{SlurEvent} à la propriété @code{'articulations} de
1487 chacune d'elles, et enfin réaliser un @code{SequentialMusic} de ces deux
1488 éléments @code{NoteEvent}. En tenant compte du fait que, dans le cadre
1489 d'un ajout, une propriété non définie est lue @code{'()} (une liste
1490 vide), aucune vérification n'est requise avant d'introduire un nouvel
1491 élément en tête de la propriété @code{articulations}.
1494 doubleSlur = #(define-music-function (note) (ly:music?)
1495 "Renvoie : @{ note ( note ) @}.
1496 `note' est censé être une note unique."
1497 (let ((note2 (ly:music-deep-copy note)))
1498 (set! (ly:music-property note 'articulations)
1499 (cons (make-music 'SlurEvent 'span-direction -1)
1500 (ly:music-property note 'articulations)))
1501 (set! (ly:music-property note2 'articulations)
1502 (cons (make-music 'SlurEvent 'span-direction 1)
1503 (ly:music-property note2 'articulations)))
1504 (make-music 'SequentialMusic 'elements (list note note2))))
1508 @node Ajout d'articulation à des notes (exemple)
1509 @subsection Ajout d'articulation à des notes (exemple)
1510 @translationof Adding articulation to notes (example)
1512 Le moyen d'ajouter une articulation à des notes consiste à fusionner
1513 deux expressions musicales en un même contexte. L'option de réaliser
1514 nous-mêmes une fonction musicale à cette fin nous offre l'avantage de
1515 pouvoir alors ajouter une articulation, telle qu'une instruction de
1516 doigté, individuellement à l'une des notes d'un accord, ce qui est
1517 impossible dans le cadre d'une simple fusion de musique indépendante.
1519 Un @code{$variable} au milieu de la notation @code{#@{ @dots{} #@}} se
1520 comporte exactement comme un banal @code{\variable} en notation LilyPond
1521 traditionnelle. Nous savons déjà que
1524 @{ \musique -. -> @}
1528 n'est pas admis par LilyPond. Nous pourrions tout à fait contourner ce
1529 problème en attachant l'articulation à un accord vide,
1532 @{ << \musique <> -. -> >> @}
1536 mais, pour les besoins de la démonstration, nous allons voir comment
1537 réaliser ceci en Scheme. Commençons par examiner une saisie simple et
1538 le résultat auquel nous désirons aboutir :
1547 (ly:make-duration 2 0 1/1)
1549 (ly:make-pitch -1 0 0))))
1562 (ly:make-duration 2 0 1/1)
1564 (ly:make-pitch -1 0 0))
1567 Nous voyons qu'une note (@code{c4}) est représentée par une expression
1568 @code{NoteEvent}. Si nous souhaitons ajouter une articulation
1569 @notation{accent}, nous devrons ajouter une expression
1570 @code{ArticulationEvent} à la propriété @code{articulations} de
1571 l'expression @code{NoteEvent}.
1573 Construisons notre fonction en commençant par
1576 (define (ajoute-accent note-event)
1577 "Ajoute un accent (ArticulationEvent) aux articulations de `note-event',
1578 qui est censé être une expression NoteEvent."
1579 (set! (ly:music-property note-event 'articulations)
1580 (cons (make-music 'ArticulationEvent
1581 'articulation-type "accent")
1582 (ly:music-property note-event 'articulations)))
1586 La première ligne est la manière de définir une fonction en Scheme : la
1587 fonction Scheme a pour nom @code{ajoute-accent} et elle comporte une
1588 variable appelée @code{note-event}. En Scheme, le type d'une variable
1589 se déduit la plupart de temps de par son nom -- c'est d'ailleurs une
1590 excellente pratique que l'on retrouve dans de nombreux autres langages.
1593 "Ajoute un accent@dots{}"
1597 décrit ce que fait la fonction. Bien que ceci ne soit pas primordial,
1598 tout comme des noms de variable évidents, tâchons néanmoins de prendre
1599 de bonnes habitudes dès nos premiers pas.
1601 Vous pouvez vous demander pourquoi nous modifions directement
1602 l'événement note plutôt que d'en manipuler une copie -- on pourrait
1603 utiliser @code{ly:music-deep-copy} à cette fin. La raison en est qu'il
1604 existe un contrat tacite : les fonctions musicales sont autorisées
1605 à modifier leurs arguments -- ils sont générés en partant de zéro (comme
1606 les notes que vous saisissez) ou déjà recopiés (faire référence à une
1607 variable musicale avec @samp{\name} ou à de la musique issue
1608 d'expressions Scheme @samp{$(@dots{})} aboutit à une copie). Dans la
1609 mesure où surmultiplier les copies serait contre productif, la valeur de
1610 retour d'une fonction musicale n'est @strong{pas} recopiée. Afin de
1611 respecter ce contrat, n'utilisez pas un même argument à plusieurs
1612 reprises, et n'oubliez pas que le retourner compte pour une utilisation.
1614 Dans un exemple précédent, nous avons construit de la musique en
1615 répétant un certain argument musical. Dans ce cas là, l'une des
1616 répétitions se devait d'être une copie. Dans le cas contraire,
1617 certaines bizarreries auraient pu survenir. Par exemple, la présence
1618 d'un @code{\relative} ou d'un @code{\transpose}, après plusieurs
1619 répétitions du même élément, entraînerait des « relativisations » ou
1620 transpositions en cascade. Si nous les assignons à une variable
1621 musicale, l'enchaînement est rompu puisque la référence à @samp{\nom}
1622 créera une nouvelle copie sans toutefois prendre en considération
1623 l'identité des éléments répétés.
1625 Cette fonction n'étant pas une fonction musicale à part entière, elle
1626 peut s'utiliser dans d'autres fonctions musicales. Il est donc sensé de
1627 respecter le même contrat que pour les fonctions musicales :
1628 l'entrée peut être modifiée pour arriver à une sortie, et il est de la
1629 responsabilité de l'appelant d'effectuer des copies s'il a réellement
1630 besoin de l'argument dans son état originel. Vous constaterez, à la
1631 lecture des fonctions propres à LilyPond, comme @code{music-map}, que ce
1632 principe est toujours respecté.
1634 Revenons à nos moutons… Nous disposons maintenant d'un @code{note-event}
1635 que nous pouvons modifier, non pas grâce à un @code{ly:music-deep-copy},
1636 mais plutôt en raison de notre précédente réflexion. Nous ajoutons
1637 @notation{l'accent} à la liste de ses propriétés @code{'articulations}.
1640 (set! emplacement nouvelle-valeur)
1643 L'emplacement est ce que nous voulons ici définir. Il s'agit de la
1644 propriété @code{'articulations} de l'expression @code{note-event}.
1647 (ly:music-property note-event 'articulations)
1650 La fonction @code{ly:music-property} permet d'accéder aux propriétés
1651 musicales -- les @code{'articulations}, @code{'duration}, @code{'pitch},
1652 etc. que @code{\displayMusic} nous a indiquées. La nouvelle valeur sera
1653 l'ancienne propriété @code{'articulations}, augmentée d'un
1654 élément : l'expression @code{ArticulationEvent}, que nous
1655 recopions à partir des informations de @code{\displayMusic}.
1658 (cons (make-music 'ArticulationEvent
1659 'articulation-type "accent")
1660 (ly:music-property result-event-chord 'articulations))
1663 @code{cons} permet d'ajouter un élément en tête de liste sans pour
1664 autant modifier la liste originale. C'est exactement ce que nous
1665 recherchons : la même liste qu'auparavant, plus la nouvelle
1666 expression @code{ArticulationEvent}. L'ordre au sein de la propriété
1667 @code{'articulations} n'a ici aucune importance.
1669 Enfin, après avoir ajouté l'articulation @notation{accent} à sa
1670 propriété @code{articulations}, nous pouvons renvoyer le
1671 @code{note-event}, ce que réalise la dernière ligne de notre fonction.
1673 Nous pouvons à présent transformer la fonction @code{ajoute-accent} en
1674 fonction musicale, à l'aide d'un peu d'enrobage syntaxique et mention du
1675 type de son argument.
1678 ajouteAccent = #(define-music-function (note-event)
1680 "Ajoute un accent (ArticulationEvent) aux articulations de `note-event',
1681 qui est censé être une expression NoteEvent."
1682 (set! (ly:music-property note-event 'articulations)
1683 (cons (make-music 'ArticulationEvent
1684 'articulation-type "accent")
1685 (ly:music-property note-event 'articulations)))
1689 Par acquis de conscience, vérifions que tout ceci fonctione :
1692 \displayMusic \ajouteAccent c4
1699 * Tweaking with Scheme::
1702 @c @nod e Tweaking with Scheme
1703 @c @sectio n Tweaking with Scheme
1705 We have seen how LilyPond output can be heavily modified using
1707 @code{\override TextScript.extra-offset = ( 1 . -1)}. But
1708 we have even more power if we use Scheme. For a full explanation
1709 of this, see the @ref{Scheme tutorial}, and
1710 @ref{Interfaces for programmers}.
1712 We can use Scheme to simply @code{\override} commands,
1714 TODO Find a simple example
1715 @c This isn't a valid example with skylining
1716 @c It works fine without padText -td
1720 @lilypond[quote,verbatim,ragged-right]
1721 padText = #(define-music-function (padding) (number?)
1723 \once \override TextScript.padding = #padding
1727 c'''4^"piu mosso" b a b
1729 c4^"piu mosso" d e f
1731 c4^"piu mosso" fis a g
1737 We can use it to create new commands:
1739 @c Check this is a valid example with skylining
1740 @c It is - 'padding still works
1743 @lilypond[quote,verbatim,ragged-right]
1744 tempoPadded = #(define-music-function (padding tempotext)
1747 \once \override Score.MetronomeMark.padding = #padding
1748 \tempo \markup { \bold #tempotext }
1752 \tempo \markup { "Low tempo" }
1754 \tempoPadded #4.0 "High tempo"
1760 Even music expressions can be passed in:
1762 @lilypond[quote,verbatim,ragged-right]
1763 pattern = #(define-music-function (x y) (ly:music? ly:music?)
1770 \pattern {d16 dis} { ais16-> b\p }