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