1@c -*- coding: utf-8; mode: texinfo; documentlanguage: fr -*-
2
3@ignore
4   Translation of GIT committish: 529eb23f3ddb597ae0738685d194cb88b4733054
5
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..
9@end ignore
10
11@c \version "2.19.24"
12
13@c Translators: Valentin Villenave, Jean-Charles Malahieude
14@c Translation checkers: Gilles Thibault
15
16
17@node Interfaces pour programmeurs
18@chapter Interfaces pour programmeurs
19@translationof Interfaces for programmers
20
21Scheme permet de réaliser des affinages très pointus.  Si vous ne
22connaissez rien de Scheme, vous en aurez un aperçu au travers de notre
23@ref{Tutoriel Scheme}.
24
25@menu
26* Blocs de code LilyPond::
27* Fonctions Scheme::
28* Fonctions musicales::
29* Fonctions événementielles::
30* Fonctions pour markups::
31* Contextes pour programmeurs::
32* Fonctions de rappel::
33* Retouches complexes::
34@end menu
35
36
37@node Blocs de code LilyPond
38@section Blocs de code LilyPond
39@translationof LilyPond code blocks
40
41@cindex code, blocs LilyPond
42@cindex LilyPond, bloc de code
43
44@funindex #@{ ... #@}
45@funindex $
46@funindex #
47
48L'utilisation de Scheme pour créer des expressions musicales peut
49s'avérer ardue, principalement à cause des imbrications et de la
50longueur du code Scheme qui en résulte.  Dans le cas de tâches
51simples, on peut toutefois contourner une partie du problème en
52utilisant des blocs de code LilyPond, ce qui autorise la syntaxe
53habituelle de LilyPond au sein même de Scheme.
54
55Les blocs de code LilyPond ressemblent à
56
57@example
58  #@{ @var{du code LilyPond} #@}
59@end example
60
61En voici un exemple basique :
62
63@lilypond[verbatim,quote]
64ritpp = #(define-event-function () ()
65  #{ ^"rit." \pp #}
66)
67
68{ c'4 e'4\ritpp g'2 }
69@end lilypond
70
71Les blocs de code LilyPond peuvent s'utiliser partout où vous pouvez
72écrire du code Scheme.  Le lecteur Scheme est en fait quelque peu adapté
73pour accepter des blocs de code LilyPond ; il est capable de traiter des
74expressions Scheme intégrées débutant par @code{$} ou @code{#}.
75
76Le lecteur Scheme extrait le bloc de code LilyPond et déclenche un appel
77à l'analyseur grammatical de LilyPond (le @emph{parser}) qui réalise en
78temps réel l'interprétation de ce bloc de code LilyPond.  Toute
79expression Scheme imbriquée est exécutée dans l'environnement lexical du
80bloc de code LilyPond, de telle sorte que vous avez accès aux variables
81locales et aux paramètres de la fonction au moment même où le bloc de
82code LilyPond est écrit.  Les variables définies dans d'autres modules
83Scheme, tels ceux contenant les blocs @code{\header} ou @code{\layout},
84ne sont pas accessibles en tant que variables Scheme (préfixées par
85un @code{#}) mais en tant que variables LilyPond (préfixées par
86un @code{\}).
87
88Toute la musique générée au sein de ce bloc de code voit son
89@code{origine} établie à cet @emph{emplacement}.
90
91Un bloc de code LilyPond peut contenir tout ce que vous pourriez mettre
92à droite de l'assignation.  Par ailleurs, un bloc LilyPond vide
93correspond à une expression fantôme, et un bloc LilyPond de multiples
94événements musicaux sera transformé en une expression de musique
95séquentielle.
96
97
98@node Fonctions Scheme
99@section Fonctions Scheme
100@translationof Scheme functions
101
102@cindex Scheme, fonctions (syntaxe LilyPond)
103
104Les @emph{fonctions Scheme} sont des procédures Scheme chargées de créer
105des expressions Scheme à partir de code rédigé selon la syntaxe de
106LilyPond.  Elles peuvent être appelées en de nombreux endroits, à l'aide
107d'un @code{#}, où spécifier une valeur en syntaxe Scheme est autorisé.
108Bien que Scheme dispose de fonctions en propre, nous nous intéresserons,
109au fil des paragraphes qui suivent, aux fonctions @emph{syntaxiques},
110autrement dit des fonctions qui reçoivent des arguments libellés dans la
111syntaxe de LilyPond.
112
113@menu
114* Définition de fonctions Scheme::
115* Utilisation de fonctions Scheme::
116* Fonctions Scheme fantômes::
117@end menu
118
119
120@node Définition de fonctions Scheme
121@subsection Définition de fonctions Scheme
122@translationof Scheme function definitions
123
124@funindex define-scheme-function
125
126D'une manière générale, une fonction Scheme se définit ainsi :
127
128@example
129fonction =
130#(define-scheme-function
131     (@var{arg1} @var{arg2}@dots{})
132     (@var{type1?} @var{type2?}@dots{})
133   @var{corps})
134@end example
135
136@noindent
137138
139@multitable @columnfractions .33 .66
140@item @code{@var{argN}}
141@tab @var{n}-ième argument.
142
143@item @code{@var{typeN?}}
144@tab un @emph{type de prédicat} Scheme pour lequel @code{@var{argN}}
145devra retourner @code{#t}.  Il existe aussi une forme spécifique --
146@code{(@emph{prédicat?} @emph{default})} -- qui permet de fournir des
147argument optionnels.  En l'absence d'argument réel au moment de l'appel
148à la fonction, c'est la valeur par défaut qui lui sera substituée.  Les
149valeurs par défaut sont évaluées dès l'apparition de la définition, y
150compris dans le cas de blocs de code LilyPond ; vous devrez donc,
151si ces valeurs par défaut ne peuvent être déterminées que plus tard,
152mentionner une valeur spéciale que vous reconnaîtrez facilement.
153Lorsque vous mentionnez un prédicat entre parenthèses sans toutefois
154fournir sa valeur par défaut, celle-ci sera considérée comme
155étant @code{#f}.  Les valeurs par défaut d'un @code{prédicat?} ne sont
156vérifiées ni au moment de la définition, ni à l'exécution ; il est
157de votre ressort de gérer les valeurs que vous spécifiez.  Une valeur
158par défaut constituée d'une expression musicale est recopiée dès la
159définition de @code{origin} à l'emplacement courant du code.
160
161@item @code{@var{corps}}
162@tab une séquence de formules Scheme évaluées dans l'ordre, la dernière
163servant de valeur de retour de la fonction. Il peut contenir des blocs
164de code LilyPond, enchâssés dans des accolades et @emph{hashes} --
165@w{@code{#@{@dots{}#@}}} -- comme indiqué à la rubrique
166@ref{Blocs de code LilyPond}.  Au sein d'un bloc de code LilyPond, un
167@code{#} permet de référencer des arguments de la fonction -- tel
168@samp{#arg1} -- ou d'ouvrir une expression Scheme contenant les
169arguments de la fonction -- par exemple @w{@samp{#(cons arg1 arg2)}}.
170Dans le cas où une expression Scheme introduite par @code{#} ne vous
171permet pas de parvenir à vos fins, vous pourriez devoir revenir à une
172expression Scheme « immédiate » à l'aide d'un @code{$}, comme
173@samp{$music}.
174
175Lorsque votre fonction retourne une expression musicale, lui est
176attribuée la valeur @code{origin}.
177@end multitable
178
179@noindent
180La recevabilité des arguments est déterminée par un appel effectif au
181prédicat après que LilyPond les a déjà convertis en expression Scheme.
182Par voie de conséquence, l'argument peut tout à fait se libeller en
183syntaxe Scheme -- introduite par un @code{#} ou en tant que résultat
184d'un appel à une fonction Scheme.  Par ailleurs, LilyPond convertira en
185Scheme un certain nombre de constructions purement LilyPond avant même
186d'en avoir vérifié le prédicat.  C'est notamment le cas de la musique,
187des @emph{postévénements}, des chaînes simples (avec ou sans
188guillemets), des nombres, des @emph{markups} et listes de
189@emph{markups}, ainsi que des blocs @emph{score}, @emph{book},
190@emph{bookpart}, ou qui définissent un contexte ou un format de sortie.
191
192Il existe certaines situations pour lesquelles LilyPond lèvera toute
193ambiguïté grâce aux fonctions de prédicat : un @samp{-3} est-il un
194@emph{postévénement} de type doigté ou un nombre négatif ?  Un
195@code{"a" 4} en mode paroles est-il une chaîne suivie d'un nombre ou
196bien un événement syllabe de durée @code{4} ?  LilyPond répondra à ces
197questions par des interprétations successives du prédicat de l'argument,
198dans un ordre défini de sorte à minimiser les interprétations erronées
199et le besoin de lecture en avance.
200
201Un prédicat qui accepte par exemple aussi bien une expression musicale
202qu'une hauteur considèrera @code{c''} comme étant une hauteur plutôt
203qu'une expression musicale.  Les durées ou @emph{postévénements} qui
204viennent juste après viendront modifier cette interprétation.  C'est la
205raison pour laquelle il vaut mieux éviter des prédicats par trop
206permissifs tel que @code{Scheme?} lorsque l'application fait plutôt
207appel à des types d'argument plus spécifiques.
208
209Les différents types de prédicat propres à LilyPond sont recensés à
210l'annexe @ruser{Types de prédicats prédéfinis}.
211
212@morerefs
213Manuel de notation :
214@ruser{Types de prédicats prédéfinis}.
215
216Fichiers d'initialisation :
217@file{lily/music-scheme.cc},
218@file{scm/c++.scm},
219@file{scm/lily.scm}.
220
221
222@node Utilisation de fonctions Scheme
223@subsection Utilisation de fonctions Scheme
224@translationof Scheme function usage
225
226Vous pouvez appeler une fonction Scheme pratiquement partout où une
227expression Scheme derrière un @code{#} peut prendre place.  Vous appelez
228une fonction Scheme à partir de LilyPond en faisant précéder son nom
229d'un @code{\}, et en le faisant suivre de ses arguments.  Lorsqu'un
230prédicat d'argument optionnel ne correspond pas à un argument, LilyPond
231l'ignore ainsi que tous les arguments optionnels qui suivent, les
232remplaçant par leur valeur par défaut, et « sauvegarde » en tant que
233prochain argument obligatoire l'argument qui ne correspondait pas.  Dans
234la mesure où l'argument sauvegardé doit servir, les argument optionnels
235ne sont en fait pas considérés comme optionnels, sauf à être suivis d'un
236argument obligatoire.
237
238Une exception cependant à cette règle : le fait de donner un
239@code{\default} en tant qu'argument optionnel aura pour résultat que cet
240argument et tous les autres arguments optionnels qui suivent seront
241ignorés et remplacés par leur valeur par défaut.  Il en va de même
242lorsqu'aucun argument obligatoire ne suit, du fait que @code{\default}
243ne requiert pas de sauvegarde.  C'est d'ailleurs ainsi que fonctionnent
244les commandes @code{mark} et @code{key}, qui retrouvent leur
245comportement par défaut lorsque vous les faites suivre d'un
246@code{\default}.
247
248En plus de là où une expression Scheme est requise, il y a quelques
249endroits où des expressions @code{#} sont acceptées et évaluées
250uniquement pour leurs effets annexes.  Il s'agit, dans la plupart des
251cas, d'endroits où une affectation serait tout à fait envisageable.
252
253Dans la mesure où il n'est pas bon de renvoyer une valeur qui pourrait
254être mal interprétée dans certains contextes, nous vous enjoignons à
255utiliser des fonctions Scheme normales uniquement dans les cas où vous
256renvoyez toujours une valeur utile, et une fonction fantôme -- voir
257@ref{Fonctions Scheme fantômes} -- dans le cas contraire.
258
259Pour des raisons de commodité, il est possible de faire appel à des
260fonctions Scheme directement en Scheme, courcircuitant ainsi l'analyseur
261de LilyPond.  Leur nom s'utilise comme n'importe quel nom de fonction.
262Le contrôle de typologie des arguments et l'omission des arguments
263optionnels seront traîtés de la même manière que lorsque l'appel est
264fait à partir de LilyPond, la valeur Scheme @code{*unspecified*} ayant
265le rôle du mot réservé @code{\default} pour omettre explicitement les
266arguments optionnels.
267
268
269@node Fonctions Scheme fantômes
270@subsection Fonctions Scheme fantômes
271@translationof Void scheme functions
272
273@cindex @emph{void}, fonction
274@cindex fantôme, fonction
275
276@funindex define-void-function
277@funindex \void
278
279Il arrive qu'une procédure soit exécutée pour réaliser une action, non
280pour renvoyer une valeur.  Certains langages de programmation, tels
281le C et Scheme, utilisent des fonctions dans les deux cas et se
282débarrassent tout bonnement de la valeur renvoyée ; en règle
283générale, il suffit que l'expression fasse office de déclaration, et
284d'ignorer le résultat.  C'est futé, mais pas sans risque d'erreur :
285la plupart des compilateurs C actuels déclenchent un avertissement si
286l'on se débarrasse de certaines expressions non @emph{void}.  Pour de
287nombreuses fonctions réalisant une action, les standards Scheme
288déclarent que la valeur de retour est indéfinie.  L'interpréteur Guile
289qu'utilise le Scheme de LilyPond dispose d'une valeur unique
290@code{*unspecified*} qu'il retourne alors, en règle générale -- notamment
291lorsqu'on utilise @code{set!} directement sur une variable -- mais
292malheureusement pas toujours.
293
294Une fonction LilyPond définie à l'aide de la clause
295@code{define-void-function} vous apporte l'assurance que c'est cette
296valeur spéciale -- la seule valeur qui satisfasse au prédicat
297@code{void?} -- qui sera retournée.
298
299@example
300noPointAndClick =
301#(define-void-function
302     ()
303     ()
304   (ly:set-option 'point-and-click #f))
305@dots{}
306\noPointAndClick   % desactive le "pointer-cliquer"
307@end example
308
309L'utilisation d'un préfixe @code{\void} permet ainsi d'évaluer une
310expression pour ses effets annexes sans interprétation d'une quelconque
311valeur de retour :
312
313@example
314\void #(hashq-set! une-table une-clé une-valeur)
315@end example
316
317Vous serez alors assuré que LilyPond ne tentera pas d'affecter un sens à
318la valeur de retour, à quelque endroit qu'elle ressorte.  Ceci est aussi
319opérationnel dans le cadre de fonctions musicales telles que
320@code{\displayMusic}.
321
322
323@node Fonctions musicales
324@section Fonctions musicales
325@translationof Music functions
326
327@cindex musicale, fonction
328
329Les @emph{fonctions musicales} sont des procédures Scheme capables de
330créer automatiquement des expressions musicales ; elles permettent
331de grandement simplifier un fichier source.
332
333@menu
334* Définition de fonctions musicales::
335* Utilisation de fonctions musicales::
336* Fonctions de substitution simple::
337* Fonctions de substitution intermédiaires::
338* De l'usage des mathématiques dans les fonctions::
339* Fonctions dépourvues d'argument::
340* Fonctions musicales fantômes::
341@end menu
342
343
344@node Définition de fonctions musicales
345@subsection Définition de fonctions musicales
346@translationof Music function definitions
347
348@cindex fonction musicale, définition
349
350@funindex define-music-function
351
352Une fonction musicale se définit ainsi :
353
354@example
355fonction =
356#(define-music-function
357     (@var{arg1} @var{arg2}@dots{})
358     (@var{type1?} @var{type2?}@dots{})
359   @var{corps})
360@end example
361
362@noindent
363de manière similaire aux @ref{Définition de fonctions Scheme, fonctions
364Scheme}.  La plupart du temps, le @var{corps} sera constitué d'un
365@ref{Blocs de code LilyPond, bloc de code LilyPond}.
366
367Les différents types des prédicat sont recensés à l'annexe
368@ruser{Types de prédicats prédéfinis}.
369
370@morerefs
371Manuel de notation :
372@ruser{Types de prédicats prédéfinis}.
373
374Fichiers d'initialisation :
375@file{lily/music-scheme.cc},
376@file{scm/c++.scm},
377@file{scm/lily.scm}.
378
379
380@node Utilisation de fonctions musicales
381@subsection Utilisation de fonctions musicales
382@translationof Music function usage
383
384Une « fonction musicale » doit impérativement renvoyer une expression
385répondant au prédicat @code{ly:music?}.  Ceci a pour conséquence
386d'autoriser l'appel à une fonction musicale en tant qu'argument de type
387@code{ly:music?} dans le cadre de l'appel à une autre fonction musicale.
388
389Certaines restrictions s'appliqueront selon le contexte où une fonction
390musicale est utilisée, de telle sorte que l'analyse syntaxique soit sans
391ambiguïté.
392
393@itemize
394@item
395Dans une expression musicale de haut niveau, aucun postévénement n'est
396toléré.
397
398@item
399Lorsqu'une fonction musicale -- contrairement à une fonction
400événementielle -- renvoie une expression de type postévénement, LilyPond
401requiert son introduction par un indicateur de positionnement -- à
402savoir @code{-}, @code{^} ou @code{_} -- de telle sorte que le
403postévénement produit par l'appel à cette fonction s'intègre
404correctement dans l'expression environnante.
405
406@item
407En tant que partie d'un accord, l'expression musicale renvoyée doit
408être du type @code{rhythmic-event}, et plus particulièrement un
409@code{NoteEvent}.
410@end itemize
411
412@noindent
413Des fonctions « polymorphes » telles que @code{\tweak} peuvent
414s'appliquer aux postévénements, constituants d'accord et expressions de
415haut niveau.
416
417
418@node Fonctions de substitution simple
419@subsection Fonctions de substitution simple
420@translationof Simple substitution functions
421
422Une fonction de substitution simple renvoie une expression musicale
423écrite au format LilyPond et contient des arguments au format de
424l'expression résultante.  Vous en trouverez une description détaillée à
425la rubrique @ruser{Exemples de fonction de substitution}.
426
427
428@node Fonctions de substitution intermédiaires
429@subsection Fonctions de substitution intermédiaires
430@translationof Intermediate substitution functions
431
432Une fonction de substitution intermédiaire est une fonction dont
433l'expression musicale résultante mélangera du code Scheme au code
434LilyPond.
435
436Certaines commandes @code{\override} nécessitent un argument
437supplémentaire constitué d'une paire de nombres, appelée @emph{cons
438cell} en Scheme -- que l'on pourrait traduire par « construction de
439cellule ».
440
441Cette paire peut se mentionner directement dans la fonction musicale à
442l'aide d'une variable @code{pair?} :
443
444@example
445manualBeam =
446#(define-music-function
447     (beg-end)
448     (pair?)
449   #@{
450     \once \override Beam.positions = #beg-end
451   #@})
452
453\relative c' @{
454  \manualBeam #'(3 . 6) c8 d e f
455@}
456@end example
457
458Autre manière de procéder, les nombres formant la paire sont transmis
459comme arguments séparés ; le code Scheme chargé de créer la paire
460pourra alors être inclus dans l'expression musicale :
461
462@lilypond[quote,verbatim,ragged-right]
463manualBeam =
464#(define-music-function
465     (beg end)
466     (number? number?)
467   #{
468     \once \override Beam.positions = #(cons beg end)
469   #})
470
471\relative c' {
472  \manualBeam #3 #6 c8 d e f
473}
474@end lilypond
475
476@funindex \temporary
477@cindex temporaire, dérogation (override)
478@cindex dérogation temporaire (override)
479@cindex propriétés, retour à la valeur précédente
480
481L'entretien des propriétés peut se voir comme un empilement par
482propriété par objet par contexte.  Les fonctions musicales peuvent
483nécessiter des dérogations pour une ou plusieurs propriétés pour la
484durée de la fonction, puis de revenir aux valeurs précédentes avant de
485quitter.  Néanmoins, une dérogation normale va retirer de la pile -- ou
486dépiler -- et supprimer le sommet de la pile de la propriété avant
487d'y ajouter quoi que ce soit -- ou empiler -- ; la valeur précédente de
488la propriété est de fait perdue.  Lorsque la valeur antérieure doit être
489préservée, l'instruction @code{\override} devra être préfixée d'un
490@code{\temporary}, comme ceci :
491
492@example
493\temporary \override @dots{}
494@end example
495
496L'utilisation d'un @code{\temporary} a pour effet d'effacer la propriété
497@code{pop-first} (@emph{commence par dépiler} normalement activée) de la
498dérogation ; la valeur antérieure ne sera alors pas supprimée de la pile
499de la propriété avant d'y empiler la nouvelle valeur.  Lorsqu'un
500@code{\revert} viendra par la suite supprimer la valeur dérogatoire
501temporaire, réapparaitra la valeur antérieure.
502
503En d'autres termes, un @code{\revert} qui suit un @code{\temporary
504\override} pour la même propriété n'apporte rien.  Ce principe est aussi
505valable pour un couple @code{\temporary} et @code{\undo} sur la même
506musique contenant des dérogations.
507
508Voici un exemple de fonction musicale utilisant cette fonctionnalité.
509La présence du @code{\temporary} permet de s'assurer qu'en sortant de la
510fonction, les propriétés @code{cross-staff} et @code{style} retrouveront
511les valeurs qu'elles avaient avant que ne soit appelée la fonction
512@code{crossStaff}.  En l'absence de @code{\temporary}, ces propriétés
513auraient retrouvé leurs valeurs par défaut à la sortie de la fonction.
514
515@example
516crossStaff =
517#(define-music-function (notes) (ly:music?)
518  (_i "Create cross-staff stems")
519  #@{
520  \temporary \override Stem.cross-staff = #cross-staff-connect
521  \temporary \override Flag.style = #'no-flag
522  #notes
523  \revert Stem.cross-staff
524  \revert Flag.style
525#@})
526@end example
527
528
529@node De l'usage des mathématiques dans les fonctions
530@subsection De l'usage des mathématiques dans les fonctions
531@translationof Mathematics in functions
532
533Une fonction musicale peut requérir, en plus d'une simple substitution,
534une part de programmation en Scheme.
535
536@lilypond[quote,verbatim,ragged-right]
537AltOn =
538#(define-music-function
539     (mag)
540     (number?)
541   #{
542     \override Stem.length = #(* 7.0 mag)
543     \override NoteHead.font-size =
544       #(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
545   #})
546
547AltOff = {
548  \revert Stem.length
549  \revert NoteHead.font-size
550}
551
552\relative {
553  c'2 \AltOn #0.5 c4 c
554  \AltOn #1.5 c c \AltOff c2
555}
556@end lilypond
557
558@noindent
559Cette fonction pourrait tout à fait être réécrite de telle sorte qu'elle
560s'applique à une expression musicale :
561
562@lilypond[quote,verbatim,ragged-right]
563withAlt =
564#(define-music-function
565     (mag music)
566     (number? ly:music?)
567   #{
568     \override Stem.length = #(* 7.0 mag)
569     \override NoteHead.font-size =
570       #(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
571     #music
572     \revert Stem.length
573     \revert NoteHead.font-size
574   #})
575
576\relative {
577  c'2 \withAlt #0.5 { c4 c }
578  \withAlt #1.5 { c c } c2
579}
580@end lilypond
581
582
583@node Fonctions dépourvues d'argument
584@subsection Fonctions dépourvues d'argument
585@translationof Functions without arguments
586
587Dans la plupart des cas, une fonction dépourvue d'argument devrait
588être créée à l'aide d'une variable :
589
590@example
591dolce = \markup@{ \italic \bold dolce @}
592@end example
593
594Il peut, dans certains cas particuliers, s'avérer utile de créer une
595fonction sans argument comme ici,
596
597@example
598displayBarNum =
599#(define-music-function
600     ()
601     ()
602   (if (eq? #t (ly:get-option 'display-bar-numbers))
603       #@{ \once \override Score.BarNumber.break-visibility = ##f #@}
604       #@{#@}))
605@end example
606
607@noindent
608de manière à pouvoir afficher les numéros de mesure grâce à un appel à
609cette fonction.  En pareil cas, vous devrez invoquer @command{lilypond}
610en respectant la syntaxe
611
612@example
613lilypond -d display-bar-numbers MONFICHIER.ly
614@end example
615
616
617@node Fonctions musicales fantômes
618@subsection Fonctions musicales fantômes
619@translationof Void music functions
620
621Une fonction musicale doit renvoyer une expression musicale.  Toutefois,
622une fonction musicale peut n'être exécutée que dans le but d'en retenir
623les effets annexes ; vous devrez alors utiliser une procédure
624@code{define-void-function}.  Il peut cependant arriver que vous ayez
625besoin d'une fonction qui, selon le cas, produise ou non (comme dans
626l'exemple de la rubrique précédente) une expression musicale.
627L'utilisation d'un @code{#@{ #@}} vous permettra de renvoyer une
628expression musicale @code{void}.
629
630
631@node Fonctions événementielles
632@section Fonctions événementielles
633@translationof Event functions
634
635@funindex define-event-function
636@cindex événementielle, fonction
637
638L'utilisation d'une fonction musicale pour placer un événement requiert
639l'insertion d'un indicateur de position, ce qui peut ne pas correspondre
640à la syntaxe de la construction à remplacer.  C'est par exemple le cas
641lorsque vous voulez écrire une commande de nuance, instruction qui
642ne comporte habituellement pas d'indicateur de positionnement, comme
643dans @code{c'\pp}.  Voici de quoi vous permettre de mentionner n'importe
644quelle nuance :
645
646@lilypond[quote,verbatim,ragged-right]
647dyn=#(define-event-function (arg) (markup?)
648         (make-dynamic-script arg))
649\relative { c'\dyn pfsss }
650@end lilypond
651
652Vous pourriez obtenir le même résultat avec une fonction musicale, à
653ceci près que chaque appel à la fonction devra être précédé d'un
654indicateur de positionnement, comme @code{c-\dyn pfsss}.
655
656
657@node Fonctions pour markups
658@section Fonctions pour @emph{markups}
659@translationof Markup functions
660
661Les @emph{markups} sont implémentés au travers de fonctions Scheme
662spécifiques qui produisent des objets @code{Stencil} comprenant un
663certain nombre d'arguments.
664
665@menu
666* Construction d'un markup en Scheme::
667* Fonctionnement interne des markups::
668* Définition d'une nouvelle commande de markup::
669* Définition d'une nouvelle commande de liste de markups::
670@end menu
671
672
673@node Construction d'un markup en Scheme
674@subsection Construction d'un @emph{markup} en Scheme
675@translationof Markup construction in Scheme
676
677@cindex définition d'une commande markup
678@cindex markup, définition d'une commande
679
680@funindex \displayScheme
681
682Les expressions @emph{markup} sont représentées en Scheme de manière
683interne par la macro @code{markup} :
684
685@example
686(markup @var{expression})
687@end example
688
689La commande @code{\displayScheme} permet d'obtenir la représentation en
690Scheme d'une expression @emph{markup} :
691
692@example
693\displayScheme
694\markup @{
695  \column @{
696    \line @{ \bold \italic "hello" \raise #0.4 "world" @}
697    \larger \line @{ foo bar baz @}
698  @}
699@}
700@end example
701
702@noindent
703Compiler ce code renverra en console les lignes suivantes :
704
705@example
706(markup
707  #:line
708  (#:column
709   (#:line
710    (#:bold (#:italic "hello") #:raise 0.4 "world")
711    #:larger
712    (#:line
713     (#:simple "foo" #:simple "bar" #:simple "baz")))))
714@end example
715
716L'impression du @emph{markup} sera suspendue dès lors qu'apparaîtra un
717@w{@samp{\void \displayScheme @var{markup}}}.  Tout comme pour la
718commande @code{\displayMusic}, le résultat de @code{\displayScheme} peut
719être sauvegardé dans un fichier séparé.  Voir à ce sujet
720@ref{Affichage d'expressions musicales}.
721
722@noindent
723Vous pouvez constater les principales règles de traduction entre les
724syntaxes respectives de LilyPond et de Scheme en matière de
725@emph{markup}.  Bien que le passage en syntaxe LilyPond grâce à
726@code{#@{ @dots{} #@}} apporte de la souplesse, nous allons voir comment
727utiliser la macro @code{markup} en Scheme exclusivement.
728
729@quotation
730@multitable @columnfractions .3 .3
731@item @b{LilyPond} @tab @b{Scheme}
732@item @code{\markup markup1} @tab @code{(markup markup1)}
733@item @code{\markup @{ markup1 markup2@dots{} @}} @tab
734        @code{(markup markup1 markup2@dots{} )}
735@item @code{\commande-markup} @tab @code{#:commande-markup}
736@item @code{\variable} @tab @code{variable}
737@item @code{\center-column @{ @dots{} @}} @tab
738        @code{#:center-column ( @dots{} )}
739@item @code{chaîne} @tab @code{"chaîne"}
740@item @code{#argument-scheme} @tab @code{argument-scheme}
741@end multitable
742@end quotation
743
744L'intégralité du langage Scheme est accessible à l'intérieur même de la
745macro @code{markup}.  Vous pouvez ainsi appeler des fonctions à partir
746de @code{markup} pour manipuler des chaînes de caractères, ce qui est
747particulièrement pratique lorsque vous créez votre propre commande de
748@emph{markup} -- voir
749@ref{Définition d'une nouvelle commande de markup}.
750
751@knownissues
752L'argument @var{markup-list} des commandes @code{#:line},
753@code{#:center} ou @code{#:column} ne saurait être une variable ni le
754résultat de l'appel à une fonction.
755
756@lisp
757(markup #:line (fonction-qui-retourne-des-markups))
758@end lisp
759
760@noindent
761n'est pas valide.  Il vaut mieux, en pareil cas, utiliser les fonctions
762@code{make-line-markup}, @code{make-center-markup} ou
763@code{make-column-markup} :
764
765@lisp
766(markup (make-line-markup (fonction-qui-retourne-des-markups)))
767@end lisp
768
769
770@node Fonctionnement interne des markups
771@subsection Fonctionnement interne des @emph{markups}
772@translationof How markups work internally
773
774Dans un @emph{markup} tel que
775
776@example
777\raise #0.5 "text example"
778@end example
779
780@noindent
781@code{\raise} représente en fait la fonction @code{raise-markup}.
782L'expression @emph{markup} est enregistrée sous la forme
783
784@example
785(list raise-markup 0.5 (list simple-markup "text example"))
786@end example
787
788Lorsque ce @emph{markup} est converti en objets imprimables (stencils),
789la fonction @code{raise-markup} est appelée ainsi :
790
791@example
792(apply raise-markup
793       @var{\layout objet}
794       @var{liste des alists de propriété}
795       0.5
796       @var{le @emph{markup} "text example"})
797@end example
798
799La fonction @code{raise-markup} commence par créer le stencil pour la
800chaîne @code{text example}, puis remonte ce stencil d'un demi espace de
801portée.  Il s'agit là d'un exemple relativement simple, et nous en
802aborderons de plus complexes au fil des paragraphes suivants ;
803d'autres exemples se trouvent directement dans le fichier
804@file{scm/define-markup-commands.scm}.
805
806
807@node Définition d'une nouvelle commande de markup
808@subsection Définition d'une nouvelle commande de @emph{markup}
809@translationof New markup command definition
810
811Nous allons étudier dans ce qui suit la manière de définir une nouvelle
812commande de @emph{markup}.
813
814@menu
815* Syntaxe d'une commande markup::
816* Attribution de propriétés::
817* Exemple commenté::
818* Adaptation d'une commande incorporée::
819@end menu
820
821
822@node Syntaxe d'une commande markup
823@unnumberedsubsubsec Syntaxe d'une commande @emph{markup}
824@translationof Markup command definition syntax
825
826Une commande de @emph{markup} personnalisée se définit à l'aide de la
827macro Scheme @code{define-markup-command}, placée en tête de fichier.
828
829@lisp
830(define-markup-command (@var{nom-commande} @var{layout} @var{props} @var{arg1} @var{arg2}@dots{})
831    (@var{arg1-type?} @var{arg2-type?}@dots{})
832    [ #:properties ((@var{propriété1} @var{valeur-par-défaut1})
833                    @dots{}) ]
834  @dots{}corps de la commande@dots{})
835@end lisp
836
837Quelques commentaires sur les arguments :
838
839@table @code
840@item @var{nom-commande}
841le nom que vous attribuez à votre commande de @emph{markup}.
842@item layout
843la définition du « layout » -- son formatage.
844@item props
845une liste de listes associatives, comprenant toutes les propriétés actives.
846@item @var{argi}
847le @var{ième} argument de la commande.
848@item @var{argi-type?}
849un type de prédicat pour le @var{ième} argument.
850@end table
851
852Si la commande utilise des propriétés à partir des arguments
853@code{props}, le mot-clé @code{#:properties} permet de spécifier ces
854différentes propriétés ainsi que leur valeur par défaut.
855
856Les arguments se distinguent selon leur type :
857@itemize
858@item un @emph{markup}, correspondant au type de prédicat
859@code{markup?} ;
860@item une liste de @emph{markups}, correspondant au type de prédicat
861@code{markup-list?} ;
862@item tout autre objet Scheme, correspondant au types de prédicat tels
863que @code{list?}, @code{number?}, @code{boolean?}, etc.
864@end itemize
865
866Il n'existe aucune restriction quant à l'ordre des arguments fournis à
867la suite des arguments @code{layout} et @code{props}.  Néanmoins, les
868fonctions @emph{markup} qui ont en dernier argument un @emph{markup} ont
869ceci de particulier qu'elles peuvent s'appliquer à des listes de
870@emph{markups} ; ceci résultera en une liste de @emph{markups} où
871tous les éléments de la liste originelle se verront appliquer cette
872fonction @emph{markup} avec ses arguments de tête.
873
874La réplication des arguments de tête dans le but d'appliquer une
875fonction @emph{markup} à une liste de markups est économique,
876principalement lorsqu'il s'agit d'arguments Scheme.  Vous éviterez
877ainsi d'éventuelles pertes de performance en utilisant des arguments
878Scheme en tant qu'arguments principaux d'une fonction @emph{markup} dont
879le dernier argument est un @emph{markup}.
880
881@cindex markup macro
882@cindex macro de markup
883@funindex \markup
884@funindex interpret-markup
885
886Les commandes de @emph{markup} ont un cycle de vie relativement
887complexe.  Le corps de la définition d'une commande de @emph{markup} est
888chargé de convertir les arguments de la commande en expression stencil
889qui sera alors renvoyée.  Bien souvent, ceci s'accomplit par un appel à
890la fonction @code{interpret-markup}, en lui passant les arguments
891@var{layout} et @var{props}.  Ces arguments ne seront en principe connus
892que bien plus tardivement dans le processus typographique.  Lors de
893l'expansion d'une expression LilyPond @code{\markup} ou d'une macro
894Scheme @code{markup}, les expressions @emph{markup} auront déjà vu leurs
895composants assemblés en expressions @emph{markup}.  L'évaluation et le
896contrôle du type des arguments à une commande de @emph{markup}
897n'interviennent qu'au moment de l'interprétation de @code{\markup} ou
898@code{markup}.
899
900Seule l'application de @code{interpret-markup} sur une expression
901@emph{markup} réalisera effectivement la conversion des expressions
902@emph{markup} en stencil, au travers de l'exécution du corps des
903fonctions @emph{markup}.
904
905
906@node Attribution de propriétés
907@unnumberedsubsubsec Attribution de propriétés
908@translationof On properties
909
910Les arguments @code{layout} et @code{props} d'une commande de
911@emph{markup} fournissent un contexte à l'interprétation du
912@emph{markup} : taille de fonte, longueur de ligne, etc.
913
914L'argument @code{layout} permet d'accéder aux propriétés définies dans
915les blocs @code{\paper}, grâce à la fonction
916@code{ly:output-def-lookup}.  Par exemple, la longueur de ligne,
917identique à celle de la partition, est lue au travers de
918
919@example
920(ly:output-def-lookup layout 'line-width)
921@end example
922
923L'argument @code{props} rend certaines propriétés accessibles aux
924commandes de @emph{markup}.  Il en va ainsi lors de l'interprétation
925d'un @emph{markup} de titre d'ouvrage : toutes les variables
926définies dans le bloc @code{\header} sont automatiquement ajoutées aux
927@code{props}, de telle sorte que le @emph{markup} de titrage de
928l'ouvrage pourra accéder aux différents champs titre, compositeur, etc.
929Ceci permet aussi de configurer le comportement d'une commande de
930@emph{markup} : la taille des fontes, par exemple, est lue à
931partir de @code{props} plutôt que grâce à un argument @code{font-size}.
932La fonction appelant une commande de @emph{markup} peut altérer la
933valeur de la propriété taille des fontes et donc en modifier le
934comportement.  L'utilisation du mot-clé @code{#:properties}, attaché à
935@code{define-markup-command}, permet de spécifier les propriétés devant
936être lues parmi les arguments @code{props}.
937
938L'exemple proposé à la rubrique suivante illustre comment, au sein d'une
939commande de @emph{markup}, accéder aux différentes propriétés et les
940modifier.
941
942
943@node Exemple commenté
944@unnumberedsubsubsec Exemple commenté
945@translationof A complete example
946
947Nous allons, dans cet exemple, nous attacher à encadrer du texte avec un
948double liseré.
949
950Commençons par construire quelque chose d'approximatif à l'aide d'un
951simple @emph{markup}.  La lecture de @ruser{Commandes pour markup} nous
952indique la commande @code{\box}, qui semble ici appropriée.
953
954@lilypond[quote,verbatim,ragged-right]
955\markup \box \box HELLO
956@end lilypond
957
958Dans un souci d'esthétique, nous aimerions que le texte et les
959encadrements ne soient pas autant accolés.  Selon la documentation de
960@code{\box}, cette commande utilise la propriété @code{box-padding},
961fixée par défaut à 0,2.  Cette même documentation nous indique
962aussi comment la modifier :
963
964@lilypond[quote,verbatim,ragged-right]
965\markup \box \override #'(box-padding . 0.6) \box A
966@end lilypond
967
968L'espacement des deux liserés est cependant toujours trop réduit ;
969modifions le à son tour :
970
971@lilypond[quote,verbatim,ragged-right]
972\markup \override #'(box-padding . 0.4) \box
973     \override #'(box-padding . 0.6) \box A
974@end lilypond
975
976Vous conviendrez que recopier une telle définition de @emph{markup}
977deviendra vite fastidieux.  C'est pourquoi nous écrivons la commande de
978@emph{markup} @code{double-box} qui prendra un seul argument -- le
979texte.  Cette commande se chargera de dessiner les encadrements, en
980tenant compte des espacements.
981
982@lisp
983#(define-markup-command (double-box layout props text) (markup?)
984  "Dessine un double encadrement autour du texte."
985  (interpret-markup layout props
986    #@{\markup \override #'(box-padding . 0.4) \box
987            \override #'(box-padding . 0.6) \box @{ #text @}#@}))
988@end lisp
989
990@noindent
991ou bien son équivalent
992
993@lisp
994#(define-markup-command (double-box layout props text) (markup?)
995  "Dessine un double encadrement autour du texte."
996  (interpret-markup layout props
997    (markup #:override '(box-padding . 0.4) #:box
998            #:override '(box-padding . 0.6) #:box text)))
999@end lisp
1000
1001@code{text} est le nom de l'argument de notre commande, et
1002@code{markup?} son type -- l'argument sera identifié comme étant un
1003@emph{markup}.  La fonction @code{interpret-markup}, utilisée dans la
1004plupart des commandes de @emph{markup}, construira un stencil à partir
1005de @code{layout}, @code{props} et un @emph{markup}.  Dans la seconde
1006variante, ce @emph{markup} sera construit à l'aide de la macro Scheme
1007@code{markup} -- voir @ref{Construction d'un markup en Scheme}.  La
1008transformation d'une expression @code{\markup} en expression Scheme est
1009des plus triviales.
1010
1011Notre commande personnalisée s'utilise ainsi :
1012
1013@example
1014\markup \double-box A
1015@end example
1016
1017Il serait intéressant de rendre cette commande @code{double-box} plus
1018souple :  les valeurs de @code{box-padding} sont figées et ne
1019peuvent être modifiées à l'envie.  Pareillement, il serait bien de
1020distinguer l'espacement entre les encadrements de l'espacement entre le
1021texte et ses encadrements.  Nous allons donc introduire une propriété
1022supplémentaire, que nous appellerons @code{inter-box-padding}, chargée
1023de gérer l'espacement des encadrements ; @code{box-padding} ne
1024servira alors que pour l'espacement intérieur.  Voici le code adapté à
1025ces évolutions :
1026
1027@lisp
1028#(define-markup-command (double-box layout props text) (markup?)
1029  #:properties ((inter-box-padding 0.4)
1030                (box-padding 0.6))
1031  "Dessine un double encadrement autour du texte."
1032  (interpret-markup layout props
1033    #@{\markup \override #`(box-padding . ,inter-box-padding) \box
1034               \override #`(box-padding . ,box-padding) \box
1035               @{ #text @} #@}))
1036@end lisp
1037
1038Ainsi que son équivalent à partir de la macro @emph{markup} :
1039
1040@lisp
1041#(define-markup-command (double-box layout props text) (markup?)
1042  #:properties ((inter-box-padding 0.4)
1043                (box-padding 0.6))
1044  "Dessine un double encadrement autour du texte."
1045  (interpret-markup layout props
1046    (markup #:override `(box-padding . ,inter-box-padding) #:box
1047            #:override `(box-padding . ,box-padding) #:box text)))
1048@end lisp
1049
1050C'est ici le mot-clé @code{#:properties} qui permet de lire les
1051propriétés @code{inter-box-padding} et @code{box-padding} à partir de
1052l'argumenet @code{props} ; on leur a d'ailleurs fourni des valeurs
1053par défaut au cas où elles ne seraient pas définies.
1054
1055Ces valeurs permettront alors d'adapter les propriétés de
1056@code{box-padding} utilisées par les deux commandes @code{\box}.  Vous
1057aurez remarqué, dans l'argument @code{\override}, la présence de
1058l'apostrophe inversée (@code{`}) et de la virgule ; elles vous
1059permettent d'insérer une valeur variable au sein d'une expression
1060littérale.
1061
1062Notre commande est maintenant prête à servir dans un @emph{markup}, et
1063les encadrements sont repositionnables.
1064
1065@lilypond[quote,verbatim,ragged-right]
1066#(define-markup-command (double-box layout props text) (markup?)
1067  #:properties ((inter-box-padding 0.4)
1068                (box-padding 0.6))
1069  "Draw a double box around text."
1070  (interpret-markup layout props
1071    #{\markup \override #`(box-padding . ,inter-box-padding) \box
1072              \override #`(box-padding . ,box-padding) \box
1073              { #text } #}))
1074
1075\markup \double-box A
1076\markup \override #'(inter-box-padding . 0.8) \double-box A
1077\markup \override #'(box-padding . 1.0) \double-box A
1078@end lilypond
1079
1080
1081@node Adaptation d'une commande incorporée
1082@unnumberedsubsubsec Adaptation d'une commande incorporée
1083@translationof Adapting builtin commands
1084
1085Le meilleur moyen de construire ses propres commandes de @emph{markup}
1086consiste à prendre exemple sur les commandes déjà incorporées.  La
1087plupart des commandes de @emph{markup} fournies avec LilyPond sont
1088répertoriées dans le fichier @file{scm/define-markup-commands.scm}.
1089
1090Nous pourrions, par exemple, envisager d'adapter la commande
1091@code{\draw-line} pour dessiner plutôt une ligne double.  Voici comment
1092est définie la commande @code{\draw-line}, expurgée de sa
1093documentation :
1094
1095@lisp
1096(define-markup-command (draw-line layout props dest)
1097  (number-pair?)
1098  #:category graphic
1099  #:properties ((thickness 1))
1100  "@dots{}documentation@dots{}"
1101  (let ((th (* (ly:output-def-lookup layout 'line-thickness)
1102               thickness))
1103        (x (car dest))
1104        (y (cdr dest)))
1105    (make-line-stencil th 0 0 x y)))
1106@end lisp
1107
1108Avant de définir notre propre commande basée sur l'une de celles
1109fournies par LilyPond, commençons par en recopier la définition, puis
1110attribuons lui un autre nom.  Le mot-clé @code{#:category} peut être
1111supprimé sans risque ; il ne sert que lors de la génération de la
1112documentation et n'est d'aucune utilité pour une commande personnalisée.
1113
1114@lisp
1115(define-markup-command (draw-double-line layout props dest)
1116  (number-pair?)
1117  #:properties ((thickness 1))
1118  "@dots{}documentation@dots{}"
1119  (let ((th (* (ly:output-def-lookup layout 'line-thickness)
1120               thickness))
1121        (x (car dest))
1122        (y (cdr dest)))
1123    (make-line-stencil th 0 0 x y)))
1124@end lisp
1125
1126Nous ajoutons ensuite une propriété pour gérer l'écart entre les deux
1127lignes, que nous appelons @code{line-gap}, et lui attribuons une valeur
1128par défaut de 6 dixièmes :
1129
1130@lisp
1131(define-markup-command (draw-double-line layout props dest)
1132  (number-pair?)
1133  #:properties ((thickness 1)
1134                (line-gap 0.6))
1135  "@dots{}documentation@dots{}"
1136  @dots{}
1137@end lisp
1138
1139Nous ajoutons enfin le code qui dessinera nos deux lignes.  Deux appels
1140à @code{make-line-stencil} permettrons de dessiner les lignes dont nous
1141regrouperons les stencils à l'aide de @code{ly:stencil-add} :
1142
1143@lilypond[quote,verbatim,ragged-right]
1144#(define-markup-command (my-draw-line layout props dest)
1145  (number-pair?)
1146  #:properties ((thickness 1)
1147                (line-gap 0.6))
1148  "..documentation.."
1149  (let* ((th (* (ly:output-def-lookup layout 'line-thickness)
1150                thickness))
1151         (dx (car dest))
1152         (dy (cdr dest))
1153         (w (/ line-gap 2.0))
1154         (x (cond ((= dx 0) w)
1155                  ((= dy 0) 0)
1156                  (else (/ w (sqrt (+ 1 (* (/ dx dy) (/ dx dy))))))))
1157         (y (* (if (< (* dx dy) 0) 1 -1)
1158               (cond ((= dy 0) w)
1159                     ((= dx 0) 0)
1160                     (else (/ w (sqrt (+ 1 (* (/ dy dx) (/ dy dx))))))))))
1161     (ly:stencil-add (make-line-stencil th x y (+ dx x) (+ dy y))
1162                     (make-line-stencil th (- x) (- y) (- dx x) (- dy y)))))
1163
1164\markup \my-draw-line #'(4 . 3)
1165\markup \override #'(line-gap . 1.2) \my-draw-line #'(4 . 3)
1166@end lilypond
1167
1168
1169@node Définition d'une nouvelle commande de liste de markups
1170@subsection Définition d'une nouvelle commande de liste de @emph{markups}
1171@translationof New markup list command definition
1172
1173@cindex liste de markup, définition de commande
1174@funindex define-markup-list-command
1175@funindex interpret-markup-list
1176
1177Une commande traitant une liste de @emph{markups} se définit à l'aide de
1178la macro Scheme @code{define-markup-list-command}, de manière analogue à
1179la macro @code{define-markup-command} abordée à la rubrique
1180@ref{Définition d'une nouvelle commande de markup}, à ceci près que
1181cette dernière renvoie un seul stencil, non une liste de stencils.
1182
1183La fonction @code{interpret-markup-list}, à l'instar de la fonction
1184@code{interpret-markup}, permet de convertir une liste de @emph{markups}
1185en liste de stencils.
1186
1187Dans l'exemple suivant, nous définissons @code{\paragraph}, une commande
1188de liste de @emph{markups}, qui renverra une liste de lignes justifiées
1189dont la première sera indentée.  La largeur de l'alinéa sera récupérée
1190par l'argument @code{props}.
1191
1192@example
1193#(define-markup-list-command (paragraph layout props args) (markup-list?)
1194   #:properties ((par-indent 2))
1195   (interpret-markup-list layout props
1196     #@{\markuplist \justified-lines @{ \hspace #par-indent #args @} #@}))
1197@end example
1198
1199La version purement Scheme est un peu plus complexe :
1200@example
1201#(define-markup-list-command (paragraph layout props args) (markup-list?)
1202   #:properties ((par-indent 2))
1203   (interpret-markup-list layout props
1204     (make-justified-lines-markup-list (cons (make-hspace-markup par-indent)
1205                                             args))))
1206@end example
1207
1208En dehors des habituels arguments @code{layout} et @code{props}, la
1209commande de liste de @emph{markups} @code{paragraph} prend en argument
1210une liste de @emph{markups} appelée @code{args}.  Le prédicat des listes
1211de @emph{markups} est @code{markup-list?}.
1212
1213Pour commencer, la fonction récupère la taille de l'alinéa, propriété
1214ici dénommée @code{par-indent}, à partir de la liste de propriétés
1215@code{props}.  En cas d'absence, la valeur par défaut sera
1216de @code{2}.  Ensuite est créée une liste de lignes justifiées
1217grâce à la commande prédéfinie @code{\justified-lines}, liée à la
1218fonction @code{make-justified-lines-markup-list}.  Un espace horizontal
1219est ajouté en tête, grâce à @code{\hspace} ou à la fonction
1220@code{make-hspace-markup}.  Enfin, la liste de @emph{markups} est
1221interprétée par la fonction @code{interpret-markup-list}.
1222
1223Voici comment utiliser cette nouvelle commande de liste de
1224@emph{markups} :
1225
1226@example
1227\markuplist @{
1228  \paragraph @{
1229    The art of music typography is called \italic @{(plate) engraving.@}
1230    The term derives from the traditional process of music printing.
1231    Just a few decades ago, sheet music was made by cutting and stamping
1232    the music into a zinc or pewter plate in mirror image.
1233  @}
1234  \override-lines #'(par-indent . 4) \paragraph @{
1235    The plate would be inked, the depressions caused by the cutting
1236    and stamping would hold ink.  An image was formed by pressing paper
1237    to the plate.  The stamping and cutting was completely done by
1238    hand.
1239  @}
1240@}
1241@end example
1242
1243
1244@node Contextes pour programmeurs
1245@section Contextes pour programmeurs
1246@translationof Contexts for programmers
1247
1248@menu
1249* Évaluation d'un contexte::
1250* Application d'une fonction à tous les objets de mise en forme::
1251@end menu
1252
1253
1254@node Évaluation d'un contexte
1255@subsection Évaluation d'un contexte
1256@translationof Context evaluation
1257
1258@cindex appel de code durant l'interprétation
1259@funindex \applyContext
1260@funindex make-apply-context
1261@funindex ly:context-property
1262@funindex ly:context-set-property!
1263@funindex ly:context-grob-definition
1264@funindex ly:assoc-get
1265@funindex ly:context-pushpop-property
1266
1267Un contexte peut être modifié, au moment même de son interprétation, par
1268du code Scheme.  La syntaxe consacrée au sein d'un bloc LilyPond est
1269
1270@example
1271\applyContext @var{fonction}
1272@end example
1273
1274@noindent
1275et, dans le cadre d'un code Scheme :
1276
1277@example
1278(make-apply-context @var{fonction})
1279@end example
1280
1281@code{@var{fonction}} est constitué d'une fonction Scheme comportant un
1282unique argument : le contexte au sein duquel la commande
1283@code{\applyContext} est appelée.  Cette fonction peut accéder aussi
1284bien aux propriétés de @emph{grob} (y compris modifiées par
1285@code{\override} ou @code{\set}) qu'aux propriétés de contexte.  Toute
1286action entreprise par la fonction et qui dépendrait de l'état du
1287contexte sera limitée à l'état de ce contexte @b{au moment de l'appel à
1288la fonction}.  Par ailleurs, les adaptations résultant d'un appel à
1289@code{\applyContext} seront effectives jusqu'à ce qu'elles soient à
1290nouveau directement modifiées ou bien annulées, quand bien même les
1291conditions initiales dont elles dépendent auraient changé.
1292
1293Voici quelques fonctions Scheme utiles avec @code{\applyContext} :
1294
1295@table @code
1296@item ly:context-property
1297recherche la valeur d'une propriété de contexte,
1298
1299@item ly:context-set-property!
1300détermine une propriété de contexte,
1301
1302@item ly:context-grob-definition
1303@itemx ly:assoc-get
1304recherche la valeur d'une propriété de @emph{grob},
1305
1306@item ly:context-pushpop-property
1307réalise un @code{\temporary \override} ou un @code{\revert} sur une
1308propriété de @emph{grob}.
1309@end table
1310
1311L'exemple suivant recherche la valeur en cours de @code{fontSize} puis
1312la double :
1313
1314@lilypond[quote,verbatim]
1315doubleFontSize =
1316\applyContext
1317  #(lambda (context)
1318     (let ((fontSize (ly:context-property context 'fontSize)))
1319       (ly:context-set-property! context 'fontSize (+ fontSize 6))))
1320
1321{
1322  \set fontSize = -3
1323  b'4
1324  \doubleFontSize
1325  b'
1326}
1327@end lilypond
1328
1329L'exemple suivant recherche la couleur des objets @code{NoteHead},
1330@code{Stem} et @code{Beam}, puis diminue pour chacun d'eux le degré de
1331saturation.
1332
1333@lilypond[quote,verbatim]
1334desaturate =
1335\applyContext
1336  #(lambda (context)
1337     (define (desaturate-grob grob)
1338       (let* ((grob-def (ly:context-grob-definition context grob))
1339              (color (ly:assoc-get 'color grob-def black))
1340              (new-color (map (lambda (x) (min 1 (/ (1+ x) 2))) color)))
1341         (ly:context-pushpop-property context grob 'color new-color)))
1342     (for-each desaturate-grob '(NoteHead Stem Beam)))
1343
1344\relative {
1345  \time 3/4
1346  g'8[ g] \desaturate g[ g] \desaturate g[ g]
1347 \override NoteHead.color = #darkred
1348  \override Stem.color = #darkred
1349  \override Beam.color = #darkred
1350  g[ g] \desaturate g[ g] \desaturate g[ g]
1351}
1352@end lilypond
1353
1354Ceci pourrait tout à fait s'implémenter sous la forme d'une fonction
1355musicale, afin d'en réduire les effets à un seul bloc de musique.  Notez
1356comment @code{ly:context-pushpop-property} est utilisé à la fois pour un
1357@code{\temporary \override} et pour un @code{\revert} :
1358
1359@lilypond[quote,verbatim]
1360desaturate =
1361#(define-music-function
1362   (music) (ly:music?)
1363   #{
1364     \applyContext
1365     #(lambda (context)
1366        (define (desaturate-grob grob)
1367          (let* ((grob-def (ly:context-grob-definition context grob))
1368                 (color (ly:assoc-get 'color grob-def black))
1369                 (new-color (map (lambda (x) (min 1 (/ (1+ x) 2))) color)))
1370            (ly:context-pushpop-property context grob 'color new-color)))
1371        (for-each desaturate-grob '(NoteHead Stem Beam)))
1372     #music
1373     \applyContext
1374     #(lambda (context)
1375        (define (revert-color grob)
1376          (ly:context-pushpop-property context grob 'color))
1377        (for-each revert-color '(NoteHead Stem Beam)))
1378   #})
1379
1380\relative {
1381  \override NoteHead.color = #darkblue
1382  \override Stem.color = #darkblue
1383  \override Beam.color = #darkblue
1384  g'8 a b c
1385  \desaturate { d c b a }
1386  g b d b g2
1387}
1388@end lilypond
1389
1390
1391@node Application d'une fonction à tous les objets de mise en forme
1392@subsection Application d'une fonction à tous les objets de mise en forme
1393@translationof Running a function on all layout objects
1394
1395@cindex appel de code sur des objets de mise en forme
1396@cindex objets de mise en forme, appel de code
1397@funindex \applyOutput
1398
1399La manière la plus souple d'affiner un objet consiste à utiliser la
1400commande @code{\applyOutput}.  Celle-ci va insérer un événement
1401(@rinternals{ApplyOutputEvent}) dans le contexte spécifié.  Elle répond
1402aussi bien à la syntaxe
1403@example
1404\applyOutput @var{Contexte} @var{procédure}
1405@end example
1406@noindent
1407que
1408@example
1409\applyOutput @var{Contexte}.@var{Grob} @var{procédure}
1410@end example
1411
1412@noindent
1413où @code{@var{procédure}} est une fonction Scheme à trois arguments.
1414
1415Lors de l'interprétation de cette commande, la fonction
1416@code{@var{procédure}} est appelée pout tout objet de rendu (nommé
1417@var{Grob} si celui-ci est spécifié) appartenant au contexte
1418@code{@var{Contexte}} à cet instant précis, avec les arguments
1419suivants :
1420@itemize
1421@item l'objet de rendu en lui-même,
1422@item le contexte au sein duquel cet objet est créé,
1423@item le contexte dans lequel @code{\applyOutput} est effectué.
1424@end itemize
1425
1426De plus, ce qui est à l'origine de l'objet de rendu -- l'expression
1427musicale ou l'objet qui l'a générée -- se retrouve en tant que propriété
1428d'objet @code{cause}.  Il s'agit, pour une tête de note, d'un événement
1429@rinternals{NoteHead}, et d'un objet @rinternals{Stem} pour une hampe.
1430
1431Voici une fonction utilisable avec la commande
1432@code{\applyOutput} : elle « blanchit » la tête des notes se trouvant
1433sur la ligne médiane ou bien directement à son contact.
1434
1435@lilypond[quote,verbatim,ragged-right]
1436#(define (blanker grob grob-origin context)
1437   (if (< (abs (ly:grob-property grob 'staff-position)) 2)
1438       (set! (ly:grob-property grob 'transparent) #t)))
1439
1440\relative {
1441  a'4 e8 <<\applyOutput Voice.NoteHead #blanker a c d>> b2
1442}
1443@end lilypond
1444
1445La @var{procédure} sera interprétée au niveau @code{Score} (partition)
1446ou @code{Staff} (portée) dès lors que vous utiliserez l'une des syntaxes
1447
1448@example
1449\applyOutput Score@dots{}
1450\applyOutput Staff@dots{}
1451@end example
1452
1453
1454@node Fonctions de rappel
1455@section Fonctions de rappel
1456@translationof Callback functions
1457
1458Certaines propriétés, entre autres @code{thickness} ou @code{direction},
1459peuvent voir leur valeur figée à l'aide d'un @code{\override} comme
1460ici :
1461
1462@example
1463\override Stem.thickness = #2.0
1464@end example
1465
1466Une procédure Scheme peut aussi se charger de modifier des propriétés :
1467
1468@lilypond[fragment,verbatim,quote]
1469\override Stem.thickness = #(lambda (grob)
1470    (if (= UP (ly:grob-property grob 'direction))
1471        2.0
1472        7.0))
1473\relative { c'' b a g b a g b }
1474@end lilypond
1475
1476@noindent
1477Dans ce cas, la procédure est exécutée dès que la valeur de la propriété
1478est nécessaire au processus de mise en forme.
1479
1480La majeure partie du procédé typographique consiste en la réalisation de
1481tels rappels (@emph{callbacks} en anglais).  Entre autres propriétés
1482utilisant particulièrement des rappels, nous mentionnerons
1483
1484@table @code
1485@item stencil
1486  Routine d'impression, construisant le dessin du symbole
1487@item X-offset
1488  Routine effectuant le positionnement horizontal
1489@item X-extent
1490  Routine calculant la largeur d'un objet
1491@end table
1492
1493La procédure prend un unique argument, en l'occurrence l'objet graphique
1494(le @emph{grob}).
1495
1496Cette procédure, grâce à un appel à la fonction de rappel dévolue à
1497cette propriété -- mentionnée dans la référence des propriétés internes
1498et dans le fichier @file{define-grobs.scm} --, pourra accéder à la
1499valeur usuelle de la propriété :
1500
1501@example
1502\relative @{
1503  \override Flag.X-offset = #(lambda (flag)
1504    (let ((default (ly:flag::calc-x-offset flag)))
1505      (* default 4.0)))
1506  c''4. d8 a4. g8
1507@}
1508@end example
1509
1510La valeur par défaut est aussi accessible à l'aide de la fonction
1511@code{grob-transformer} :
1512
1513@lilypond[verbatim,quote]
1514\relative {
1515  \override Flag.X-offset = #(grob-transformer 'X-offset
1516    (lambda (flag default) (* default 4.0)))
1517  c''4. d8 a4. g8
1518}
1519@end lilypond
1520
1521Au sein d'un @emph{callback}, le meilleur moyen d'évaluer un
1522@emph{markup} consiste à utiliser la fonction
1523@code{grob-interpret-markup}, comme ici :
1524
1525@example
1526my-callback = #(lambda (grob)
1527                 (grob-interpret-markup grob (markup "foo")))
1528@end example
1529
1530
1531@ignore
1532@n ode Code Scheme intégré
1533@s ection Code Scheme intégré
1534@t ranslationof Inline Scheme code
1535
1536À REVOIR : depuis la rédaction de cette section, LilyPond en est
1537arrivé à un point tel que trouver un exemple @emph{simple} où l'on se
1538retrouve obligé d'en venir à utiliser du code Scheme devient chose
1539ardue.
1540
1541En attendant un remaniement de cette section, faisons comme si nous
1542l'ignorions.
1543
1544L'inconvénient principal de la commande @code{\tweak} est la rigidité de
1545sa syntaxe.  Par exemple, le code suivant produit une erreur de syntaxe
1546(du moins, c'était le cas auparavant).
1547
1548@example
1549F = \tweak font-size #-3 -\flageolet
1550
1551\relative @{
1552  c''4^\F c4_\F
1553@}
1554@end example
1555
1556@noindent
1557C'est en se servant du langage Scheme que l'on peut résoudre ce
1558problème.  Dans cet exemple, on a recours aux méthodes décrites dans
1559@ref{Ajout d'articulation à des notes (exemple)}, en
1560particulier quant à l'emploi de @code{\displayMusic}.
1561
1562@example
1563F = #(let ((m (make-music 'ArticulationEvent
1564                          'articulation-type "flageolet")))
1565       (set! (ly:music-property m 'tweaks)
1566             (acons 'font-size -3
1567                    (ly:music-property m 'tweaks)))
1568       m)
1569
1570\relative @{
1571  c''4^\F c4_\F
1572@}
1573@end example
1574
1575@noindent
1576Ici les propriétés @code{tweak} de l'objet flageolet nommé @samp{m}
1577(créé au moyen de @code{make-music}) sont extraites par
1578@code{ly:music-property}, une nouvelle valeur de la taille de fonte
1579est ajoutée à la liste de ses propriétés (grâce à la fonction Scheme
1580@code{acons}), et le résultat de cette opération est renvoyé par
1581@code{set!}.  Le dernier élément, dans ce bloc @code{let}, est la valeur
1582finale de @samp{m} lui-même.
1583
1584@end ignore
1585
1586
1587@node Retouches complexes
1588@section Retouches complexes
1589@translationof Difficult tweaks
1590
1591Certains réglages sont plus délicats que d'autres.
1592
1593@itemize
1594@item
1595L'un d'entre eux est l'apparence des objets dits « extenseurs »
1596(@emph{spanner}), qui s'étendent horizontalement, tels que les liaisons.
1597Si, en principe, un seul de ces objets est créé à la fois et peut donc
1598être modifié de façon habituelle, lorsque ces objets doivent enjamber un
1599changement de ligne, ils sont dupliqués au début du ou des systèmes
1600suivants.  Comme ces objets sont des clones de l'objet d'origine, ils en
1601héritent toutes les propriétés, y compris les éventuelles commandes
1602@code{\override}.
1603
1604En d'autres termes, une commande @code{\override} affecte toujours les
1605deux extrémités d'un objet @emph{spanner}.  Pour ne modifier que la
1606partie précédant ou suivant le changement de ligne, il faut intervenir
1607directement dans le processus de mise en page.
1608La fonction de rappel @code{after-line-breaking} contient toute
1609l'opération Scheme effectuée lorsque les sauts de lignes ont été
1610déterminés, et que des objets graphiques ont été divisés sur des
1611systèmes différents.
1612
1613Dans l'exemple suivant, on définit une nouvelle opération nommée
1614@code{my-callback}.  Cette opération
1615
1616@itemize
1617@item
1618détermine si l'objet a été divisé à l'occasion d'un changement de ligne
1619@item
1620dans l'affirmative, recherche les différents tronçons de l'objet
1621@item
1622vérifie si l'objet considéré est bien la deuxième moitié d'un objet
1623divisé
1624@item
1625dans l'affirmative, applique un espacement supplémentaire
1626(@code{extra-offset}).
1627@end itemize
1628
1629On ajoute cette procédure à l'objet @rinternals{Tie} (liaison de tenue),
1630de façon à ce que le deuxième tronçon d'une liaison divisée soit
1631rehaussé.
1632
1633@c KEEP LY
1634@lilypond[quote,verbatim,ragged-right]
1635#(define (my-callback grob)
1636   (let* (
1637          ;; l'objet a-t-il été divisé ?
1638          (orig (ly:grob-original grob))
1639
1640          ;; si oui, rechercher les tronçons frères (siblings)
1641          (siblings (if (ly:grob? orig)
1642                        (ly:spanner-broken-into orig)
1643                        '())))
1644
1645     (if (and (>= (length siblings) 2)
1646              (eq? (car (last-pair siblings)) grob))
1647         (ly:grob-set-property! grob 'extra-offset '(-2 . 5)))))
1648
1649\relative {
1650  \override Tie.after-line-breaking =
1651  #my-callback
1652  c''1 ~ \break
1653  c2 ~ 2
1654}
1655@end lilypond
1656
1657@noindent
1658Lorsque cette astuce va être appliquée, notre nouvelle fonction de
1659rappel @code{after-line-breaking} devra également appeler celle
1660d'origine (@code{after-line-breaking}), si elle existe.  Ainsi, pour
1661l'utiliser dans le cas d'un crescendo (objet @code{Hairpin}), il faudra
1662également appeler @code{ly:spanner::kill-zero-spanned-time}.
1663
1664
1665@item
1666Pour des raisons d'ordre technique, certains objets ne peuvent être
1667modifiés par @code{\override}.  Parmi ceux-là, les objets
1668@code{NonMusicalPaperColumn} et @code{PaperColumn}.  La commande
1669@code{\overrideProperty} sert à les modifier, de façon similaire à
1670@code{\once \override}, mais avec une syntaxe différente :
1671
1672@example
1673\overrideProperty
1674Score.NonMusicalPaperColumn      % Nom de l'objet
1675  . line-break-system-details    % Nom de la propriété
1676  . next-padding                 % Nom de la sous-propriété (optionnel)
1677  . #20                          % Valeur
1678@end example
1679
1680Notez toutefois que la commande @code{\override} peut tout de même être
1681appliquée à @code{NonMusicalPaperColumn} et @code{PaperColumn} dans un
1682bloc @code{\context}.
1683
1684@end itemize
1685
1686
1687@node Interfaces LilyPond Scheme
1688@chapter Interfaces LilyPond Scheme
1689@translationof LilyPond Scheme interfaces
1690
1691Ce chapitre aborde les différents outils fournis par LilyPond à
1692l'intention des programmeurs en Scheme désireux d'obtenir des
1693informations à partir et autour des fluxs de musique.
1694
1695TODO -- figure out what goes in here and how to organize it
1696